From 37c02ddee1add2bafdbe49ce12edb1adbe08e4f8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 14 Apr 2012 12:03:03 +0000 Subject: [PATCH 001/360] Camera tracking: revert changes made for texture buffer frame drawing. Will be applied as another cleaned-up patch. --- release/scripts/startup/bl_ui/space_clip.py | 2 - source/blender/blenloader/intern/readfile.c | 1 - source/blender/editors/include/ED_clip.h | 4 - .../blender/editors/space_clip/CMakeLists.txt | 1 - source/blender/editors/space_clip/SConscript | 2 +- source/blender/editors/space_clip/clip_draw.c | 42 ++--- .../blender/editors/space_clip/clip_editor.c | 150 ------------------ .../blender/editors/space_clip/space_clip.c | 3 - source/blender/makesdna/DNA_space_types.h | 3 - source/blender/makesrna/intern/rna_space.c | 5 - 10 files changed, 12 insertions(+), 201 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 51a1751bb00..f83c66dc991 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -606,8 +606,6 @@ class CLIP_PT_display(Panel): elif sc.mode == 'RECONSTRUCTION': col.prop(sc, "show_stable", text="Stable") - col.prop(sc, "use_texture_buffer") - clip = sc.clip if clip: col.label(text="Display Aspect Ratio:") diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index f82f10e83f5..e9a5dada044 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5385,7 +5385,6 @@ static void lib_link_screen(FileData *fd, Main *main) sclip->clip= newlibadr_us(fd, sc->id.lib, sclip->clip); sclip->scopes.track_preview = NULL; - sclip->draw_context = NULL; sclip->scopes.ok = 0; } } diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 8e3488203a2..5e8ef618a42 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -58,10 +58,6 @@ void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2]); void ED_clip_point_stable_pos(struct bContext *C, float x, float y, float *xr, float *yr); void ED_clip_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]); -void ED_space_clip_load_movieclip_buffer(struct SpaceClip *sc, struct ImBuf *ibuf); -void ED_space_clip_unload_movieclip_buffer(struct SpaceClip *sc); -void ED_space_clip_free_texture_buffer(struct SpaceClip *sc); - /* clip_ops.c */ void ED_operatormacros_clip(void); diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt index 30d2fe57c10..4f9819e8e77 100644 --- a/source/blender/editors/space_clip/CMakeLists.txt +++ b/source/blender/editors/space_clip/CMakeLists.txt @@ -31,7 +31,6 @@ set(INC ../../makesdna ../../makesrna ../../windowmanager - ../../gpu ../../../../intern/guardedalloc ${GLEW_INCLUDE_PATH} ) diff --git a/source/blender/editors/space_clip/SConscript b/source/blender/editors/space_clip/SConscript index c9c82aea68e..70331b0ec4a 100644 --- a/source/blender/editors/space_clip/SConscript +++ b/source/blender/editors/space_clip/SConscript @@ -4,6 +4,6 @@ Import ('env') sources = env.Glob('*.c') defs = [] incs = '../include ../../blenkernel ../../blenloader ../../blenfont ../../blenlib ../../imbuf ../../makesdna' -incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew/include ../../gpu' +incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew/include' env.BlenderLib ( 'bf_editors_space_clip', sources, Split(incs), defs, libtype=['core'], priority=[95] ) diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 418b72dc944..2f9956fc143 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -229,6 +229,9 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, int x, y; MovieClip *clip = ED_space_clip(sc); + /* set zoom */ + glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y); + /* find window pixel coordinates of origin */ UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); @@ -239,35 +242,8 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, else { verify_buffer_float(ibuf); - if(ibuf->rect) { - if(sc->flag & SC_TEXTURE_BUFFER) { - ED_space_clip_load_movieclip_buffer(sc, ibuf); - - glPushMatrix(); - glTranslatef(x, y, 0.0f); - glScalef(zoomx, zoomy, 1.0f); - - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); - glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f); - glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height); - glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height); - glEnd(); - - glPopMatrix(); - - ED_space_clip_unload_movieclip_buffer(sc); - } - else { - /* set zoom */ - glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y); - - glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); - - /* reset zoom */ - glPixelZoom(1.0f, 1.0f); - } - } + if (ibuf->rect) + glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); } /* draw boundary border for frame if stabilization is enabled */ @@ -279,9 +255,9 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, glLogicOp(GL_NOR); glPushMatrix(); - glTranslatef(x, y, 0.0f); + glTranslatef(x, y, 0); - glScalef(zoomx, zoomy, 1.0f); + glScalef(zoomx, zoomy, 0); glMultMatrixf(sc->stabmat); glBegin(GL_LINE_LOOP); @@ -296,6 +272,10 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, glDisable(GL_COLOR_LOGIC_OP); glDisable(GL_LINE_STIPPLE); } + + + /* reset zoom */ + glPixelZoom(1.0f, 1.0f); } static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track) diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index dcc4f66490a..3946d4cc36d 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -31,8 +31,6 @@ #include -#include "MEM_guardedalloc.h" - #include "BKE_main.h" #include "BKE_movieclip.h" #include "BKE_context.h" @@ -42,8 +40,6 @@ #include "BLI_utildefines.h" #include "BLI_math.h" -#include "GPU_extensions.h" - #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -51,7 +47,6 @@ #include "ED_clip.h" #include "BIF_gl.h" -#include "BIF_glutil.h" #include "WM_api.h" #include "WM_types.h" @@ -319,148 +314,3 @@ void ED_clip_mouse_pos(bContext *C, wmEvent *event, float co[2]) { ED_clip_point_stable_pos(C, event->mval[0], event->mval[1], &co[0], &co[1]); } - -/* OpenGL draw context */ - -typedef struct SpaceClipDrawContext { - GLuint texture; /* OGL texture ID */ - short texture_allocated; /* flag if texture was allocated by glGenTextures */ - struct ImBuf *texture_ibuf; /* image buffer for which texture was created */ - int image_width, image_height; /* image width and height for which texture was created */ - unsigned last_texture; /* ID of previously used texture, so it'll be restored after clip drawing */ - int framenr; -} SpaceClipDrawContext; - -void ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) -{ - SpaceClipDrawContext *context = sc->draw_context; - MovieClip *clip = ED_space_clip(sc); - int need_rebind = 0; - - if (!context) { - context = MEM_callocN(sizeof(SpaceClipDrawContext), "SpaceClipDrawContext"); - sc->draw_context = context; - } - - context->last_texture = glaGetOneInteger(GL_TEXTURE_2D); - - /* image texture need to be rebinded if displaying another image buffer - * assuming displaying happens of footage frames only on which painting doesn't heppen. - * so not changed image buffer pointer means unchanged image content */ - need_rebind |= context->texture_ibuf != ibuf; - need_rebind |= context->framenr != sc->user.framenr; - - if (need_rebind) { - int width = ibuf->x, height = ibuf->y; - float *frect = NULL, *fscalerect = NULL; - unsigned int *rect = NULL, *scalerect = NULL; - int need_recreate = 0; - - rect = ibuf->rect; - frect = ibuf->rect_float; - - /* if image resolution changed (e.g. switched to proxy display) texture need to be recreated */ - need_recreate = context->image_width != ibuf->x || context->image_height != ibuf->y; - - if (context->texture_ibuf && need_recreate) { - glDeleteTextures(1, &context->texture); - context->texture_allocated = 0; - } - -#if 0 - /* disabled for now because current tracking users have got NPOT textures - * working smoothly on their computers and forcing re-scaling during playback - * slows down playback a lot */ - - /* if videocard doesn't support NPOT textures, need to do rescaling */ - if (!GPU_non_power_of_two_support()) { - if (!is_power_of_2_i(width) || !is_power_of_2_i(height)) { - width = power_of_2_max_i(width); - height = power_of_2_max_i(height); - - if (ibuf->x != width || ibuf->y != height) { - if (frect) { - fscalerect= MEM_mallocN(width*width*sizeof(*fscalerect)*4, "fscalerect"); - gluScaleImage(GL_RGBA, ibuf->x, ibuf->y, GL_FLOAT, ibuf->rect_float, width, height, GL_FLOAT, fscalerect); - - frect = fscalerect; - } - else { - scalerect= MEM_mallocN(width*height*sizeof(*scalerect), "scalerect"); - gluScaleImage(GL_RGBA, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect, width, height, GL_UNSIGNED_BYTE, scalerect); - - rect = scalerect; - } - } - } - } -#endif - - if (need_recreate || !context->texture_allocated) { - /* texture doesn't exist yet or need to be re-allocated because of changed dimensions */ - int filter = GL_LINEAR; - - /* non-scaled proxy shouldn;t use diltering */ - if ((clip->flag & MCLIP_USE_PROXY) == 0 || - ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100)) - { - filter = GL_NEAREST; - } - - glGenTextures(1, &context->texture); - glBindTexture(GL_TEXTURE_2D, context->texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - } - else { - /* if texture doesn't need to be reallocated itself, just bind it so - * loading of image will happen to a proper texture */ - glBindTexture(GL_TEXTURE_2D, context->texture); - } - - if (frect) - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, width, height, 0, GL_RGBA, GL_FLOAT, frect); - else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect); - - /* store settings */ - context->texture_allocated = 1; - context->texture_ibuf = ibuf; - context->image_width = ibuf->x; - context->image_height = ibuf->y; - context->framenr = sc->user.framenr; - - if (fscalerect) - MEM_freeN(fscalerect); - if (scalerect) - MEM_freeN(scalerect); - } - else { - /* displaying exactly the same image which was loaded t oa texture, - * just bint texture in this case */ - glBindTexture(GL_TEXTURE_2D, context->texture); - } - - glEnable(GL_TEXTURE_2D); -} - -void ED_space_clip_unload_movieclip_buffer(SpaceClip *sc) -{ - SpaceClipDrawContext *context = sc->draw_context; - - glBindTexture(GL_TEXTURE_2D, context->last_texture); - glDisable(GL_TEXTURE_2D); -} - -void ED_space_clip_free_texture_buffer(SpaceClip *sc) -{ - SpaceClipDrawContext *context = sc->draw_context; - - if (context) { - glDeleteTextures(1, &context->texture); - - MEM_freeN(context); - } -} diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index ddd8c1b6947..228c716e3b6 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -214,8 +214,6 @@ static void clip_free(SpaceLink *sl) if (sc->scopes.track_preview) IMB_freeImBuf(sc->scopes.track_preview); - - ED_space_clip_free_texture_buffer(sc); } /* spacetype; init callback */ @@ -231,7 +229,6 @@ static SpaceLink *clip_duplicate(SpaceLink *sl) /* clear or remove stuff from old */ scn->scopes.track_preview = NULL; scn->scopes.ok = FALSE; - scn->draw_context= NULL; return (SpaceLink *)scn; } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index a05dd491b69..1938c63d474 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -523,8 +523,6 @@ typedef struct SpaceClip { int postproc_flag; int runtime_flag; /* different runtime flags */ - - void *draw_context; } SpaceClip; /* view3d Now in DNA_view3d_types.h */ @@ -906,7 +904,6 @@ enum { #define SC_SHOW_GRAPH_TRACKS (1<<15) /*#define SC_SHOW_PYRAMID_LEVELS (1<<16) */ /* UNUSED */ #define SC_LOCK_TIMECURSOR (1<<17) -#define SC_TEXTURE_BUFFER (1<<18) /* SpaceClip->mode */ #define SC_MODE_TRACKING 0 diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 7289a693820..5e0a20c51ad 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -3079,11 +3079,6 @@ static void rna_def_space_clip(BlenderRNA *brna) "for the selected tracks"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); - prop= RNA_def_property(srna, "use_texture_buffer", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_ui_text(prop, "Use Texture Buffer", "Use texture buffer to display o,age frames frame on screen"); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_TEXTURE_BUFFER); - RNA_def_property_update(prop, NC_WINDOW, NULL); - /* ** channels ** */ /* show_red_channel */ From c3218ebdff43ad60d9e01b5fa13768e8416d7bd7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 14 Apr 2012 12:03:09 +0000 Subject: [PATCH 002/360] Camera tracking: use texture buffers (if supported) to display clip editor frames Initial idea was to perform bilinear filtering for displaying proxied frame to make it looking a bit smoother. It was done but it was also discovered that using such kind of texture buffers helps on some crappy videocards when playing $k footage. --- source/blender/blenloader/intern/readfile.c | 1 + source/blender/editors/include/ED_clip.h | 5 + .../blender/editors/space_clip/CMakeLists.txt | 1 + source/blender/editors/space_clip/SConscript | 2 +- source/blender/editors/space_clip/clip_draw.c | 49 +++-- .../blender/editors/space_clip/clip_editor.c | 169 ++++++++++++++++++ .../blender/editors/space_clip/space_clip.c | 5 +- source/blender/makesdna/DNA_space_types.h | 1 + 8 files changed, 220 insertions(+), 13 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index e9a5dada044..f82f10e83f5 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5385,6 +5385,7 @@ static void lib_link_screen(FileData *fd, Main *main) sclip->clip= newlibadr_us(fd, sc->id.lib, sclip->clip); sclip->scopes.track_preview = NULL; + sclip->draw_context = NULL; sclip->scopes.ok = 0; } } diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 5e8ef618a42..4474ea7f281 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -58,6 +58,11 @@ void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2]); void ED_clip_point_stable_pos(struct bContext *C, float x, float y, float *xr, float *yr); void ED_clip_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]); +int ED_space_clip_texture_buffer_supported(struct SpaceClip *sc); +int ED_space_clip_load_movieclip_buffer(struct SpaceClip *sc, struct ImBuf *ibuf); +void ED_space_clip_unload_movieclip_buffer(struct SpaceClip *sc); +void ED_space_clip_free_texture_buffer(struct SpaceClip *sc); + /* clip_ops.c */ void ED_operatormacros_clip(void); diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt index 4f9819e8e77..30d2fe57c10 100644 --- a/source/blender/editors/space_clip/CMakeLists.txt +++ b/source/blender/editors/space_clip/CMakeLists.txt @@ -31,6 +31,7 @@ set(INC ../../makesdna ../../makesrna ../../windowmanager + ../../gpu ../../../../intern/guardedalloc ${GLEW_INCLUDE_PATH} ) diff --git a/source/blender/editors/space_clip/SConscript b/source/blender/editors/space_clip/SConscript index 70331b0ec4a..c9c82aea68e 100644 --- a/source/blender/editors/space_clip/SConscript +++ b/source/blender/editors/space_clip/SConscript @@ -4,6 +4,6 @@ Import ('env') sources = env.Glob('*.c') defs = [] incs = '../include ../../blenkernel ../../blenloader ../../blenfont ../../blenlib ../../imbuf ../../makesdna' -incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew/include' +incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew/include ../../gpu' env.BlenderLib ( 'bf_editors_space_clip', sources, Split(incs), defs, libtype=['core'], priority=[95] ) diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 2f9956fc143..0d519f36ba3 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -229,9 +229,6 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, int x, y; MovieClip *clip = ED_space_clip(sc); - /* set zoom */ - glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y); - /* find window pixel coordinates of origin */ UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); @@ -242,8 +239,42 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, else { verify_buffer_float(ibuf); - if (ibuf->rect) - glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + if (ibuf->rect) { + int need_fallback = 1; + + if (ED_space_clip_texture_buffer_supported(sc)) { + if (ED_space_clip_load_movieclip_buffer(sc, ibuf)) { + glPushMatrix(); + glTranslatef(x, y, 0.0f); + glScalef(zoomx, zoomy, 1.0f); + + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); + glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f); + glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height); + glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height); + glEnd(); + + glPopMatrix(); + + ED_space_clip_unload_movieclip_buffer(sc); + + need_fallback = 0; + } + } + + /* if texture buffers aren't efifciently supported or texture is too large to + * be binder fallback to simple draw pixels solution */ + if (need_fallback) { + /* set zoom */ + glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y); + + glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + + /* reset zoom */ + glPixelZoom(1.0f, 1.0f); + } + } } /* draw boundary border for frame if stabilization is enabled */ @@ -255,9 +286,9 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, glLogicOp(GL_NOR); glPushMatrix(); - glTranslatef(x, y, 0); + glTranslatef(x, y, 0.0f); - glScalef(zoomx, zoomy, 0); + glScalef(zoomx, zoomy, 1.0f); glMultMatrixf(sc->stabmat); glBegin(GL_LINE_LOOP); @@ -272,10 +303,6 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, glDisable(GL_COLOR_LOGIC_OP); glDisable(GL_LINE_STIPPLE); } - - - /* reset zoom */ - glPixelZoom(1.0f, 1.0f); } static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track) diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 3946d4cc36d..40be2622f95 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -31,6 +31,8 @@ #include +#include "MEM_guardedalloc.h" + #include "BKE_main.h" #include "BKE_movieclip.h" #include "BKE_context.h" @@ -40,6 +42,8 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "GPU_extensions.h" + #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -47,6 +51,7 @@ #include "ED_clip.h" #include "BIF_gl.h" +#include "BIF_glutil.h" #include "WM_api.h" #include "WM_types.h" @@ -314,3 +319,167 @@ void ED_clip_mouse_pos(bContext *C, wmEvent *event, float co[2]) { ED_clip_point_stable_pos(C, event->mval[0], event->mval[1], &co[0], &co[1]); } + +/* OpenGL draw context */ + +typedef struct SpaceClipDrawContext { + int support_checked, buffers_supported; + + GLuint texture; /* OGL texture ID */ + short texture_allocated; /* flag if texture was allocated by glGenTextures */ + struct ImBuf *texture_ibuf; /* image buffer for which texture was created */ + int image_width, image_height; /* image width and height for which texture was created */ + unsigned last_texture; /* ID of previously used texture, so it'll be restored after clip drawing */ + int framenr; +} SpaceClipDrawContext; + +int ED_space_clip_texture_buffer_supported(SpaceClip *sc) +{ + SpaceClipDrawContext *context = sc->draw_context; + + if (!context) { + context = MEM_callocN(sizeof(SpaceClipDrawContext), "SpaceClipDrawContext"); + sc->draw_context = context; + } + + if (!context->support_checked) { + context->support_checked = TRUE; + context->buffers_supported = GPU_non_power_of_two_support(); + } + + return context->buffers_supported; +} + +int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) +{ + SpaceClipDrawContext *context = sc->draw_context; + MovieClip *clip = ED_space_clip(sc); + int need_rebind = 0; + + context->last_texture = glaGetOneInteger(GL_TEXTURE_2D); + + /* image texture need to be rebinded if displaying another image buffer + * assuming displaying happens of footage frames only on which painting doesn't heppen. + * so not changed image buffer pointer means unchanged image content */ + need_rebind |= context->texture_ibuf != ibuf; + need_rebind |= context->framenr != sc->user.framenr; + + if (need_rebind) { + int width = ibuf->x, height = ibuf->y; + float *frect = NULL, *fscalerect = NULL; + unsigned int *rect = NULL, *scalerect = NULL; + int need_recreate = 0; + + if (width > GL_MAX_TEXTURE_SIZE || height > GL_MAX_TEXTURE_SIZE) + return 0; + + rect = ibuf->rect; + frect = ibuf->rect_float; + + /* if image resolution changed (e.g. switched to proxy display) texture need to be recreated */ + need_recreate = context->image_width != ibuf->x || context->image_height != ibuf->y; + + if (context->texture_ibuf && need_recreate) { + glDeleteTextures(1, &context->texture); + context->texture_allocated = 0; + } + +#if 0 + /* disabled for now because current tracking users have got NPOT textures + * working smoothly on their computers and forcing re-scaling during playback + * slows down playback a lot */ + + /* if videocard doesn't support NPOT textures, need to do rescaling */ + if (!GPU_non_power_of_two_support()) { + if (!is_power_of_2_i(width) || !is_power_of_2_i(height)) { + width = power_of_2_max_i(width); + height = power_of_2_max_i(height); + + if (ibuf->x != width || ibuf->y != height) { + if (frect) { + fscalerect= MEM_mallocN(width*width*sizeof(*fscalerect)*4, "fscalerect"); + gluScaleImage(GL_RGBA, ibuf->x, ibuf->y, GL_FLOAT, ibuf->rect_float, width, height, GL_FLOAT, fscalerect); + + frect = fscalerect; + } + else { + scalerect= MEM_mallocN(width*height*sizeof(*scalerect), "scalerect"); + gluScaleImage(GL_RGBA, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect, width, height, GL_UNSIGNED_BYTE, scalerect); + + rect = scalerect; + } + } + } + } +#endif + + if (need_recreate || !context->texture_allocated) { + /* texture doesn't exist yet or need to be re-allocated because of changed dimensions */ + int filter = GL_LINEAR; + + /* non-scaled proxy shouldn;t use diltering */ + if ((clip->flag & MCLIP_USE_PROXY) == 0 || + ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100)) + { + filter = GL_NEAREST; + } + + glGenTextures(1, &context->texture); + glBindTexture(GL_TEXTURE_2D, context->texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + } + else { + /* if texture doesn't need to be reallocated itself, just bind it so + * loading of image will happen to a proper texture */ + glBindTexture(GL_TEXTURE_2D, context->texture); + } + + if (frect) + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, width, height, 0, GL_RGBA, GL_FLOAT, frect); + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect); + + /* store settings */ + context->texture_allocated = 1; + context->texture_ibuf = ibuf; + context->image_width = ibuf->x; + context->image_height = ibuf->y; + context->framenr = sc->user.framenr; + + if (fscalerect) + MEM_freeN(fscalerect); + if (scalerect) + MEM_freeN(scalerect); + } + else { + /* displaying exactly the same image which was loaded t oa texture, + * just bint texture in this case */ + glBindTexture(GL_TEXTURE_2D, context->texture); + } + + glEnable(GL_TEXTURE_2D); + + return 1; +} + +void ED_space_clip_unload_movieclip_buffer(SpaceClip *sc) +{ + SpaceClipDrawContext *context = sc->draw_context; + + glBindTexture(GL_TEXTURE_2D, context->last_texture); + glDisable(GL_TEXTURE_2D); +} + +void ED_space_clip_free_texture_buffer(SpaceClip *sc) +{ + SpaceClipDrawContext *context = sc->draw_context; + + if (context) { + glDeleteTextures(1, &context->texture); + + MEM_freeN(context); + } +} diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 228c716e3b6..60322098250 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -214,6 +214,8 @@ static void clip_free(SpaceLink *sl) if (sc->scopes.track_preview) IMB_freeImBuf(sc->scopes.track_preview); + + ED_space_clip_free_texture_buffer(sc); } /* spacetype; init callback */ @@ -228,7 +230,8 @@ static SpaceLink *clip_duplicate(SpaceLink *sl) /* clear or remove stuff from old */ scn->scopes.track_preview = NULL; - scn->scopes.ok = FALSE; + scn->scopes.ok = 0; + scn->draw_context = NULL; return (SpaceLink *)scn; } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 1938c63d474..958e8b44b9d 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -523,6 +523,7 @@ typedef struct SpaceClip { int postproc_flag; int runtime_flag; /* different runtime flags */ + void *draw_context; } SpaceClip; /* view3d Now in DNA_view3d_types.h */ From ec4edb94d93fe3db7e0e16bdc341cfeabfe6690f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 14 Apr 2012 12:03:23 +0000 Subject: [PATCH 003/360] Camera tracking: initial commit of dopesheet view for clip editor: - Changed regions to use the whole main region for such views as curves and dopesheet. This allows to have own panels with tools/properties in this areas. - Active clip is getting synchronized between different clip editor editors in the same screen, so updating of curve/dopesheet views happens automatically when one changes current clip in one of this editors. - Curves and dopesheet are still using PREVIEW region type instead of re-using main region. - To deal with vertical synchronization in dopesheet, re-initialization of preview region happens. - Panels in toolbox and properties panels are now separated to rely on current view mode, some operators and poll functions still need to be updated. - Added new screen called "Movie Tracking" where layout is configured to display timeline, main clip window, curves and dopesheet. --- release/scripts/startup/bl_ui/space_clip.py | 208 +- .../blender/editors/datafiles/startup.blend.c | 19131 ++++++++-------- source/blender/editors/include/ED_clip.h | 3 +- source/blender/editors/interface/resources.c | 14 + .../blender/editors/space_clip/CMakeLists.txt | 16 +- .../blender/editors/space_clip/clip_buttons.c | 8 + .../editors/space_clip/clip_dopesheet_draw.c | 380 + .../editors/space_clip/clip_dopesheet_ops.c | 166 + .../blender/editors/space_clip/clip_editor.c | 27 +- .../editors/space_clip/clip_graph_draw.c | 58 +- .../editors/space_clip/clip_graph_ops.c | 10 +- .../blender/editors/space_clip/clip_intern.h | 26 + source/blender/editors/space_clip/clip_ops.c | 2 +- .../blender/editors/space_clip/clip_toolbar.c | 8 +- .../blender/editors/space_clip/clip_utils.c | 60 + .../blender/editors/space_clip/space_clip.c | 435 +- source/blender/makesdna/DNA_space_types.h | 5 +- source/blender/makesdna/DNA_tracking_types.h | 1 + source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/intern/rna_space.c | 10 +- source/blender/makesrna/intern/rna_userdef.c | 13 + 21 files changed, 11016 insertions(+), 9566 deletions(-) create mode 100644 source/blender/editors/space_clip/clip_dopesheet_draw.c create mode 100644 source/blender/editors/space_clip/clip_dopesheet_ops.c diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index f83c66dc991..fb84fa29cbc 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -38,19 +38,21 @@ class CLIP_HT_header(Header): sub = row.row(align=True) sub.menu("CLIP_MT_view") - if clip: - sub.menu("CLIP_MT_select") + if sc.view == 'CLIP': + if clip: + sub.menu("CLIP_MT_select") - sub.menu("CLIP_MT_clip") + sub.menu("CLIP_MT_clip") - if clip: - sub.menu("CLIP_MT_track") - sub.menu("CLIP_MT_reconstruction") + if clip: + sub.menu("CLIP_MT_track") + sub.menu("CLIP_MT_reconstruction") + + layout.prop(sc, "view", text="", expand=True) if clip: - layout.prop(sc, "mode", text="") - layout.prop(sc, "view", text="", expand=True) - + if sc.view == 'CLIP': + layout.prop(sc, "mode", text="") if sc.view == 'GRAPH': row = layout.row(align=True) @@ -79,24 +81,56 @@ class CLIP_HT_header(Header): else: r = tracking.reconstruction - if r.is_valid: + if r.is_valid and sc.view == 'CLIP': layout.label(text="Average solve error: %.4f" % (r.average_error)) layout.template_running_jobs() -class CLIP_PT_tools_marker(Panel): - bl_space_type = 'CLIP_EDITOR' - bl_region_type = 'TOOLS' - bl_label = "Marker" +class CLIP_PT_clip_view_panel: @classmethod def poll(cls, context): sc = context.space_data clip = sc.clip - return clip and sc.mode == 'TRACKING' + return clip and sc.view == 'CLIP' + +class CLIP_PT_tracking_panel: + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'TRACKING' and sc.view == 'CLIP' + + +class CLIP_PT_reconstruction_panel: + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'RECONSTRUCTION' and sc.view == 'CLIP' + + +class CLIP_PT_distortion_panel: + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'DISTORTION' and sc.view == 'CLIP' + + +class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Marker" def draw(self, context): sc = context.space_data @@ -162,18 +196,11 @@ class CLIP_PT_tools_marker(Panel): text="Copy From Active Track") -class CLIP_PT_tools_tracking(Panel): +class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' bl_label = "Track" - @classmethod - def poll(cls, context): - sc = context.space_data - clip = sc.clip - - return clip and sc.mode == 'TRACKING' - def draw(self, context): layout = self.layout @@ -201,18 +228,11 @@ class CLIP_PT_tools_tracking(Panel): layout.operator("clip.join_tracks", text="Join") -class CLIP_PT_tools_solve(Panel): +class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' bl_label = "Solve" - @classmethod - def poll(cls, context): - sc = context.space_data - clip = sc.clip - - return clip and sc.mode == 'TRACKING' - def draw(self, context): layout = self.layout clip = context.space_data.clip @@ -241,18 +261,11 @@ class CLIP_PT_tools_solve(Panel): col.prop(settings, "refine_intrinsics", text="") -class CLIP_PT_tools_cleanup(Panel): +class CLIP_PT_tools_cleanup(CLIP_PT_tracking_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' bl_label = "Clean up" - @classmethod - def poll(cls, context): - sc = context.space_data - clip = sc.clip - - return clip and sc.mode == 'TRACKING' - def draw(self, context): layout = self.layout clip = context.space_data.clip @@ -265,18 +278,11 @@ class CLIP_PT_tools_cleanup(Panel): layout.prop(settings, 'clean_action', text="") -class CLIP_PT_tools_geometry(Panel): +class CLIP_PT_tools_geometry(CLIP_PT_reconstruction_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' bl_label = "Geometry" - @classmethod - def poll(cls, context): - sc = context.space_data - clip = sc.clip - - return clip and sc.mode == 'RECONSTRUCTION' - def draw(self, context): layout = self.layout @@ -284,18 +290,11 @@ class CLIP_PT_tools_geometry(Panel): layout.operator("clip.track_to_empty") -class CLIP_PT_tools_orientation(Panel): +class CLIP_PT_tools_orientation(CLIP_PT_reconstruction_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' bl_label = "Orientation" - @classmethod - def poll(cls, context): - sc = context.space_data - clip = sc.clip - - return clip and sc.mode == 'RECONSTRUCTION' - def draw(self, context): sc = context.space_data layout = self.layout @@ -320,18 +319,19 @@ class CLIP_PT_tools_orientation(Panel): col.prop(settings, "distance") -class CLIP_PT_tools_object(Panel): +class CLIP_PT_tools_object(CLIP_PT_reconstruction_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' bl_label = "Object" @classmethod def poll(cls, context): - sc = context.space_data - clip = sc.clip + if CLIP_PT_reconstruction_panel.poll(context): + sc = context.space_data + clip = sc.clip - if clip and sc.mode == 'RECONSTRUCTION': tracking_object = clip.tracking.objects.active + return not tracking_object.is_camera return False @@ -354,18 +354,11 @@ class CLIP_PT_tools_object(Panel): col.prop(settings, "object_distance") -class CLIP_PT_tools_grease_pencil(Panel): +class CLIP_PT_tools_grease_pencil(CLIP_PT_distortion_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' bl_label = "Grease Pencil" - @classmethod - def poll(cls, context): - sc = context.space_data - clip = sc.clip - - return clip and sc.mode == 'DISTORTION' - def draw(self, context): layout = self.layout @@ -383,18 +376,12 @@ class CLIP_PT_tools_grease_pencil(Panel): row.prop(context.tool_settings, "use_grease_pencil_sessions") -class CLIP_PT_objects(Panel): +class CLIP_PT_objects(CLIP_PT_clip_view_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' bl_label = "Objects" bl_options = {'DEFAULT_CLOSED'} - @classmethod - def poll(cls, context): - sc = context.space_data - - return sc.clip - def draw(self, context): layout = self.layout @@ -415,18 +402,11 @@ class CLIP_PT_objects(Panel): layout.prop(active, "name") -class CLIP_PT_track(Panel): +class CLIP_PT_track(CLIP_PT_tracking_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' bl_label = "Track" - @classmethod - def poll(cls, context): - sc = context.space_data - clip = sc.clip - - return sc.mode == 'TRACKING' and clip - def draw(self, context): layout = self.layout sc = context.space_data @@ -482,18 +462,12 @@ class CLIP_PT_track(Panel): layout.label(text=label_text) -class CLIP_PT_track_settings(Panel): +class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' bl_label = "Tracking Settings" bl_options = {'DEFAULT_CLOSED'} - @classmethod - def poll(cls, context): - sc = context.space_data - - return sc.mode == 'TRACKING' and sc.clip - def draw(self, context): layout = self.layout clip = context.space_data.clip @@ -525,9 +499,12 @@ class CLIP_PT_tracking_camera(Panel): @classmethod def poll(cls, context): - sc = context.space_data + if CLIP_PT_clip_view_panel.poll(context): + sc = context.space_data - return sc.mode in {'TRACKING', 'DISTORTION'} and sc.clip + return sc.mode in {'TRACKING', 'DISTORTION'} and sc.clip + + return False def draw(self, context): layout = self.layout @@ -568,7 +545,7 @@ class CLIP_PT_tracking_camera(Panel): col.prop(clip.tracking.camera, "k3") -class CLIP_PT_display(Panel): +class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' bl_label = "Display" @@ -613,7 +590,7 @@ class CLIP_PT_display(Panel): row.prop(clip, "display_aspect", text="") -class CLIP_PT_marker_display(Panel): +class CLIP_PT_marker_display(CLIP_PT_clip_view_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' bl_label = "Marker Display" @@ -636,18 +613,12 @@ class CLIP_PT_marker_display(Panel): row.prop(sc, "path_length", text="Length") -class CLIP_PT_stabilization(Panel): +class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' bl_label = "2D Stabilization" bl_options = {'DEFAULT_CLOSED'} - @classmethod - def poll(cls, context): - sc = context.space_data - - return sc.mode == 'RECONSTRUCTION' and sc.clip - def draw_header(self, context): stab = context.space_data.clip.tracking.stabilization @@ -695,19 +666,12 @@ class CLIP_PT_stabilization(Panel): layout.prop(stab, "filter_type") -class CLIP_PT_marker(Panel): +class CLIP_PT_marker(CLIP_PT_tracking_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' bl_label = "Marker" bl_options = {'DEFAULT_CLOSED'} - @classmethod - def poll(cls, context): - sc = context.space_data - clip = sc.clip - - return sc.mode == 'TRACKING' and clip - def draw(self, context): layout = self.layout sc = context.space_data @@ -721,18 +685,12 @@ class CLIP_PT_marker(Panel): layout.label(text="No active track") -class CLIP_PT_proxy(Panel): +class CLIP_PT_proxy(CLIP_PT_clip_view_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' bl_label = "Proxy / Timecode" bl_options = {'DEFAULT_CLOSED'} - @classmethod - def poll(cls, context): - sc = context.space_data - - return sc.clip - def draw_header(self, context): sc = context.space_data @@ -782,18 +740,12 @@ class CLIP_PT_proxy(Panel): col.prop(sc.clip_user, "use_render_undistorted") -class CLIP_PT_footage(Panel): +class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' bl_label = "Footage Settings" bl_options = {'DEFAULT_CLOSED'} - @classmethod - def poll(cls, context): - sc = context.space_data - - return sc.clip - def draw(self, context): layout = self.layout @@ -806,17 +758,11 @@ class CLIP_PT_footage(Panel): layout.operator("clip.open", icon='FILESEL') -class CLIP_PT_tools_clip(Panel): +class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' bl_label = "Clip" - @classmethod - def poll(cls, context): - sc = context.space_data - - return sc.clip - def draw(self, context): layout = self.layout @@ -829,6 +775,10 @@ class CLIP_MT_view(Menu): def draw(self, context): layout = self.layout + sc = context.space_data + + layout.prop(sc, "show_seconds") + layout.separator() layout.operator("clip.properties", icon='MENU_PANEL') layout.operator("clip.tools", icon='MENU_PANEL') diff --git a/source/blender/editors/datafiles/startup.blend.c b/source/blender/editors/datafiles/startup.blend.c index 177fe320ed7..f2ea7d8bbd5 100644 --- a/source/blender/editors/datafiles/startup.blend.c +++ b/source/blender/editors/datafiles/startup.blend.c @@ -1,12 +1,12 @@ /* DataToC output of file */ -int datatoc_startup_blend_size= 358796; -char datatoc_startup_blend[]= { - 66, 76, 69, 78, 68, 69, 82, 45,118, 50, 54, 50, - 82, 69, 78, 68, 32, 0, 0, 0, 56,211, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, - 83, 99,101,110,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 76, 79, 66, 48, 4, 0, 0, -224,206, 35, 0, 0, 0, 0, 0,216, 0, 0, 0, 1, 0, 0, 0, 32, 32, 32, 51, 3, 0, 0, 0,250, 0, 0, 0, 1, 0, 0, 1, -248, 9,215, 3, 0, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 0, 16, 0, 0,128, 32, 4, 0,126,176, 0, 0, 0, 0, 0, 0, +int datatoc_startup_blend_size = 375344; +char datatoc_startup_blend[] = { + 66, 76, 69, 78, 68, 69, 82, 45,118, 50, 54, 50, 82, 69, 78, 68, + 32, 0, 0, 0, 64,202, 23,183,255,127, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 83, 99,101,110, +101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 76, 79, 66, 48, 4, 0, 0, 48,198, 23,183, +255,127, 0, 0,216, 0, 0, 0, 1, 0, 0, 0, 32, 32, 32, 51, 3, 0, 0, 0,250, 0, 0, 0, 1, 0, 0, 1,248,163,195, 6, + 0, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 16, 0, 0,128, 32, 4, 0, 53,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -38,5102 +38,133 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 87, 77, 0, 0, 88, 1, 0, 0, 8, 78,210, 3, 0, 0, 0, 0,146, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 77, 87,105,110, 77, 97,110, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,122,199, 3, 0, 0, 0, 0, 56,122,199, 3, 0, 0, 0, 0, - 56,122,199, 3, 0, 0, 0, 0, 56,122,199, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,232, 89,178, 3, 0, 0, 0, 0, -120, 93,178, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 60,171, 3, 0, 0, 0, 0, -104,164,152, 15, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 58,171, 3, 0, 0, 0, 0,120, 58,171, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 86,178, 3, 0, 0, 0, 0,184, 88,178, 3, 0, 0, 0, 0, - 88, 86,178, 3, 0, 0, 0, 0,136, 87,178, 3, 0, 0, 0, 0,184, 88,178, 3, 0, 0, 0, 0,232,255,210, 3, 0, 0, 0, 0, -232,255,210, 3, 0, 0, 0, 0,232,255,210, 3, 0, 0, 0, 0, 68, 65, 84, 65, 0, 1, 0, 0, 56,122,199, 3, 0, 0, 0, 0, -147, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93,198, 3, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0,248, 9,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,115, 99,114,101,101,110, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 0, 70, 5,178, 2, - 0, 0, 0, 0, 1, 0,238, 3, 0, 0, 0, 0, 1, 0, 0, 0,152,127,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,136, 39,205, 15, 0, 0, 0, 0,152, 0,212, 15, 0, 0, 0, 0, -168,255,211, 15, 0, 0, 0, 0,104, 12,163, 3, 0, 0, 0, 0, 56, 9,163, 3, 0, 0, 0, 0, 88, 11,163, 3, 0, 0, 0, 0, - 88, 11,163, 3, 0, 0, 0, 0,152, 84,171, 3, 0, 0, 0, 0,120,149,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0, 8, 1, 0, 0,136, 7,214, 3, 0, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0, - 8,156,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 83, 82, 65,110,105,109, 97,116,105,111,110, 0, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 9,201, 3, 0, 0, 0, 0, - 72, 20,201, 3, 0, 0, 0, 0,184, 88,171, 3, 0, 0, 0, 0,248,107,171, 3, 0, 0, 0, 0, 24, 9,214, 3, 0, 0, 0, 0, -248,150,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,168, 9,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, - 72, 10,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0, 72, 10,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,232, 10,201, 3, 0, 0, 0, 0, -168, 9,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,222, 2, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -232, 10,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,136, 11,201, 3, 0, 0, 0, 0, 72, 10,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,240, 4,222, 2, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,136, 11,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0, 40, 12,201, 3, 0, 0, 0, 0,232, 10,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 4, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 40, 12,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, -200, 12,201, 3, 0, 0, 0, 0,136, 11,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195, 2, 1, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0,200, 12,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,104, 13,201, 3, 0, 0, 0, 0, - 40, 12,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4,195, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -104, 13,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 8, 14,201, 3, 0, 0, 0, 0,200, 12,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 24, 4, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8, 14,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0,168, 14,201, 3, 0, 0, 0, 0,104, 13,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 24, 4,195, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,168, 14,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, - 72, 15,201, 3, 0, 0, 0, 0, 8, 14,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 4, 60, 1, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0, 72, 15,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,232, 15,201, 3, 0, 0, 0, 0, -168, 14,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 60, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -232, 15,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,136, 16,201, 3, 0, 0, 0, 0, 72, 15,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,136, 16,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0, 40, 17,201, 3, 0, 0, 0, 0,232, 15,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 24, 4, 88, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 40, 17,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, -200, 17,201, 3, 0, 0, 0, 0,136, 16,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 1, 88, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0,200, 17,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,104, 18,201, 3, 0, 0, 0, 0, - 40, 17,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 1,195, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -104, 18,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 8, 19,201, 3, 0, 0, 0, 0,200, 17,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8, 19,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0,168, 19,201, 3, 0, 0, 0, 0,104, 18,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 1, 4, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,168, 19,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, - 72, 20,201, 3, 0, 0, 0, 0, 8, 19,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 4, 60, 2, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0, 72, 20,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168, 19,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 60, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -184, 88,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104, 89,171, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 72, 10,201, 3, 0, 0, 0, 0,232, 10,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -104, 89,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24, 90,171, 3, 0, 0, 0, 0,184, 88,171, 3, 0, 0, 0, 0, - 72, 10,201, 3, 0, 0, 0, 0, 40, 12,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 24, 90,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200, 90,171, 3, 0, 0, 0, 0,104, 89,171, 3, 0, 0, 0, 0, -232, 10,201, 3, 0, 0, 0, 0,200, 12,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -200, 90,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120, 91,171, 3, 0, 0, 0, 0, 24, 90,171, 3, 0, 0, 0, 0, - 40, 12,201, 3, 0, 0, 0, 0,200, 12,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -120, 91,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40, 92,171, 3, 0, 0, 0, 0,200, 90,171, 3, 0, 0, 0, 0, -168, 9,201, 3, 0, 0, 0, 0,104, 13,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 40, 92,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216, 92,171, 3, 0, 0, 0, 0,120, 91,171, 3, 0, 0, 0, 0, -136, 11,201, 3, 0, 0, 0, 0,104, 13,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -216, 92,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,136, 93,171, 3, 0, 0, 0, 0, 40, 92,171, 3, 0, 0, 0, 0, -200, 12,201, 3, 0, 0, 0, 0, 8, 14,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -136, 93,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56, 94,171, 3, 0, 0, 0, 0,216, 92,171, 3, 0, 0, 0, 0, -104, 13,201, 3, 0, 0, 0, 0,168, 14,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 56, 94,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232, 94,171, 3, 0, 0, 0, 0,136, 93,171, 3, 0, 0, 0, 0, -136, 11,201, 3, 0, 0, 0, 0, 72, 15,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -232, 94,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152, 95,171, 3, 0, 0, 0, 0, 56, 94,171, 3, 0, 0, 0, 0, -168, 14,201, 3, 0, 0, 0, 0, 72, 15,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -152, 95,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72, 96,171, 3, 0, 0, 0, 0,232, 94,171, 3, 0, 0, 0, 0, -168, 9,201, 3, 0, 0, 0, 0,232, 15,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 72, 96,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,248, 96,171, 3, 0, 0, 0, 0,152, 95,171, 3, 0, 0, 0, 0, - 8, 14,201, 3, 0, 0, 0, 0,136, 16,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -248, 96,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168, 97,171, 3, 0, 0, 0, 0, 72, 96,171, 3, 0, 0, 0, 0, -104, 13,201, 3, 0, 0, 0, 0,136, 16,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -168, 97,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88, 98,171, 3, 0, 0, 0, 0,248, 96,171, 3, 0, 0, 0, 0, -232, 15,201, 3, 0, 0, 0, 0,136, 16,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 88, 98,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8, 99,171, 3, 0, 0, 0, 0,168, 97,171, 3, 0, 0, 0, 0, -232, 15,201, 3, 0, 0, 0, 0, 40, 17,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 8, 99,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184, 99,171, 3, 0, 0, 0, 0, 88, 98,171, 3, 0, 0, 0, 0, -136, 16,201, 3, 0, 0, 0, 0, 40, 17,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -184, 99,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104,100,171, 3, 0, 0, 0, 0, 8, 99,171, 3, 0, 0, 0, 0, - 40, 12,201, 3, 0, 0, 0, 0,200, 17,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -104,100,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24,101,171, 3, 0, 0, 0, 0,184, 99,171, 3, 0, 0, 0, 0, - 8, 14,201, 3, 0, 0, 0, 0,200, 17,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 24,101,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200,101,171, 3, 0, 0, 0, 0,104,100,171, 3, 0, 0, 0, 0, - 40, 17,201, 3, 0, 0, 0, 0,200, 17,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -200,101,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120,102,171, 3, 0, 0, 0, 0, 24,101,171, 3, 0, 0, 0, 0, -232, 15,201, 3, 0, 0, 0, 0,104, 18,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -120,102,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40,103,171, 3, 0, 0, 0, 0,200,101,171, 3, 0, 0, 0, 0, - 40, 17,201, 3, 0, 0, 0, 0, 8, 19,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 40,103,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216,103,171, 3, 0, 0, 0, 0,120,102,171, 3, 0, 0, 0, 0, -104, 18,201, 3, 0, 0, 0, 0, 8, 19,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -216,103,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,136,104,171, 3, 0, 0, 0, 0, 40,103,171, 3, 0, 0, 0, 0, -168, 14,201, 3, 0, 0, 0, 0,168, 19,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -136,104,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56,105,171, 3, 0, 0, 0, 0,216,103,171, 3, 0, 0, 0, 0, - 8, 14,201, 3, 0, 0, 0, 0,168, 19,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 56,105,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232,105,171, 3, 0, 0, 0, 0,136,104,171, 3, 0, 0, 0, 0, -200, 12,201, 3, 0, 0, 0, 0, 72, 20,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -232,105,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152,106,171, 3, 0, 0, 0, 0, 56,105,171, 3, 0, 0, 0, 0, - 72, 15,201, 3, 0, 0, 0, 0, 72, 20,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -152,106,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72,107,171, 3, 0, 0, 0, 0,232,105,171, 3, 0, 0, 0, 0, -168, 19,201, 3, 0, 0, 0, 0, 72, 20,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 72,107,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,248,107,171, 3, 0, 0, 0, 0,152,106,171, 3, 0, 0, 0, 0, - 40, 12,201, 3, 0, 0, 0, 0,104, 18,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -248,107,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,107,171, 3, 0, 0, 0, 0, -200, 17,201, 3, 0, 0, 0, 0, 8, 19,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, - 24, 9,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 56, 10,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40, 12,201, 3, 0, 0, 0, 0, 72, 10,201, 3, 0, 0, 0, 0,232, 10,201, 3, 0, 0, 0, 0,200, 12,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0,196, 2, 0, 0,222, 2, 0, 0, 7, 7,241, 4, 27, 0, 1, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,197,207, 3, 0, 0, 0, 0,152,197,207, 3, 0, 0, 0, 0, -136,221,175, 3, 0, 0, 0, 0, 56,223,175, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136,221,175, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 56,223,175, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,148, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 32,158, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0, 0,158, 68, 0, 0,200, 65, 0, 0,158, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,241, 4, 26, 0,241, 4, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0,196, 2, 0, 0,221, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,241, 4, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 56,223,175, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,221,175, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,109, 69, - 0, 0,128,192, 0, 0, 0, 0, 0, 0, 0, 0,255,255,109, 69, 0, 0, 0,192, 0, 0, 0, 0,112, 7, 0, 0,129, 7, 0, 0, - 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, - 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 2, 0, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, 10, 0,129, 7, 2, 0,112, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,222, 2, 0, 0,222, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 56, 10,214, 3, 0, 0, 0, 0, -214, 0, 0, 0, 1, 0, 0, 0, 88, 11,214, 3, 0, 0, 0, 0, 24, 9,214, 3, 0, 0, 0, 0,104, 13,201, 3, 0, 0, 0, 0, -168, 14,201, 3, 0, 0, 0, 0, 72, 15,201, 3, 0, 0, 0, 0,136, 11,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 25, 4, 0, 0,240, 4, 0, 0, 0, 0, 0, 0, 59, 1, 0, 0, 4, 4,216, 0, 60, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,184,123,199, 3, 0, 0, 0, 0,184,123,199, 3, 0, 0, 0, 0,232,224,175, 3, 0, 0, 0, 0, -152,226,175, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,232,224,175, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, -152,226,175, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,148, 67, 0, 0, 0, 0, 0, 0,208, 65, - 98, 39, 38, 54, 0, 0, 88, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, - 0, 0, 87, 67, 0, 0,200, 65, 0, 0, 87, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, - 4, 0, 12, 0, 10, 0,216, 0, 26, 0,216, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 25, 4, 0, 0,240, 4, 0, 0, 34, 1, 0, 0, 59, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -216, 0, 26, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,152,226,175, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,232,224,175, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 67, 0, 0, 61,196, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 71, 67, 1, 0,145,195, 0, 0, 0, 0,199, 0, 0, 0,216, 0, 0, 0, 0, 0, 0, 0, 33, 1, 0, 0, - 0, 0, 0, 0, 62, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,198, 0, 0, 0, 0, 0, 0, 0, 33, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 1, 0, 0, 1, 0, 7, 0, - 18, 0, 0, 4, 6, 0,216, 0, 34, 1,199, 0, 34, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 25, 4, 0, 0,240, 4, 0, 0, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -216, 0, 34, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 51,214, 3, 0, 0, 0, 0, -216, 71,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 56, 51,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, - 24, 53,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 67,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,220,255,199, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, - 24, 53,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,248, 54,214, 3, 0, 0, 0, 0, 56, 51,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,255,199, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,248, 54,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, -216, 56,214, 3, 0, 0, 0, 0, 24, 53,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 76, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,111,255,199, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, -216, 56,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,184, 58,214, 3, 0, 0, 0, 0,248, 54,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115, -105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115, -105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,254,199, 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,184, 58,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, -152, 60,214, 3, 0, 0, 0, 0,216, 56,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 65,110,116,105, 45, 65,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 58,254,199, 0, 58, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, -152, 60,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,120, 62,214, 3, 0, 0, 0, 0,184, 58,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, - 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, - 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 97,109,112,108,101,100, 32, 77,111,116,105,111,110, 32, 66, -108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,254,199, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,120, 62,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, - 88, 64,214, 3, 0, 0, 0, 0,152, 60,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 83,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 10,254,199, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, - 88, 64,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 56, 66,214, 3, 0, 0, 0, 0,120, 62,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114, -109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114, -109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,242,253,199, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 56, 66,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, - 24, 68,214, 3, 0, 0, 0, 0, 88, 64,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 80,111,115,116, 32, 80,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,218,253,199, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, - 24, 68,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,248, 69,214, 3, 0, 0, 0, 0, 56, 66,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194,253,199, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,248, 69,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, -216, 71,214, 3, 0, 0, 0, 0, 24, 68,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 79,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 40,253,199, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, -216, 71,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 69,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,253,199, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,184,123,199, 3, 0, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 21, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, - 88, 11,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,120, 12,214, 3, 0, 0, 0, 0, 56, 10,214, 3, 0, 0, 0, 0, -168, 9,201, 3, 0, 0, 0, 0,232, 15,201, 3, 0, 0, 0, 0,136, 16,201, 3, 0, 0, 0, 0,104, 13,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 15, 15, 24, 4, 88, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 92,200, 3, 0, 0, 0, 0,216, 92,200, 3, 0, 0, 0, 0, - 72,228,175, 3, 0, 0, 0, 0,248,229,175, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72,228,175, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0,248,229,175, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,140, 68, - 0, 0, 0, 0, 0, 0,208, 65, 39,182,158, 55, 0, 0,131, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,224,130, 68, 0, 0,200, 65, 0,224,130, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 24, 4, 26, 0, 24, 4, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 24, 4, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248,229,175, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,228,175, 3, 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67, - 0, 0, 0, 0, 0, 0, 72, 66,112,189, 17,192,246, 70,125, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, - 18, 0, 0, 0, 61, 0, 0, 0, 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65, - 72, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 4, 8, 0, 24, 4, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 26, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 24, 4, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0,216, 92,200, 3, 0, 0, 0, 0, -190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, -120, 12,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 40, 14,214, 3, 0, 0, 0, 0, 88, 11,214, 3, 0, 0, 0, 0, -168, 14,201, 3, 0, 0, 0, 0,168, 19,201, 3, 0, 0, 0, 0, 72, 20,201, 3, 0, 0, 0, 0, 72, 15,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 61, 1, 0, 0, 59, 2, 0, 0, 3, 3,216, 0,255, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,255,208, 3, 0, 0, 0, 0, 40,255,208, 3, 0, 0, 0, 0, -168,231,175, 3, 0, 0, 0, 0, 88,233,175, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168,231,175, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 88,233,175, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,244, 67, - 0, 0, 0, 0, 0, 0,208, 65, 98, 39, 38, 54, 0, 0, 88, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 0, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 87, 67, 0, 0,200, 65, 0, 0, 87, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,216, 0, 26, 0,216, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 34, 2, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,216, 0, 26, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88,233,175, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,231,175, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,141, 67, - 0, 0,244,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 67, 0, 0, 83,195, 0, 0, 0, 0,199, 0, 0, 0,216, 0, 0, 0, - 18, 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 0,198, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,198, 0, 0, 0, - 18, 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 18, 2, 0, 0, 2, 0, 3, 3, 0, 0, 12, 4, 6, 0,216, 0,229, 0,199, 0,211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 61, 1, 0, 0, 33, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,216, 0,229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 1, 0, 0, 40,255,208, 3, 0, 0, 0, 0, -183, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -152, 13,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 68, 65, 84, 65, 16, 0, 0, 0,152, 13,214, 3, 0, 0, 0, 0,237, 0, 0, 0, 1, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, -248, 30,199, 3, 0, 0, 0, 0, 68, 65, 84, 65,224, 0, 0, 0,248, 30,199, 3, 0, 0, 0, 0,236, 0, 0, 0, 14, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, 19, 0, 0, 0, 1, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, - 20, 0, 0, 0, 1, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, 21, 0, 1, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0, 24, 51,163, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,184,219,217, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0,136, 48,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,152, 7,218, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0,216, 29,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,168,225,217, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0,120,209,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,200,213,217, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0, 24, 98,200, 3, 0, 0, 0, 0, 21, 0, 0, 0, 1, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, - 68, 65, 84, 65,160, 0, 0, 0, 40, 14,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 72, 15,214, 3, 0, 0, 0, 0, -120, 12,214, 3, 0, 0, 0, 0, 40, 17,201, 3, 0, 0, 0, 0,200, 17,201, 3, 0, 0, 0, 0, 8, 14,201, 3, 0, 0, 0, 0, -136, 16,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 1, 0, 0, 23, 4, 0, 0, 89, 0, 0, 0,194, 2, 0, 0, - 1, 1, 87, 2,106, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 73,214, 3, 0, 0, 0, 0, -184, 73,214, 3, 0, 0, 0, 0, 8,235,175, 3, 0, 0, 0, 0, 72, 88,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, - 8,235,175, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 56, 83,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 64,113, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,192, 21, 68, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 86, 2, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128, 21, 68, 0, 0,200, 65, 0,128, 21, 68, 0, 0,200, 65, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 87, 2, 26, 0, 87, 2, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 1, 0, 0, 23, 4, 0, 0, 89, 0, 0, 0,114, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 2, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, - 56, 83,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,232, 84,214, 3, 0, 0, 0, 0, 8,235,175, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 67, 0, 64, 70,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67,255,127, 70,196, 0, 0, 0, 0, -143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0, 44, 3,143, 0, 26, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 1, 0, 0,193, 1, 0, 0,115, 0, 0, 0,194, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 80, 2, 0, 0, 5, 0, 3, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -232, 84,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,152, 86,214, 3, 0, 0, 0, 0, 56, 83,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 16, 67, 0, 0,206,194, 0, 0, 0, 0, 0, 0, 0, 0,231,102, 16, 67, 0, 0,206,194, 0, 0, 0, 0, -143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,120, 0,143, 0,102, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 1, 0, 0,193, 1, 0, 0,115, 0, 0, 0,115, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 6, 0, 34, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -152, 86,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 72, 88,214, 3, 0, 0, 0, 0,232, 84,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 35, 67, 0,128, 96,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, 0,128, 96,196, 0, 0, 0, 0, -163, 0, 0, 0,180, 0, 0, 0, 18, 0, 0, 0,147, 3, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0,162, 0, 0, 0, 18, 0, 0, 0,147, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,180, 0,148, 3,163, 0,130, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 23, 4, 0, 0,115, 0, 0, 0,194, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, - 72, 88,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 86,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 1, 0, 0, 23, 4, 0, 0,115, 0, 0, 0,194, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 2, 80, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,115,214, 3, 0, 0, 0, 0, 68, 65, 84, 65,112, 3, 0, 0, - 8,115,214, 3, 0, 0, 0, 0,173, 0, 0, 0, 1, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,200,167,141, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 13,128,191, 0, 0,128,191, - 0, 0, 0, 0, 0, 0, 0, 0, 74,215, 76,190, 0, 0, 0, 0, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, 0, 0, 0, 0, - 70,119,105, 63,143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,214,211,111,193, 0, 0,128, 63, 69,239,209, 62, 70,119,105, 63,176, 84, 89,188, 0, 0, 0, 0, - 53,177,205,190,142, 74, 70, 62,166, 33,101, 63, 0, 0, 0, 0,185,158, 81, 63, 35, 44,185,190, 43, 61,228, 62, 0, 0, 0, 0, -164, 96, 68, 65,111,121,173,192,248,209,213, 64, 0, 0,128, 63,178,157,229, 62,209,162,227,190, 48,180, 81,191,184,158, 81,191, -117, 90,127, 63, 13,114, 91, 62, 26, 63,185, 62, 35, 44,185, 62,145,180,109,188,105,147,125, 63,138, 84,228,190, 42, 61,228,190, - 0, 0, 0, 0, 0, 0, 0, 0, 9,185,108, 65,214,211,111, 65, 99,240,191, 62,110,116, 85, 63, 64,185, 70,188, 0, 0, 82,180, - 48,221,185,190, 44, 45, 51, 62, 28, 11, 79, 63, 0, 0, 56,179, 67,108,117,194,183,204,216, 65,105,156, 5,194,212,247,159,192, -235, 62,114, 66, 59,254,213,193,158,225, 3, 66, 55, 8,160, 64, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, 0, 0, 0, 0, - 70,119,105, 63,143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,214,211,111,193, 0, 0,128, 63,178,157,229, 62,209,162,227,190, 48,180, 81,191,184,158, 81,191, -117, 90,127, 63, 13,114, 91, 62, 26, 63,185, 62, 35, 44,185, 62,145,180,109,188,105,147,125, 63,138, 84,228,190, 42, 61,228,190, - 0, 0, 0, 0, 0, 0, 0, 0, 9,185,108, 65,214,211,111, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,163, 91, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 12,163, 91, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,163, 91, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 92, 62, 55, 63, 56,186,224,190,237,203,148,190, 3,236,234,190, -214,211,111, 65,214,211,111, 65, 0, 0, 0, 0, 0, 0, 0, 0,236, 15, 72, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 32, 33, 12, 66, 86,152,137, 66,113, 27,126, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 96, 1, 0, 0,184, 73,214, 3, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 51, 51, 51, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 32, 65,205,204, 76, 62, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,200,213,217, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, 8, 8,128, 0, 0, 0, 12, 66, - 0, 0,128, 63,205,204,204, 61, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 16, 0, 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, - 72, 15,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,104, 16,214, 3, 0, 0, 0, 0, 40, 14,214, 3, 0, 0, 0, 0, -232, 15,201, 3, 0, 0, 0, 0,104, 18,201, 3, 0, 0, 0, 0, 8, 19,201, 3, 0, 0, 0, 0, 40, 17,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 1, 0, 0, 89, 0, 0, 0, 3, 1, 0, 0, 2, 2,192, 1,171, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,149,199, 3, 0, 0, 0, 0, 8,149,199, 3, 0, 0, 0, 0, -248, 89,214, 3, 0, 0, 0, 0, 8, 95,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248, 89,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0,168, 91,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 89, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,224, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 1, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,128,223, 67, 0, 0,200, 65, 0,128,223, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,192, 1, 26, 0,192, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 1, 0, 0, 89, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,192, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168, 91,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 88, 93,214, 3, 0, 0, 0, 0,248, 89,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 67, - 0, 0,112,193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 67, 0, 0,254,194, 0, 0, 0, 0,200, 0, 0, 0,217, 0, 0, 0, - 18, 0, 0, 0,144, 0, 0, 0, 0, 0, 0, 0,199, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,199, 0, 0, 0, - 18, 0, 0, 0,144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 10, 6, 0, 0, 2, 0, 3, 3, 0, 0, 0, 4, 6, 0,217, 0,145, 0,200, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 0, 0, 0,115, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,217, 0,145, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88, 93,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 8, 95,214, 3, 0, 0, 0, 0,168, 91,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,191, 1, 0, 0,191, 1, 0, 0,115, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8, 95,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 93,214, 3, 0, 0, 0, 0, 0, 0, 16,193, 0, 0,130, 67, - 0, 0,160,192, 0, 0,160, 64, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 16,193, 0, 0, 32, 65, 0, 0, 0, 0, 17, 0, 0, 0, - 18, 0, 0, 0,144, 0, 0, 0, 18, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0,230, 0, 0, 0, - 18, 0, 0, 0,144, 0, 0, 0,111, 18,131, 58,111, 18,131, 58, 0,124,146, 72, 0, 80, 67, 71, 0, 0, 0, 0, 0, 0, 0, 0, -105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,231, 0,145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,217, 0, 0, 0,191, 1, 0, 0,115, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,231, 0,145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,240, 0, 0, 0, 8,149,199, 3, 0, 0, 0, 0, -178, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,119,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,112, 0, 0, 0, - 40,119,214, 3, 0, 0, 0, 0, 37, 1, 0, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65,160, 0, 0, 0,104, 16,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,248,150,214, 3, 0, 0, 0, 0, - 72, 15,214, 3, 0, 0, 0, 0,104, 18,201, 3, 0, 0, 0, 0, 40, 12,201, 3, 0, 0, 0, 0,200, 17,201, 3, 0, 0, 0, 0, - 8, 19,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 1, 0, 0, 5, 1, 0, 0,194, 2, 0, 0, - 12, 12,192, 1,190, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,230,208, 3, 0, 0, 0, 0, -200,230,208, 3, 0, 0, 0, 0,184, 96,214, 3, 0, 0, 0, 0, 24,100,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -184, 96,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,104, 98,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,192, 94, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,224, 67, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,191, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,223, 67, 0, 0,200, 65, 0,128,223, 67, 0, 0,200, 65, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,192, 1, 26, 0,192, 1, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 1, 0, 0, 5, 1, 0, 0, 30, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -104, 98,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 24,100,214, 3, 0, 0, 0, 0,184, 96,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 67, 0, 0, 0,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 67, 0, 0,201,195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,199, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0,199, 0, 0, 0, 18, 0, 0, 0,163, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 8, 4, 0, 0, 2, 0, 3, 3, 0, 0, 2, 4, 6, 0,200, 0,164, 1,200, 0,146, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,199, 0, 0, 0, 31, 1, 0, 0,194, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 0,164, 1, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, - 24,100,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 98,214, 3, 0, 0, 0, 0, - 0, 0, 32,193, 0, 0,104, 68, 0, 0, 72,194, 0, 0, 0, 0, 0, 0, 32,193, 0, 0,104, 68, 0, 0,201,195, 0, 0, 0, 0, -231, 0, 0, 0,248, 0, 0, 0, 18, 0, 0, 0,163, 1, 0, 0, 0, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0,230, 0, 0, 0, 18, 0, 0, 0,163, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,124,146, 72, 0, 64, 28, 70, - 10,215, 35, 60, 0, 0, 72, 66, 74, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 4, 4, 0,248, 0,164, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 0, 0, 0,191, 1, 0, 0, 31, 1, 0, 0,194, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 0,164, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 72, 1, 0, 0, -200,230,208, 3, 0, 0, 0, 0, 38, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, -248,150,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 16,214, 3, 0, 0, 0, 0, -168, 19,201, 3, 0, 0, 0, 0, 8, 14,201, 3, 0, 0, 0, 0,200, 12,201, 3, 0, 0, 0, 0, 72, 20,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 61, 2, 0, 0,194, 2, 0, 0, 1, 1,216, 0,134, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 75,214, 3, 0, 0, 0, 0,152, 75,214, 3, 0, 0, 0, 0, -200,101,214, 3, 0, 0, 0, 0,120,103,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,200,101,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0,120,103,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,165, 67, 0, 0, 0, 64, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 1, 0, 0, - 0, 0, 0, 0, 23, 0, 0, 0, 0,128,164, 67, 0, 0,200, 65, 0,128,164, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 74, 1, 24, 0, 74, 1, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 61, 2, 0, 0, 61, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,120,103,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,101,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 61, 2, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,216, 0,134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 24,152,214, 3, 0, 0, 0, 0, 68, 65, 84, 65,112, 3, 0, 0, 24,152,214, 3, 0, 0, 0, 0, -173, 0, 0, 0, 1, 0, 0, 0, 56,255, 13, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,100, 64, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154, 65,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, - 72, 1, 77,190, 0, 0, 0, 0,221,149, 47, 63, 86,126,162,190, 8,165, 39, 63, 0, 0, 0, 0, 51, 70, 58, 63,225,251,159, 62, -149, 84, 28,191, 0, 0, 0, 0,192, 56, 49,188, 55, 53,101, 63, 52,247,227, 62, 0, 0, 0, 0, 90, 38,173,190, 0,222,192,190, -152, 9, 52,193, 0, 0,128, 63,223,149, 47, 63, 55, 70, 58, 63,160, 56, 49,188, 0, 0, 0, 0, 88,126,162,190,229,251,159, 62, - 55, 53,101, 63, 0, 0, 0, 0, 7,165, 39, 63,150, 84, 28,191, 51,247,227, 62, 0, 0, 0, 0,110,101,239, 64,151, 62,208,192, - 78,255,170, 64, 0, 0,128, 63, 47,201,194, 63, 61, 73,145,191,244,250, 39,191, 8,165, 39,191,190,164,206, 63,209, 10,143, 63, -180,164, 28, 63,149, 84, 28, 63,224,153,196,188,136,239, 76, 64, 10,108,228,190, 52,247,227,190,125, 21, 64,191,126,113,172,191, -216, 49, 49, 65,152, 9, 52, 65,149, 70,158, 62, 24,234,167, 62,192,214,159,187, 0, 0, 6,181,196,188,181,189, 71,238,178, 61, -127, 45,128, 62, 0, 0,226, 51,168,120, 21,194,107, 5, 2, 66,203,135,213,193,147,214,159,192,177, 38, 19, 66,124,173,255,193, - 96,101,210, 65,128, 40,160, 64,221,149, 47, 63, 86,126,162,190, 8,165, 39, 63, 0, 0, 0, 0, 51, 70, 58, 63,225,251,159, 62, -149, 84, 28,191, 0, 0, 0, 0,192, 56, 49,188, 55, 53,101, 63, 52,247,227, 62, 0, 0, 0, 0, 90, 38,173,190, 0,222,192,190, -152, 9, 52,193, 0, 0,128, 63, 47,201,194, 63, 61, 73,145,191,244,250, 39,191, 8,165, 39,191,190,164,206, 63,209, 10,143, 63, -180,164, 28, 63,149, 84, 28, 63,224,153,196,188,136,239, 76, 64, 10,108,228,190, 52,247,227,190,125, 21, 64,191,126,113,172,191, -216, 49, 49, 65,152, 9, 52, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,102,103, 97, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102,103, 97, 64, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102,103, 97, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63,241, 22, 72, 63, 78,162,246,190, 43, 8, 90,190, 2, 35,171,190, 0, 0, 32, 65, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,253,191,136, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 65, 1, 2, 0, 0, -255,255, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 0, 0, 0,128, 63,190,133, 65, 66, - 99,212, 90, 66, 27,183,118, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 1, 0, 0, -152, 75,214, 3, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65,205,204, 76, 62, - 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,200,213,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 3, 0, 8, 0,128, 0, 0, 0, 12, 66, 0, 0,128, 63, 10,215, 35, 60, - 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, - 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0, 8, 1, 0, 0, 8,156,214, 3, 0, 0, 0, 0, -210, 0, 0, 0, 1, 0, 0, 0,248, 9,215, 3, 0, 0, 0, 0,136, 7,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 67,111,109,112,111,115,105,116,105,110,103, 0,103, 46, 48, 48, 49, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -232, 20,201, 3, 0, 0, 0, 0, 8, 29,201, 3, 0, 0, 0, 0,168,108,171, 3, 0, 0, 0, 0, 24,123,171, 3, 0, 0, 0, 0, -152,157,214, 3, 0, 0, 0, 0, 40,231,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,232, 20,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0,136, 21,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,136, 21,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, - 40, 22,201, 3, 0, 0, 0, 0,232, 20,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0, 40, 22,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200, 22,201, 3, 0, 0, 0, 0, -136, 21,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -200, 22,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,104, 23,201, 3, 0, 0, 0, 0, 40, 22,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,104, 23,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0, 8, 24,201, 3, 0, 0, 0, 0,200, 22,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8, 24,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, -168, 24,201, 3, 0, 0, 0, 0,104, 23,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,234, 3, 1, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0,168, 24,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72, 25,201, 3, 0, 0, 0, 0, - 8, 24,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 92, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, - 72, 25,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,232, 25,201, 3, 0, 0, 0, 0,168, 24,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 92, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,232, 25,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0,136, 26,201, 3, 0, 0, 0, 0, 72, 25,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 32, 6,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,136, 26,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, - 40, 27,201, 3, 0, 0, 0, 0,232, 25,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 1, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0, 40, 27,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200, 27,201, 3, 0, 0, 0, 0, -136, 26,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -200, 27,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,104, 28,201, 3, 0, 0, 0, 0, 40, 27,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4, 3,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,104, 28,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0, 8, 29,201, 3, 0, 0, 0, 0,200, 27,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 3, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8, 29,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,104, 28,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,168,108,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88,109,171, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,136, 21,201, 3, 0, 0, 0, 0, 40, 22,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0, 88,109,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8,110,171, 3, 0, 0, 0, 0, -168,108,171, 3, 0, 0, 0, 0,136, 21,201, 3, 0, 0, 0, 0,104, 23,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0, 8,110,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184,110,171, 3, 0, 0, 0, 0, - 88,109,171, 3, 0, 0, 0, 0, 40, 22,201, 3, 0, 0, 0, 0, 8, 24,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,184,110,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104,111,171, 3, 0, 0, 0, 0, - 8,110,171, 3, 0, 0, 0, 0,104, 23,201, 3, 0, 0, 0, 0, 8, 24,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,104,111,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24,112,171, 3, 0, 0, 0, 0, -184,110,171, 3, 0, 0, 0, 0,200, 22,201, 3, 0, 0, 0, 0, 72, 25,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0, 24,112,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200,112,171, 3, 0, 0, 0, 0, -104,111,171, 3, 0, 0, 0, 0,168, 24,201, 3, 0, 0, 0, 0, 72, 25,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,200,112,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120,113,171, 3, 0, 0, 0, 0, - 24,112,171, 3, 0, 0, 0, 0, 8, 24,201, 3, 0, 0, 0, 0,232, 25,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,120,113,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40,114,171, 3, 0, 0, 0, 0, -200,112,171, 3, 0, 0, 0, 0,104, 23,201, 3, 0, 0, 0, 0,232, 25,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0, 40,114,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216,114,171, 3, 0, 0, 0, 0, -120,113,171, 3, 0, 0, 0, 0,168, 24,201, 3, 0, 0, 0, 0,232, 25,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,216,114,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,136,115,171, 3, 0, 0, 0, 0, - 40,114,171, 3, 0, 0, 0, 0, 8, 24,201, 3, 0, 0, 0, 0, 72, 25,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,136,115,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56,116,171, 3, 0, 0, 0, 0, -216,114,171, 3, 0, 0, 0, 0,104, 23,201, 3, 0, 0, 0, 0,136, 26,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0, 56,116,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232,116,171, 3, 0, 0, 0, 0, -136,115,171, 3, 0, 0, 0, 0,232, 25,201, 3, 0, 0, 0, 0, 40, 27,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,232,116,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152,117,171, 3, 0, 0, 0, 0, - 56,116,171, 3, 0, 0, 0, 0,136, 26,201, 3, 0, 0, 0, 0, 40, 27,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,152,117,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72,118,171, 3, 0, 0, 0, 0, -232,116,171, 3, 0, 0, 0, 0,136, 26,201, 3, 0, 0, 0, 0,200, 27,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0, 72,118,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,248,118,171, 3, 0, 0, 0, 0, -152,117,171, 3, 0, 0, 0, 0, 40, 27,201, 3, 0, 0, 0, 0,200, 27,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,248,118,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168,119,171, 3, 0, 0, 0, 0, - 72,118,171, 3, 0, 0, 0, 0,232, 20,201, 3, 0, 0, 0, 0,104, 28,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,168,119,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88,120,171, 3, 0, 0, 0, 0, -248,118,171, 3, 0, 0, 0, 0,104, 28,201, 3, 0, 0, 0, 0, 8, 29,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0, 88,120,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8,121,171, 3, 0, 0, 0, 0, -168,119,171, 3, 0, 0, 0, 0,200, 22,201, 3, 0, 0, 0, 0, 8, 29,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0, 8,121,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184,121,171, 3, 0, 0, 0, 0, - 88,120,171, 3, 0, 0, 0, 0,168, 24,201, 3, 0, 0, 0, 0, 8, 29,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,184,121,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104,122,171, 3, 0, 0, 0, 0, - 8,121,171, 3, 0, 0, 0, 0,200, 27,201, 3, 0, 0, 0, 0,104, 28,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,104,122,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24,123,171, 3, 0, 0, 0, 0, -184,121,171, 3, 0, 0, 0, 0, 40, 27,201, 3, 0, 0, 0, 0, 8, 29,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0, 24,123,171, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -104,122,171, 3, 0, 0, 0, 0,232, 20,201, 3, 0, 0, 0, 0,136, 26,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65,160, 0, 0, 0,152,157,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,184,158,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,104, 23,201, 3, 0, 0, 0, 0,136, 21,201, 3, 0, 0, 0, 0, 40, 22,201, 3, 0, 0, 0, 0, - 8, 24,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,235, 3, 0, 0, 5, 4, 0, 0, - 7, 7,127, 7, 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,198,207, 3, 0, 0, 0, 0, - 88,198,207, 3, 0, 0, 0, 0, 40,105,214, 3, 0, 0, 0, 0,216,106,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, - 40,105,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,216,106,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 32,148, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,239, 68, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, 0, 0,200, 65, 0,192,239, 68, 0, 0,200, 65, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,127, 7, 26, 0,127, 7, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,235, 3, 0, 0, 4, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -216,106,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,105,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0,240,109, 69, 0, 0,128,192, 0, 0, 0, 0, 0, 0, 0, 0,255,255,109, 69, 0, 0, 0,192, 0, 0, 0, 0, -112, 7, 0, 0,129, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0,111, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 2, 0, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, 10, 0,129, 7, 2, 0,112, 7, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 5, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, -184,158,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,216,159,214, 3, 0, 0, 0, 0,152,157,214, 3, 0, 0, 0, 0, - 8, 29,201, 3, 0, 0, 0, 0,168, 24,201, 3, 0, 0, 0, 0, 72, 25,201, 3, 0, 0, 0, 0,200, 22,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 15, 15, 94, 1, 92, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 94,200, 3, 0, 0, 0, 0, 40, 94,200, 3, 0, 0, 0, 0, -136,108,214, 3, 0, 0, 0, 0, 56,110,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136,108,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 56,110,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,115, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,175, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 1, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,128,174, 67, 0, 0,200, 65, 0,128,174, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 94, 1, 26, 0, 94, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 94, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 56,110,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,108,214, 3, 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67, - 0, 0, 0, 0, 0, 0, 72, 66, 50, 51, 74,193,154,209,131, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 93, 1, 0, 0, - 18, 0, 0, 0, 65, 0, 0, 0, 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65, - 72, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 4, 8, 0, 94, 1, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 26, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 94, 1, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0, 40, 94,200, 3, 0, 0, 0, 0, -190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, -216,159,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,248,224,214, 3, 0, 0, 0, 0,184,158,214, 3, 0, 0, 0, 0, -168, 24,201, 3, 0, 0, 0, 0,232, 25,201, 3, 0, 0, 0, 0, 8, 24,201, 3, 0, 0, 0, 0, 72, 25,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 93, 0, 0, 0,233, 3, 0, 0, 4, 4, 94, 1,141, 3, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,125,199, 3, 0, 0, 0, 0, 56,125,199, 3, 0, 0, 0, 0, -232,111,214, 3, 0, 0, 0, 0, 40,161,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,232,111,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 40,161,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,148, 67, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,175, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 1, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,128,174, 67, 0, 0,200, 65, 0,128,174, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 94, 1, 26, 0, 94, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0,208, 3, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 94, 1, 26, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 40,161,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,111,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,174, 67, - 0,128, 92,196, 0, 0, 0, 0, 0, 0, 0, 0,255,127,166, 67,255,191, 92,196, 0, 0, 0, 0, 77, 1, 0, 0, 94, 1, 0, 0, - 0, 0, 0, 0,114, 3, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 76, 1, 0, 0, - 0, 0, 0, 0,114, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, - 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0, 94, 1,115, 3, 77, 1,115, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 93, 0, 0, 0,207, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 94, 1,115, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -120, 77,214, 3, 0, 0, 0, 0, 8,210,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,120, 77,214, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 88, 79,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 67,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,255, 76, 1, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 88, 79,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 40,193,214, 3, 0, 0, 0, 0, -120, 77,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82,101,110,100,101,114, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,255, 76, 1, 61, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 40,193,214, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 8,195,214, 3, 0, 0, 0, 0, 88, 79,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 76, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111,255, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 8,195,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,232,196,214, 3, 0, 0, 0, 0, - 40,193,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,105,109,101,110,115,105,111, -110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,254, 76, 1,203, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,232,196,214, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,200,198,214, 3, 0, 0, 0, 0, 8,195,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 65,110,116,105, 45, 65,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58,254, 76, 1, 58, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,200,198,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,168,200,214, 3, 0, 0, 0, 0, -232,196,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 97,109,112,108,101,100, 32, - 77,111,116,105,111,110, 32, 66,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,254, 76, 1, 0, 0, - 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,168,200,214, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,136,202,214, 3, 0, 0, 0, 0,200,198,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,254, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,136,202,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,104,204,214, 3, 0, 0, 0, 0, -168,200,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,101,114,102,111,114,109, 97, -110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,242,253, 76, 1, 0, 0, - 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,104,204,214, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 72,206,214, 3, 0, 0, 0, 0,136,202,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110, -103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110, -103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 80,111,115,116, 32, 80,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,218,253, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 72,206,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 40,208,214, 3, 0, 0, 0, 0, -104,204,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,116, 97,109,112, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194,253, 76, 1, 0, 0, - 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 40,208,214, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 8,210,214, 3, 0, 0, 0, 0, 72,206,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 79,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,253, 76, 1,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 8,210,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40,208,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 97,107,101, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,253, 76, 1, 0, 0, - 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0, 56,125,199, 3, 0, 0, 0, 0, -179, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,255, 21, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65,160, 0, 0, 0,248,224,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 8,230,214, 3, 0, 0, 0, 0, -216,159,214, 3, 0, 0, 0, 0,104, 28,201, 3, 0, 0, 0, 0,200, 27,201, 3, 0, 0, 0, 0, 40, 27,201, 3, 0, 0, 0, 0, - 8, 29,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0, 0, 31, 6, 0, 0, 0, 0, 0, 0,139, 1, 0, 0, - 1, 1, 27, 3,140, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,211,214, 3, 0, 0, 0, 0, -232,211,214, 3, 0, 0, 0, 0,216,162,214, 3, 0, 0, 0, 0,152,169,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -216,162,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,136,164,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 64,113, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,192, 70, 68, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 26, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128, 70, 68, 0, 0,200, 65, 0,128, 70, 68, 0, 0,200, 65, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 27, 3, 26, 0, 27, 3, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0, 0, 31, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 3, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -136,164,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 56,166,214, 3, 0, 0, 0, 0,216,162,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 67, 0, 64, 70,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67,255,127, 70,196, 0, 0, 0, 0, -143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0, 44, 3,143, 0, 26, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0, 0, 5, 3, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,114, 1, 0, 0, 5, 0, 3, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, - 56,166,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,232,167,214, 3, 0, 0, 0, 0,136,164,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 16, 67, 0, 0,206,194, 0, 0, 0, 0, 0, 0, 0, 0,231,102, 16, 67, 0, 0,206,194, 0, 0, 0, 0, -143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,120, 0,143, 0,102, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0, 0, 31, 6, 0, 0, 26, 0, 0, 0, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 6, 0, 34, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -232,167,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,152,169,214, 3, 0, 0, 0, 0, 56,166,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 35, 67, 0,192,108,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, 0, 0,184,195, 0, 0, 0, 0, -163, 0, 0, 0,180, 0, 0, 0, 18, 0, 0, 0,129, 1, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0,162, 0, 0, 0, 18, 0, 0, 0,129, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,180, 0,130, 1,163, 0,112, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0, 31, 6, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -152,169,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,167,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0, 0, 31, 6, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 3,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,226,214, 3, 0, 0, 0, 0, 68, 65, 84, 65,112, 3, 0, 0, - 24,226,214, 3, 0, 0, 0, 0,173, 0, 0, 0, 1, 0, 0, 0, 93,101,230, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 30,133,119, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154, 65,128,191, 0, 0,128,191, - 0, 0, 0, 0, 0, 0, 0, 0, 72, 1, 77,190, 0, 0, 0, 0,221,149, 47, 63, 85,126,162,190, 8,165, 39, 63, 0, 0, 0, 0, - 51, 70, 58, 63,225,251,159, 62,149, 84, 28,191, 0, 0, 0, 0,191, 56, 49,188, 54, 53,101, 63, 50,247,227, 62, 0, 0, 0, 0, - 90, 38,173,190,254,221,192,190,152, 9, 52,193, 0, 0,128, 63,223,149, 47, 63, 55, 70, 58, 63,192, 56, 49,188, 0, 0, 0, 0, - 87,126,162,190,228,251,159, 62, 56, 53,101, 63, 0, 0, 0, 0, 7,165, 39, 63,150, 84, 28,191, 50,247,227, 62, 0, 0, 0, 0, -110,101,239, 64,151, 62,208,192, 77,255,170, 64, 0, 0,128, 63, 42, 6,158, 63, 99, 28,157,191,244,250, 39,191, 8,165, 39,191, -211,164,167, 63, 55,175,154, 63,180,164, 28, 63,149, 84, 28, 63, 39,127,159,188,135,157, 93, 64, 8,108,228,190, 50,247,227,190, - 4,213, 27,191,122,122,186,191,216, 49, 49, 65,152, 9, 52, 65, 25, 25,195, 62,176,249,206, 62,128,238,196,187, 0, 0,192,179, - 55, 15,168,189,201,118,165, 61,152, 15,109, 62, 0, 0,152, 51,211,120, 21,194,144, 5, 2, 66, 6,136,213,193,193,214,159,192, -219, 38, 19, 66,196,173,255,193,154,101,210, 65,173, 40,160, 64,221,149, 47, 63, 85,126,162,190, 8,165, 39, 63, 0, 0, 0, 0, - 51, 70, 58, 63,225,251,159, 62,149, 84, 28,191, 0, 0, 0, 0,191, 56, 49,188, 54, 53,101, 63, 50,247,227, 62, 0, 0, 0, 0, - 90, 38,173,190,254,221,192,190,152, 9, 52,193, 0, 0,128, 63, 42, 6,158, 63, 99, 28,157,191,244,250, 39,191, 8,165, 39,191, -211,164,167, 63, 55,175,154, 63,180,164, 28, 63,149, 84, 28, 63, 39,127,159,188,135,157, 93, 64, 8,108,228,190, 50,247,227,190, - 4,213, 27,191,122,122,186,191,216, 49, 49, 65,152, 9, 52, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,250,150, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 62,250,150, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,250,150, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,241, 22, 72, 63, 78,162,246,190, 44, 8, 90,190, 3, 35,171,190, -214,211,111, 65,214,211,111, 65, 0, 0, 0, 0, 0, 0, 0, 0, 80, 49,183, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,160, 65, 1, 2, 0, 0,255,255, 0, 0, 92, 62, 55, 63, 56,186,224,190,237,203,148,190, 3,236,234,190, 1, 0, 0, 0, - 0, 0,128, 63,190,133, 65, 66,100,212, 90, 66, 31,183,118, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 96, 1, 0, 0,232,211,214, 3, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 51, 51, 51, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 32, 65,205,204, 76, 62, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,200,213,217, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, 8, 8,128, 0, 0, 0, 12, 66, - 0, 0,128, 63,205,204,204, 61, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 16, 0, 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, - 8,230,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 40,231,214, 3, 0, 0, 0, 0,248,224,214, 3, 0, 0, 0, 0, -136, 26,201, 3, 0, 0, 0, 0,104, 23,201, 3, 0, 0, 0, 0,232, 25,201, 3, 0, 0, 0, 0, 40, 27,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0,141, 1, 0, 0,233, 3, 0, 0, 16, 16, 32, 6, 93, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,174,214, 3, 0, 0, 0, 0,168,174,214, 3, 0, 0, 0, 0, - 72,171,214, 3, 0, 0, 0, 0,248,172,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72,171,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0,248,172,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 66, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,196, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,224,195, 68, 0, 0,200, 65, 0,224,195, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 32, 6, 26, 0, 32, 6, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0,141, 1, 0, 0,166, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248,172,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,171,214, 3, 0, 0, 0, 0, 0, 0, 32,193, 0, 0, 0, 68, - 0, 0, 32,193, 0, 0, 0, 68,128,195,217,195,192,225,108, 68, 96,240,187, 64, 62, 16,253, 67, 15, 6, 0, 0, 32, 6, 0, 0, - 18, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 14, 6, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 14, 6, 0, 0, - 18, 0, 0, 0, 66, 2, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,250, 70, 0, 0,250, 70,236, 81,184, 61, 10,215, 19, 64, - 10, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 32, 6, 67, 2, 15, 6, 49, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0,167, 1, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 67, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 1, 0, 0,168,174,214, 3, 0, 0, 0, 0, -191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 10,215, 19, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 10,206, 97, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, - 40,231,214, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,230,214, 3, 0, 0, 0, 0, -232, 20,201, 3, 0, 0, 0, 0,136, 26,201, 3, 0, 0, 0, 0,200, 27,201, 3, 0, 0, 0, 0,104, 28,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0,139, 1, 0, 0, 6, 6, 4, 3,140, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,232,214, 3, 0, 0, 0, 0, 72,232,214, 3, 0, 0, 0, 0, - 88,176,214, 3, 0, 0, 0, 0,184,179,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88,176,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 8,178,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 67, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 65, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,192, 64, 68, 0, 0,200, 65, 0,192, 64, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 4, 3, 26, 0, 4, 3, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8,178,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0,184,179,214, 3, 0, 0, 0, 0, 88,176,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,184,179,214, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,178,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 67, 0, 0,129,191, 0,128, 0, 64, 0, 0,100,190, 0,128,156, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, - 0, 0, 0, 0,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4, 3,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 33, 0, 0, 72,232,214, 3, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 65, 0, 0, 0, 0,154,153,153, 62, - 0, 0, 0, 0,100, 0, 0, 0,154,153,153, 62,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0, 8, 1, 0, 0,248, 9,215, 3, 0, 0, 0, 0, -210, 0, 0, 0, 1, 0, 0, 0,152, 66,216, 3, 0, 0, 0, 0, 8,156,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 68,101,102, 97,117,108,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168, 29,201, 3, 0, 0, 0, 0,136, 36,201, 3, 0, 0, 0, 0,200,123,171, 3, 0, 0, 0, 0,120,135,171, 3, 0, 0, 0, 0, -184, 11,215, 3, 0, 0, 0, 0, 56, 16,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48,102, 10, 64, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,168, 29,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0, 72, 30,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72, 30,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, -232, 30,201, 3, 0, 0, 0, 0,168, 29,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,178, 2, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0,232, 30,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,136, 31,201, 3, 0, 0, 0, 0, - 72, 30,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 5,178, 2, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -136, 31,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40, 32,201, 3, 0, 0, 0, 0,232, 30,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 70, 5, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 40, 32,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0,200, 32,201, 3, 0, 0, 0, 0,136, 31,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,151, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,200, 32,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, -104, 33,201, 3, 0, 0, 0, 0, 40, 32,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 5,151, 2, 1, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0,104, 33,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 8, 34,201, 3, 0, 0, 0, 0, -200, 32,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,112, 4, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, - 8, 34,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,168, 34,201, 3, 0, 0, 0, 0,104, 33,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,112, 4,151, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,168, 34,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0, 72, 35,201, 3, 0, 0, 0, 0, 8, 34,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -112, 4, 56, 2, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72, 35,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, -232, 35,201, 3, 0, 0, 0, 0,168, 34,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 5, 56, 2, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0,232, 35,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,136, 36,201, 3, 0, 0, 0, 0, - 72, 35,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -136, 36,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232, 35,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,112, 4, 84, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200,123,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,120,124,171, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 30,201, 3, 0, 0, 0, 0, -232, 30,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,120,124,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 40,125,171, 3, 0, 0, 0, 0,200,123,171, 3, 0, 0, 0, 0, 72, 30,201, 3, 0, 0, 0, 0, - 40, 32,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40,125,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,216,125,171, 3, 0, 0, 0, 0,120,124,171, 3, 0, 0, 0, 0,232, 30,201, 3, 0, 0, 0, 0, -200, 32,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216,125,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,136,126,171, 3, 0, 0, 0, 0, 40,125,171, 3, 0, 0, 0, 0, 40, 32,201, 3, 0, 0, 0, 0, -200, 32,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136,126,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 56,127,171, 3, 0, 0, 0, 0,216,125,171, 3, 0, 0, 0, 0,168, 29,201, 3, 0, 0, 0, 0, -104, 33,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56,127,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,232,127,171, 3, 0, 0, 0, 0,136,126,171, 3, 0, 0, 0, 0,136, 31,201, 3, 0, 0, 0, 0, -104, 33,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,232,127,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,152,128,171, 3, 0, 0, 0, 0, 56,127,171, 3, 0, 0, 0, 0, 40, 32,201, 3, 0, 0, 0, 0, - 8, 34,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,152,128,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 72,129,171, 3, 0, 0, 0, 0,232,127,171, 3, 0, 0, 0, 0,200, 32,201, 3, 0, 0, 0, 0, - 8, 34,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72,129,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,248,129,171, 3, 0, 0, 0, 0,152,128,171, 3, 0, 0, 0, 0,104, 33,201, 3, 0, 0, 0, 0, -168, 34,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,248,129,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,168,130,171, 3, 0, 0, 0, 0, 72,129,171, 3, 0, 0, 0, 0, 8, 34,201, 3, 0, 0, 0, 0, -168, 34,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,168,130,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 88,131,171, 3, 0, 0, 0, 0,248,129,171, 3, 0, 0, 0, 0,200, 32,201, 3, 0, 0, 0, 0, - 72, 35,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88,131,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 8,132,171, 3, 0, 0, 0, 0,168,130,171, 3, 0, 0, 0, 0,136, 31,201, 3, 0, 0, 0, 0, - 72, 35,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 8,132,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,184,132,171, 3, 0, 0, 0, 0, 88,131,171, 3, 0, 0, 0, 0,168, 34,201, 3, 0, 0, 0, 0, - 72, 35,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184,132,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,104,133,171, 3, 0, 0, 0, 0, 8,132,171, 3, 0, 0, 0, 0,168, 29,201, 3, 0, 0, 0, 0, -232, 35,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,104,133,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 24,134,171, 3, 0, 0, 0, 0,184,132,171, 3, 0, 0, 0, 0, 40, 32,201, 3, 0, 0, 0, 0, -232, 35,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 24,134,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,200,134,171, 3, 0, 0, 0, 0,104,133,171, 3, 0, 0, 0, 0, 8, 34,201, 3, 0, 0, 0, 0, -136, 36,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200,134,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,120,135,171, 3, 0, 0, 0, 0, 24,134,171, 3, 0, 0, 0, 0,104, 33,201, 3, 0, 0, 0, 0, -136, 36,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,120,135,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,134,171, 3, 0, 0, 0, 0,232, 35,201, 3, 0, 0, 0, 0, -136, 36,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,184, 11,215, 3, 0, 0, 0, 0, -214, 0, 0, 0, 1, 0, 0, 0,216, 12,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 32,201, 3, 0, 0, 0, 0, - 72, 30,201, 3, 0, 0, 0, 0,232, 30,201, 3, 0, 0, 0, 0,200, 32,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 70, 5, 0, 0,152, 2, 0, 0,178, 2, 0, 0, 7, 7, 71, 5, 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 8, 0, - 72,207,177, 3, 0, 0, 0, 0, 24,199,207, 3, 0, 0, 0, 0, 24,199,207, 3, 0, 0, 0, 0,104,181,214, 3, 0, 0, 0, 0, - 24,183,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,196,207, 3, 0, 0, 0, 0, -216,196,207, 3, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,104,181,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, - 24,183,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,163, 68, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0,224,168, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 5, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, - 0,192,168, 68, 0, 0,200, 65, 0,192,168, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, - 4, 0, 12, 0, 10, 0, 71, 5, 26, 0, 71, 5, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 70, 5, 0, 0,152, 2, 0, 0,177, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 71, 5, 26, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 88, 6,178, 3, 0, 0, 0, 0,120,128,214, 15, 0, 0, 0, 0,120,128,214, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,120, 13,163, 3, 0, 0, 0, 0,216, 19,163, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 24,183,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,104,181,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,109, 69, 0, 0,128,192, 0, 0, 0, 0, - 0, 0, 0, 0, 0,192,168, 68, 0, 0, 0, 0, 0, 0, 0, 64, 70, 5, 0, 0, 87, 5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 69, 5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 2, 0, 0, 0, 1, 0, 3, 3, - 2, 0, 0, 4, 10, 0, 87, 5, 2, 0, 70, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,178, 2, 0, 0,178, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40, 5,178, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,232, 20,163, 3, 0, 0, 0, 0,248,116,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,216, 12,215, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, -248, 13,215, 3, 0, 0, 0, 0,184, 11,215, 3, 0, 0, 0, 0,104, 33,201, 3, 0, 0, 0, 0,168, 34,201, 3, 0, 0, 0, 0, - 72, 35,201, 3, 0, 0, 0, 0,136, 31,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,113, 4, 0, 0, 70, 5, 0, 0, - 0, 0, 0, 0, 55, 2, 0, 0, 4, 4,214, 0, 56, 2, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0,248,205,177, 3, 0, 0, 0, 0, -184,126,199, 3, 0, 0, 0, 0,184,126,199, 3, 0, 0, 0, 0,200,184,214, 3, 0, 0, 0, 0,120,186,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,205,207, 3, 0, 0, 0, 0, 88,195,207, 3, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0,200,184,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,120,186,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,148, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 86, 67, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,213, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 85, 67, 0, 0,200, 65, - 0, 0, 85, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,214, 0, - 26, 0,214, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,113, 4, 0, 0, 70, 5, 0, 0, - 30, 2, 0, 0, 55, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,214, 0, 26, 0, 4, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 3,178, 3, 0, 0, 0, 0, -200, 53,163, 3, 0, 0, 0, 0,200, 53,163, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8,118,208, 3, 0, 0, 0, 0, 56,121,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0,120,186,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200,184,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, 0, 0, 61,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 67, - 0,128, 7,196, 0, 0, 0, 0,197, 0, 0, 0,214, 0, 0, 0, 0, 0, 0, 0, 29, 2, 0, 0, 0, 0, 0, 0, 74, 1, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,196, 0, 0, 0, 0, 0, 0, 0, 29, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 1, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,214, 0, - 30, 2,197, 0, 30, 2, 0, 0, 72, 91,192, 15, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,113, 4, 0, 0, 70, 5, 0, 0, - 0, 0, 0, 0, 29, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,214, 0, 30, 2, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 2,178, 3, 0, 0, 0, 0, - 8,150,212, 15, 0, 0, 0, 0,152, 72,163, 3, 0, 0, 0, 0,200,213,214, 3, 0, 0, 0, 0,184, 75,215, 3, 0, 0, 0, 0, - 72,122,208, 3, 0, 0, 0, 0,152,127,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,200,213,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,168,215,214, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,232, 35,178, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, - 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, - 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,110,116,101,120,116, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,255,197, 0, 36, 0, - 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,168,215,214, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,136,217,214, 3, 0, 0, 0, 0,200,213,214, 3, 0, 0, 0, 0, 40, 34,221, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,255,197, 0, 61, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 11, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,136,217,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,104,219,214, 3, 0, 0, 0, 0, -168,215,214, 3, 0, 0, 0, 0,200, 35,221, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 97,121,101,114,115, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111,255,197, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 6, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,104,219,214, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 72,221,214, 3, 0, 0, 0, 0,136,217,214, 3, 0, 0, 0, 0,104, 37,221, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,254,197, 0,203, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 72,221,214, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,184, 43,215, 3, 0, 0, 0, 0, -104,219,214, 3, 0, 0, 0, 0, 8, 39,221, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65,110,116,105, 45, 65,108,105, - 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58,254,197, 0, 58, 0, - 20, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,184, 43,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,152, 45,215, 3, 0, 0, 0, 0, 72,221,214, 3, 0, 0, 0, 0,168, 40,221, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 97,109,112,108,101,100, 32, 77,111,116,105,111,110, 32, 66,108,117,114, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,254,197, 0, 0, 0, 20, 0, 0, 0, 4, 0, 6, 0, 0, 0, 0, 0, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,152, 45,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,120, 47,215, 3, 0, 0, 0, 0, -184, 43,215, 3, 0, 0, 0, 0, 72, 42,221, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,104, 97,100,105,110,103, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,254,197, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 6, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,120, 47,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 88, 49,215, 3, 0, 0, 0, 0,152, 45,215, 3, 0, 0, 0, 0,232, 43,221, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 80,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,242,253,197, 0, 0, 0, 0, 0, 0, 0, 4, 0, 6, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 88, 49,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 56, 51,215, 3, 0, 0, 0, 0, -120, 47,215, 3, 0, 0, 0, 0,136, 45,221, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,111,115,116, 32, 80,114,111, - 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,218,253,197, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 6, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 56, 51,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 24, 53,215, 3, 0, 0, 0, 0, 88, 49,215, 3, 0, 0, 0, 0, 72, 48,221, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194,253,197, 0, 0, 0, 20, 0, 0, 0, 4, 0, 6, 0, 0, 0, 0, 0, 19, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 24, 53,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,248, 54,215, 3, 0, 0, 0, 0, - 56, 51,215, 3, 0, 0, 0, 0,232, 49,221, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79,117,116,112,117,116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36,253,197, 0,134, 0, - 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,248, 54,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,216, 56,215, 3, 0, 0, 0, 0, 24, 53,215, 3, 0, 0, 0, 0, 40, 53,221, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,253,197, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 0, 0, 0, 0, 0, 21, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,216, 56,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,184, 58,215, 3, 0, 0, 0, 0, -248, 54,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, - 95,115, 99,101,110,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, - 95,115, 99,101,110,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 99,101,110,101, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,255, 41, 1, 61, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,184, 58,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,152, 60,215, 3, 0, 0, 0, 0,216, 56,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,117,110,105,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,117,110,105,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 85,110,105,116,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28,255, 41, 1, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,152, 60,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,120, 62,215, 3, 0, 0, 0, 0, -184, 58,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, - 95,107,101,121,105,110,103, 95,115,101,116,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, - 95,107,101,121,105,110,103, 95,115,101,116,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75,101,121,105,110,103, 32, 83, -101,116,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191,254, 41, 1, 69, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,120, 62,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 88, 64,215, 3, 0, 0, 0, 0,152, 60,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,112,104,121,115,105, 99,115, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,112,104,121,115,105, 99,115, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 71,114, 97,118,105,116,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,131,254, 41, 1, 36, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 88, 64,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 56, 66,215, 3, 0, 0, 0, 0, -120, 62,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, - 95,115,105,109,112,108,105,102,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, - 95,115,105,109,112,108,105,102,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,105,109,112,108,105,102,121, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27,254, 41, 1, 80, 0, - 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 56, 66,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 24, 68,215, 3, 0, 0, 0, 0, 88, 64,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95, 99,117,115,116,111,109, 95,112,114,111,112,115, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95, 99,117,115,116,111,109, 95,112,114,111,112,115, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 67,117,115,116,111,109, 32, 80,114,111,112,101,114,116,105,101,115, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,223,253, 41, 1, 36, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 24, 68,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,248, 69,215, 3, 0, 0, 0, 0, - 56, 66,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, - 80, 84, 95, 99,111,110,116,101,120,116, 95,116,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, - 80, 84, 95, 99,111,110,116,101,120,116, 95,116,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,255,187, 0,204, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,248, 69,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,216, 71,215, 3, 0, 0, 0, 0, 24, 68,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, 80, 84, 95,109, 97,112,112,105,110,103, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, 80, 84, 95,109, 97,112,112,105,110,103, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 77, 97,112,112,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77,254,187, 0,171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,216, 71,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,184, 75,215, 3, 0, 0, 0, 0, -248, 69,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, - 80, 84, 95,105,110,102,108,117,101,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, - 80, 84, 95,105,110,102,108,117,101,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73,110,102,108,117,101,110, 99, -101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,223,252,187, 0, 86, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,184, 75,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 71,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 74, 69, 67, 84, 95, 80, 84, 95, 99,111,110,115,116,114, 97,105,110,116,115, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 74, 69, 67, 84, 95, 80, 84, 95, 99,111,110,115,116,114, 97,105,110,116,115, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 79, 98,106,101, 99,116, 32, 67,111,110,115,116,114, 97,105,110,116,115, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,255,187, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65,248, 0, 0, 0,184,126,199, 3, 0, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0,232,198,226, 3, 0, 0, 0, 0,255, 21, 0, 0,160, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,248, 13,215, 3, 0, 0, 0, 0, -214, 0, 0, 0, 1, 0, 0, 0, 24, 15,215, 3, 0, 0, 0, 0,216, 12,215, 3, 0, 0, 0, 0,168, 29,201, 3, 0, 0, 0, 0, -232, 35,201, 3, 0, 0, 0, 0,136, 36,201, 3, 0, 0, 0, 0,104, 33,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,111, 4, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 15, 15,112, 4, 84, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -152,104,177, 3, 0, 0, 0, 0,120, 95,200, 3, 0, 0, 0, 0,120, 95,200, 3, 0, 0, 0, 0, 40,188,214, 3, 0, 0, 0, 0, -216,189,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,207,207, 3, 0, 0, 0, 0, -216,205,207, 3, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 40,188,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, -216,189,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,146, 68, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0, 0,142, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, - 0,224,141, 68, 0, 0,200, 65, 0,224,141, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, - 4, 0, 12, 0, 10, 0,112, 4, 26, 0,112, 4, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,111, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -112, 4, 26, 0, 6, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -232,186,177, 3, 0, 0, 0, 0,232,169,209, 15, 0, 0, 0, 0,232,169,209, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,168,128,208, 3, 0, 0, 0, 0,216,131,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,216,189,214, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 40,188,214, 3, 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67, 0, 0, 0, 0, 0, 0, 72, 66, - 88,218,103,194, 40,147,141, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,111, 4, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,111, 4, 0, 0, 18, 0, 0, 0, 57, 0, 0, 0, - 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65, 72, 0, 0, 0, 0, 0, 0, 2, - 4, 0, 0, 4, 8, 0,112, 4, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,111, 4, 0, 0, 26, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -112, 4, 58, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184,185,177, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,232,132,208, 3, 0, 0, 0, 0, 88,140,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0,120, 95,200, 3, 0, 0, 0, 0,190, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 24, 15,215, 3, 0, 0, 0, 0, -214, 0, 0, 0, 1, 0, 0, 0, 56, 16,215, 3, 0, 0, 0, 0,248, 13,215, 3, 0, 0, 0, 0,168, 34,201, 3, 0, 0, 0, 0, - 8, 34,201, 3, 0, 0, 0, 0,200, 32,201, 3, 0, 0, 0, 0, 72, 35,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -113, 4, 0, 0, 70, 5, 0, 0, 57, 2, 0, 0,150, 2, 0, 0, 3, 3,214, 0, 94, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, - 72,103,177, 3, 0, 0, 0, 0,200, 0,209, 3, 0, 0, 0, 0,200, 0,209, 3, 0, 0, 0, 0,184,107,215, 3, 0, 0, 0, 0, -104,109,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,209,207, 3, 0, 0, 0, 0, - 24,208,207, 3, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,184,107,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, -104,109,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,244, 67, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0, 0, 86, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,213, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, - 0, 0, 85, 67, 0, 0,200, 65, 0, 0, 85, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, - 4, 0, 12, 0, 10, 0,214, 0, 26, 0,214, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -113, 4, 0, 0, 70, 5, 0, 0,125, 2, 0, 0,150, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -214, 0, 26, 0, 8, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -136,184,177, 3, 0, 0, 0, 0, 40, 59,163, 3, 0, 0, 0, 0, 40, 59,163, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,104,141,208, 3, 0, 0, 0, 0,152,144,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,104,109,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,184,107,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,141, 67, 0, 0,244,194, 0, 0, 0, 0, - 0, 0, 0, 64, 0, 0, 71, 67, 0, 0,143,194, 0, 0,172,193,197, 0, 0, 0,214, 0, 0, 0, 18, 0, 0, 0, 67, 0, 0, 0, - 0, 0, 0, 0,196, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,196, 0, 0, 0, 18, 0, 0, 0, 67, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 18, 0, 0, 0, 2, 0, 3, 3, - 0, 0, 12, 4, 6, 0,214, 0, 68, 0,197, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -113, 4, 0, 0, 70, 5, 0, 0, 57, 2, 0, 0,124, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -214, 0, 68, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 88,183,177, 3, 0, 0, 0, 0,232, 69,163, 3, 0, 0, 0, 0,232, 69,163, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,168,145,208, 3, 0, 0, 0, 0, 8,231,207, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 1, 0, 0,200, 0,209, 3, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,120,243,211, 15, 0, 0, 0, 0,120,243,211, 15, 0, 0, 0, 0,136, 17,214, 3, 0, 0, 0, 0, - 0,115,101, 32, 83, 99,117,108,112,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65, 16, 0, 0, 0, -136, 17,214, 3, 0, 0, 0, 0,237, 0, 0, 0, 1, 0, 0, 0, 42, 11, 0, 0, 42, 11, 0, 0,136,139,215, 3, 0, 0, 0, 0, - 68, 65, 84, 65,160,178, 0, 0,136,139,215, 3, 0, 0, 0, 0,236, 0, 0, 0, 42, 11, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, -168,194,217, 3, 0, 0, 0, 0, 19, 0, 0, 0, 1, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, 20, 0, 0, 0, 1, 0, 1, 0, -168,194,217, 3, 0, 0, 0, 0, 21, 0, 1, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, - 24, 51,163, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,184,219,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, -136, 48,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,152, 7,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, -216, 29,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,168,225,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, -120,209,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,200,213,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, - 24, 98,200, 3, 0, 0, 0, 0, 21, 0, 0, 0, 1, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, -200, 66,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 30, 0,255,255, 3, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,136, 7,214, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, - 8,156,214, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,248, 9,215, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -152, 66,216, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 56, 43,217, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -232,117,217, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 24,157,217, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, -216, 29,218, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 8, 78,210, 3, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, - 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, - 40, 77,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -200, 85,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -104, 94,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, - 8,103,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -168,111,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, - 72,120,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -232,128,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -136,137,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -104,176,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, - 72,183,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, - 40,190,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, - 8,197,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -232,203,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -200,210,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -168,217,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -136,224,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -184,212,210, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -200,219,210, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -216,226,210, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -232,233,210, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -248,240,210, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -152,231,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -168,238,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -184,245,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -200,252,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -216, 3,219, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -232, 10,219, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -248, 17,219, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, - 8, 25,219, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, - 24, 98,200, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -120,209,217, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 70, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 71, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 72, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 73, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 74, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 75, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 76, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 77, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 78, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 79, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 80, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 81, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 82, 0, 1, 0, 0, 0, -152, 7,218, 3, 0, 0, 0, 0, 31, 0, 83, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, -136, 48,218, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 70, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 71, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 72, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 73, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 74, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 75, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 76, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 77, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 78, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 79, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 80, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 81, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 82, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 83, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 84, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 85, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 86, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 87, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 88, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 89, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 90, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 91, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 92, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 93, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 94, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 95, 0, 1, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 31, 0, 96, 0, 1, 0, 0, 0, -200,213,217, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 70, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 71, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 72, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 73, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 74, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 75, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 76, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 77, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 78, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 79, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 80, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 81, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 82, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 83, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 84, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 85, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 86, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 87, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 88, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 89, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 90, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 91, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 92, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 93, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 94, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 95, 0, 1, 0, 0, 0, -184,219,217, 3, 0, 0, 0, 0, 31, 0, 96, 0, 1, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 70, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 71, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 72, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 73, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 74, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 75, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 76, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 77, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 78, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 79, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 80, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 81, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 82, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 83, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 84, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 85, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 86, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 87, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 88, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 89, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 90, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 91, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 92, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 93, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 94, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 95, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0, 31, 0, 96, 0, 1, 0, 0, 0, -168,225,217, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,136, 7,214, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -136, 7,214, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,136, 7,214, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -136, 7,214, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,136, 7,214, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -136, 7,214, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,136, 7,214, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -136, 7,214, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,136, 7,214, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -136, 7,214, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 8,156,214, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 8,156,214, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 8,156,214, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 8,156,214, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 8,156,214, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 8,156,214, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 8,156,214, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 8,156,214, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 8,156,214, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 8,156,214, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,248, 9,215, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -248, 9,215, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,248, 9,215, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -248, 9,215, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,248, 9,215, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -248, 9,215, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,248, 9,215, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -248, 9,215, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,248, 9,215, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -248, 9,215, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,152, 66,216, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -152, 66,216, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,152, 66,216, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -152, 66,216, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,152, 66,216, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -152, 66,216, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,152, 66,216, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -152, 66,216, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,152, 66,216, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -152, 66,216, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 56, 43,217, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 56, 43,217, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 56, 43,217, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 56, 43,217, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 56, 43,217, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 56, 43,217, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 56, 43,217, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 56, 43,217, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 56, 43,217, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 56, 43,217, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,232,117,217, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -232,117,217, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,232,117,217, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -232,117,217, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,232,117,217, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -232,117,217, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,232,117,217, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -232,117,217, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,232,117,217, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -232,117,217, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 24,157,217, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 24,157,217, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 24,157,217, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 24,157,217, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 24,157,217, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 24,157,217, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 24,157,217, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 24,157,217, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 24,157,217, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 24,157,217, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, -216, 29,218, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, -216, 29,218, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, -216, 29,218, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, -216, 29,218, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, -216, 29,218, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, -216, 29,218, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, -216, 29,218, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, -216, 29,218, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, -216, 29,218, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, - 8, 78,210, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 8, 78,210, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, - 8, 78,210, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 8, 78,210, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, - 8, 78,210, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 8, 78,210, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, - 8, 78,210, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 8, 78,210, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, - 8, 78,210, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 8, 78,210, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, - 8, 78,210, 3, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, - 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, - 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, - 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, - 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, - 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, - 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, - 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, - 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, - 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, - 24, 51,163, 3, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, - 56, 16,215, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 15,215, 3, 0, 0, 0, 0, -232, 35,201, 3, 0, 0, 0, 0, 40, 32,201, 3, 0, 0, 0, 0, 8, 34,201, 3, 0, 0, 0, 0,136, 36,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 4, 0, 0, 85, 0, 0, 0,150, 2, 0, 0, 1, 1,112, 4, 66, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 8, 0,232,105,177, 3, 0, 0, 0, 0,152, 92,215, 3, 0, 0, 0, 0,152, 92,215, 3, 0, 0, 0, 0, - 24,111,215, 3, 0, 0, 0, 0,216,117,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 24,214,207, 3, 0, 0, 0, 0, 88,210,207, 3, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 24,111,215, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0,200,112,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,108, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,142, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 4, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,224,141, 68, 0, 0,200, 65, 0,224,141, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,112, 4, 26, 0,112, 4, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 4, 0, 0, 85, 0, 0, 0,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,112, 4, 26, 0, 10, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 88,199,177, 3, 0, 0, 0, 0,248, 77,163, 3, 0, 0, 0, 0,248, 77,163, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,233,207, 3, 0, 0, 0, 0,120,238,207, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,200,112,215, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0,120,114,215, 3, 0, 0, 0, 0, 24,111,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, - 0,192, 5,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 0,168,195, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, - 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, - 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, - 10, 1, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0, 80, 1,143, 0, 80, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0, 71, 1, 0, 0,150, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,160, 0, 80, 1, 11, 0, 5, 0, 3, 0, 0, 0, 0, 0, 0, 0,160, 0, 50, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 88,195,177, 3, 0, 0, 0, 0,136, 64,163, 3, 0, 0, 0, 0,136, 64,163, 3, 0, 0, 0, 0, -152, 77,215, 3, 0, 0, 0, 0, 8,165,165, 15, 0, 0, 0, 0,136,239,207, 3, 0, 0, 0, 0,184,242,207, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,152, 77,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,120, 79,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,235,223, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,111, 98,106,101, 99,116,109,111, -100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,111, 98,106,101, 99,116,109,111, -100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 79, 98,106,101, 99,116, 32, 84,111,111,108,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,233,253,143, 0,255, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,120, 79,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 88, 81,215, 3, 0, 0, 0, 0, -152, 77,215, 3, 0, 0, 0, 0,136, 0,225, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66,114,117,115,104, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117,254,143, 0,115, 1, - 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 88, 81,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 56, 83,215, 3, 0, 0, 0, 0,120, 79,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95,116,111, -111,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95,116,111, -111,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 84,111,111,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74,254,143, 0, 61, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 56, 83,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 24, 85,215, 3, 0, 0, 0, 0, - 88, 81,215, 3, 0, 0, 0, 0,200, 3,225, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95,115,116,114,111,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95,115,116,114,111,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,116,114,111,107,101, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,254,143, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 24, 85,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,248, 86,215, 3, 0, 0, 0, 0, 56, 83,215, 3, 0, 0, 0, 0,104, 5,225, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95, 99,117, -114,118,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95, 99,117, -114,118,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 67,117,114,118,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45,254,143, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,248, 86,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,216, 88,215, 3, 0, 0, 0, 0, - 24, 85,215, 3, 0, 0, 0, 0, 72, 10,225, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95, 97,112,112,101, 97,114, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95, 97,112,112,101, 97,114, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65,112,112,101, 97,114, 97,110, - 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,229,253,143, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,216, 88,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,200,168,165, 15, 0, 0, 0, 0,248, 86,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,118,101,114,116,101,120,112, 97, -105,110,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,118,101,114,116,101,120,112, 97, -105,110,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 79,112,116,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,149,253,143, 0,146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,200,168,165, 15, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,232,166,165, 15, 0, 0, 0, 0, -216, 88,215, 3, 0, 0, 0, 0, 40, 2,225, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95,116,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95,116,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84,101,120,116,117,114,101, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93,254,143, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,232,166,165, 15, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 8,165,165, 15, 0, 0, 0, 0,200,168,165, 15, 0, 0, 0, 0, 8, 7,225, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,115, 99,117,108,112,116, 95,111,112,116,105,111,110,115, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,115, 99,117,108,112,116, 95,111,112,116,105,111,110,115, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 79,112,116,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21,254,143, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 8,165,165, 15, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -232,166,165, 15, 0, 0, 0, 0,168, 8,225, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95,115, 99,117,108,112,116, 95,115,121,109,109,101,116,114,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95,115, 99,117,108,112,116, 95,115,121,109,109,101,116,114,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,121,109,109,101,116,114,121, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,253,253,143, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,120,114,215, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 40,116,215, 3, 0, 0, 0, 0,200,112,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, - 0, 0, 90,195, 0, 0, 0, 0, 0, 0, 0, 0,227,102, 16, 67, 24, 30, 90,195, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, - 0, 0, 0, 0,215, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, - 0, 0, 0, 0,215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, - 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,216, 0,143, 0,216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0,111, 0, 0, 0, 70, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,160, 0,216, 0, 12, 0, 6, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,136,196,177, 3, 0, 0, 0, 0, 88, 83,163, 3, 0, 0, 0, 0, 88, 83,163, 3, 0, 0, 0, 0, -184, 90,215, 3, 0, 0, 0, 0,184, 90,215, 3, 0, 0, 0, 0,200,243,207, 3, 0, 0, 0, 0,248,246,207, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,184, 90,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,197,177, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 99,117,108,112,116, 32, 77,111,100,101, 0, 32, 77,111,100,101, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,255,144, 0, 16, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0, 40,116,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,216,117,215, 3, 0, 0, 0, 0, -120,114,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 67, 0, 96,158,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, - 0, 96,158,196, 0,128,142,195,163, 0, 0, 0,180, 0, 0, 0, 0, 0, 0, 0,213, 3, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0,213, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 1, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,180, 0, -214, 3,163, 0,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 4, 0, 0,111, 4, 0, 0, -111, 0, 0, 0,150, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, - 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,189,177, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0,216,117,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40,116,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0, 0, 0,111, 4, 0, 0, -111, 0, 0, 0,150, 2, 0, 0,160, 0, 0, 0,111, 4, 0, 0,111, 0, 0, 0,150, 2, 0, 0,208, 3, 40, 2, 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,188,177, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40,151,207, 3, 0, 0, 0, 0,168, 34,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 62,216, 3, 0, 0, 0, 0, - 68, 65, 84, 65,112, 3, 0, 0,168, 62,216, 3, 0, 0, 0, 0,173, 0, 0, 0, 1, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71,137,247, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -142, 6,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, 11,210, 76,190, 0, 0, 0, 0, 68,239,209, 62, 51,177,205,190, -184,158, 81, 63, 0, 0, 0, 0, 70,119,105, 63,143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, - 42, 61,228, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33,210,111,193, 0, 0,128, 63, 68,239,209, 62, 70,119,105, 63, -176, 84, 89,188, 0, 0, 0, 0, 52,177,205,190,142, 74, 70, 62,166, 33,101, 63, 0, 0, 0, 0,185,158, 81, 63, 35, 44,185,190, - 43, 61,228, 62, 0, 0, 0, 0, 62, 95, 68, 65, 51,120,173,192,115,208,213, 64, 0, 0,128, 63,178,157,229, 62, 69,228, 70,191, -116,169, 81,191,184,158, 81,191,117, 90,127, 63, 69,188,191, 62,158, 53,185, 62, 35, 44,185, 62,145,180,109,188, 86,142,221, 63, -218, 72,228,190, 42, 61,228,190, 0, 0, 0, 0, 0, 0, 0, 0, 33,171,108, 65, 33,210,111, 65,100,240,191, 62,110,116, 85, 63, - 48,185, 70,188, 0, 0, 82,180,137,185, 84,190, 30, 18,205, 61, 77,247,236, 62, 0, 0, 40, 51,197,112,117,194,178,208,216, 65, -220,158, 5,194,231,251,159,192,221, 54,114, 66, 29,247,213,193, 58,221, 3, 66, 25, 4,160, 64, 68,239,209, 62, 51,177,205,190, -184,158, 81, 63, 0, 0, 0, 0, 70,119,105, 63,143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, - 42, 61,228, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33,210,111,193, 0, 0,128, 63,178,157,229, 62, 69,228, 70,191, -116,169, 81,191,184,158, 81,191,117, 90,127, 63, 69,188,191, 62,158, 53,185, 62, 35, 44,185, 62,145,180,109,188, 86,142,221, 63, -218, 72,228,190, 42, 61,228,190, 0, 0, 0, 0, 0, 0, 0, 0, 33,171,108, 65, 33,210,111, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60,203, 6, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60,203, 6, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 60,203, 6, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 92, 62, 55, 63, 56,186,224,190, -237,203,148,190, 3,236,234,190, 33,210,111, 65, 33,210,111, 65, 0, 0, 0, 0, 0, 0, 0, 0,114,145,245, 58, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 32, 33, 12, 66, 85,152,137, 66,113, 27,126, 66, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 1, 0, 0,152, 92,215, 3, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65,205,204, 76, 62, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, -200,213,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, - 8, 24,128, 0, 0, 0, 12, 66, 0, 0,128, 63,205,204,204, 61, 0, 0,122, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 83, 78, 0, 0, 8, 1, 0, 0,152, 66,216, 3, 0, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0, 56, 43,217, 3, 0, 0, 0, 0, -248, 9,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 71, 97,109,101, 32, 76, -111,103,105, 99, 0, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 37,201, 3, 0, 0, 0, 0, 72, 45,201, 3, 0, 0, 0, 0, - 40,136,171, 3, 0, 0, 0, 0,184, 80,216, 3, 0, 0, 0, 0, 88, 17,215, 3, 0, 0, 0, 0,248, 22,215, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0, 40, 37,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200, 37,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -200, 37,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,104, 38,201, 3, 0, 0, 0, 0, 40, 37,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,104, 38,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0, 8, 39,201, 3, 0, 0, 0, 0,200, 37,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -126, 7, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8, 39,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, -168, 39,201, 3, 0, 0, 0, 0,104, 38,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0,168, 39,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72, 40,201, 3, 0, 0, 0, 0, - 8, 39,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, - 72, 40,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,232, 40,201, 3, 0, 0, 0, 0,168, 39,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,126, 7,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,232, 40,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0,136, 41,201, 3, 0, 0, 0, 0, 72, 40,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,136, 41,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, - 40, 42,201, 3, 0, 0, 0, 0,232, 40,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6,140, 1, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0, 40, 42,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200, 42,201, 3, 0, 0, 0, 0, -136, 41,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -200, 42,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,104, 43,201, 3, 0, 0, 0, 0, 40, 42,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,126, 7,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,104, 43,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0, 8, 44,201, 3, 0, 0, 0, 0,200, 42,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 64, 5,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8, 44,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, -168, 44,201, 3, 0, 0, 0, 0,104, 43,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 5,234, 3, 1, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0,168, 44,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72, 45,201, 3, 0, 0, 0, 0, - 8, 44,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 1,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, - 72, 45,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 44,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 1,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40,136,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,216,136,171, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 37,201, 3, 0, 0, 0, 0, -104, 38,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216,136,171, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 88, 68,216, 3, 0, 0, 0, 0, 40,136,171, 3, 0, 0, 0, 0,200, 37,201, 3, 0, 0, 0, 0, -168, 39,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88, 68,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 8, 69,216, 3, 0, 0, 0, 0,216,136,171, 3, 0, 0, 0, 0,104, 38,201, 3, 0, 0, 0, 0, - 72, 40,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 8, 69,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,184, 69,216, 3, 0, 0, 0, 0, 88, 68,216, 3, 0, 0, 0, 0,168, 39,201, 3, 0, 0, 0, 0, - 72, 40,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184, 69,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,104, 70,216, 3, 0, 0, 0, 0, 8, 69,216, 3, 0, 0, 0, 0,168, 39,201, 3, 0, 0, 0, 0, -232, 40,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,104, 70,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 24, 71,216, 3, 0, 0, 0, 0,184, 69,216, 3, 0, 0, 0, 0,232, 40,201, 3, 0, 0, 0, 0, -136, 41,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 24, 71,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,200, 71,216, 3, 0, 0, 0, 0,104, 70,216, 3, 0, 0, 0, 0, 8, 39,201, 3, 0, 0, 0, 0, - 40, 42,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200, 71,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,120, 72,216, 3, 0, 0, 0, 0, 24, 71,216, 3, 0, 0, 0, 0,136, 41,201, 3, 0, 0, 0, 0, - 40, 42,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,120, 72,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 40, 73,216, 3, 0, 0, 0, 0,200, 71,216, 3, 0, 0, 0, 0, 40, 37,201, 3, 0, 0, 0, 0, -232, 40,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40, 73,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,216, 73,216, 3, 0, 0, 0, 0,120, 72,216, 3, 0, 0, 0, 0, 40, 37,201, 3, 0, 0, 0, 0, - 40, 42,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216, 73,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,136, 74,216, 3, 0, 0, 0, 0, 40, 73,216, 3, 0, 0, 0, 0, 72, 40,201, 3, 0, 0, 0, 0, -200, 42,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136, 74,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 56, 75,216, 3, 0, 0, 0, 0,216, 73,216, 3, 0, 0, 0, 0, 8, 39,201, 3, 0, 0, 0, 0, -200, 42,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56, 75,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,232, 75,216, 3, 0, 0, 0, 0,136, 74,216, 3, 0, 0, 0, 0,136, 41,201, 3, 0, 0, 0, 0, -200, 42,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,232, 75,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,152, 76,216, 3, 0, 0, 0, 0, 56, 75,216, 3, 0, 0, 0, 0,104, 43,201, 3, 0, 0, 0, 0, - 8, 44,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,152, 76,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 72, 77,216, 3, 0, 0, 0, 0,232, 75,216, 3, 0, 0, 0, 0, 72, 40,201, 3, 0, 0, 0, 0, - 8, 44,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72, 77,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,248, 77,216, 3, 0, 0, 0, 0,152, 76,216, 3, 0, 0, 0, 0,200, 42,201, 3, 0, 0, 0, 0, -104, 43,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,248, 77,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,168, 78,216, 3, 0, 0, 0, 0, 72, 77,216, 3, 0, 0, 0, 0,232, 40,201, 3, 0, 0, 0, 0, -168, 44,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,168, 78,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 88, 79,216, 3, 0, 0, 0, 0,248, 77,216, 3, 0, 0, 0, 0,104, 43,201, 3, 0, 0, 0, 0, -168, 44,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88, 79,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 8, 80,216, 3, 0, 0, 0, 0,168, 78,216, 3, 0, 0, 0, 0,168, 39,201, 3, 0, 0, 0, 0, - 72, 45,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 8, 80,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0,184, 80,216, 3, 0, 0, 0, 0, 88, 79,216, 3, 0, 0, 0, 0, 8, 44,201, 3, 0, 0, 0, 0, - 72, 45,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184, 80,216, 3, 0, 0, 0, 0, -212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80,216, 3, 0, 0, 0, 0,168, 44,201, 3, 0, 0, 0, 0, - 72, 45,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 88, 17,215, 3, 0, 0, 0, 0, -214, 0, 0, 0, 1, 0, 0, 0,120, 18,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 39,201, 3, 0, 0, 0, 0, -200, 37,201, 3, 0, 0, 0, 0,104, 38,201, 3, 0, 0, 0, 0, 72, 40,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,126, 7, 0, 0,235, 3, 0, 0, 5, 4, 0, 0, 7, 7,127, 7, 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,216,199,207, 3, 0, 0, 0, 0,216,199,207, 3, 0, 0, 0, 0,136,119,215, 3, 0, 0, 0, 0, - 56,121,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136,119,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, - 56,121,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,148, 68, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0,224,239, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, - 0,192,239, 68, 0, 0,200, 65, 0,192,239, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, - 4, 0, 12, 0, 10, 0,127, 7, 26, 0,127, 7, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,126, 7, 0, 0,235, 3, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -127, 7, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 56,121,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,136,119,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,109, 69, 0, 0,128,192, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,238, 68, 0, 0, 0, 0, 0, 0, 0, 64,112, 7, 0, 0,129, 7, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 2, 0, 0, 0, 1, 0, 3, 3, - 2, 0, 0, 4, 10, 0,129, 7, 2, 0,112, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,120, 18,215, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, -152, 19,215, 3, 0, 0, 0, 0, 88, 17,215, 3, 0, 0, 0, 0, 40, 42,201, 3, 0, 0, 0, 0,136, 41,201, 3, 0, 0, 0, 0, -200, 42,201, 3, 0, 0, 0, 0, 8, 39,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, - 0, 0, 0, 0,139, 1, 0, 0, 4, 4, 94, 1,140, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 56,128,199, 3, 0, 0, 0, 0, 56,128,199, 3, 0, 0, 0, 0,232,122,215, 3, 0, 0, 0, 0,152,124,215, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0,232,122,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,152,124,215, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,148, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,175, 67, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,174, 67, 0, 0,200, 65, - 0,128,174, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 94, 1, - 26, 0, 94, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, -114, 1, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 1, 26, 0, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0,152,124,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -232,122,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,174, 67, 0, 0, 61,196, 0, 0, 0, 0, 0, 0, 0, 0,255,127,166, 67, -255,255,184,195, 0, 0, 0, 0, 77, 1, 0, 0, 94, 1, 0, 0, 0, 0, 0, 0,113, 1, 0, 0, 0, 0, 0, 0, 78, 1, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 76, 1, 0, 0, 0, 0, 0, 0,113, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 1, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0, 94, 1, -114, 1, 77, 1,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, - 0, 0, 0, 0,113, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 1,114, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 94,215, 3, 0, 0, 0, 0,184,205,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,120, 94,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 88, 96,215, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, - 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, - 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,110,116,101,120,116, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,255, 76, 1, 36, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 88, 96,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 56, 98,215, 3, 0, 0, 0, 0,120, 94,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,255, 76, 1, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 56, 98,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 24,100,215, 3, 0, 0, 0, 0, - 88, 96,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 97,121,101,114,115, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111,255, 76, 1, 0, 0, - 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 24,100,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,248,101,215, 3, 0, 0, 0, 0, 56, 98,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,254, 76, 1,203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,248,101,215, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,216,103,215, 3, 0, 0, 0, 0, - 24,100,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65,110,116,105, 45, 65,108,105, - 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58,254, 76, 1, 58, 0, - 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,216,103,215, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 88,196,216, 3, 0, 0, 0, 0,248,101,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83, 97,109,112,108,101,100, 32, 77,111,116,105,111,110, 32, 66,108,117,114, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,254, 76, 1, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 88,196,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 56,198,216, 3, 0, 0, 0, 0, -216,103,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,104, 97,100,105,110,103, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,254, 76, 1, 0, 0, - 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 56,198,216, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 24,200,216, 3, 0, 0, 0, 0, 88,196,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 80,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,242,253, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0, 24,200,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,248,201,216, 3, 0, 0, 0, 0, - 56,198,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,111,115,116, 32, 80,114,111, - 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,218,253, 76, 1, 0, 0, - 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,248,201,216, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0,216,203,216, 3, 0, 0, 0, 0, 24,200,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 83,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194,253, 76, 1, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 88, 1, 0, 0,216,203,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,184,205,216, 3, 0, 0, 0, 0, -248,201,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, - 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79,117,116,112,117,116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,253, 76, 1,130, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,184,205,216, 3, 0, 0, 0, 0, -213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,203,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,253, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65,248, 0, 0, 0, 56,128,199, 3, 0, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 21, 0, 0,160, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,152, 19,215, 3, 0, 0, 0, 0, -214, 0, 0, 0, 1, 0, 0, 0,184, 20,215, 3, 0, 0, 0, 0,120, 18,215, 3, 0, 0, 0, 0, 40, 37,201, 3, 0, 0, 0, 0, -232, 40,201, 3, 0, 0, 0, 0,136, 41,201, 3, 0, 0, 0, 0, 40, 42,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 31, 6, 0, 0, 0, 0, 0, 0,139, 1, 0, 0, 17, 17, 32, 6,140, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,248,217,208, 3, 0, 0, 0, 0,248,217,208, 3, 0, 0, 0, 0, 72,126,215, 3, 0, 0, 0, 0, -168,129,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72,126,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, -248,127,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 67, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0, 0,196, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, - 0,224,195, 68, 0, 0,200, 65, 0,224,195, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, - 4, 0, 12, 0, 10, 0, 32, 6, 26, 0, 32, 6, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 31, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 32, 6, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248,127,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, -168,129,215, 3, 0, 0, 0, 0, 72,126,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 67, 0, 0,185,195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 75, 67, 0, 0,185,195, 0, 0, 0, 0,203, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0,113, 1, 0, 0, - 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0,113, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, - 18, 0, 0, 4, 6, 0,220, 0,114, 1,203, 0,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,219, 0, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -220, 0,114, 1, 0, 0, 4, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,207,216, 3, 0, 0, 0, 0, -152,207,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,152,207,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 76, 79, 71, 73, 67, 95, 80, 84, 95,112,114,111,112,101,114,116,105,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 76, 79, 71, 73, 67, 95, 80, 84, 95,112,114,111,112,101,114,116,105,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 80,114,111,112,101,114,116,105,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,196,255,203, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -168,129,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,127,215, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,160, 68, 0, 0, 0, 0, 0, 0,112, 67, 0, 80, 31,195, 0,234,179, 68,224,198,182,194,184,177,165, 67, - 51, 5, 0, 0, 68, 5, 0, 0, 18, 0, 0, 0,113, 1, 0, 0, 0, 0, 0, 0, 50, 5, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0, 50, 5, 0, 0, 18, 0, 0, 0,113, 1, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,250, 70, 0, 0,250, 70, - 0, 0, 0, 63, 72,225,154, 63, 10, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 68, 5,114, 1, 51, 5, 96, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0, 0, 0, 31, 6, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 5,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 72, 0, 0, 0, -248,217,208, 3, 0, 0, 0, 0,192, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, -184, 20,215, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,216, 21,215, 3, 0, 0, 0, 0,152, 19,215, 3, 0, 0, 0, 0, -104, 43,201, 3, 0, 0, 0, 0, 8, 44,201, 3, 0, 0, 0, 0, 72, 40,201, 3, 0, 0, 0, 0,200, 42,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 65, 5, 0, 0,126, 7, 0, 0,141, 1, 0, 0,233, 3, 0, 0, 9, 9, 62, 2, 93, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,228,216, 3, 0, 0, 0, 0, 40,228,216, 3, 0, 0, 0, 0, - 88,131,215, 3, 0, 0, 0, 0, 8,133,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88,131,215, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 8,133,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230, 67, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,128, 15, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 2, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0, 64, 15, 68, 0, 0,200, 65, 0, 64, 15, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 62, 2, 26, 0, 62, 2, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 65, 5, 0, 0,126, 7, 0, 0,141, 1, 0, 0,166, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 62, 2, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8,133,215, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,131,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,181, 67, - 0, 0, 0, 0, 0,128,218, 67, 0, 0, 0, 0,131,248, 1, 68, 0, 0, 0, 0, 86, 26, 3, 68, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 2, 0, 0, - 0, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,215, 35, 60, 0, 0,122, 68, - 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 4, 10, 0, 62, 2, 67, 2, 62, 2, 67, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 65, 5, 0, 0,126, 7, 0, 0,167, 1, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 62, 2, 67, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 2, 0, 0, 40,228,216, 3, 0, 0, 0, 0, -186, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,216, 21,215, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, -248, 22,215, 3, 0, 0, 0, 0,184, 20,215, 3, 0, 0, 0, 0,168, 44,201, 3, 0, 0, 0, 0, 72, 45,201, 3, 0, 0, 0, 0, - 8, 44,201, 3, 0, 0, 0, 0,104, 43,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 63, 5, 0, 0, -141, 1, 0, 0,233, 3, 0, 0, 1, 1,251, 3, 93, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -120,209,216, 3, 0, 0, 0, 0,120,209,216, 3, 0, 0, 0, 0,184,134,215, 3, 0, 0, 0, 0,216,234,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0,184,134,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,104,136,215, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,113, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,192,126, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,126, 68, 0, 0,200, 65, - 0,128,126, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,251, 3, - 26, 0,251, 3, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 63, 5, 0, 0, -141, 1, 0, 0,166, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,251, 3, 26, 0, 0, 0, 1, 0, - 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0,104,136,215, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,120,231,216, 3, 0, 0, 0, 0, -184,134,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 64, 70,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, -255,127, 70,196, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0, - 44, 3,143, 0, 26, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, -167, 1, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 67, 2, 0, 0, 5, 0, - 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0,120,231,216, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 40,233,216, 3, 0, 0, 0, 0, -104,136,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 67, 0, 0,206,194, 0, 0, 0, 0, 0, 0, 0, 0,231,102, 16, 67, - 0, 0,206,194, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0, -120, 0,143, 0,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 63, 5, 0, 0, -167, 1, 0, 0,167, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 6, 0, - 34, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0, 40,233,216, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,216,234,216, 3, 0, 0, 0, 0, -120,231,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 67, 0, 0,109,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, - 0, 0,109,196, 0,128,145,195,163, 0, 0, 0,180, 0, 0, 0, 0, 0, 0, 0,144, 2, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0,144, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 1, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,180, 0, -145, 2,163, 0,145, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 5, 0, 0, 63, 5, 0, 0, -167, 1, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, - 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0,216,234,216, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40,233,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 63, 5, 0, 0, -167, 1, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,251, 3, 67, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 7,217, 3, 0, 0, 0, 0, - 68, 65, 84, 65,112, 3, 0, 0, 72, 7,217, 3, 0, 0, 0, 0,173, 0, 0, 0, 1, 0, 0, 0,190, 35, 30, 61, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 40,139, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -111, 18, 3,187, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,190, 35, 30, 61, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 40,139, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -111, 18, 3,187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,149, 53,207, 65, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,112,121,107, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255,255,249,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,190, 35, 30, 61, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 40,139, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -111, 18, 3,187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,207, 3,116, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,207, 3,116, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, 3,116, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,149, 53,207, 65,214,211,111, 65, 0, 0, 0, 0, 0, 0, 0, 0,221, 57, 80, 61, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 65, 0, 0, 5, 0,251,251, 0, 0, 92, 62, 55, 63, 56,186,224,190,237,203,148,190, - 3,236,234,190, 1, 0, 0, 0, 0, 0,128, 63, 0, 0,180, 66, 0, 0,180, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 1, 0, 0,120,209,216, 3, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65,205,204, 76, 62, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, -200,213,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, - 8, 8,128, 0, 0, 0, 12, 66, 0, 0,128, 63,205,204,204, 61, 0, 0,122, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65,160, 0, 0, 0,248, 22,215, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -216, 21,215, 3, 0, 0, 0, 0,232, 40,201, 3, 0, 0, 0, 0,168, 39,201, 3, 0, 0, 0, 0, 72, 45,201, 3, 0, 0, 0, 0, -168, 44,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 1, 0, 0,141, 1, 0, 0,233, 3, 0, 0, - 3, 3, 68, 1, 93, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 2,209, 3, 0, 0, 0, 0, -104, 2,209, 3, 0, 0, 0, 0,136,236,216, 3, 0, 0, 0, 0, 56,238,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -136,236,216, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 56,238,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,128,244, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,162, 67, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,161, 67, 0, 0,200, 65, 0,128,161, 67, 0, 0,200, 65, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 68, 1, 26, 0, 68, 1, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 1, 0, 0,141, 1, 0, 0,166, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, - 56,238,216, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,236,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0,128,141, 67, 0, 0,244,194, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,153, 67, 0, 64, 12,196, 0, 0, 0, 0, - 51, 1, 0, 0, 68, 1, 0, 0, 18, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0, 50, 1, 0, 0, 18, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 18, 6, 0, 0, 2, 0, 3, 3, 0, 0, 12, 4, 6, 0, 68, 1, 67, 2, 51, 1, 49, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 1, 0, 0,167, 1, 0, 0,233, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 1, 67, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 1, 0, 0, -104, 2,209, 3, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,104, 11,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65, 16, 0, 0, 0,104, 11,217, 3, 0, 0, 0, 0,237, 0, 0, 0, 1, 0, 0, 0, - 14, 0, 0, 0, 14, 0, 0, 0, 88, 32,199, 3, 0, 0, 0, 0, 68, 65, 84, 65,224, 0, 0, 0, 88, 32,199, 3, 0, 0, 0, 0, -236, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, 19, 0, 0, 0, 1, 0, 1, 0, -168,194,217, 3, 0, 0, 0, 0, 20, 0, 0, 0, 1, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, 21, 0, 1, 0, 1, 0, 0, 0, -168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 24, 51,163, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, -184,219,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,136, 48,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, -152, 7,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,216, 29,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, -168,225,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,120,209,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, -200,213,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 24, 98,200, 3, 0, 0, 0, 0, 21, 0, 0, 0, 1, 0, 1, 0, -168,194,217, 3, 0, 0, 0, 0, 83, 78, 0, 0, 8, 1, 0, 0, 56, 43,217, 3, 0, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0, -232,117,217, 3, 0, 0, 0, 0,152, 66,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 83, 82, 83, 99,114,105,112,116,105,110,103, 0,103, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232, 45,201, 3, 0, 0, 0, 0, - 8, 54,201, 3, 0, 0, 0, 0,104, 81,216, 3, 0, 0, 0, 0,216, 95,216, 3, 0, 0, 0, 0, 24, 24,215, 3, 0, 0, 0, 0, -184, 29,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,232, 45,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, -136, 46,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0,136, 46,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40, 47,201, 3, 0, 0, 0, 0, -232, 45,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, - 40, 47,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200, 47,201, 3, 0, 0, 0, 0,136, 46,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,200, 47,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0,104, 48,201, 3, 0, 0, 0, 0, 40, 47,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -126, 7, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,104, 48,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, - 8, 49,201, 3, 0, 0, 0, 0,200, 47,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 3, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0, 8, 49,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,168, 49,201, 3, 0, 0, 0, 0, -104, 48,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,168, 3, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -168, 49,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72, 50,201, 3, 0, 0, 0, 0, 8, 49,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,240, 5,168, 3, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72, 50,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0,232, 50,201, 3, 0, 0, 0, 0,168, 49,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 5, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,232, 50,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, -136, 51,201, 3, 0, 0, 0, 0, 72, 50,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 1, 1, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0,136, 51,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40, 52,201, 3, 0, 0, 0, 0, -232, 50,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 5,104, 1, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, - 40, 52,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200, 52,201, 3, 0, 0, 0, 0,136, 51,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,248, 2,104, 1, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,200, 52,201, 3, 0, 0, 0, 0, -211, 0, 0, 0, 1, 0, 0, 0,104, 53,201, 3, 0, 0, 0, 0, 40, 52,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 5,236, 2, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,104, 53,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, - 8, 54,201, 3, 0, 0, 0, 0,200, 52,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,236, 2, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0, 8, 54,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -104, 53,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 2,168, 3, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -104, 81,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24, 82,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -136, 46,201, 3, 0, 0, 0, 0, 40, 47,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 24, 82,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200, 82,216, 3, 0, 0, 0, 0,104, 81,216, 3, 0, 0, 0, 0, -136, 46,201, 3, 0, 0, 0, 0,104, 48,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -200, 82,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120, 83,216, 3, 0, 0, 0, 0, 24, 82,216, 3, 0, 0, 0, 0, - 40, 47,201, 3, 0, 0, 0, 0, 8, 49,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -120, 83,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40, 84,216, 3, 0, 0, 0, 0,200, 82,216, 3, 0, 0, 0, 0, -104, 48,201, 3, 0, 0, 0, 0, 8, 49,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 40, 84,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216, 84,216, 3, 0, 0, 0, 0,120, 83,216, 3, 0, 0, 0, 0, - 8, 49,201, 3, 0, 0, 0, 0,168, 49,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -216, 84,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,136, 85,216, 3, 0, 0, 0, 0, 40, 84,216, 3, 0, 0, 0, 0, -200, 47,201, 3, 0, 0, 0, 0, 72, 50,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -136, 85,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56, 86,216, 3, 0, 0, 0, 0,216, 84,216, 3, 0, 0, 0, 0, -232, 45,201, 3, 0, 0, 0, 0,232, 50,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 56, 86,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232, 86,216, 3, 0, 0, 0, 0,136, 85,216, 3, 0, 0, 0, 0, -104, 48,201, 3, 0, 0, 0, 0,232, 50,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -232, 86,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152, 87,216, 3, 0, 0, 0, 0, 56, 86,216, 3, 0, 0, 0, 0, -168, 49,201, 3, 0, 0, 0, 0,136, 51,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -152, 87,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72, 88,216, 3, 0, 0, 0, 0,232, 86,216, 3, 0, 0, 0, 0, - 72, 50,201, 3, 0, 0, 0, 0,136, 51,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 72, 88,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,248, 88,216, 3, 0, 0, 0, 0,152, 87,216, 3, 0, 0, 0, 0, -232, 50,201, 3, 0, 0, 0, 0, 40, 52,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -248, 88,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168, 89,216, 3, 0, 0, 0, 0, 72, 88,216, 3, 0, 0, 0, 0, -136, 51,201, 3, 0, 0, 0, 0, 40, 52,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -168, 89,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88, 90,216, 3, 0, 0, 0, 0,248, 88,216, 3, 0, 0, 0, 0, - 72, 50,201, 3, 0, 0, 0, 0,200, 52,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 88, 90,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8, 91,216, 3, 0, 0, 0, 0,168, 89,216, 3, 0, 0, 0, 0, -168, 49,201, 3, 0, 0, 0, 0,200, 52,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 8, 91,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184, 91,216, 3, 0, 0, 0, 0, 88, 90,216, 3, 0, 0, 0, 0, - 8, 49,201, 3, 0, 0, 0, 0,104, 53,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -184, 91,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104, 92,216, 3, 0, 0, 0, 0, 8, 91,216, 3, 0, 0, 0, 0, -200, 47,201, 3, 0, 0, 0, 0,104, 53,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -104, 92,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24, 93,216, 3, 0, 0, 0, 0,184, 91,216, 3, 0, 0, 0, 0, -200, 52,201, 3, 0, 0, 0, 0,104, 53,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 24, 93,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200, 93,216, 3, 0, 0, 0, 0,104, 92,216, 3, 0, 0, 0, 0, -104, 48,201, 3, 0, 0, 0, 0, 8, 54,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -200, 93,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120, 94,216, 3, 0, 0, 0, 0, 24, 93,216, 3, 0, 0, 0, 0, -168, 49,201, 3, 0, 0, 0, 0, 8, 54,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -120, 94,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40, 95,216, 3, 0, 0, 0, 0,200, 93,216, 3, 0, 0, 0, 0, - 40, 52,201, 3, 0, 0, 0, 0, 8, 54,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 40, 95,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216, 95,216, 3, 0, 0, 0, 0,120, 94,216, 3, 0, 0, 0, 0, -232, 50,201, 3, 0, 0, 0, 0,136, 51,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -216, 95,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 95,216, 3, 0, 0, 0, 0, -232, 45,201, 3, 0, 0, 0, 0, 72, 50,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, - 24, 24,215, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 56, 25,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -104, 48,201, 3, 0, 0, 0, 0,136, 46,201, 3, 0, 0, 0, 0, 40, 47,201, 3, 0, 0, 0, 0, 8, 49,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,169, 3, 0, 0, 5, 4, 0, 0, 7, 7,127, 7, 93, 0, 1, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,200,207, 3, 0, 0, 0, 0,152,200,207, 3, 0, 0, 0, 0, -232,239,216, 3, 0, 0, 0, 0,152,241,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,232,239,216, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0,152,241,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,148, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,239, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, 0, 0,200, 65, 0,192,239, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,127, 7, 26, 0,127, 7, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,236, 3, 0, 0, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,152,241,216, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,239,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,239, 68, - 0, 0, 0, 0, 0, 0, 28, 66, 0, 0, 0, 0, 0,192,237, 68, 0, 0, 0, 0, 0, 0,134, 66,110, 7, 0, 0,127, 7, 0, 0, - 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,109, 7, 0, 0, - 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 2, 2, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, 10, 0,127, 7, 67, 0,110, 7, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,169, 3, 0, 0,235, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 56, 25,215, 3, 0, 0, 0, 0, -214, 0, 0, 0, 1, 0, 0, 0, 88, 26,215, 3, 0, 0, 0, 0, 24, 24,215, 3, 0, 0, 0, 0, 72, 50,201, 3, 0, 0, 0, 0, -200, 52,201, 3, 0, 0, 0, 0,104, 53,201, 3, 0, 0, 0, 0,200, 47,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, 5, 0, 0,126, 7, 0, 0, 0, 0, 0, 0,235, 2, 0, 0, 4, 4,142, 1,236, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,184,129,199, 3, 0, 0, 0, 0,184,129,199, 3, 0, 0, 0, 0, 72,243,216, 3, 0, 0, 0, 0, -248,244,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72,243,216, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, -248,244,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,148, 67, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0, 0,199, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,141, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, - 0,128,198, 67, 0, 0,200, 65, 0,128,198, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, - 4, 0, 12, 0, 10, 0,142, 1, 26, 0,142, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, 5, 0, 0,126, 7, 0, 0,210, 2, 0, 0,235, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -142, 1, 26, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248,244,216, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 72,243,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,198, 67, 0, 0, 61,196, 0, 0, 0, 0, - 0, 0, 0, 0,254,127,190, 67,254,127, 52,196, 0, 0, 0, 0,125, 1, 0, 0,142, 1, 0, 0, 0, 0, 0, 0,209, 2, 0, 0, - 0, 0, 0, 0,126, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0,209, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 1, 0, 0, 1, 0, 7, 0, - 18, 0, 0, 4, 6, 0,142, 1,210, 2,125, 1,210, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, 5, 0, 0,126, 7, 0, 0, 0, 0, 0, 0,209, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -142, 1,210, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,211,216, 3, 0, 0, 0, 0, -152, 50,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 88,211,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, - 56,213,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 67,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,220,255,124, 1, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, - 56,213,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 24,215,216, 3, 0, 0, 0, 0, 88,211,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,255,124, 1, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 24,215,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, -248,216,216, 3, 0, 0, 0, 0, 56,213,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 76, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,111,255,124, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, -248,216,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,216,218,216, 3, 0, 0, 0, 0, 24,215,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115, -105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115, -105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,254,124, 1,203, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,216,218,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, -184,220,216, 3, 0, 0, 0, 0,248,216,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 65,110,116,105, 45, 65,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 58,254,124, 1, 58, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, -184,220,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,152,222,216, 3, 0, 0, 0, 0,216,218,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, - 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, - 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 97,109,112,108,101,100, 32, 77,111,116,105,111,110, 32, 66, -108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,254,124, 1, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,152,222,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, -120,224,216, 3, 0, 0, 0, 0,184,220,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 83,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 10,254,124, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, -120,224,216, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,248, 44,217, 3, 0, 0, 0, 0,152,222,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114, -109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114, -109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,242,253,124, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,248, 44,217, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, -216, 46,217, 3, 0, 0, 0, 0,120,224,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 80,111,115,116, 32, 80,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,218,253,124, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, -216, 46,217, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,184, 48,217, 3, 0, 0, 0, 0,248, 44,217, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194,253,124, 1, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,184, 48,217, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, -152, 50,217, 3, 0, 0, 0, 0,216, 46,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 79,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 40,253,124, 1,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, -152, 50,217, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 48,217, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,253,124, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,184,129,199, 3, 0, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 21, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, - 88, 26,215, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,120, 27,215, 3, 0, 0, 0, 0, 56, 25,215, 3, 0, 0, 0, 0, - 40, 52,201, 3, 0, 0, 0, 0, 8, 54,201, 3, 0, 0, 0, 0,168, 49,201, 3, 0, 0, 0, 0,136, 51,201, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,249, 2, 0, 0,239, 5, 0, 0,105, 1, 0, 0,167, 3, 0, 0, 1, 1,247, 2, 63, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 52,217, 3, 0, 0, 0, 0,120, 52,217, 3, 0, 0, 0, 0, -168,246,216, 3, 0, 0, 0, 0,104,253,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168,246,216, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 88,248,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,113, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,192, 61, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,246, 2, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,128, 61, 68, 0, 0,200, 65, 0,128, 61, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,247, 2, 26, 0,247, 2, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,249, 2, 0, 0,239, 5, 0, 0,105, 1, 0, 0,130, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,247, 2, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88,248,216, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 8,250,216, 3, 0, 0, 0, 0,168,246,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, - 0, 64, 70,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67,255,127, 70,196, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, - 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, - 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, - 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0, 44, 3,143, 0, 26, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,249, 2, 0, 0,249, 2, 0, 0,131, 1, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 37, 2, 0, 0, 5, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8,250,216, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0,184,251,216, 3, 0, 0, 0, 0, 88,248,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 67, - 0, 0,206,194, 0, 0, 0, 0, 0, 0, 0, 0,231,102, 16, 67, 0, 0,206,194, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, - 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, - 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, - 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,120, 0,143, 0,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,249, 2, 0, 0,239, 5, 0, 0,131, 1, 0, 0,131, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 6, 0, 34, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,184,251,216, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0,104,253,216, 3, 0, 0, 0, 0, 8,250,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, - 0,128,142,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, 0, 0, 26,196, 0, 0, 0, 0,163, 0, 0, 0,180, 0, 0, 0, - 18, 0, 0, 0,121, 2, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, - 18, 0, 0, 0,121, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, - 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,180, 0,122, 2,163, 0,104, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,239, 5, 0, 0,239, 5, 0, 0,131, 1, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,104,253,216, 3, 0, 0, 0, 0, -215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,251,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,249, 2, 0, 0,239, 5, 0, 0,131, 1, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,247, 2, 37, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,200, 76,217, 3, 0, 0, 0, 0, 68, 65, 84, 65,112, 3, 0, 0,200, 76,217, 3, 0, 0, 0, 0, -173, 0, 0, 0, 1, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74,141,193, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, -225,215,163,188, 0, 0, 0, 0, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, 0, 0, 0, 0, 70,119,105, 63,143, 74, 70, 62, - 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -214,211,111,193, 0, 0,128, 63, 69,239,209, 62, 70,119,105, 63,176, 84, 89,188, 0, 0, 0, 0, 53,177,205,190,142, 74, 70, 62, -166, 33,101, 63, 0, 0, 0, 0,185,158, 81, 63, 35, 44,185,190, 43, 61,228, 62, 0, 0, 0, 0,164, 96, 68, 65,111,121,173,192, -248,209,213, 64, 0, 0,128, 63,178,157,229, 62, 30,132, 27,191,222,160, 81,191,184,158, 81,191,117, 90,127, 63,166,235,149, 62, - 9, 46,185, 62, 35, 44,185, 62,145,180,109,188,212, 60,173, 63,129, 63,228,190, 42, 61,228,190, 0, 0, 0, 0, 0, 0, 0, 0, - 96,132,111, 65,214,211,111, 65,217,236,191, 62, 54,117, 85, 63,224,246, 70,188, 0,160, 32,182,252, 5,136,190, 43, 33, 3, 62, -235,135, 23, 63, 0, 0, 96, 53,215,104, 25,196,133,132,135, 67, 37, 9,167,195,136,252, 71,194, 3, 54, 25, 68,158, 87,135,195, -205,209,166, 67,151,254, 71, 66, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, 0, 0, 0, 0, 70,119,105, 63,143, 74, 70, 62, - 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -214,211,111,193, 0, 0,128, 63,178,157,229, 62, 30,132, 27,191,222,160, 81,191,184,158, 81,191,117, 90,127, 63,166,235,149, 62, - 9, 46,185, 62, 35, 44,185, 62,145,180,109,188,212, 60,173, 63,129, 63,228,190, 42, 61,228,190, 0, 0, 0, 0, 0, 0, 0, 0, - 96,132,111, 65,214,211,111, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 46, 86, 45, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 86, 45, 64, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 86, 45, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 92, 62, 55, 63, 56,186,224,190,237,203,148,190, 3,236,234,190,214,211,111, 65,214,211,111, 65, - 0, 0, 0, 0, 0, 0, 0, 0,107,227, 29, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, -255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 30, 33, 12, 66, - 86,152,137, 66,116, 27,126, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 1, 0, 0, -120, 52,217, 3, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65,205,204, 76, 62, - 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,200,213,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, 8, 8,128, 0, 0, 0, 12, 66, 0, 0,128, 63, 10,215, 35, 60, - 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, - 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,120, 27,215, 3, 0, 0, 0, 0, -214, 0, 0, 0, 1, 0, 0, 0,152, 28,215, 3, 0, 0, 0, 0, 88, 26,215, 3, 0, 0, 0, 0,232, 45,201, 3, 0, 0, 0, 0, -232, 50,201, 3, 0, 0, 0, 0,136, 51,201, 3, 0, 0, 0, 0, 72, 50,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,239, 5, 0, 0, 0, 0, 0, 0,103, 1, 0, 0, 18, 18,240, 5,104, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,184, 80,217, 3, 0, 0, 0, 0,184, 80,217, 3, 0, 0, 0, 0, 24,255,216, 3, 0, 0, 0, 0, -200, 0,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 24,255,216, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, -200, 0,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,160, 67, 0, 0, 0, 0, 0, 0,208, 65, - 0, 0, 0, 0, 0, 0,190, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,239, 5, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, - 0,224,189, 68, 0, 0,200, 65, 0,224,189, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, - 4, 0, 12, 0, 10, 0,240, 5, 26, 0,240, 5, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,239, 5, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 5, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,200, 0,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 24,255,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,189, 68, 0, 0, 0, 0, 0, 0, 51, 67, - 0, 0, 0, 0, 0,224,187, 68, 0, 0, 0, 0, 0, 0,167, 67,223, 5, 0, 0,240, 5, 0, 0, 0, 0, 0, 0, 77, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,222, 5, 0, 0, 0, 0, 0, 0, 77, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 2, 2, 0, 0, 1, 0, 3, 3, - 2, 0, 0, 4, 10, 0,240, 5, 78, 1,223, 5, 78, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,239, 5, 0, 0, 26, 0, 0, 0,103, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 5, 78, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136, 96,216, 3, 0, 0, 0, 0,193, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 40,182,117, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0, 40,182,117, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65,136, 1, 0, 0,184, 80,217, 3, 0, 0, 0, 0,194, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 96,216, 3, 0, 0, 0, 0,136, 96,216, 3, 0, 0, 0, 0, 62, 62, 62, 32, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,112,121,116,104, -111,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 0, 0, - 8, 4, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,152, 28,215, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,184, 29,215, 3, - 0, 0, 0, 0,120, 27,215, 3, 0, 0, 0, 0,200, 52,201, 3, 0, 0, 0, 0,168, 49,201, 3, 0, 0, 0, 0, 8, 49,201, 3, - 0, 0, 0, 0,104, 53,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241, 5, 0, 0,126, 7, 0, 0,237, 2, 0, 0, -167, 3, 0, 0, 3, 3,142, 1,187, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4,209, 3, - 0, 0, 0, 0, 8, 4,209, 3, 0, 0, 0, 0,120, 2,217, 3, 0, 0, 0, 0, 40, 4,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 1, 0, 0,120, 2,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 40, 4,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,128,244, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,199, 67, 0, 0, 0, 0, - 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,141, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,198, 67, 0, 0,200, 65, 0,128,198, 67, - 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,142, 1, 26, 0,142, 1, - 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241, 5, 0, 0,126, 7, 0, 0,237, 2, 0, 0, - 6, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 1, 0, 0, 40, 4,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 2,217, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0,128,141, 67, 0, 0,244,194, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,190, 67, 0, 0, 15,195, - 0, 0, 0, 0,125, 1, 0, 0,142, 1, 0, 0, 18, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, - 17, 0, 0, 0, 0, 0, 0, 0,124, 1, 0, 0, 18, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 18, 6, 0, 0, 2, 0, 3, 3, 0, 0, 12, 4, 6, 0,142, 1,161, 0,125, 1, -143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241, 5, 0, 0,126, 7, 0, 0, 7, 3, 0, 0, -167, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 1,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 24, 1, 0, 0, 8, 4,209, 3, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 11,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65, 16, 0, 0, 0,248, 11,217, 3, 0, 0, 0, 0,237, 0, 0, 0, - 1, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0,184, 33,199, 3, 0, 0, 0, 0, 68, 65, 84, 65,224, 0, 0, 0,184, 33,199, 3, - 0, 0, 0, 0,236, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, 19, 0, 0, 0, - 1, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, 20, 0, 0, 0, 1, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, 21, 0, 1, 0, - 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 24, 51,163, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 0,184,219,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,136, 48,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 0,152, 7,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,216, 29,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 0,168,225,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,120,209,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 0,200,213,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 24, 98,200, 3, 0, 0, 0, 0, 21, 0, 0, 0, - 1, 0, 1, 0,168,194,217, 3, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,184, 29,215, 3, 0, 0, 0, 0,214, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 28,215, 3, 0, 0, 0, 0,232, 50,201, 3, 0, 0, 0, 0,104, 48,201, 3, - 0, 0, 0, 0, 8, 54,201, 3, 0, 0, 0, 0, 40, 52,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, 2, 0, 0,105, 1, 0, 0,167, 3, 0, 0, 9, 9,248, 2, 63, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,200,114,217, 3, 0, 0, 0, 0,200,114,217, 3, 0, 0, 0, 0,248, 82,217, 3, 0, 0, 0, 0,168, 84,217, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248, 82,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,168, 84,217, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, - 0, 0, 62, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,247, 2, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192, 61, 68, - 0, 0,200, 65, 0,192, 61, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, - 10, 0,248, 2, 26, 0,248, 2, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, 2, 0, 0,105, 1, 0, 0,130, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 2, 26, 0, - 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168, 84,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,248, 82,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,189, 68, 0, 0, 0, 0, 0,192, 22, 68,248,150, 23, 68, - 8, 41,100, 68, 46,224, 62, 67,233, 15,206, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,247, 2, 0, 0, 0, 0, 0, 0, 36, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,215, 35, 60, 0, 0,122, 68, 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 4, - 10, 0,248, 2, 37, 2,248, 2, 37, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, 2, 0, 0,131, 1, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 2, 37, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65,160, 2, 0, 0,200,114,217, 3, 0, 0, 0, 0,186, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 32, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -205,204,204, 61,231, 1, 0, 0,243, 1, 0, 0,122, 1, 0, 0,124, 1, 0, 0,231, 1, 0, 0,243, 1, 0, 0, 4, 0, 0, 0, -124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0, - 8, 1, 0, 0,232,117,217, 3, 0, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0, 24,157,217, 3, 0, 0, 0, 0, 56, 43,217, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 85, 86, 32, 69,100,105,116,105,110,103, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 77, 0, 0, + 88, 1, 0, 0,152,208,194, 6, 0, 0, 0, 0,146, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 77, 87,105,110, 77, 97,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 54,201, 3, 0, 0, 0, 0, 8, 59,201, 3, 0, 0, 0, 0, 56, 97,216, 3, - 0, 0, 0, 0, 24,104,216, 3, 0, 0, 0, 0,216, 30,215, 3, 0, 0, 0, 0, 24, 33,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,210,194, 6, 0, 0, 0, 0, 56,210,194, 6, 0, 0, 0, 0, 56,210,194, 6, + 0, 0, 0, 0, 56,210,194, 6, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 23, 3, 0, 73,127, 0, 0, 56, 25, 3, 0, 73,127, 0, 0, 88, 23, 3, 0, + 73,127, 0, 0, 72, 24, 3, 0, 73,127, 0, 0, 56, 25, 3, 0, 73,127, 0, 0, 40, 26, 3, 0, 73,127, 0, 0, 40, 26, 3, 0, + 73,127, 0, 0, 40, 26, 3, 0, 73,127, 0, 0, 68, 65, 84, 65, 0, 1, 0, 0, 56,210,194, 6, 0, 0, 0, 0,147, 1, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,188, 2, 0, 73,127, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0,248,163,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,115, 99,114,101,101,110, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 6, 1, 0,126, 7,146, 4, 0, 0, 0, 0, + 1, 0,238, 3, 0, 0, 0, 0, 1, 0, 0, 0,200,225, 12, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,184, 35, 13, 0, 73,127, 0, 0, 8, 93,223, 0, 73,127, 0, 0, 8, 93,223, 0, + 73,127, 0, 0, 8,228, 12, 0, 73,127, 0, 0,120,203, 12, 0, 73,127, 0, 0, 56,213,226, 0, 73,127, 0, 0,136,226, 12, 0, + 73,127, 0, 0, 24, 41, 13, 0, 73,127, 0, 0, 8,237,224, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 78, 0, 0, 8, 1, 0, 0,136,211,194, 6, 0, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0,120, 55,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 65,110, +105,109, 97,116,105,111,110, 0, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,154,194, 6, 0, 0, 0, 0,104,219,194, 6, + 0, 0, 0, 0,216,219,194, 6, 0, 0, 0, 0, 24,232,194, 6, 0, 0, 0, 0,136,232,194, 6, 0, 0, 0, 0,168, 45,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,184,154,194, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40,155,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 32, 0, 0, 0,168, 54,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72, 55,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72, 55,201, 3, - 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,232, 55,201, 3, 0, 0, 0, 0,168, 54,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,232, 55,201, 3, 0, 0, 0, 0,211, 0, 0, 0, - 1, 0, 0, 0,136, 56,201, 3, 0, 0, 0, 0, 72, 55,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 5, 4, - 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,136, 56,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40, 57,201, 3, - 0, 0, 0, 0,232, 55,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 32, 0, 0, 0, 40, 57,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200, 57,201, 3, 0, 0, 0, 0,136, 56,201, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,200, 57,201, 3, - 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,104, 58,201, 3, 0, 0, 0, 0, 40, 57,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,126, 7,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,104, 58,201, 3, 0, 0, 0, 0,211, 0, 0, 0, - 1, 0, 0, 0, 8, 59,201, 3, 0, 0, 0, 0,200, 57,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 3,234, 3, - 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8, 59,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,104, 58,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 3, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0, 56, 97,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232, 97,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 72, 55,201, 3, 0, 0, 0, 0,232, 55,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0,232, 97,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152, 98,216, 3, 0, 0, 0, 0, 56, 97,216, 3, - 0, 0, 0, 0, 72, 55,201, 3, 0, 0, 0, 0, 40, 57,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0,152, 98,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72, 99,216, 3, 0, 0, 0, 0,232, 97,216, 3, - 0, 0, 0, 0,232, 55,201, 3, 0, 0, 0, 0,200, 57,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0, 72, 99,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,248, 99,216, 3, 0, 0, 0, 0,152, 98,216, 3, - 0, 0, 0, 0, 40, 57,201, 3, 0, 0, 0, 0,200, 57,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0,248, 99,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168,100,216, 3, 0, 0, 0, 0, 72, 99,216, 3, - 0, 0, 0, 0, 40, 57,201, 3, 0, 0, 0, 0,104, 58,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0,168,100,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88,101,216, 3, 0, 0, 0, 0,248, 99,216, 3, - 0, 0, 0, 0,168, 54,201, 3, 0, 0, 0, 0, 8, 59,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0, 88,101,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8,102,216, 3, 0, 0, 0, 0,168,100,216, 3, - 0, 0, 0, 0,168, 54,201, 3, 0, 0, 0, 0, 40, 57,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0, 8,102,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184,102,216, 3, 0, 0, 0, 0, 88,101,216, 3, - 0, 0, 0, 0,104, 58,201, 3, 0, 0, 0, 0, 8, 59,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0,184,102,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104,103,216, 3, 0, 0, 0, 0, 8,102,216, 3, - 0, 0, 0, 0,200, 57,201, 3, 0, 0, 0, 0,104, 58,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0,104,103,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24,104,216, 3, 0, 0, 0, 0,184,102,216, 3, - 0, 0, 0, 0,136, 56,201, 3, 0, 0, 0, 0, 8, 59,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0, 24,104,216, 3, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,103,216, 3, - 0, 0, 0, 0,136, 56,201, 3, 0, 0, 0, 0,200, 57,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, -160, 0, 0, 0,216, 30,215, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,248, 31,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 40, 57,201, 3, 0, 0, 0, 0, 72, 55,201, 3, 0, 0, 0, 0,232, 55,201, 3, 0, 0, 0, 0,200, 57,201, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,235, 3, 0, 0, 5, 4, 0, 0, 7, 7,127, 7, - 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,201,207, 3, 0, 0, 0, 0, 88,201,207, 3, - 0, 0, 0, 0, 88, 86,217, 3, 0, 0, 0, 0, 8, 88,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88, 86,217, 3, - 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 8, 88,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32,148, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,239, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, 0, 0,200, 65, 0,192,239, 68, 0, 0,200, 65, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,127, 7, 26, 0,127, 7, 26, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,235, 3, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8, 88,217, 3, - 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 86,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0,240,109, 69, 0, 0,128,192, 0, 0, 0, 0, 0, 0, 0, 0,255,255,109, 69, 0, 0, 0,192, 0, 0, 0, 0,112, 7, 0, 0, -129, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, -111, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 2, 0, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, 10, 0,129, 7, 2, 0,112, 7, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 5, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,248, 31,215, 3, - 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 24, 33,215, 3, 0, 0, 0, 0,216, 30,215, 3, 0, 0, 0, 0,168, 54,201, 3, - 0, 0, 0, 0, 40, 57,201, 3, 0, 0, 0, 0,104, 58,201, 3, 0, 0, 0, 0, 8, 59,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,199, 3, 0, 0, 0, 0, 0, 0,233, 3, 0, 0, 6, 6,200, 3,234, 3, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,119,217, 3, 0, 0, 0, 0,120,119,217, 3, 0, 0, 0, 0,184, 89,217, 3, - 0, 0, 0, 0, 24, 93,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,184, 89,217, 3, 0, 0, 0, 0,215, 0, 0, 0, - 1, 0, 0, 0,104, 91,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 67, 0, 0, 0, 0, - 0, 0,208, 65, 0, 0, 0, 0, 0, 0,114, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,199, 3, 0, 0, 0, 0, 0, 0, - 25, 0, 0, 0, 0,192,113, 68, 0, 0,200, 65, 0,192,113, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,200, 3, 26, 0,200, 3, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,199, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,200, 3, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,104, 91,217, 3, 0, 0, 0, 0,215, 0, 0, 0, - 1, 0, 0, 0, 24, 93,217, 3, 0, 0, 0, 0,184, 89,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 67, 0,192,115,196, - 0, 0, 0, 0, 0, 0, 0, 0,254,255, 74, 67,254,255,115,196, 0, 0, 0, 0,203, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0, -207, 3, 0, 0, 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, -207, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, - 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,220, 0,208, 3,203, 0,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,219, 0, 0, 0, 26, 0, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,220, 0,208, 3, 0, 0, 4, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 54,217, 3, - 0, 0, 0, 0, 88, 54,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 88, 54,217, 3, 0, 0, 0, 0,213, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 73, 77, 65, 71, 69, 95, 80, 84, 95,103,112,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 73, 77, 65, 71, 69, 95, 80, 84, 95,103,112,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 71,114,101, 97,115,101, 32, 80,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,152,255,202, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 1, 0, 0, 24, 93,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 91,217, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 67, 51, 51, 43,191,154,153,213, 63, 51, 51,131,191, -154,153, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,236, 2, 0, 0, 0, 0, 0, 0,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0, 0, 0,199, 3, 0, 0, 26, 0, 0, 0, -233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,236, 2,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 33, 0, 0,120,119,217, 3, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,240, 65, 0, 0, 0, 0,154,153,153, 62, 0, 0, 0, 0,100, 0, 0, 0,154,153,153, 62,100, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,160, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, -160, 0, 0, 0, 24, 33,215, 3, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 31,215, 3, - 0, 0, 0, 0, 8, 59,201, 3, 0, 0, 0, 0,104, 58,201, 3, 0, 0, 0, 0,200, 57,201, 3, 0, 0, 0, 0,136, 56,201, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,201, 3, 0, 0,126, 7, 0, 0, 0, 0, 0, 0,233, 3, 0, 0, 1, 1,182, 3, -234, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 59,217, 3, 0, 0, 0, 0,248, 59,217, 3, - 0, 0, 0, 0,200, 94,217, 3, 0, 0, 0, 0,136,101,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,200, 94,217, 3, - 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,120, 96,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 64,113, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,128,109, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -181, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 64,109, 68, 0, 0,200, 65, 0, 64,109, 68, 0, 0,200, 65, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,182, 3, 26, 0,182, 3, 26, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,201, 3, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,182, 3, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,120, 96,217, 3, - 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 40, 98,217, 3, 0, 0, 0, 0,200, 94,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 32, 67, 0, 0, 86,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 0, 86,196, 0, 0, 0, 0,143, 0, 0, 0, -160, 0, 0, 0, 0, 0, 0, 0, 87, 3, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, -142, 0, 0, 0, 0, 0, 0, 0, 87, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, - 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0, 88, 3,143, 0, 88, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,201, 3, 0, 0,104, 4, 0, 0,146, 0, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0, 88, 3, 0, 0, 5, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 56, 56,217, 3, 0, 0, 0, 0, 56, 56,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 56, 56,217, 3, - 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,111, 98,106,101, - 99,116,109,111,100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,111, 98,106,101, - 99,116,109,111,100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 98,106,101, 99,116, 32, 84,111,111,108,115, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,233,253,143, 0,255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 40, 98,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,216, 99,217, 3, - 0, 0, 0, 0,120, 96,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0,242,194, 0, 0, 0, 0, 0, 0, 0, 0, -231,102, 16, 67, 91, 90,242,194, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, -142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, - 6, 0,160, 0,120, 0,143, 0,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,201, 3, 0, 0, -104, 4, 0, 0, 26, 0, 0, 0,145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0,120, 0, - 0, 0, 6, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 58,217, 3, 0, 0, 0, 0, 24, 58,217, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 24, 58,217, 3, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, - 51, 68, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, - 51, 68, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79,112,101,114, - 97,116,111,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,255, -144, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,216, 99,217, 3, - 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,136,101,217, 3, 0, 0, 0, 0, 40, 98,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 35, 67, 0,128,126,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67,255,191,126,196, 0, 0, 0, 0,163, 0, 0, 0, -180, 0, 0, 0, 18, 0, 0, 0, 12, 4, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, -162, 0, 0, 0, 18, 0, 0, 0, 12, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, - 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,180, 0, 13, 4,163, 0,251, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,126, 7, 0, 0, 26, 0, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136,101,217, 3, - 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 99,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 4, 0, 0,126, 7, 0, 0, 26, 0, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 3,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,153,217, 3, 0, 0, 0, 0, 68, 65, 84, 65,112, 3, 0, 0, 40,153,217, 3, - 0, 0, 0, 0,173, 0, 0, 0, 1, 0, 0, 0, 72,246,172, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 13,128,191, 0, 0,128,191, 0, 0, 0, 0, - 0, 0, 0, 0, 74,215, 76,190, 0, 0, 0, 0, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, 0, 0, 0, 0, 70,119,105, 63, -143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 25, 95,192, 0, 0,128, 63, 69,239,209, 62, 70,119,105, 63,160, 84, 89,188, 0, 0, 0, 0, 52,177,205,190, -142, 74, 70, 62,166, 33,101, 63, 0, 0, 0, 0,185,158, 81, 63, 35, 44,185,190, 43, 61,228, 62, 0, 0, 0, 0,188,173, 54, 64, -136, 95,161,191,147,231,198, 63, 0, 0,128, 63,185,214, 13, 63,208,249,224,190, 48,180, 81,191,184,158, 81,191,189,188,157, 63, -140,225, 88, 62, 26, 63,185, 62, 35, 44,185, 62,241,213,146,188,206,156,122, 63,138, 84,228,190, 42, 61,228,190, 0, 0, 0, 0, - 0, 0, 0, 0,100, 98, 82, 64, 0, 25, 95, 64,121, 92,155, 62,151,198, 44, 63,192,214, 32,188, 0, 0, 40,180,195, 15,188,190, -132, 75, 53, 62,216,125, 81, 63, 0, 0,192,179,115, 77,100,193, 17,173,201, 64,181,148,248,192,203,247,159,192,233, 74, 87, 65, -247, 46,190,192, 88,106,234, 64, 45, 8,160, 64, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, 0, 0, 0, 0, 70,119,105, 63, -143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 25, 95,192, 0, 0,128, 63,185,214, 13, 63,208,249,224,190, 48,180, 81,191,184,158, 81,191,189,188,157, 63, -140,225, 88, 62, 26, 63,185, 62, 35, 44,185, 62,241,213,146,188,206,156,122, 63,138, 84,228,190, 42, 61,228,190, 0, 0, 0, 0, - 0, 0, 0, 0,100, 98, 82, 64, 0, 25, 95, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,201,250, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248,201,250, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,201,250, 62, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 92, 62, 55, 63, 56,186,224,190,237,203,148,190, 3,236,234,190, 0, 25, 95, 64, - 0, 25, 95, 64, 0, 0, 0, 0, 0, 0, 0, 0,114,145,245, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 30, 33, 12, 66, 85,152,137, 66,116, 27,126, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 96, 1, 0, 0,248, 59,217, 3, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, -205,204, 76, 62, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,200,213,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, 8, 8,128, 0, 0, 0, 12, 66, 0, 0,128, 63, -205,204,204, 61, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 16, 0, 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0, 8, 1, 0, 0, 24,157,217, 3, - 0, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,117,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 86,105,100,101,111, 32, 69,100,105,116,105,110,103, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,168, 59,201, 3, 0, 0, 0, 0,136, 66,201, 3, 0, 0, 0, 0,200,104,216, 3, 0, 0, 0, 0,120,116,216, 3, - 0, 0, 0, 0, 56, 34,215, 3, 0, 0, 0, 0,184, 38,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,168, 59,201, 3, - 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72, 60,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72, 60,201, 3, 0, 0, 0, 0,211, 0, 0, 0, - 1, 0, 0, 0,232, 60,201, 3, 0, 0, 0, 0,168, 59,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,222, 2, - 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,232, 60,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,136, 61,201, 3, - 0, 0, 0, 0, 72, 60,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4,222, 2, 0, 0, 0, 0, 68, 65, 84, 65, - 32, 0, 0, 0,136, 61,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40, 62,201, 3, 0, 0, 0, 0,232, 60,201, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 40, 62,201, 3, - 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200, 62,201, 3, 0, 0, 0, 0,136, 61,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,195, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,200, 62,201, 3, 0, 0, 0, 0,211, 0, 0, 0, - 1, 0, 0, 0,104, 63,201, 3, 0, 0, 0, 0, 40, 62,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4,195, 2, - 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,104, 63,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 8, 64,201, 3, - 0, 0, 0, 0,200, 62,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 92, 1, 0, 0, 0, 0, 68, 65, 84, 65, - 32, 0, 0, 0, 8, 64,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,168, 64,201, 3, 0, 0, 0, 0,104, 63,201, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,168, 64,201, 3, - 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72, 65,201, 3, 0, 0, 0, 0, 8, 64,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 48, 2,195, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72, 65,201, 3, 0, 0, 0, 0,211, 0, 0, 0, - 1, 0, 0, 0,232, 65,201, 3, 0, 0, 0, 0,168, 64,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 1, - 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,232, 65,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,136, 66,201, 3, - 0, 0, 0, 0, 72, 65,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 2, 92, 1, 0, 0, 0, 0, 68, 65, 84, 65, - 32, 0, 0, 0,136, 66,201, 3, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232, 65,201, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 68, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200,104,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120,105,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 60,201, 3, - 0, 0, 0, 0,232, 60,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,120,105,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40,106,216, 3, 0, 0, 0, 0,200,104,216, 3, 0, 0, 0, 0, 72, 60,201, 3, - 0, 0, 0, 0, 40, 62,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40,106,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216,106,216, 3, 0, 0, 0, 0,120,105,216, 3, 0, 0, 0, 0,232, 60,201, 3, - 0, 0, 0, 0,200, 62,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216,106,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,136,107,216, 3, 0, 0, 0, 0, 40,106,216, 3, 0, 0, 0, 0, 40, 62,201, 3, - 0, 0, 0, 0,200, 62,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136,107,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56,108,216, 3, 0, 0, 0, 0,216,106,216, 3, 0, 0, 0, 0,200, 62,201, 3, - 0, 0, 0, 0,104, 63,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56,108,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232,108,216, 3, 0, 0, 0, 0,136,107,216, 3, 0, 0, 0, 0,168, 59,201, 3, - 0, 0, 0, 0, 8, 64,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,232,108,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152,109,216, 3, 0, 0, 0, 0, 56,108,216, 3, 0, 0, 0, 0, 40, 62,201, 3, - 0, 0, 0, 0,168, 64,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,152,109,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72,110,216, 3, 0, 0, 0, 0,232,108,216, 3, 0, 0, 0, 0, 8, 64,201, 3, - 0, 0, 0, 0, 72, 65,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72,110,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,248,110,216, 3, 0, 0, 0, 0,152,109,216, 3, 0, 0, 0, 0, 72, 65,201, 3, - 0, 0, 0, 0,232, 65,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,248,110,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168,111,216, 3, 0, 0, 0, 0, 72,110,216, 3, 0, 0, 0, 0,168, 64,201, 3, - 0, 0, 0, 0,232, 65,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,168,111,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88,112,216, 3, 0, 0, 0, 0,248,110,216, 3, 0, 0, 0, 0,104, 63,201, 3, - 0, 0, 0, 0,136, 66,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88,112,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8,113,216, 3, 0, 0, 0, 0,168,111,216, 3, 0, 0, 0, 0,136, 61,201, 3, - 0, 0, 0, 0,136, 66,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 8,113,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184,113,216, 3, 0, 0, 0, 0, 88,112,216, 3, 0, 0, 0, 0, 8, 64,201, 3, - 0, 0, 0, 0,136, 66,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184,113,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104,114,216, 3, 0, 0, 0, 0, 8,113,216, 3, 0, 0, 0, 0,168, 59,201, 3, - 0, 0, 0, 0,136, 61,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,104,114,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24,115,216, 3, 0, 0, 0, 0,184,113,216, 3, 0, 0, 0, 0,200, 62,201, 3, - 0, 0, 0, 0,168, 64,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 24,115,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200,115,216, 3, 0, 0, 0, 0,104,114,216, 3, 0, 0, 0, 0,104, 63,201, 3, - 0, 0, 0, 0,232, 65,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200,115,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120,116,216, 3, 0, 0, 0, 0, 24,115,216, 3, 0, 0, 0, 0, 40, 62,201, 3, - 0, 0, 0, 0, 72, 65,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,120,116,216, 3, - 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,115,216, 3, 0, 0, 0, 0,104, 63,201, 3, - 0, 0, 0, 0, 72, 65,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 56, 34,215, 3, - 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 88, 35,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 62,201, 3, - 0, 0, 0, 0, 72, 60,201, 3, 0, 0, 0, 0,232, 60,201, 3, 0, 0, 0, 0,200, 62,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 32, 0, 0, 0, 40,155,194, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,216,212,194, 6, 0, 0, 0, 0,184,154,194, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,222, 2, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,216,212,194, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72,213,194, 6, 0, 0, 0, 0, 40,155,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,240, 4,222, 2, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72,213,194, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,184,213,194, 6, 0, 0, 0, 0,216,212,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,184,213,194, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40,214,194, 6, + 0, 0, 0, 0, 72,213,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195, 2, 1, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0, 40,214,194, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,152,214,194, 6, 0, 0, 0, 0,184,213,194, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4,195, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,152,214,194, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 8,215,194, 6, 0, 0, 0, 0, 40,214,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 4, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8,215,194, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,120,215,194, 6, 0, 0, 0, 0,152,214,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 4,195, 2, + 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,120,215,194, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,232,215,194, 6, + 0, 0, 0, 0, 8,215,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 4, 60, 1, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,232,215,194, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 88,216,194, 6, 0, 0, 0, 0,120,215,194, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 60, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 88,216,194, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200,216,194, 6, 0, 0, 0, 0,232,215,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,200,216,194, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0, 56,217,194, 6, 0, 0, 0, 0, 88,216,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 4, 88, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 56,217,194, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,168,217,194, 6, + 0, 0, 0, 0,200,216,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 1, 88, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,168,217,194, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 24,218,194, 6, 0, 0, 0, 0, 56,217,194, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 1,195, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 24,218,194, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,136,218,194, 6, 0, 0, 0, 0,168,217,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,136,218,194, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,248,218,194, 6, 0, 0, 0, 0, 24,218,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 1, 4, 1, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,248,218,194, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,104,219,194, 6, + 0, 0, 0, 0,136,218,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 4, 60, 2, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,104,219,194, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,218,194, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 60, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216,219,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72,220,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,155,194, 6, + 0, 0, 0, 0,216,212,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72,220,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184,220,194, 6, 0, 0, 0, 0,216,219,194, 6, 0, 0, 0, 0, 40,155,194, 6, + 0, 0, 0, 0,184,213,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184,220,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40,221,194, 6, 0, 0, 0, 0, 72,220,194, 6, 0, 0, 0, 0,216,212,194, 6, + 0, 0, 0, 0, 40,214,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40,221,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152,221,194, 6, 0, 0, 0, 0,184,220,194, 6, 0, 0, 0, 0,184,213,194, 6, + 0, 0, 0, 0, 40,214,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,152,221,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8,222,194, 6, 0, 0, 0, 0, 40,221,194, 6, 0, 0, 0, 0,184,154,194, 6, + 0, 0, 0, 0,152,214,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 8,222,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120,222,194, 6, 0, 0, 0, 0,152,221,194, 6, 0, 0, 0, 0, 72,213,194, 6, + 0, 0, 0, 0,152,214,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,120,222,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232,222,194, 6, 0, 0, 0, 0, 8,222,194, 6, 0, 0, 0, 0, 40,214,194, 6, + 0, 0, 0, 0, 8,215,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,232,222,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88,223,194, 6, 0, 0, 0, 0,120,222,194, 6, 0, 0, 0, 0,152,214,194, 6, + 0, 0, 0, 0,120,215,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88,223,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200,223,194, 6, 0, 0, 0, 0,232,222,194, 6, 0, 0, 0, 0, 72,213,194, 6, + 0, 0, 0, 0,232,215,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200,223,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56,224,194, 6, 0, 0, 0, 0, 88,223,194, 6, 0, 0, 0, 0,120,215,194, 6, + 0, 0, 0, 0,232,215,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56,224,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168,224,194, 6, 0, 0, 0, 0,200,223,194, 6, 0, 0, 0, 0,184,154,194, 6, + 0, 0, 0, 0, 88,216,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,168,224,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24,225,194, 6, 0, 0, 0, 0, 56,224,194, 6, 0, 0, 0, 0, 8,215,194, 6, + 0, 0, 0, 0,200,216,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 24,225,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,136,225,194, 6, 0, 0, 0, 0,168,224,194, 6, 0, 0, 0, 0,152,214,194, 6, + 0, 0, 0, 0,200,216,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136,225,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,248,225,194, 6, 0, 0, 0, 0, 24,225,194, 6, 0, 0, 0, 0, 88,216,194, 6, + 0, 0, 0, 0,200,216,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,248,225,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104,226,194, 6, 0, 0, 0, 0,136,225,194, 6, 0, 0, 0, 0, 88,216,194, 6, + 0, 0, 0, 0, 56,217,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,104,226,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216,226,194, 6, 0, 0, 0, 0,248,225,194, 6, 0, 0, 0, 0,200,216,194, 6, + 0, 0, 0, 0, 56,217,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216,226,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72,227,194, 6, 0, 0, 0, 0,104,226,194, 6, 0, 0, 0, 0,184,213,194, 6, + 0, 0, 0, 0,168,217,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72,227,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184,227,194, 6, 0, 0, 0, 0,216,226,194, 6, 0, 0, 0, 0, 8,215,194, 6, + 0, 0, 0, 0,168,217,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184,227,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40,228,194, 6, 0, 0, 0, 0, 72,227,194, 6, 0, 0, 0, 0, 56,217,194, 6, + 0, 0, 0, 0,168,217,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40,228,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152,228,194, 6, 0, 0, 0, 0,184,227,194, 6, 0, 0, 0, 0, 88,216,194, 6, + 0, 0, 0, 0, 24,218,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,152,228,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8,229,194, 6, 0, 0, 0, 0, 40,228,194, 6, 0, 0, 0, 0, 56,217,194, 6, + 0, 0, 0, 0,136,218,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 8,229,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120,229,194, 6, 0, 0, 0, 0,152,228,194, 6, 0, 0, 0, 0, 24,218,194, 6, + 0, 0, 0, 0,136,218,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,120,229,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232,229,194, 6, 0, 0, 0, 0, 8,229,194, 6, 0, 0, 0, 0,120,215,194, 6, + 0, 0, 0, 0,248,218,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,232,229,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88,230,194, 6, 0, 0, 0, 0,120,229,194, 6, 0, 0, 0, 0, 8,215,194, 6, + 0, 0, 0, 0,248,218,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88,230,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200,230,194, 6, 0, 0, 0, 0,232,229,194, 6, 0, 0, 0, 0, 40,214,194, 6, + 0, 0, 0, 0,104,219,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200,230,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56,231,194, 6, 0, 0, 0, 0, 88,230,194, 6, 0, 0, 0, 0,232,215,194, 6, + 0, 0, 0, 0,104,219,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56,231,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168,231,194, 6, 0, 0, 0, 0,200,230,194, 6, 0, 0, 0, 0,248,218,194, 6, + 0, 0, 0, 0,104,219,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,168,231,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24,232,194, 6, 0, 0, 0, 0, 56,231,194, 6, 0, 0, 0, 0,184,213,194, 6, + 0, 0, 0, 0, 24,218,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 24,232,194, 6, + 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,231,194, 6, 0, 0, 0, 0,168,217,194, 6, + 0, 0, 0, 0,136,218,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,136,232,194, 6, + 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 88,236,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,213,194, 6, + 0, 0, 0, 0, 40,155,194, 6, 0, 0, 0, 0,216,212,194, 6, 0, 0, 0, 0, 40,214,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0,196, 2, 0, 0,222, 2, 0, 0, 7, 7,241, 4, 27, 0, 1, 0, 0, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,202,207, 3, 0, 0, 0, 0, 24,202,207, 3, 0, 0, 0, 0, 56,103,217, 3, - 0, 0, 0, 0,232,104,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 56,103,217, 3, 0, 0, 0, 0,215, 0, 0, 0, - 1, 0, 0, 0,232,104,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,148, 68, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232, 54,195, 6, 0, 0, 0, 0,232, 54,195, 6, 0, 0, 0, 0,120,233,194, 6, + 0, 0, 0, 0,232,234,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,120,233,194, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,232,234,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,148, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 32,158, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0,158, 68, 0, 0,200, 65, 0, 0,158, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, @@ -5142,8 +173,8 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0,241, 4, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,232,104,217, 3, 0, 0, 0, 0,215, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,103,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,109, 69, 0, 0,128,192, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,232,234,194, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,233,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,109, 69, 0, 0,128,192, 0, 0, 0, 0, 0, 0, 0, 0,255,255,109, 69, 0, 0, 0,192, 0, 0, 0, 0,112, 7, 0, 0,129, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 2, 0, 0, 0, @@ -5152,737 +183,6242 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 88, 35,215, 3, 0, 0, 0, 0,214, 0, 0, 0, - 1, 0, 0, 0,120, 36,215, 3, 0, 0, 0, 0, 56, 34,215, 3, 0, 0, 0, 0,168, 59,201, 3, 0, 0, 0, 0, 8, 64,201, 3, - 0, 0, 0, 0,136, 66,201, 3, 0, 0, 0, 0,136, 61,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 4, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 15, 15,241, 4, 68, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,200, 96,200, 3, 0, 0, 0, 0,200, 96,200, 3, 0, 0, 0, 0,152,106,217, 3, 0, 0, 0, 0, 72,108,217, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 88,236,194, 6, 0, 0, 0, 0,214, 0, 0, 0, + 1, 0, 0, 0,232, 4,195, 6, 0, 0, 0, 0,136,232,194, 6, 0, 0, 0, 0,152,214,194, 6, 0, 0, 0, 0,120,215,194, 6, + 0, 0, 0, 0,232,215,194, 6, 0, 0, 0, 0, 72,213,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 4, 0, 0, +240, 4, 0, 0, 0, 0, 0, 0, 59, 1, 0, 0, 4, 4,216, 0, 60, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,168, 3,195, 6, 0, 0, 0, 0,168, 3,195, 6, 0, 0, 0, 0, 72,237,194, 6, 0, 0, 0, 0,184,238,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,152,106,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 72,108,217, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,140, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, - 0, 32,158, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0,158, 68, - 0, 0,200, 65, 0, 0,158, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, - 10, 0,241, 4, 26, 0,241, 4, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241, 4, 26, 0, - 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72,237,194, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,184,238,194, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,148, 67, 0, 0, 0, 0, 0, 0,208, 65, 98, 39, 38, 54, + 0, 0, 88, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 87, 67, + 0, 0,200, 65, 0, 0, 87, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, + 10, 0,216, 0, 26, 0,216, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 4, 0, 0, +240, 4, 0, 0, 34, 1, 0, 0, 59, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 0, 26, 0, + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72,108,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,152,106,217, 3, 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67, 0, 0, 0, 0, 0, 0, 72, 66,112,189, 17,192, -246, 70,125, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 4, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 18, 0, 0, 0, 41, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,184,238,194, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 72,237,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 67, 0, 0, 61,196, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 71, 67, 1, 0,145,195, 0, 0, 0, 0,199, 0, 0, 0,216, 0, 0, 0, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 0, 0, + 62, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,198, 0, 0, 0, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 1, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, + 6, 0,216, 0, 34, 1,199, 0, 34, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 4, 0, 0, +240, 4, 0, 0, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 0, 34, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,240,194, 6, 0, 0, 0, 0, 8, 2,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 40,240,194, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,200,241,194, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, + 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, + 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,110,116, +101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,255, +199, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,200,241,194, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,104,243,194, 6, 0, 0, 0, 0, 40,240,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,255,199, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,104,243,194, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 8,245,194, 6, + 0, 0, 0, 0,200,241,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 97,121,101, +114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111,255, +199, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 8,245,194, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,168,246,194, 6, 0, 0, 0, 0,104,243,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,254,199, 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,168,246,194, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 72,248,194, 6, + 0, 0, 0, 0, 8,245,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65,110,116,105, + 45, 65,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58,254, +199, 0, 58, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 72,248,194, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,232,249,194, 6, 0, 0, 0, 0,168,246,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117, +114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117, +114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 97,109,112,108,101,100, 32, 77,111,116,105,111,110, 32, 66,108,117,114, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,254,199, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,232,249,194, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,136,251,194, 6, + 0, 0, 0, 0, 72,248,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,104, 97,100, +105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,254, +199, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,136,251,194, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 40,253,194, 6, 0, 0, 0, 0,232,249,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99, +101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99, +101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,242,253,199, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 40,253,194, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,200,254,194, 6, + 0, 0, 0, 0,136,251,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,111,115,116, + 32, 80,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,218,253, +199, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,200,254,194, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,104, 0,195, 6, 0, 0, 0, 0, 40,253,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194,253,199, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,104, 0,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 8, 2,195, 6, + 0, 0, 0, 0,200,254,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79,117,116,112, +117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,253, +199, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 8, 2,195, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,253,199, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,168, 3,195, 6, 0, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 21, 0, 0, +160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,232, 4,195, 6, + 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,216, 9,195, 6, 0, 0, 0, 0, 88,236,194, 6, 0, 0, 0, 0,184,154,194, 6, + 0, 0, 0, 0, 88,216,194, 6, 0, 0, 0, 0,200,216,194, 6, 0, 0, 0, 0,152,214,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 15, 15, 24, 4, 88, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 8,195, 6, 0, 0, 0, 0,184, 8,195, 6, 0, 0, 0, 0,216, 5,195, 6, + 0, 0, 0, 0, 72, 7,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,216, 5,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 72, 7,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,140, 68, 0, 0, 0, 0, + 0, 0,208, 65, 39,182,158, 55, 0, 0,131, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0,224,130, 68, 0, 0,200, 65, 0,224,130, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 24, 4, 26, 0, 24, 4, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 4, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72, 7,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 5,195, 6, 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67, 0, 0, 0, 0, + 0, 0, 72, 66,112,189, 17,192,246, 70,125, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 18, 0, 0, 0, + 61, 0, 0, 0, 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65, 72, 0, 0, 0, + 0, 0, 0, 2, 4, 0, 0, 4, 8, 0, 24, 4, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 26, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 4, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0,184, 8,195, 6, 0, 0, 0, 0,190, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,216, 9,195, 6, + 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,152, 16,195, 6, 0, 0, 0, 0,232, 4,195, 6, 0, 0, 0, 0,120,215,194, 6, + 0, 0, 0, 0,248,218,194, 6, 0, 0, 0, 0,104,219,194, 6, 0, 0, 0, 0,232,215,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 61, 1, 0, 0, 59, 2, 0, 0, 3, 3,216, 0,255, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 13,195, 6, 0, 0, 0, 0,168, 13,195, 6, 0, 0, 0, 0,200, 10,195, 6, + 0, 0, 0, 0, 56, 12,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,200, 10,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 56, 12,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,244, 67, 0, 0, 0, 0, + 0, 0,208, 65, 98, 39, 38, 54, 0, 0, 88, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0, 0, 87, 67, 0, 0,200, 65, 0, 0, 87, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,216, 0, 26, 0,216, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 34, 2, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,216, 0, 26, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 56, 12,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 10,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,141, 67, 0, 0,244,194, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 67, 0, 0, 83,195, 0, 0, 0, 0,199, 0, 0, 0,216, 0, 0, 0, 18, 0, 0, 0, +228, 0, 0, 0, 0, 0, 0, 0,198, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,198, 0, 0, 0, 18, 0, 0, 0, +228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 18, 2, 0, 0, + 2, 0, 3, 3, 0, 0, 12, 4, 6, 0,216, 0,229, 0,199, 0,211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 61, 1, 0, 0, 33, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,216, 0,229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 1, 0, 0,168, 13,195, 6, 0, 0, 0, 0,183, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 15,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65, + 16, 0, 0, 0, 8, 15,195, 6, 0, 0, 0, 0,237, 0, 0, 0, 1, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0,104, 15,195, 6, + 0, 0, 0, 0, 68, 65, 84, 65,224, 0, 0, 0,104, 15,195, 6, 0, 0, 0, 0,236, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0,104, 38,198, 6, 0, 0, 0, 0, 19, 0, 0, 0, 1, 0, 1, 0,104, 38,198, 6, 0, 0, 0, 0, 20, 0, 0, 0, + 1, 0, 1, 0,104, 38,198, 6, 0, 0, 0, 0, 21, 0, 1, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0,248, 64,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,104, 74,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 8,129,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 72, 88,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 88,110,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,168, 81,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 56, 60,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,200, 67,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 40, 59,198, 6, 0, 0, 0, 0, 21, 0, 0, 0, 1, 0, 1, 0,104, 38,198, 6, 0, 0, 0, 0, 68, 65, 84, 65, +160, 0, 0, 0,152, 16,195, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 40, 30,195, 6, 0, 0, 0, 0,216, 9,195, 6, + 0, 0, 0, 0, 56,217,194, 6, 0, 0, 0, 0,168,217,194, 6, 0, 0, 0, 0, 8,215,194, 6, 0, 0, 0, 0,200,216,194, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 1, 0, 0, 23, 4, 0, 0, 89, 0, 0, 0,194, 2, 0, 0, 1, 1, 87, 2, +106, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 28,195, 6, 0, 0, 0, 0,120, 28,195, 6, + 0, 0, 0, 0,136, 17,195, 6, 0, 0, 0, 0, 72, 23,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136, 17,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,248, 18,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 64,113, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,192, 21, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 2, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128, 21, 68, 0, 0,200, 65, 0,128, 21, 68, 0, 0,200, 65, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 87, 2, 26, 0, 87, 2, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 1, 0, 0, 23, 4, 0, 0, 89, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 2, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248, 18,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,104, 20,195, 6, 0, 0, 0, 0,136, 17,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 67, 0, 64, 70,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67,255,127, 70,196, 0, 0, 0, 0,143, 0, 0, 0, +160, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +142, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0, 44, 3,143, 0, 26, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 1, 0, 0,193, 1, 0, 0,115, 0, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 80, 2, 0, 0, 5, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,104, 20,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,216, 21,195, 6, 0, 0, 0, 0,248, 18,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 67, 0, 0,206,194, 0, 0, 0, 0, 0, 0, 0, 0,231,102, 16, 67, 0, 0,206,194, 0, 0, 0, 0,143, 0, 0, 0, +160, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +142, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,120, 0,143, 0,102, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 1, 0, 0,193, 1, 0, 0,115, 0, 0, 0,115, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 6, 0, 34, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,216, 21,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 72, 23,195, 6, 0, 0, 0, 0,104, 20,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 35, 67, 0,128, 96,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, 0,128, 96,196, 0, 0, 0, 0,163, 0, 0, 0, +180, 0, 0, 0, 18, 0, 0, 0,147, 3, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +162, 0, 0, 0, 18, 0, 0, 0,147, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,180, 0,148, 3,163, 0,130, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 0, 0, 23, 4, 0, 0,115, 0, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72, 23,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 21,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 1, 0, 0, 23, 4, 0, 0,115, 0, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 2, 80, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 24,195, 6, 0, 0, 0, 0, 68, 65, 84, 65,112, 3, 0, 0,184, 24,195, 6, + 0, 0, 0, 0,173, 0, 0, 0, 1, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +200,167,141, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 13,128,191, 0, 0,128,191, 0, 0, 0, 0, + 0, 0, 0, 0, 74,215, 76,190, 0, 0, 0, 0, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, 0, 0, 0, 0, 70,119,105, 63, +143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,214,211,111,193, 0, 0,128, 63, 69,239,209, 62, 70,119,105, 63,176, 84, 89,188, 0, 0, 0, 0, 53,177,205,190, +142, 74, 70, 62,166, 33,101, 63, 0, 0, 0, 0,185,158, 81, 63, 35, 44,185,190, 43, 61,228, 62, 0, 0, 0, 0,164, 96, 68, 65, +111,121,173,192,248,209,213, 64, 0, 0,128, 63,178,157,229, 62,209,162,227,190, 48,180, 81,191,184,158, 81,191,117, 90,127, 63, + 13,114, 91, 62, 26, 63,185, 62, 35, 44,185, 62,145,180,109,188,105,147,125, 63,138, 84,228,190, 42, 61,228,190, 0, 0, 0, 0, + 0, 0, 0, 0, 9,185,108, 65,214,211,111, 65, 99,240,191, 62,110,116, 85, 63, 64,185, 70,188, 0, 0, 82,180, 48,221,185,190, + 44, 45, 51, 62, 28, 11, 79, 63, 0, 0, 56,179, 67,108,117,194,183,204,216, 65,105,156, 5,194,212,247,159,192,235, 62,114, 66, + 59,254,213,193,158,225, 3, 66, 55, 8,160, 64, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, 0, 0, 0, 0, 70,119,105, 63, +143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,214,211,111,193, 0, 0,128, 63,178,157,229, 62,209,162,227,190, 48,180, 81,191,184,158, 81,191,117, 90,127, 63, + 13,114, 91, 62, 26, 63,185, 62, 35, 44,185, 62,145,180,109,188,105,147,125, 63,138, 84,228,190, 42, 61,228,190, 0, 0, 0, 0, + 0, 0, 0, 0, 9,185,108, 65,214,211,111, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,163, 91, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 12,163, 91, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,163, 91, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 92, 62, 55, 63, 56,186,224,190,237,203,148,190, 3,236,234,190,214,211,111, 65, +214,211,111, 65, 0, 0, 0, 0, 0, 0, 0, 0,236, 15, 72, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 32, 33, 12, 66, 86,152,137, 66,113, 27,126, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 96, 1, 0, 0,120, 28,195, 6, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, +205,204, 76, 62, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,200, 67,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, 8, 8,128, 0, 0, 0, 12, 66, 0, 0,128, 63, +205,204,204, 61, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 40, 30,195, 6, + 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,216, 38,195, 6, 0, 0, 0, 0,152, 16,195, 6, 0, 0, 0, 0, 88,216,194, 6, + 0, 0, 0, 0, 24,218,194, 6, 0, 0, 0, 0,136,218,194, 6, 0, 0, 0, 0, 56,217,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,191, 1, 0, 0, 89, 0, 0, 0, 3, 1, 0, 0, 2, 2,192, 1,171, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 36,195, 6, 0, 0, 0, 0,216, 36,195, 6, 0, 0, 0, 0, 24, 31,195, 6, + 0, 0, 0, 0,104, 35,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 24, 31,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,136, 32,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 89, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0,224, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 1, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0,128,223, 67, 0, 0,200, 65, 0,128,223, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,192, 1, 26, 0,192, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,191, 1, 0, 0, 89, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,192, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136, 32,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,248, 33,195, 6, 0, 0, 0, 0, 24, 31,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 67, 0, 0,112,193, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 67, 0, 0,254,194, 0, 0, 0, 0,200, 0, 0, 0,217, 0, 0, 0, 18, 0, 0, 0, +144, 0, 0, 0, 0, 0, 0, 0,199, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,199, 0, 0, 0, 18, 0, 0, 0, +144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 10, 6, 0, 0, + 2, 0, 3, 3, 0, 0, 0, 4, 6, 0,217, 0,145, 0,200, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,216, 0, 0, 0,115, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,217, 0,145, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248, 33,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,104, 35,195, 6, 0, 0, 0, 0,136, 32,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,191, 1, 0, 0,191, 1, 0, 0,115, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,104, 35,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 33,195, 6, 0, 0, 0, 0, 0, 0, 16,193, 0, 0,130, 67, 0, 0,160,192, + 0, 0,160, 64, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 16,193, 0, 0, 32, 65, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, +144, 0, 0, 0, 18, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0,230, 0, 0, 0, 18, 0, 0, 0, +144, 0, 0, 0,111, 18,131, 58,111, 18,131, 58, 0,124,146, 72, 0, 80, 67, 71, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,231, 0,145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,217, 0, 0, 0,191, 1, 0, 0,115, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,231, 0,145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,240, 0, 0, 0,216, 36,195, 6, 0, 0, 0, 0,178, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 38,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,112, 0, 0, 0, 24, 38,195, 6, + 0, 0, 0, 0, 37, 1, 0, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +160, 0, 0, 0,216, 38,195, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,168, 45,195, 6, 0, 0, 0, 0, 40, 30,195, 6, + 0, 0, 0, 0, 24,218,194, 6, 0, 0, 0, 0,184,213,194, 6, 0, 0, 0, 0,168,217,194, 6, 0, 0, 0, 0,136,218,194, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 1, 0, 0, 5, 1, 0, 0,194, 2, 0, 0, 12, 12,192, 1, +190, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 44,195, 6, 0, 0, 0, 0, 24, 44,195, 6, + 0, 0, 0, 0,200, 39,195, 6, 0, 0, 0, 0,168, 42,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,200, 39,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 56, 41,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,192, 94, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,224, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +191, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,223, 67, 0, 0,200, 65, 0,128,223, 67, 0, 0,200, 65, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,192, 1, 26, 0,192, 1, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 1, 0, 0, 5, 1, 0, 0, 30, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 56, 41,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,168, 42,195, 6, 0, 0, 0, 0,200, 39,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 67, 0, 0, 0,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 67, 0, 0,201,195, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,199, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +199, 0, 0, 0, 18, 0, 0, 0,163, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 8, 4, 0, 0, 2, 0, 3, 3, 0, 0, 2, 4, 6, 0,200, 0,164, 1,200, 0,146, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,199, 0, 0, 0, 31, 1, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 0,164, 1, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168, 42,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 41,195, 6, 0, 0, 0, 0, 0, 0, 32,193, + 0, 0,104, 68, 0, 0, 72,194, 0, 0, 0, 0, 0, 0, 32,193, 0, 0,104, 68, 0, 0,201,195, 0, 0, 0, 0,231, 0, 0, 0, +248, 0, 0, 0, 18, 0, 0, 0,163, 1, 0, 0, 0, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +230, 0, 0, 0, 18, 0, 0, 0,163, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,124,146, 72, 0, 64, 28, 70, 10,215, 35, 60, + 0, 0, 72, 66, 74, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 4, 4, 0,248, 0,164, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 0, 0, 0,191, 1, 0, 0, 31, 1, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 0,164, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 72, 1, 0, 0, 24, 44,195, 6, + 0, 0, 0, 0, 38, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,168, 45,195, 6, + 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 38,195, 6, 0, 0, 0, 0,248,218,194, 6, + 0, 0, 0, 0, 8,215,194, 6, 0, 0, 0, 0, 40,214,194, 6, 0, 0, 0, 0,104,219,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 61, 2, 0, 0,194, 2, 0, 0, 1, 1,216, 0,134, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 53,195, 6, 0, 0, 0, 0, 56, 53,195, 6, 0, 0, 0, 0,152, 46,195, 6, + 0, 0, 0, 0, 8, 48,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,152, 46,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 8, 48,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0,165, 67, 0, 0, 0, 64, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 0, 0, + 23, 0, 0, 0, 0,128,164, 67, 0, 0,200, 65, 0,128,164, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 74, 1, 24, 0, 74, 1, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 61, 2, 0, 0, 61, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8, 48,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 46,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 4, 0, 0,240, 4, 0, 0, 61, 2, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,216, 0,134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,120, 49,195, 6, 0, 0, 0, 0, 68, 65, 84, 65,112, 3, 0, 0,120, 49,195, 6, 0, 0, 0, 0,173, 0, 0, 0, + 1, 0, 0, 0, 56,255, 13, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,100, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154, 65,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, 72, 1, 77,190, + 0, 0, 0, 0,221,149, 47, 63, 86,126,162,190, 8,165, 39, 63, 0, 0, 0, 0, 51, 70, 58, 63,225,251,159, 62,149, 84, 28,191, + 0, 0, 0, 0,192, 56, 49,188, 55, 53,101, 63, 52,247,227, 62, 0, 0, 0, 0, 90, 38,173,190, 0,222,192,190,152, 9, 52,193, + 0, 0,128, 63,223,149, 47, 63, 55, 70, 58, 63,160, 56, 49,188, 0, 0, 0, 0, 88,126,162,190,229,251,159, 62, 55, 53,101, 63, + 0, 0, 0, 0, 7,165, 39, 63,150, 84, 28,191, 51,247,227, 62, 0, 0, 0, 0,110,101,239, 64,151, 62,208,192, 78,255,170, 64, + 0, 0,128, 63, 47,201,194, 63, 61, 73,145,191,244,250, 39,191, 8,165, 39,191,190,164,206, 63,209, 10,143, 63,180,164, 28, 63, +149, 84, 28, 63,224,153,196,188,136,239, 76, 64, 10,108,228,190, 52,247,227,190,125, 21, 64,191,126,113,172,191,216, 49, 49, 65, +152, 9, 52, 65,149, 70,158, 62, 24,234,167, 62,192,214,159,187, 0, 0, 6,181,196,188,181,189, 71,238,178, 61,127, 45,128, 62, + 0, 0,226, 51,168,120, 21,194,107, 5, 2, 66,203,135,213,193,147,214,159,192,177, 38, 19, 66,124,173,255,193, 96,101,210, 65, +128, 40,160, 64,221,149, 47, 63, 86,126,162,190, 8,165, 39, 63, 0, 0, 0, 0, 51, 70, 58, 63,225,251,159, 62,149, 84, 28,191, + 0, 0, 0, 0,192, 56, 49,188, 55, 53,101, 63, 52,247,227, 62, 0, 0, 0, 0, 90, 38,173,190, 0,222,192,190,152, 9, 52,193, + 0, 0,128, 63, 47,201,194, 63, 61, 73,145,191,244,250, 39,191, 8,165, 39,191,190,164,206, 63,209, 10,143, 63,180,164, 28, 63, +149, 84, 28, 63,224,153,196,188,136,239, 76, 64, 10,108,228,190, 52,247,227,190,125, 21, 64,191,126,113,172,191,216, 49, 49, 65, +152, 9, 52, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,102,103, 97, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102,103, 97, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102,103, 97, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63,241, 22, 72, 63, 78,162,246,190, 43, 8, 90,190, 2, 35,171,190, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,253,191,136, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 65, 1, 2, 0, 0,255,255, 0, 0, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 0, 0, 0,128, 63,190,133, 65, 66, 99,212, 90, 66, + 27,183,118, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 1, 0, 0, 56, 53,195, 6, + 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65,205,204, 76, 62, 2, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,200, 67,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 3, 0, 8, 0,128, 0, 0, 0, 12, 66, 0, 0,128, 63, 10,215, 35, 60, 0, 0,250, 67, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 10, 0, 7, 1, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0, 8, 1, 0, 0,120, 55,195, 6, 0, 0, 0, 0,210, 0, 0, 0, + 1, 0, 0, 0,248,163,195, 6, 0, 0, 0, 0,136,211,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 82, 67,111,109,112,111,115,105,116,105,110,103, 0,103, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 56,195, 6, + 0, 0, 0, 0,120, 62,195, 6, 0, 0, 0, 0,232, 62,195, 6, 0, 0, 0, 0, 24, 72,195, 6, 0, 0, 0, 0,136, 72,195, 6, + 0, 0, 0, 0,184,124,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,200, 56,195, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0, 56, 57,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 56, 57,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,168, 57,195, 6, + 0, 0, 0, 0,200, 56,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,168, 57,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 24, 58,195, 6, 0, 0, 0, 0, 56, 57,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 24, 58,195, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,136, 58,195, 6, 0, 0, 0, 0,168, 57,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,136, 58,195, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,248, 58,195, 6, 0, 0, 0, 0, 24, 58,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,234, 3, + 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,248, 58,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,104, 59,195, 6, + 0, 0, 0, 0,136, 58,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,104, 59,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,216, 59,195, 6, 0, 0, 0, 0,248, 58,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 92, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,216, 59,195, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72, 60,195, 6, 0, 0, 0, 0,104, 59,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,126, 7, 92, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72, 60,195, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,184, 60,195, 6, 0, 0, 0, 0,216, 59,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6,234, 3, + 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,184, 60,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40, 61,195, 6, + 0, 0, 0, 0, 72, 60,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0, 40, 61,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,152, 61,195, 6, 0, 0, 0, 0,184, 60,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,152, 61,195, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 8, 62,195, 6, 0, 0, 0, 0, 40, 61,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 3,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8, 62,195, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,120, 62,195, 6, 0, 0, 0, 0,152, 61,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,120, 62,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8, 62,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,232, 62,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88, 63,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 57,195, 6, 0, 0, 0, 0,168, 57,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0, 88, 63,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200, 63,195, 6, 0, 0, 0, 0,232, 62,195, 6, + 0, 0, 0, 0, 56, 57,195, 6, 0, 0, 0, 0,136, 58,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,200, 63,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56, 64,195, 6, 0, 0, 0, 0, 88, 63,195, 6, + 0, 0, 0, 0,168, 57,195, 6, 0, 0, 0, 0,248, 58,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0, 56, 64,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168, 64,195, 6, 0, 0, 0, 0,200, 63,195, 6, + 0, 0, 0, 0,136, 58,195, 6, 0, 0, 0, 0,248, 58,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,168, 64,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24, 65,195, 6, 0, 0, 0, 0, 56, 64,195, 6, + 0, 0, 0, 0, 24, 58,195, 6, 0, 0, 0, 0,216, 59,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0, 24, 65,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,136, 65,195, 6, 0, 0, 0, 0,168, 64,195, 6, + 0, 0, 0, 0,104, 59,195, 6, 0, 0, 0, 0,216, 59,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,136, 65,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,248, 65,195, 6, 0, 0, 0, 0, 24, 65,195, 6, + 0, 0, 0, 0,248, 58,195, 6, 0, 0, 0, 0, 72, 60,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,248, 65,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104, 66,195, 6, 0, 0, 0, 0,136, 65,195, 6, + 0, 0, 0, 0,136, 58,195, 6, 0, 0, 0, 0, 72, 60,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,104, 66,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216, 66,195, 6, 0, 0, 0, 0,248, 65,195, 6, + 0, 0, 0, 0,104, 59,195, 6, 0, 0, 0, 0, 72, 60,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,216, 66,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72, 67,195, 6, 0, 0, 0, 0,104, 66,195, 6, + 0, 0, 0, 0,248, 58,195, 6, 0, 0, 0, 0,216, 59,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0, 72, 67,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184, 67,195, 6, 0, 0, 0, 0,216, 66,195, 6, + 0, 0, 0, 0,136, 58,195, 6, 0, 0, 0, 0,184, 60,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,184, 67,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40, 68,195, 6, 0, 0, 0, 0, 72, 67,195, 6, + 0, 0, 0, 0, 72, 60,195, 6, 0, 0, 0, 0, 40, 61,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0, 40, 68,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152, 68,195, 6, 0, 0, 0, 0,184, 67,195, 6, + 0, 0, 0, 0,184, 60,195, 6, 0, 0, 0, 0, 40, 61,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,152, 68,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8, 69,195, 6, 0, 0, 0, 0, 40, 68,195, 6, + 0, 0, 0, 0,184, 60,195, 6, 0, 0, 0, 0,152, 61,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0, 8, 69,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120, 69,195, 6, 0, 0, 0, 0,152, 68,195, 6, + 0, 0, 0, 0, 40, 61,195, 6, 0, 0, 0, 0,152, 61,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,120, 69,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232, 69,195, 6, 0, 0, 0, 0, 8, 69,195, 6, + 0, 0, 0, 0,200, 56,195, 6, 0, 0, 0, 0, 8, 62,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,232, 69,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88, 70,195, 6, 0, 0, 0, 0,120, 69,195, 6, + 0, 0, 0, 0, 8, 62,195, 6, 0, 0, 0, 0,120, 62,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0, 88, 70,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200, 70,195, 6, 0, 0, 0, 0,232, 69,195, 6, + 0, 0, 0, 0, 24, 58,195, 6, 0, 0, 0, 0,120, 62,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,200, 70,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56, 71,195, 6, 0, 0, 0, 0, 88, 70,195, 6, + 0, 0, 0, 0,104, 59,195, 6, 0, 0, 0, 0,120, 62,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0, 56, 71,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168, 71,195, 6, 0, 0, 0, 0,200, 70,195, 6, + 0, 0, 0, 0,152, 61,195, 6, 0, 0, 0, 0, 8, 62,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0,168, 71,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24, 72,195, 6, 0, 0, 0, 0, 56, 71,195, 6, + 0, 0, 0, 0, 40, 61,195, 6, 0, 0, 0, 0,120, 62,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 0, 0, 0, 24, 72,195, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 71,195, 6, + 0, 0, 0, 0,200, 56,195, 6, 0, 0, 0, 0,184, 60,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +160, 0, 0, 0,136, 72,195, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 88, 76,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,136, 58,195, 6, 0, 0, 0, 0, 56, 57,195, 6, 0, 0, 0, 0,168, 57,195, 6, 0, 0, 0, 0,248, 58,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,235, 3, 0, 0, 5, 4, 0, 0, 7, 7,127, 7, + 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,163,195, 6, 0, 0, 0, 0,104,163,195, 6, + 0, 0, 0, 0,120, 73,195, 6, 0, 0, 0, 0,232, 74,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,120, 73,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,232, 74,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32,148, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,239, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, 0, 0,200, 65, 0,192,239, 68, 0, 0,200, 65, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,127, 7, 26, 0,127, 7, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,235, 3, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,232, 74,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 73,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0,240,109, 69, 0, 0,128,192, 0, 0, 0, 0, 0, 0, 0, 0,255,255,109, 69, 0, 0, 0,192, 0, 0, 0, 0,112, 7, 0, 0, +129, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +111, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 2, 0, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, 10, 0,129, 7, 2, 0,112, 7, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 5, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 88, 76,195, 6, + 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 72, 81,195, 6, 0, 0, 0, 0,136, 72,195, 6, 0, 0, 0, 0,120, 62,195, 6, + 0, 0, 0, 0,104, 59,195, 6, 0, 0, 0, 0,216, 59,195, 6, 0, 0, 0, 0, 24, 58,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 15, 15, 94, 1, 92, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 80,195, 6, 0, 0, 0, 0, 40, 80,195, 6, 0, 0, 0, 0, 72, 77,195, 6, + 0, 0, 0, 0,184, 78,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72, 77,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,184, 78,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,115, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0,175, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0,128,174, 67, 0, 0,200, 65, 0,128,174, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 94, 1, 26, 0, 94, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 94, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,184, 78,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 77,195, 6, 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67, 0, 0, 0, 0, + 0, 0, 72, 66, 50, 51, 74,193,154,209,131, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 93, 1, 0, 0, 18, 0, 0, 0, + 65, 0, 0, 0, 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65, 72, 0, 0, 0, + 0, 0, 0, 2, 4, 0, 0, 4, 8, 0, 94, 1, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 26, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 94, 1, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0, 40, 80,195, 6, 0, 0, 0, 0,190, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 72, 81,195, 6, + 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,216,105,195, 6, 0, 0, 0, 0, 88, 76,195, 6, 0, 0, 0, 0,104, 59,195, 6, + 0, 0, 0, 0, 72, 60,195, 6, 0, 0, 0, 0,248, 58,195, 6, 0, 0, 0, 0,216, 59,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 93, 0, 0, 0,233, 3, 0, 0, 4, 4, 94, 1,141, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,104,195, 6, 0, 0, 0, 0,152,104,195, 6, 0, 0, 0, 0, 56, 82,195, 6, + 0, 0, 0, 0,168, 83,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 56, 82,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,168, 83,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,148, 67, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0,175, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0,128,174, 67, 0, 0,200, 65, 0,128,174, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 94, 1, 26, 0, 94, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0,208, 3, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 94, 1, 26, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168, 83,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 82,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,174, 67, 0,128, 92,196, + 0, 0, 0, 0, 0, 0, 0, 0,255,127,166, 67,255,191, 92,196, 0, 0, 0, 0, 77, 1, 0, 0, 94, 1, 0, 0, 0, 0, 0, 0, +114, 3, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 76, 1, 0, 0, 0, 0, 0, 0, +114, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, + 1, 0, 7, 0, 18, 0, 0, 4, 6, 0, 94, 1,115, 3, 77, 1,115, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 93, 0, 0, 0,207, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 94, 1,115, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 85,195, 6, + 0, 0, 0, 0,248,102,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 24, 85,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,184, 86,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,220,255, 76, 1, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,184, 86,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 88, 88,195, 6, 0, 0, 0, 0, 24, 85,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101, +110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101, +110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82,101,110,100,101,114, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,255, 76, 1, 61, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 88, 88,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,248, 89,195, 6, 0, 0, 0, 0,184, 86,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 76, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,111,255, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,248, 89,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,152, 91,195, 6, 0, 0, 0, 0, 88, 88,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105, +109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105, +109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,105,109,101,110,115,105,111,110,115, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,254, 76, 1,203, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,152, 91,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 56, 93,195, 6, 0, 0, 0, 0,248, 89,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 65,110,116,105, 45, 65,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 58,254, 76, 1, 58, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0, 56, 93,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,216, 94,195, 6, 0, 0, 0, 0,152, 91,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111, +116,105,111,110, 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111, +116,105,111,110, 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 97,109,112,108,101,100, 32, 77,111,116,105, +111,110, 32, 66,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,254, 76, 1, 0, 0, 20, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,216, 94,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,120, 96,195, 6, 0, 0, 0, 0, 56, 93,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10,254, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,120, 96,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 24, 98,195, 6, 0, 0, 0, 0,216, 94,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101, +114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101, +114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,101,114,102,111,114,109, 97,110, 99,101, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,242,253, 76, 1, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 24, 98,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,184, 99,195, 6, 0, 0, 0, 0,120, 96,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80,111,115,116, 32, 80,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,218,253, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,184, 99,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 88,101,195, 6, 0, 0, 0, 0, 24, 98,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, + 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, + 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194,253, 76, 1, 0, 0, 20, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 88,101,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,248,102,195, 6, 0, 0, 0, 0,184, 99,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 79,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 40,253, 76, 1,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,248,102,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,101,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97, +107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97, +107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,253, 76, 1, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,152,104,195, 6, 0, 0, 0, 0,179, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,255, 21, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +160, 0, 0, 0,216,105,195, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,104,119,195, 6, 0, 0, 0, 0, 72, 81,195, 6, + 0, 0, 0, 0, 8, 62,195, 6, 0, 0, 0, 0,152, 61,195, 6, 0, 0, 0, 0, 40, 61,195, 6, 0, 0, 0, 0,120, 62,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0, 0, 31, 6, 0, 0, 0, 0, 0, 0,139, 1, 0, 0, 1, 1, 27, 3, +140, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,117,195, 6, 0, 0, 0, 0,184,117,195, 6, + 0, 0, 0, 0,200,106,195, 6, 0, 0, 0, 0,136,112,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,200,106,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 56,108,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 64,113, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,192, 70, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128, 70, 68, 0, 0,200, 65, 0,128, 70, 68, 0, 0,200, 65, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 27, 3, 26, 0, 27, 3, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0, 0, 31, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 3, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 56,108,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,168,109,195, 6, 0, 0, 0, 0,200,106,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 67, 0, 64, 70,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67,255,127, 70,196, 0, 0, 0, 0,143, 0, 0, 0, +160, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +142, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0, 44, 3,143, 0, 26, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0, 0, 5, 3, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,114, 1, 0, 0, 5, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168,109,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 24,111,195, 6, 0, 0, 0, 0, 56,108,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 67, 0, 0,206,194, 0, 0, 0, 0, 0, 0, 0, 0,231,102, 16, 67, 0, 0,206,194, 0, 0, 0, 0,143, 0, 0, 0, +160, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +142, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,120, 0,143, 0,102, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0, 0, 31, 6, 0, 0, 26, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 6, 0, 34, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 24,111,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,136,112,195, 6, 0, 0, 0, 0,168,109,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 35, 67, 0,192,108,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, 0, 0,184,195, 0, 0, 0, 0,163, 0, 0, 0, +180, 0, 0, 0, 18, 0, 0, 0,129, 1, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +162, 0, 0, 0, 18, 0, 0, 0,129, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,180, 0,130, 1,163, 0,112, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0, 31, 6, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136,112,195, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,111,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0, 0, 31, 6, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 3,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,113,195, 6, 0, 0, 0, 0, 68, 65, 84, 65,112, 3, 0, 0,248,113,195, 6, + 0, 0, 0, 0,173, 0, 0, 0, 1, 0, 0, 0, 93,101,230, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30,133,119, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154, 65,128,191, 0, 0,128,191, 0, 0, 0, 0, + 0, 0, 0, 0, 72, 1, 77,190, 0, 0, 0, 0,221,149, 47, 63, 85,126,162,190, 8,165, 39, 63, 0, 0, 0, 0, 51, 70, 58, 63, +225,251,159, 62,149, 84, 28,191, 0, 0, 0, 0,191, 56, 49,188, 54, 53,101, 63, 50,247,227, 62, 0, 0, 0, 0, 90, 38,173,190, +254,221,192,190,152, 9, 52,193, 0, 0,128, 63,223,149, 47, 63, 55, 70, 58, 63,192, 56, 49,188, 0, 0, 0, 0, 87,126,162,190, +228,251,159, 62, 56, 53,101, 63, 0, 0, 0, 0, 7,165, 39, 63,150, 84, 28,191, 50,247,227, 62, 0, 0, 0, 0,110,101,239, 64, +151, 62,208,192, 77,255,170, 64, 0, 0,128, 63, 42, 6,158, 63, 99, 28,157,191,244,250, 39,191, 8,165, 39,191,211,164,167, 63, + 55,175,154, 63,180,164, 28, 63,149, 84, 28, 63, 39,127,159,188,135,157, 93, 64, 8,108,228,190, 50,247,227,190, 4,213, 27,191, +122,122,186,191,216, 49, 49, 65,152, 9, 52, 65, 25, 25,195, 62,176,249,206, 62,128,238,196,187, 0, 0,192,179, 55, 15,168,189, +201,118,165, 61,152, 15,109, 62, 0, 0,152, 51,211,120, 21,194,144, 5, 2, 66, 6,136,213,193,193,214,159,192,219, 38, 19, 66, +196,173,255,193,154,101,210, 65,173, 40,160, 64,221,149, 47, 63, 85,126,162,190, 8,165, 39, 63, 0, 0, 0, 0, 51, 70, 58, 63, +225,251,159, 62,149, 84, 28,191, 0, 0, 0, 0,191, 56, 49,188, 54, 53,101, 63, 50,247,227, 62, 0, 0, 0, 0, 90, 38,173,190, +254,221,192,190,152, 9, 52,193, 0, 0,128, 63, 42, 6,158, 63, 99, 28,157,191,244,250, 39,191, 8,165, 39,191,211,164,167, 63, + 55,175,154, 63,180,164, 28, 63,149, 84, 28, 63, 39,127,159,188,135,157, 93, 64, 8,108,228,190, 50,247,227,190, 4,213, 27,191, +122,122,186,191,216, 49, 49, 65,152, 9, 52, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,250,150, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 62,250,150, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,250,150, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,241, 22, 72, 63, 78,162,246,190, 44, 8, 90,190, 3, 35,171,190,214,211,111, 65, +214,211,111, 65, 0, 0, 0, 0, 0, 0, 0, 0, 80, 49,183, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 65, + 1, 2, 0, 0,255,255, 0, 0, 92, 62, 55, 63, 56,186,224,190,237,203,148,190, 3,236,234,190, 1, 0, 0, 0, 0, 0,128, 63, +190,133, 65, 66,100,212, 90, 66, 31,183,118, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 96, 1, 0, 0,184,117,195, 6, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, +205,204, 76, 62, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,200, 67,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, 8, 8,128, 0, 0, 0, 12, 66, 0, 0,128, 63, +205,204,204, 61, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,104,119,195, 6, + 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,184,124,195, 6, 0, 0, 0, 0,216,105,195, 6, 0, 0, 0, 0,184, 60,195, 6, + 0, 0, 0, 0,136, 58,195, 6, 0, 0, 0, 0, 72, 60,195, 6, 0, 0, 0, 0, 40, 61,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0,141, 1, 0, 0,233, 3, 0, 0, 16, 16, 32, 6, 93, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,123,195, 6, 0, 0, 0, 0, 56,123,195, 6, 0, 0, 0, 0, 88,120,195, 6, + 0, 0, 0, 0,200,121,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88,120,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,200,121,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 66, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0,196, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0,224,195, 68, 0, 0,200, 65, 0,224,195, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 32, 6, 26, 0, 32, 6, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0,141, 1, 0, 0,166, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32, 6, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,200,121,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,120,195, 6, 0, 0, 0, 0, 0, 0, 32,193, 0, 0, 0, 68, 0, 0, 32,193, + 0, 0, 0, 68,128,195,217,195,192,225,108, 68, 96,240,187, 64, 62, 16,253, 67, 15, 6, 0, 0, 32, 6, 0, 0, 18, 0, 0, 0, + 66, 2, 0, 0, 0, 0, 0, 0, 14, 6, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 14, 6, 0, 0, 18, 0, 0, 0, + 66, 2, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,250, 70, 0, 0,250, 70,236, 81,184, 61, 10,215, 19, 64, 10, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 32, 6, 67, 2, 15, 6, 49, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0,167, 1, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32, 6, 67, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 1, 0, 0, 56,123,195, 6, 0, 0, 0, 0,191, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10,215, 19, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10,206, 97, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,184,124,195, 6, + 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,119,195, 6, 0, 0, 0, 0,200, 56,195, 6, + 0, 0, 0, 0,184, 60,195, 6, 0, 0, 0, 0,152, 61,195, 6, 0, 0, 0, 0, 8, 62,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0,139, 1, 0, 0, 6, 6, 4, 3,140, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,129,195, 6, 0, 0, 0, 0,248,129,195, 6, 0, 0, 0, 0,168,125,195, 6, + 0, 0, 0, 0,136,128,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168,125,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 24,127,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 67, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 65, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0,192, 64, 68, 0, 0,200, 65, 0,192, 64, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 4, 3, 26, 0, 4, 3, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 3, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 24,127,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,136,128,195, 6, 0, 0, 0, 0,168,125,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136,128,195, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,127,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, + 0, 0,128, 67, 0, 0,129,191, 0,128, 0, 64, 0, 0,100,190, 0,128,156, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, +114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 3,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 33, 0, 0,248,129,195, 6, 0, 0, 0, 0,184, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 65, 0, 0, 0, 0,154,153,153, 62, 0, 0, 0, 0, +100, 0, 0, 0,154,153,153, 62,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0, 8, 1, 0, 0,248,163,195, 6, 0, 0, 0, 0,210, 0, 0, 0, + 1, 0, 0, 0,120,188,196, 6, 0, 0, 0, 0,120, 55,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 82, 68,101,102, 97,117,108,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,165,195, 6, + 0, 0, 0, 0, 24,170,195, 6, 0, 0, 0, 0,136,170,195, 6, 0, 0, 0, 0,248,177,195, 6, 0, 0, 0, 0,104,178,195, 6, + 0, 0, 0, 0,120,156,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,123,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72,165,195, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,184,165,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,184,165,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40,166,195, 6, + 0, 0, 0, 0, 72,165,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,146, 4, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0, 40,166,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,152,166,195, 6, 0, 0, 0, 0,184,165,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,146, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,152,166,195, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 8,167,195, 6, 0, 0, 0, 0, 40,166,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8,167,195, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,120,167,195, 6, 0, 0, 0, 0,152,166,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 4, + 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,120,167,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,232,167,195, 6, + 0, 0, 0, 0, 8,167,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,104, 4, 1, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,232,167,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 88,168,195, 6, 0, 0, 0, 0,120,167,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 6, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 88,168,195, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200,168,195, 6, 0, 0, 0, 0,232,167,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 6,104, 4, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,200,168,195, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0, 56,169,195, 6, 0, 0, 0, 0, 88,168,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 6,196, 3, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 56,169,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,168,169,195, 6, + 0, 0, 0, 0,200,168,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,196, 3, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,168,169,195, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 24,170,195, 6, 0, 0, 0, 0, 56,169,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 24,170,195, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,169,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 6,144, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136,170,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,248,170,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,165,195, 6, 0, 0, 0, 0, 40,166,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,248,170,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,104,171,195, 6, 0, 0, 0, 0,136,170,195, 6, 0, 0, 0, 0,184,165,195, 6, 0, 0, 0, 0, 8,167,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,104,171,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,216,171,195, 6, 0, 0, 0, 0,248,170,195, 6, 0, 0, 0, 0, 40,166,195, 6, 0, 0, 0, 0,120,167,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216,171,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 72,172,195, 6, 0, 0, 0, 0,104,171,195, 6, 0, 0, 0, 0, 8,167,195, 6, 0, 0, 0, 0,120,167,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72,172,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,184,172,195, 6, 0, 0, 0, 0,216,171,195, 6, 0, 0, 0, 0, 72,165,195, 6, 0, 0, 0, 0,232,167,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184,172,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 40,173,195, 6, 0, 0, 0, 0, 72,172,195, 6, 0, 0, 0, 0,152,166,195, 6, 0, 0, 0, 0,232,167,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40,173,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,152,173,195, 6, 0, 0, 0, 0,184,172,195, 6, 0, 0, 0, 0, 8,167,195, 6, 0, 0, 0, 0, 88,168,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,152,173,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 8,174,195, 6, 0, 0, 0, 0, 40,173,195, 6, 0, 0, 0, 0,120,167,195, 6, 0, 0, 0, 0, 88,168,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 8,174,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,120,174,195, 6, 0, 0, 0, 0,152,173,195, 6, 0, 0, 0, 0,232,167,195, 6, 0, 0, 0, 0,200,168,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,120,174,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,232,174,195, 6, 0, 0, 0, 0, 8,174,195, 6, 0, 0, 0, 0, 88,168,195, 6, 0, 0, 0, 0,200,168,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,232,174,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 88,175,195, 6, 0, 0, 0, 0,120,174,195, 6, 0, 0, 0, 0,120,167,195, 6, 0, 0, 0, 0, 56,169,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88,175,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,200,175,195, 6, 0, 0, 0, 0,232,174,195, 6, 0, 0, 0, 0,152,166,195, 6, 0, 0, 0, 0, 56,169,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200,175,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 56,176,195, 6, 0, 0, 0, 0, 88,175,195, 6, 0, 0, 0, 0,200,168,195, 6, 0, 0, 0, 0, 56,169,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56,176,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,168,176,195, 6, 0, 0, 0, 0,200,175,195, 6, 0, 0, 0, 0, 72,165,195, 6, 0, 0, 0, 0,168,169,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,168,176,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 24,177,195, 6, 0, 0, 0, 0, 56,176,195, 6, 0, 0, 0, 0, 8,167,195, 6, 0, 0, 0, 0,168,169,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 24,177,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,136,177,195, 6, 0, 0, 0, 0,168,176,195, 6, 0, 0, 0, 0, 88,168,195, 6, 0, 0, 0, 0, 24,170,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136,177,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,248,177,195, 6, 0, 0, 0, 0, 24,177,195, 6, 0, 0, 0, 0,232,167,195, 6, 0, 0, 0, 0, 24,170,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,248,177,195, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,177,195, 6, 0, 0, 0, 0,168,169,195, 6, 0, 0, 0, 0, 24,170,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,104,178,195, 6, 0, 0, 0, 0,214, 0, 0, 0, + 1, 0, 0, 0, 56,182,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,167,195, 6, 0, 0, 0, 0,184,165,195, 6, + 0, 0, 0, 0, 40,166,195, 6, 0, 0, 0, 0,120,167,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0,105, 4, 0, 0,146, 4, 0, 0, 7, 7,127, 7, 42, 0, 1, 0, 0, 0, 0, 0, 7, 0, 8, 0, 8, 77,163, 6, + 0, 0, 0, 0,232,187,196, 6, 0, 0, 0, 0,232,187,196, 6, 0, 0, 0, 0, 88,179,195, 6, 0, 0, 0, 0,200,180,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,230, 12, 0, 73,127, 0, 0, 24,234, 12, 0, + 73,127, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88,179,195, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,200,180,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,163, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0,224,239, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, + 0, 0,200, 65, 0,192,239, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, + 10, 0,127, 7, 26, 0,127, 7, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0,105, 4, 0, 0,130, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, + 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 79,163, 6, + 0, 0, 0, 0,168,144,231, 0, 73,127, 0, 0,168,144,231, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,184,235, 12, 0, 73,127, 0, 0, 8,246, 12, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,200,180,195, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 88,179,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,239, 68, 0, 0, 0, 0, 0, 0, 48, 65, 0, 0, 0, 0, + 1,192,237, 68, 0, 0, 0, 0, 0, 0,128, 65,110, 7, 0, 0,127, 7, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, +111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,109, 7, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 2, 2, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, + 10, 0,127, 7, 16, 0,110, 7, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0,131, 4, 0, 0,146, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 16, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 78,163, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,168,247, 12, 0, 73,127, 0, 0,120, 6, 13, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 56,182,195, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 8,223,195, 6, + 0, 0, 0, 0,104,178,195, 6, 0, 0, 0, 0,232,167,195, 6, 0, 0, 0, 0,200,168,195, 6, 0, 0, 0, 0, 56,169,195, 6, + 0, 0, 0, 0,152,166,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 6, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, +195, 3, 0, 0, 4, 4, 46, 1,196, 3, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0,168, 72,163, 6, 0, 0, 0, 0,200,221,195, 6, + 0, 0, 0, 0,200,221,195, 6, 0, 0, 0, 0, 40,183,195, 6, 0, 0, 0, 0,152,184,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 13, 13, 0, 73,127, 0, 0,152, 29, 13, 0, 73,127, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0, 40,183,195, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,152,184,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,148, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,151, 67, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,150, 67, 0, 0,200, 65, 0,128,150, 67, + 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 46, 1, 26, 0, 46, 1, + 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 6, 0, 0,126, 7, 0, 0,170, 3, 0, 0, +195, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 1, 26, 0, 4, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 76,163, 6, 0, 0, 0, 0,104,215,226, 0, + 73,127, 0, 0,104,215,226, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232, 34, 13, 0, + 73,127, 0, 0, 88, 93,226, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,152,184,195, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,183,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, 0,128,106,196, 0, 0, 0, 0, 0, 0, 0, 0, 1,128,142, 67, 2,128,106,196, + 0, 0, 0, 0, 29, 1, 0, 0, 46, 1, 0, 0, 0, 0, 0, 0,169, 3, 0, 0, 0, 0, 0, 0, 74, 1, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0, 28, 1, 0, 0, 0, 0, 0, 0,169, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0, 46, 1,170, 3, 29, 1, +170, 3, 0, 0,248, 81,229, 0, 73,127, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 81, 6, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, +169, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 1,170, 3, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 73,163, 6, 0, 0, 0, 0, 40,189,225, 0, + 73,127, 0, 0,232, 26,225, 0, 73,127, 0, 0, 8,186,195, 6, 0, 0, 0, 0, 40,220,195, 6, 0, 0, 0, 0,248,236, 12, 0, + 73,127, 0, 0, 56,181,226, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0, 8,186,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,168,187,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,184, 74,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99, +111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99, +111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,110,116,101,120,116, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,255, 29, 1, 36, 0, 0, 0, 0, 0, + 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,168,187,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 72,189,195, 6, 0, 0, 0, 0, 8,186,195, 6, 0, 0, 0, 0,168, 73, 76, 0, 73,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,135,255, 29, 1, 61, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0, 72,189,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,232,190,195, 6, 0, 0, 0, 0,168,187,195, 6, + 0, 0, 0, 0, 24, 76, 76, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97, +121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97, +121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111,255, 29, 1, 0, 0, 0, 0, 0, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,232,190,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,136,192,195, 6, 0, 0, 0, 0, 72,189,195, 6, 0, 0, 0, 0,136, 78, 76, 0, 73,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,140,254, 29, 1,203, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,136,192,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 40,194,195, 6, 0, 0, 0, 0,232,190,195, 6, + 0, 0, 0, 0,248, 80, 76, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110, +116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110, +116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65,110,116,105, 45, 65,108,105, 97,115,105,110, +103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58,254, 29, 1, 58, 0, 20, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 40,194,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,200,195,195, 6, 0, 0, 0, 0,136,192,195, 6, 0, 0, 0, 0,104, 83, 76, 0, 73,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 97,109,112,108,101,100, 32, 77,111,116,105,111,110, 32, 66,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 34,254, 29, 1, 0, 0, 20, 0, 0, 0, 4, 0, 2, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,200,195,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,104,197,195, 6, 0, 0, 0, 0, 40,194,195, 6, + 0, 0, 0, 0, 72,156, 53, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, + 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, + 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,104, 97,100,105,110,103, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,254, 29, 1, 0, 0, 0, 0, 0, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,104,197,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 8,199,195, 6, 0, 0, 0, 0,200,195,195, 6, 0, 0, 0, 0,248, 92, 76, 0, 73,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,242,253, 29, 1, 0, 0, 0, 0, 0, 0, 4, 0, 2, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0, 8,199,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,168,200,195, 6, 0, 0, 0, 0,104,197,195, 6, + 0, 0, 0, 0,104, 95, 76, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111, +115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111, +115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,111,115,116, 32, 80,114,111, 99,101,115,115, +105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,218,253, 29, 1, 0, 0, 0, 0, 0, 0, + 4, 0, 2, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,168,200,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 72,202,195, 6, 0, 0, 0, 0, 8,199,195, 6, 0, 0, 0, 0,216, 97, 76, 0, 73,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,194,253, 29, 1, 0, 0, 20, 0, 0, 0, 4, 0, 2, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0, 72,202,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,232,203,195, 6, 0, 0, 0, 0,168,200,195, 6, + 0, 0, 0, 0, 72,100, 76, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117, +116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117, +116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79,117,116,112,117,116, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36,253, 29, 1,134, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,232,203,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,136,205,195, 6, 0, 0, 0, 0, 72,202,195, 6, 0, 0, 0, 0, 40,105, 76, 0, 73,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 66, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 12,253, 29, 1, 0, 0, 0, 0, 0, 0, 4, 0, 3, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,136,205,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 40,207,195, 6, 0, 0, 0, 0,232,203,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,115, 99,101, +110,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,115, 99,101, +110,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 99,101,110,101, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,255, 41, 1, 61, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 40,207,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,200,208,195, 6, 0, 0, 0, 0,136,205,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,117,110,105,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,117,110,105,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85,110,105,116,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 28,255, 41, 1, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,200,208,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,104,210,195, 6, 0, 0, 0, 0, 40,207,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,107,101,121, +105,110,103, 95,115,101,116,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,107,101,121, +105,110,103, 95,115,101,116,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75,101,121,105,110,103, 32, 83,101,116,115, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191,254, 41, 1, 69, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,104,210,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 8,212,195, 6, 0, 0, 0, 0,200,208,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,112,104,121,115,105, 99,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,112,104,121,115,105, 99,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 71,114, 97,118,105,116,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,131,254, 41, 1, 36, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0, 8,212,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,168,213,195, 6, 0, 0, 0, 0,104,210,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,115,105,109, +112,108,105,102,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,115,105,109, +112,108,105,102,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,105,109,112,108,105,102,121, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27,254, 41, 1, 80, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,168,213,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 72,215,195, 6, 0, 0, 0, 0, 8,212,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95, 99,117,115,116,111,109, 95,112,114,111,112,115, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95, 99,117,115,116,111,109, 95,112,114,111,112,115, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67,117,115,116,111,109, 32, 80,114,111,112,101,114,116,105,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,223,253, 41, 1, 36, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0, 72,215,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,232,216,195, 6, 0, 0, 0, 0,168,213,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, 80, 84, 95, 99, +111,110,116,101,120,116, 95,116,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, 80, 84, 95, 99, +111,110,116,101,120,116, 95,116,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,255,187, 0,204, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,232,216,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,136,218,195, 6, 0, 0, 0, 0, 72,215,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, 80, 84, 95,109, 97,112,112,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, 80, 84, 95,109, 97,112,112,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 97,112,112,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 77,254,187, 0,171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,136,218,195, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 40,220,195, 6, 0, 0, 0, 0,232,216,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, 80, 84, 95,105, +110,102,108,117,101,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 84, 85, 82, 69, 95, 80, 84, 95,105, +110,102,108,117,101,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73,110,102,108,117,101,110, 99,101, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,223,252,187, 0, 86, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 40,220,195, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,218,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 79, 66, 74, 69, 67, 84, 95, 80, 84, 95, 99,111,110,115,116,114, 97,105,110,116,115, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 79, 66, 74, 69, 67, 84, 95, 80, 84, 95, 99,111,110,115,116,114, 97,105,110,116,115, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 79, 98,106,101, 99,116, 32, 67,111,110,115,116,114, 97,105,110,116,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,160,255,187, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +248, 0, 0, 0,200,221,195, 6, 0, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 40, 97,228, 0, 73,127, 0, 0,255, 21, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 8,223,195, 6, 0, 0, 0, 0,214, 0, 0, 0, + 1, 0, 0, 0,248,227,195, 6, 0, 0, 0, 0, 56,182,195, 6, 0, 0, 0, 0, 72,165,195, 6, 0, 0, 0, 0,168,169,195, 6, + 0, 0, 0, 0, 24,170,195, 6, 0, 0, 0, 0,232,167,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 79, 6, 0, 0, 0, 0, 0, 0,143, 0, 0, 0, 15, 15, 80, 6,144, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 28,163, 6, + 0, 0, 0, 0,216,226,195, 6, 0, 0, 0, 0,216,226,195, 6, 0, 0, 0, 0,248,223,195, 6, 0, 0, 0, 0,104,225,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 94,226, 0, 73,127, 0, 0,216,249, 12, 0, + 73,127, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248,223,195, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,104,225,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,146, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0,202, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,224,201, 68, + 0, 0,200, 65, 0,224,201, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, + 10, 0, 80, 6, 26, 0, 80, 6, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 79, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 6, 26, 0, + 6, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 30,163, 6, + 0, 0, 0, 0,120,171,230, 0, 73,127, 0, 0,120,171,230, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,120, 47,225, 0, 73,127, 0, 0,216, 4, 13, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,104,225,195, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,248,223,195, 6, 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67, 0, 0, 0, 0, 0, 0, 72, 66, 88,218,103,194, + 40,147,141, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 79, 6, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 79, 6, 0, 0, 18, 0, 0, 0,117, 0, 0, 0, 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65, 72, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 4, - 8, 0,241, 4, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 4, 0, 0, 26, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241, 4, 42, 0, + 8, 0, 80, 6,118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 79, 6, 0, 0, 26, 0, 0, 0,143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 6,118, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 29,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0,200, 96,200, 3, 0, 0, 0, 0,190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 15, 13, 0, 73,127, 0, 0, 40, 27, 13, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0,216,226,195, 6, 0, 0, 0, 0,190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,120, 36,215, 3, 0, 0, 0, 0,214, 0, 0, 0, - 1, 0, 0, 0,152, 37,215, 3, 0, 0, 0, 0, 88, 35,215, 3, 0, 0, 0, 0, 8, 64,201, 3, 0, 0, 0, 0, 72, 65,201, 3, - 0, 0, 0, 0,104, 63,201, 3, 0, 0, 0, 0,136, 66,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 4, 0, 0, 69, 0, 0, 0, 91, 1, 0, 0, 8, 8,241, 4, 23, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,120,150,199, 3, 0, 0, 0, 0,120,150,199, 3, 0, 0, 0, 0,248,109,217, 3, 0, 0, 0, 0,136,160,217, 3, + 0, 0, 0, 0, 63, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,248,227,195, 6, 0, 0, 0, 0,214, 0, 0, 0, + 1, 0, 0, 0,120,156,196, 6, 0, 0, 0, 0, 8,223,195, 6, 0, 0, 0, 0,200,168,195, 6, 0, 0, 0, 0, 88,168,195, 6, + 0, 0, 0, 0,120,167,195, 6, 0, 0, 0, 0, 56,169,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 6, 0, 0, +126, 7, 0, 0,197, 3, 0, 0,103, 4, 0, 0, 3, 3, 46, 1,163, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0,120, 25,163, 6, + 0, 0, 0, 0,200,231,195, 6, 0, 0, 0, 0,200,231,195, 6, 0, 0, 0, 0,232,228,195, 6, 0, 0, 0, 0, 88,230,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 27, 13, 0, 73,127, 0, 0, 40, 88,226, 0, + 73,127, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,232,228,195, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 88,230,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,244, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0,151, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,150, 67, + 0, 0,200, 65, 0,128,150, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, + 10, 0, 46, 1, 26, 0, 46, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 6, 0, 0, +126, 7, 0, 0, 78, 4, 0, 0,103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 1, 26, 0, + 8, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 27,163, 6, + 0, 0, 0, 0, 56, 30,231, 0, 73,127, 0, 0, 56, 30,231, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,184, 88,226, 0, 73,127, 0, 0, 88,114,225, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88,230,195, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,232,228,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,141, 67, 0, 0,244,194, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,142, 67, 0, 0,242,194, 0, 0, 0,192, 29, 1, 0, 0, 46, 1, 0, 0, 18, 0, 0, 0,136, 0, 0, 0, 0, 0, 0, 0, + 28, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 28, 1, 0, 0, 18, 0, 0, 0,136, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 18, 4, 0, 0, 2, 0, 3, 3, 0, 0, 12, 4, + 6, 0, 46, 1,137, 0, 29, 1,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 6, 0, 0, +126, 7, 0, 0,197, 3, 0, 0, 77, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 1,137, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 26,163, 6, + 0, 0, 0, 0,248, 69,231, 0, 73,127, 0, 0,248, 69,231, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,248,105,228, 0, 73,127, 0, 0, 8,229,225, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 24, 1, 0, 0,200,231,195, 6, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248,109,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,168,111,217, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 26, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, - 0, 32,158, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0,158, 68, - 0, 0,200, 65, 0, 0,158, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, - 10, 0,241, 4, 26, 0,241, 4, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 4, 0, 0, 69, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241, 4, 26, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,104, 35,231, 0, 73,127, 0, 0,104, 35,231, 0, 73,127, 0, 0, 40,233,195, 6, 0, 0, 0, 0, 0,115,101, 32, + 83, 99,117,108,112,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65, 16, 0, 0, 0, 40,233,195, 6, + 0, 0, 0, 0,237, 0, 0, 0, 1, 0, 0, 0, 42, 11, 0, 0, 42, 11, 0, 0,136,233,195, 6, 0, 0, 0, 0, 68, 65, 84, 65, +160,178, 0, 0,136,233,195, 6, 0, 0, 0, 0,236, 0, 0, 0, 42, 11, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0,104, 38,198, 6, + 0, 0, 0, 0, 19, 0, 0, 0, 1, 0, 1, 0,104, 38,198, 6, 0, 0, 0, 0, 20, 0, 0, 0, 1, 0, 1, 0,104, 38,198, 6, + 0, 0, 0, 0, 21, 0, 1, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,248, 64,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,104, 74,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 8,129,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 72, 88,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 88,110,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,168, 81,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 56, 60,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,200, 67,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 40, 59,198, 6, + 0, 0, 0, 0, 21, 0, 0, 0, 1, 0, 1, 0,104, 38,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,232,147,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 30, 0,255,255, 3, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,136,211,194, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,120, 55,195, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,248,163,195, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,120,188,196, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,136, 95,197, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,248,174,197, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 24,246,197, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0, 88,110,198, 6, + 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,152,208,194, 6, 0, 0, 0, 0, 30, 0,255,255, 1, 0, 0, 0,248, 64,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 8,154,199, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 40, 59,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 70, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 71, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 72, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 73, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 74, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 75, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 76, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 77, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 78, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 79, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 80, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 81, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 82, 0, 1, 0, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 31, 0, 83, 0, 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0, 8,129,198, 6, + 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 70, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 71, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 72, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 73, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 74, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 75, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 76, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 77, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 78, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 79, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 80, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 81, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 82, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 83, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 84, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 85, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 86, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 87, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 88, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 89, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 90, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 91, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 92, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 93, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 94, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 95, 0, 1, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 31, 0, 96, 0, 1, 0, 0, 0,200, 67,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 70, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 71, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 72, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 73, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 74, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 75, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 76, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 77, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 78, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 79, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 80, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 81, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 82, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 83, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 84, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 85, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 86, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 87, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 88, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 89, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 90, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 91, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 92, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 93, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 94, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 95, 0, 1, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 31, 0, 96, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 21, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 22, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 23, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 24, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 25, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 26, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 27, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 28, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 29, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 30, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 31, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 32, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 33, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 34, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 35, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 36, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 37, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 38, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 39, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 40, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 41, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 42, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 43, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 44, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 45, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 46, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 47, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 48, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 49, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 50, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 51, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 52, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 53, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 54, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 55, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 56, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 57, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 58, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 59, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 60, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 61, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 62, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 63, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 64, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 65, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 66, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 67, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 68, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 69, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 70, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 71, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 72, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 73, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 74, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 75, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 76, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 77, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 78, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 79, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 80, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 81, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 82, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 83, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 84, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 85, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 86, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 87, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 88, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 89, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 90, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 91, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 92, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 93, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 94, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 95, 0, 1, 0, 0, 0,168, 81,198, 6, 0, 0, 0, 0, 31, 0, 96, 0, 1, 0, 0, 0,168, 81,198, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,136,211,194, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,136,211,194, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,136,211,194, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,136,211,194, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,136,211,194, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,136,211,194, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,136,211,194, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,136,211,194, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,136,211,194, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,136,211,194, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,120, 55,195, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,120, 55,195, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,120, 55,195, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,120, 55,195, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,120, 55,195, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,120, 55,195, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,120, 55,195, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,120, 55,195, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,120, 55,195, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,120, 55,195, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,248,163,195, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,248,163,195, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,248,163,195, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,248,163,195, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,248,163,195, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,248,163,195, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,248,163,195, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,248,163,195, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,248,163,195, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,248,163,195, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,120,188,196, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,120,188,196, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,120,188,196, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,120,188,196, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,120,188,196, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,120,188,196, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,120,188,196, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,120,188,196, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,120,188,196, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,120,188,196, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,136, 95,197, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,136, 95,197, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,136, 95,197, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,136, 95,197, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,136, 95,197, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,136, 95,197, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,136, 95,197, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,136, 95,197, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,136, 95,197, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,136, 95,197, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,248,174,197, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,248,174,197, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,248,174,197, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,248,174,197, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,248,174,197, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,248,174,197, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,248,174,197, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,248,174,197, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,248,174,197, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,248,174,197, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 24,246,197, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 24,246,197, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 24,246,197, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 24,246,197, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 24,246,197, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 24,246,197, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 24,246,197, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 24,246,197, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 24,246,197, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 24,246,197, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 88,110,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0, 88,110,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0, 88,110,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0, 88,110,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0, 88,110,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0, 88,110,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0, 88,110,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0, 88,110,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0, 88,110,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0, 88,110,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0, 88,110,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0, 88,110,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0, 88,110,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0, 88,110,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0, 88,110,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0, 88,110,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0, 88,110,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0, 88,110,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0, 88,110,198, 6, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,152,208,194, 6, + 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,152,208,194, 6, 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,152,208,194, 6, + 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,152,208,194, 6, 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,152,208,194, 6, + 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,152,208,194, 6, 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,152,208,194, 6, + 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,152,208,194, 6, 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,152,208,194, 6, + 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,152,208,194, 6, 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,152,208,194, 6, + 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0,248, 64,198, 6, 0, 0, 0, 0, 31, 0, 1, 0, 1, 0, 0, 0,248, 64,198, 6, + 0, 0, 0, 0, 31, 0, 2, 0, 1, 0, 0, 0,248, 64,198, 6, 0, 0, 0, 0, 31, 0, 3, 0, 1, 0, 0, 0,248, 64,198, 6, + 0, 0, 0, 0, 31, 0, 4, 0, 1, 0, 0, 0,248, 64,198, 6, 0, 0, 0, 0, 31, 0, 5, 0, 1, 0, 0, 0,248, 64,198, 6, + 0, 0, 0, 0, 31, 0, 6, 0, 1, 0, 0, 0,248, 64,198, 6, 0, 0, 0, 0, 31, 0, 7, 0, 1, 0, 0, 0,248, 64,198, 6, + 0, 0, 0, 0, 31, 0, 8, 0, 1, 0, 0, 0,248, 64,198, 6, 0, 0, 0, 0, 31, 0, 9, 0, 1, 0, 0, 0,248, 64,198, 6, + 0, 0, 0, 0, 31, 0, 10, 0, 1, 0, 0, 0,248, 64,198, 6, 0, 0, 0, 0, 31, 0, 11, 0, 1, 0, 0, 0,248, 64,198, 6, + 0, 0, 0, 0, 31, 0, 12, 0, 1, 0, 0, 0,248, 64,198, 6, 0, 0, 0, 0, 31, 0, 13, 0, 1, 0, 0, 0,248, 64,198, 6, + 0, 0, 0, 0, 31, 0, 14, 0, 1, 0, 0, 0,248, 64,198, 6, 0, 0, 0, 0, 31, 0, 15, 0, 1, 0, 0, 0,248, 64,198, 6, + 0, 0, 0, 0, 31, 0, 16, 0, 1, 0, 0, 0,248, 64,198, 6, 0, 0, 0, 0, 31, 0, 17, 0, 1, 0, 0, 0,248, 64,198, 6, + 0, 0, 0, 0, 31, 0, 18, 0, 1, 0, 0, 0,248, 64,198, 6, 0, 0, 0, 0, 31, 0, 19, 0, 1, 0, 0, 0,248, 64,198, 6, + 0, 0, 0, 0, 31, 0, 20, 0, 1, 0, 0, 0,248, 64,198, 6, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,120,156,196, 6, + 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,227,195, 6, 0, 0, 0, 0,168,169,195, 6, + 0, 0, 0, 0, 8,167,195, 6, 0, 0, 0, 0, 88,168,195, 6, 0, 0, 0, 0, 24,170,195, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 79, 6, 0, 0,145, 0, 0, 0,103, 4, 0, 0, 1, 1, 80, 6,215, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 8, 0,120, 31,163, 6, 0, 0, 0, 0, 56,186,196, 6, 0, 0, 0, 0, 56,186,196, 6, 0, 0, 0, 0,104,157,196, 6, + 0, 0, 0, 0, 8,181,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,106,228, 0, + 73,127, 0, 0,104, 9, 13, 0, 73,127, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,104,157,196, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,216,158,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,108, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0,202, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 6, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0,224,201, 68, 0, 0,200, 65, 0,224,201, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 80, 6, 26, 0, 80, 6, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 79, 6, 0, 0,145, 0, 0, 0,170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 6, 26, 0, 10, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,216, 41,163, 6, 0, 0, 0, 0,232,105,233, 0, 73,127, 0, 0,232,105,233, 0, 73,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,176,229, 0, 73,127, 0, 0,104, 11, 13, 0, 73,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,216,158,196, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,136,176,196, 6, 0, 0, 0, 0,104,157,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, 0, 64, 57,196, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 64, 57,196, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, +228, 2, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, +228, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, + 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,229, 2,143, 0,229, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0,131, 1, 0, 0,103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,160, 0,229, 2, 11, 0, 5, 0, 3, 0, 0, 0, 0, 0, 0, 0,160, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,152, 38,163, 6, 0, 0, 0, 0, 40, 93,232, 0, 73,127, 0, 0, 40, 93,232, 0, 73,127, 0, 0, 72,160,196, 6, + 0, 0, 0, 0,232,174,196, 6, 0, 0, 0, 0, 56, 12, 13, 0, 73,127, 0, 0, 88, 96,228, 0, 73,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 72,160,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,232,161,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,130, 79, 0, 73,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,111, 98,106,101, 99,116,109,111,100,101, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,111, 98,106,101, 99,116,109,111,100,101, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 79, 98,106,101, 99,116, 32, 84,111,111,108,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,233,253,143, 0,255, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,232,161,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,136,163,196, 6, 0, 0, 0, 0, 72,160,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111, +111,108,115, 95, 98,114,117,115,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111, +111,108,115, 95, 98,114,117,115,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66,114,117,115,104, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117,254,143, 0,115, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,136,163,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 40,165,196, 6, 0, 0, 0, 0,232,161,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95,116,111,111,108, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95,116,111,111,108, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84,111,111,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 74,254,143, 0, 61, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0, 40,165,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,200,166,196, 6, 0, 0, 0, 0,136,163,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111, +111,108,115, 95, 98,114,117,115,104, 95,115,116,114,111,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111, +111,108,115, 95, 98,114,117,115,104, 95,115,116,114,111,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,116,114,111,107,101, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,254,143, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,200,166,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,104,168,196, 6, 0, 0, 0, 0, 40,165,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95, 99,117,114,118,101, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95, 98,114,117,115,104, 95, 99,117,114,118,101, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67,117,114,118,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 45,254,143, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,104,168,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 8,170,196, 6, 0, 0, 0, 0,200,166,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111, +111,108,115, 95, 98,114,117,115,104, 95, 97,112,112,101, 97,114, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111, +111,108,115, 95, 98,114,117,115,104, 95, 97,112,112,101, 97,114, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65,112,112,101, 97,114, 97,110, 99,101, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,229,253,143, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 8,170,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,168,171,196, 6, 0, 0, 0, 0,104,168,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,118,101,114,116,101,120,112, 97,105,110,116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108,115, 95,118,101,114,116,101,120,112, 97,105,110,116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 79,112,116,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,149,253,143, 0,146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,168,171,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 72,173,196, 6, 0, 0, 0, 0, 8,170,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111, +111,108,115, 95, 98,114,117,115,104, 95,116,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111, +111,108,115, 95, 98,114,117,115,104, 95,116,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84,101,120,116,117,114,101, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93,254,143, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 72,173,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,232,174,196, 6, 0, 0, 0, 0,168,171,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,115, 99,117,108,112,116, 95,111,112,116,105,111,110,115, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,115, 99,117,108,112,116, 95,111,112,116,105,111,110,115, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 79,112,116,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21,254,143, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,232,174,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,173,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,115, 99, +117,108,112,116, 95,115,121,109,109,101,116,114,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,115, 99, +117,108,112,116, 95,115,121,109,109,101,116,114,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,121,109,109,101,116,114,121, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,253,253,143, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136,176,196, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,152,179,196, 6, 0, 0, 0, 0,216,158,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, 0, 0, 90,195, + 0, 0, 0, 0, 0, 0, 0, 0,227,102, 16, 67, 24, 30, 90,195, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, +215, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, +215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, + 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,216, 0,143, 0,216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0,171, 0, 0, 0,130, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,160, 0,216, 0, 12, 0, 6, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,136, 39,163, 6, 0, 0, 0, 0,200,253,232, 0, 73,127, 0, 0,200,253,232, 0, 73,127, 0, 0,248,177,196, 6, + 0, 0, 0, 0,248,177,196, 6, 0, 0, 0, 0,200, 46,228, 0, 73,127, 0, 0, 24,181,229, 0, 73,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,248,177,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 40,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 79,112,101,114, 97,116,111,114, 0,100,101, 0, 32, 77,111,100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,216,255,144, 0, 16, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,152,179,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 8,181,196, 6, 0, 0, 0, 0,136,176,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 67, 0, 96,158,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, 0, 96,158,196, + 0,128,142,195,163, 0, 0, 0,180, 0, 0, 0, 0, 0, 0, 0,213, 3, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0,213, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 1, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,180, 0,214, 3,163, 0, +214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 6, 0, 0, 79, 6, 0, 0,171, 0, 0, 0, +103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 33,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0, 8,181,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,179,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0, 0, 0, 79, 6, 0, 0,171, 0, 0, 0, +103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176, 5,189, 3, 13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 32,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,226,224, 0, + 73,127, 0, 0, 72, 40, 13, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,182,196, 6, 0, 0, 0, 0, 68, 65, 84, 65, +112, 3, 0, 0,120,182,196, 6, 0, 0, 0, 0,173, 0, 0, 0, 1, 0, 0, 0, 1, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,188,255,212, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 6,128,191, + 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, 11,210, 76,190, 0, 0, 0, 0, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, + 0, 0, 0, 0, 70,119,105, 63,143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33,210,111,193, 0, 0,128, 63, 68,239,209, 62, 70,119,105, 63,176, 84, 89,188, + 0, 0, 0, 0, 52,177,205,190,142, 74, 70, 62,166, 33,101, 63, 0, 0, 0, 0,185,158, 81, 63, 35, 44,185,190, 43, 61,228, 62, + 0, 0, 0, 0, 62, 95, 68, 65, 51,120,173,192,115,208,213, 64, 0, 0,128, 63,180,157,229, 62, 57, 36, 43,191,116,169, 81,191, +184,158, 81,191,118, 90,127, 63,212,251,164, 62,158, 53,185, 62, 35, 44,185, 62,147,180,109,188,194,164,190, 63,218, 72,228,190, + 42, 61,228,190, 0, 0, 0, 0, 0, 0, 0, 0, 33,171,108, 65, 33,210,111, 65,100,240,191, 62,110,116, 85, 63, 32,185, 70,188, + 0, 0, 80,180,122, 55,119,190, 96, 82,238, 61,227,177, 9, 63, 0, 0,248, 51,197,112,117,194,179,208,216, 65,220,158, 5,194, +231,251,159,192,221, 54,114, 66, 30,247,213,193, 58,221, 3, 66, 25, 4,160, 64, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, + 0, 0, 0, 0, 70,119,105, 63,143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33,210,111,193, 0, 0,128, 63,180,157,229, 62, 57, 36, 43,191,116,169, 81,191, +184,158, 81,191,118, 90,127, 63,212,251,164, 62,158, 53,185, 62, 35, 44,185, 62,147,180,109,188,194,164,190, 63,218, 72,228,190, + 42, 61,228,190, 0, 0, 0, 0, 0, 0, 0, 0, 33,171,108, 65, 33,210,111, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,182,180, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,114,182,180, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,182,180, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 92, 62, 55, 63, 56,186,224,190,237,203,148,190, + 3,236,234,190, 33,210,111, 65, 33,210,111, 65, 0, 0, 0, 0, 0, 0, 0, 0,146,156,164, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 32, 33, 12, 66, 85,152,137, 66,113, 27,126, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 96, 1, 0, 0, 56,186,196, 6, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 32, 65,205,204, 76, 62, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,200, 67,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, 8, 24,128, 0, + 0, 0, 12, 66, 0, 0,128, 63,205,204,204, 61, 0, 0,122, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0, + 8, 1, 0, 0,120,188,196, 6, 0, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0,136, 12,197, 6, 0, 0, 0, 0,248,163,195, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 71, 97,109,101, 32, 76,111,103,105, 99, + 0, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,189,196, 6, 0, 0, 0, 0,120,195,196, 6, 0, 0, 0, 0,232,195,196, 6, + 0, 0, 0, 0,168,204,196, 6, 0, 0, 0, 0, 24,205,196, 6, 0, 0, 0, 0, 56, 5,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,200,189,196, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 56,190,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 56,190,196, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,168,190,196, 6, 0, 0, 0, 0,200,189,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,168,190,196, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0, 24,191,196, 6, 0, 0, 0, 0, 56,190,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 5, 4, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 24,191,196, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,136,191,196, 6, + 0, 0, 0, 0,168,190,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,136,191,196, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,248,191,196, 6, 0, 0, 0, 0, 24,191,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,248,191,196, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,104,192,196, 6, 0, 0, 0, 0,136,191,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,126, 7,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,104,192,196, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,216,192,196, 6, 0, 0, 0, 0,248,191,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 1, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,216,192,196, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72,193,196, 6, + 0, 0, 0, 0,104,192,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0, 72,193,196, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,184,193,196, 6, 0, 0, 0, 0,216,192,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,184,193,196, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40,194,196, 6, 0, 0, 0, 0, 72,193,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,126, 7,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 40,194,196, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,152,194,196, 6, 0, 0, 0, 0,184,193,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 5,140, 1, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,152,194,196, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 8,195,196, 6, + 0, 0, 0, 0, 40,194,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 5,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0, 8,195,196, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,120,195,196, 6, 0, 0, 0, 0,152,194,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 1,140, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,120,195,196, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,195,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 1,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,232,195,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 88,196,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,190,196, 6, 0, 0, 0, 0,168,190,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88,196,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,200,196,196, 6, 0, 0, 0, 0,232,195,196, 6, 0, 0, 0, 0, 56,190,196, 6, 0, 0, 0, 0,136,191,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200,196,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 56,197,196, 6, 0, 0, 0, 0, 88,196,196, 6, 0, 0, 0, 0,168,190,196, 6, 0, 0, 0, 0,248,191,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56,197,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,168,197,196, 6, 0, 0, 0, 0,200,196,196, 6, 0, 0, 0, 0,136,191,196, 6, 0, 0, 0, 0,248,191,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,168,197,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 24,198,196, 6, 0, 0, 0, 0, 56,197,196, 6, 0, 0, 0, 0,136,191,196, 6, 0, 0, 0, 0,104,192,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 24,198,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,136,198,196, 6, 0, 0, 0, 0,168,197,196, 6, 0, 0, 0, 0,104,192,196, 6, 0, 0, 0, 0,216,192,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136,198,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,248,198,196, 6, 0, 0, 0, 0, 24,198,196, 6, 0, 0, 0, 0, 24,191,196, 6, 0, 0, 0, 0, 72,193,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,248,198,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,104,199,196, 6, 0, 0, 0, 0,136,198,196, 6, 0, 0, 0, 0,216,192,196, 6, 0, 0, 0, 0, 72,193,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,104,199,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,216,199,196, 6, 0, 0, 0, 0,248,198,196, 6, 0, 0, 0, 0,200,189,196, 6, 0, 0, 0, 0,104,192,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216,199,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 72,200,196, 6, 0, 0, 0, 0,104,199,196, 6, 0, 0, 0, 0,200,189,196, 6, 0, 0, 0, 0, 72,193,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72,200,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,184,200,196, 6, 0, 0, 0, 0,216,199,196, 6, 0, 0, 0, 0,248,191,196, 6, 0, 0, 0, 0,184,193,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184,200,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 40,201,196, 6, 0, 0, 0, 0, 72,200,196, 6, 0, 0, 0, 0, 24,191,196, 6, 0, 0, 0, 0,184,193,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40,201,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,152,201,196, 6, 0, 0, 0, 0,184,200,196, 6, 0, 0, 0, 0,216,192,196, 6, 0, 0, 0, 0,184,193,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,152,201,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 8,202,196, 6, 0, 0, 0, 0, 40,201,196, 6, 0, 0, 0, 0, 40,194,196, 6, 0, 0, 0, 0,152,194,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 8,202,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,120,202,196, 6, 0, 0, 0, 0,152,201,196, 6, 0, 0, 0, 0,248,191,196, 6, 0, 0, 0, 0,152,194,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,120,202,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,232,202,196, 6, 0, 0, 0, 0, 8,202,196, 6, 0, 0, 0, 0,184,193,196, 6, 0, 0, 0, 0, 40,194,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,232,202,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 88,203,196, 6, 0, 0, 0, 0,120,202,196, 6, 0, 0, 0, 0,104,192,196, 6, 0, 0, 0, 0, 8,195,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88,203,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,200,203,196, 6, 0, 0, 0, 0,232,202,196, 6, 0, 0, 0, 0, 40,194,196, 6, 0, 0, 0, 0, 8,195,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200,203,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 56,204,196, 6, 0, 0, 0, 0, 88,203,196, 6, 0, 0, 0, 0,136,191,196, 6, 0, 0, 0, 0,120,195,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56,204,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0,168,204,196, 6, 0, 0, 0, 0,200,203,196, 6, 0, 0, 0, 0,152,194,196, 6, 0, 0, 0, 0,120,195,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,168,204,196, 6, 0, 0, 0, 0,212, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,204,196, 6, 0, 0, 0, 0, 8,195,196, 6, 0, 0, 0, 0,120,195,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 24,205,196, 6, 0, 0, 0, 0,214, 0, 0, 0, + 1, 0, 0, 0,232,208,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,191,196, 6, 0, 0, 0, 0, 56,190,196, 6, + 0, 0, 0, 0,168,190,196, 6, 0, 0, 0, 0,248,191,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0,235, 3, 0, 0, 5, 4, 0, 0, 7, 7,127, 7, 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,248, 11,197, 6, 0, 0, 0, 0,248, 11,197, 6, 0, 0, 0, 0, 8,206,196, 6, 0, 0, 0, 0,120,207,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8,206,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,120,207,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,148, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0,224,239, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, + 0, 0,200, 65, 0,192,239, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, + 10, 0,127, 7, 26, 0,127, 7, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0,235, 3, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168,111,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,216,158,217, 3, - 0, 0, 0, 0,248,109,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 67, 0, 0,125,195, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 75, 67, 1, 0,125,195, 0, 0, 0, 0,203, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0,252, 0, 0, 0, 0, 0, 0, 0, -202, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0,252, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,120,207,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8,206,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,109, 69, 0, 0,128,192, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,238, 68, 0, 0, 0, 0, 0, 0, 0, 64,112, 7, 0, 0,129, 7, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 2, 0, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, + 10, 0,129, 7, 2, 0,112, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 4, 0, 0, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,232,208,196, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,120,233,196, 6, + 0, 0, 0, 0, 24,205,196, 6, 0, 0, 0, 0, 72,193,196, 6, 0, 0, 0, 0,216,192,196, 6, 0, 0, 0, 0,184,193,196, 6, + 0, 0, 0, 0, 24,191,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, +139, 1, 0, 0, 4, 4, 94, 1,140, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,232,196, 6, + 0, 0, 0, 0, 56,232,196, 6, 0, 0, 0, 0,216,209,196, 6, 0, 0, 0, 0, 72,211,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,216,209,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 72,211,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,148, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,175, 67, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,174, 67, 0, 0,200, 65, 0,128,174, 67, + 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 94, 1, 26, 0, 94, 1, + 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0,114, 1, 0, 0, +139, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 1, 26, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0, 72,211,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,209,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0,128,174, 67, 0, 0, 61,196, 0, 0, 0, 0, 0, 0, 0, 0,255,127,166, 67,255,255,184,195, + 0, 0, 0, 0, 77, 1, 0, 0, 94, 1, 0, 0, 0, 0, 0, 0,113, 1, 0, 0, 0, 0, 0, 0, 78, 1, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0, 76, 1, 0, 0, 0, 0, 0, 0,113, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 1, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0, 94, 1,114, 1, 77, 1, +114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 6, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, +113, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 1,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,212,196, 6, 0, 0, 0, 0,152,230,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,184,212,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 88,214,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99, +111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99, +111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,110,116,101,120,116, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,255, 76, 1, 36, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 88,214,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,248,215,196, 6, 0, 0, 0, 0,184,212,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,135,255, 76, 1, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,248,215,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,152,217,196, 6, 0, 0, 0, 0, 88,214,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97, +121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97, +121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111,255, 76, 1, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,152,217,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 56,219,196, 6, 0, 0, 0, 0,248,215,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,140,254, 76, 1,203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0, 56,219,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,216,220,196, 6, 0, 0, 0, 0,152,217,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110, +116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110, +116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65,110,116,105, 45, 65,108,105, 97,115,105,110, +103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58,254, 76, 1, 58, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,216,220,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,120,222,196, 6, 0, 0, 0, 0, 56,219,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 97,109,112,108,101,100, 32, 77,111,116,105,111,110, 32, 66,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 34,254, 76, 1, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,120,222,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 24,224,196, 6, 0, 0, 0, 0,216,220,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, + 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, + 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,104, 97,100,105,110,103, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,254, 76, 1, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 24,224,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,184,225,196, 6, 0, 0, 0, 0,120,222,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,242,253, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,184,225,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 88,227,196, 6, 0, 0, 0, 0, 24,224,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111, +115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111, +115,116, 95,112,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,111,115,116, 32, 80,114,111, 99,101,115,115, +105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,218,253, 76, 1, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 88,227,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0,248,228,196, 6, 0, 0, 0, 0,184,225,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,194,253, 76, 1, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,248,228,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,152,230,196, 6, 0, 0, 0, 0, 88,227,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117, +116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117, +116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79,117,116,112,117,116, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,253, 76, 1,130, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,152,230,196, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,228,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 66, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16,253, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +248, 0, 0, 0, 56,232,196, 6, 0, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 21, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,120,233,196, 6, 0, 0, 0, 0,214, 0, 0, 0, + 1, 0, 0, 0,232,240,196, 6, 0, 0, 0, 0,232,208,196, 6, 0, 0, 0, 0,200,189,196, 6, 0, 0, 0, 0,104,192,196, 6, + 0, 0, 0, 0,216,192,196, 6, 0, 0, 0, 0, 72,193,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 31, 6, 0, 0, 0, 0, 0, 0,139, 1, 0, 0, 17, 17, 32, 6,140, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 88,240,196, 6, 0, 0, 0, 0, 88,240,196, 6, 0, 0, 0, 0,104,234,196, 6, 0, 0, 0, 0,232,238,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,104,234,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,216,235,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0,196, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,224,195, 68, + 0, 0,200, 65, 0,224,195, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, + 10, 0, 32, 6, 26, 0, 32, 6, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 31, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 6, 26, 0, + 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,216,235,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,232,238,196, 6, + 0, 0, 0, 0,104,234,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 67, 0, 0,185,195, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 75, 67, 0, 0,185,195, 0, 0, 0, 0,203, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0,113, 1, 0, 0, 0, 0, 0, 0, +202, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0,113, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, - 6, 0,220, 0,253, 0,203, 0,253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 4, 0, 0, -240, 4, 0, 0, 95, 0, 0, 0, 91, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0,253, 0, - 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0,220, 0,114, 1,203, 0,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +219, 0, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0,114, 1, + 0, 0, 4, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,237,196, 6, 0, 0, 0, 0, 72,237,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 72,237,196, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 79, 71, 73, + 67, 95, 80, 84, 95,112,114,111,112,101,114,116,105,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 79, 71, 73, + 67, 95, 80, 84, 95,112,114,111,112,101,114,116,105,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,114,111,112, +101,114,116,105,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,196,255, +203, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,216,158,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,136,160,217, 3, - 0, 0, 0, 0,168,111,217, 3, 0, 0, 0, 0, 0, 0,112,196, 0, 0,112, 68, 0, 0, 7,196, 0, 0, 7, 68, 0, 0,112,196, - 0, 0,112, 68, 0, 0, 7,196, 0, 0, 7, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,128, 59, 70, 0,128, 59, 70,172,197, 39, 55, 0, 80,195, 71, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 20, 4, 0, 0, 91, 1, 0, 0, 91, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, - 0, 0, 7, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,232,238,196, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,235,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,160, 68, 0, 0, 0, 0, 0, 0,112, 67, 0, 80, 31,195, 0,234,179, 68,224,198,182,194,184,177,165, 67, 51, 5, 0, 0, + 68, 5, 0, 0, 18, 0, 0, 0,113, 1, 0, 0, 0, 0, 0, 0, 50, 5, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, + 50, 5, 0, 0, 18, 0, 0, 0,113, 1, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,250, 70, 0, 0,250, 70, 0, 0, 0, 63, + 72,225,154, 63, 10, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 68, 5,114, 1, 51, 5, 96, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0, 0, 0, 31, 6, 0, 0, 26, 0, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 5,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136,160,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,216,158,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, - 0, 0,122, 67, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0,252, 0, 0, 0, 18, 0, 0, 0, - 20, 4, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 20, 4, 0, 0, 18, 0, 0, 0,252, 0, 0, 0, 0, 0, 32, 65, - 0, 0, 0, 63, 0,124,146, 72, 0, 0, 0, 66, 10,215, 35, 60, 0, 0,200, 66,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, - 8, 0, 21, 4,253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 20, 4, 0, 0, 95, 0, 0, 0, 91, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 4,253, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 72, 0, 0, 0, 88,240,196, 6, + 0, 0, 0, 0,192, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,255, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,232,240,196, 6, + 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,168,247,196, 6, 0, 0, 0, 0,120,233,196, 6, 0, 0, 0, 0, 40,194,196, 6, + 0, 0, 0, 0,152,194,196, 6, 0, 0, 0, 0,248,191,196, 6, 0, 0, 0, 0,184,193,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 65, 5, 0, 0,126, 7, 0, 0,141, 1, 0, 0,233, 3, 0, 0, 9, 9, 62, 2, 93, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,244,196, 6, 0, 0, 0, 0,184,244,196, 6, 0, 0, 0, 0,216,241,196, 6, + 0, 0, 0, 0, 72,243,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,216,241,196, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 72,243,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230, 67, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0,128, 15, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 2, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0, 64, 15, 68, 0, 0,200, 65, 0, 64, 15, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 62, 2, 26, 0, 62, 2, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 65, 5, 0, 0,126, 7, 0, 0,141, 1, 0, 0,166, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 62, 2, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72,243,196, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,241,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,181, 67, 0, 0, 0, 0, + 0,128,218, 67, 0, 0, 0, 0,131,248, 1, 68, 0, 0, 0, 0, 86, 26, 3, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 2, 0, 0, 0, 0, 0, 0, + 66, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,215, 35, 60, 0, 0,122, 68, 0, 0, 0, 0, + 1, 0, 3, 0, 0, 0, 0, 4, 10, 0, 62, 2, 67, 2, 62, 2, 67, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 65, 5, 0, 0,126, 7, 0, 0,167, 1, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 62, 2, 67, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65,240, 0, 0, 0,120,150,199, 3, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 2, 0, 0,184,244,196, 6, 0, 0, 0, 0,186, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 64, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,152, 37,215, 3, 0, 0, 0, 0,214, 0, 0, 0, - 1, 0, 0, 0,184, 38,215, 3, 0, 0, 0, 0,120, 36,215, 3, 0, 0, 0, 0, 72, 65,201, 3, 0, 0, 0, 0, 40, 62,201, 3, - 0, 0, 0, 0,168, 64,201, 3, 0, 0, 0, 0,232, 65,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 47, 2, 0, 0, 93, 1, 0, 0,194, 2, 0, 0, 2, 2, 48, 2,102, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,232,151,199, 3, 0, 0, 0, 0,232,151,199, 3, 0, 0, 0, 0, 56,162,217, 3, 0, 0, 0, 0, 72,167,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 56,162,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,232,163,217, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 89, 68, 0, 0, 0, 0, 0, 0,208, 65,154,216, 65, 55, - 0, 0, 12, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 2, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192, 11, 68, - 0, 0,200, 65, 0,192, 11, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, - 10, 0, 48, 2, 26, 0, 48, 2, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 47, 2, 0, 0, 93, 1, 0, 0,118, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 2, 26, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,168,247,196, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 56, 5,197, 6, + 0, 0, 0, 0,232,240,196, 6, 0, 0, 0, 0, 8,195,196, 6, 0, 0, 0, 0,120,195,196, 6, 0, 0, 0, 0,152,194,196, 6, + 0, 0, 0, 0, 40,194,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 63, 5, 0, 0,141, 1, 0, 0, +233, 3, 0, 0, 1, 1,251, 3, 93, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 3,197, 6, + 0, 0, 0, 0,136, 3,197, 6, 0, 0, 0, 0,152,248,196, 6, 0, 0, 0, 0, 88,254,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,152,248,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 8,250,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,113, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,192,126, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,250, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,126, 68, 0, 0,200, 65, 0,128,126, 68, + 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,251, 3, 26, 0,251, 3, + 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 63, 5, 0, 0,141, 1, 0, 0, +166, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,251, 3, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0, 8,250,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,120,251,196, 6, 0, 0, 0, 0,152,248,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 64, 70,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67,255,127, 70,196, + 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0, 44, 3,143, 0, + 26, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0,167, 1, 0, 0, +233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 67, 2, 0, 0, 5, 0, 3, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,120,251,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,232,252,196, 6, 0, 0, 0, 0, 8,250,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 67, 0, 0,206,194, 0, 0, 0, 0, 0, 0, 0, 0,231,102, 16, 67, 0, 0,206,194, + 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,120, 0,143, 0, +102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 63, 5, 0, 0,167, 1, 0, 0, +167, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 6, 0, 34, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,232,252,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 88,254,196, 6, 0, 0, 0, 0,120,251,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 67, 0, 0,109,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, 0, 0,109,196, + 0,128,145,195,163, 0, 0, 0,180, 0, 0, 0, 0, 0, 0, 0,144, 2, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0,144, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 1, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,180, 0,145, 2,163, 0, +145, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 5, 0, 0, 63, 5, 0, 0,167, 1, 0, 0, +233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0, 88,254,196, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,252,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 63, 5, 0, 0,167, 1, 0, 0, +233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,251, 3, 67, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,255,196, 6, 0, 0, 0, 0, 68, 65, 84, 65, +112, 3, 0, 0,200,255,196, 6, 0, 0, 0, 0,173, 0, 0, 0, 1, 0, 0, 0,190, 35, 30, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 75, 40,139, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 18, 3,187, + 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,190, 35, 30, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 75, 40,139, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 18, 3,187, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,149, 53,207, 65, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,112,121,107, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,249,195, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,190, 35, 30, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 75, 40,139, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 18, 3,187, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,207, 3,116, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,207, 3,116, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,207, 3,116, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,149, 53,207, 65,214,211,111, 65, 0, 0, 0, 0, 0, 0, 0, 0,221, 57, 80, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,160, 65, 0, 0, 5, 0,251,251, 0, 0, 92, 62, 55, 63, 56,186,224,190,237,203,148,190, 3,236,234,190, + 1, 0, 0, 0, 0, 0,128, 63, 0, 0,180, 66, 0, 0,180, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 96, 1, 0, 0,136, 3,197, 6, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 32, 65,205,204, 76, 62, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,200, 67,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, 8, 8,128, 0, + 0, 0, 12, 66, 0, 0,128, 63,205,204,204, 61, 0, 0,122, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +160, 0, 0, 0, 56, 5,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,247,196, 6, + 0, 0, 0, 0,104,192,196, 6, 0, 0, 0, 0,136,191,196, 6, 0, 0, 0, 0,120,195,196, 6, 0, 0, 0, 0, 8,195,196, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 1, 0, 0,141, 1, 0, 0,233, 3, 0, 0, 3, 3, 68, 1, + 93, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9,197, 6, 0, 0, 0, 0, 8, 9,197, 6, + 0, 0, 0, 0, 40, 6,197, 6, 0, 0, 0, 0,152, 7,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 40, 6,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,152, 7,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,244, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,162, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 67, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,161, 67, 0, 0,200, 65, 0,128,161, 67, 0, 0,200, 65, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 68, 1, 26, 0, 68, 1, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 1, 0, 0,141, 1, 0, 0,166, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,152, 7,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 6,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,141, 67, 0, 0,244,194, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,153, 67, 0, 64, 12,196, 0, 0, 0, 0, 51, 1, 0, 0, + 68, 1, 0, 0, 18, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, + 50, 1, 0, 0, 18, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 18, 6, 0, 0, 2, 0, 3, 3, 0, 0, 12, 4, 6, 0, 68, 1, 67, 2, 51, 1, 49, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 1, 0, 0,167, 1, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 1, 67, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 1, 0, 0, 8, 9,197, 6, + 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,104, 10,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 68, 65, 84, 65, 16, 0, 0, 0,104, 10,197, 6, 0, 0, 0, 0,237, 0, 0, 0, 1, 0, 0, 0, 14, 0, 0, 0, + 14, 0, 0, 0,200, 10,197, 6, 0, 0, 0, 0, 68, 65, 84, 65,224, 0, 0, 0,200, 10,197, 6, 0, 0, 0, 0,236, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,104, 38,198, 6, 0, 0, 0, 0, 19, 0, 0, 0, 1, 0, 1, 0,104, 38,198, 6, + 0, 0, 0, 0, 20, 0, 0, 0, 1, 0, 1, 0,104, 38,198, 6, 0, 0, 0, 0, 21, 0, 1, 0, 1, 0, 0, 0,104, 38,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,248, 64,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,104, 74,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 8,129,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 72, 88,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 88,110,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,168, 81,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 56, 60,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,200, 67,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 40, 59,198, 6, 0, 0, 0, 0, 21, 0, 0, 0, 1, 0, 1, 0,104, 38,198, 6, + 0, 0, 0, 0, 83, 78, 0, 0, 8, 1, 0, 0,136, 12,197, 6, 0, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0,136, 95,197, 6, + 0, 0, 0, 0,120,188,196, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 77,111, +118,105,101, 32, 84,114, 97, 99,107,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 13,197, 6, 0, 0, 0, 0,168, 18,197, 6, + 0, 0, 0, 0, 24, 19,197, 6, 0, 0, 0, 0,136, 26,197, 6, 0, 0, 0, 0,248, 26,197, 6, 0, 0, 0, 0, 56, 75,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,123,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,216, 13,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72, 14,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0, 72, 14,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,184, 14,197, 6, 0, 0, 0, 0,216, 13,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,146, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,184, 14,197, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40, 15,197, 6, 0, 0, 0, 0, 72, 14,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,126, 7,146, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 40, 15,197, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,152, 15,197, 6, 0, 0, 0, 0,184, 14,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,152, 15,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 8, 16,197, 6, + 0, 0, 0, 0, 40, 15,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 4, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0, 8, 16,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,120, 16,197, 6, 0, 0, 0, 0,152, 15,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,104, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,120, 16,197, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,232, 16,197, 6, 0, 0, 0, 0, 8, 16,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,124, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,232, 16,197, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0, 88, 17,197, 6, 0, 0, 0, 0,120, 16,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,124, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 88, 17,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200, 17,197, 6, + 0, 0, 0, 0,232, 16,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 3, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,200, 17,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 56, 18,197, 6, 0, 0, 0, 0, 88, 17,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,168, 3, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 56, 18,197, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,168, 18,197, 6, 0, 0, 0, 0,200, 17,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,168, 3,168, 3, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,168, 18,197, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 18,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 3,104, 4, + 1, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 24, 19,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,136, 19,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 14,197, 6, 0, 0, 0, 0,184, 14,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136, 19,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,248, 19,197, 6, + 0, 0, 0, 0, 24, 19,197, 6, 0, 0, 0, 0, 72, 14,197, 6, 0, 0, 0, 0,152, 15,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,248, 19,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104, 20,197, 6, + 0, 0, 0, 0,136, 19,197, 6, 0, 0, 0, 0,184, 14,197, 6, 0, 0, 0, 0, 8, 16,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,104, 20,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216, 20,197, 6, + 0, 0, 0, 0,248, 19,197, 6, 0, 0, 0, 0,152, 15,197, 6, 0, 0, 0, 0, 8, 16,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216, 20,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72, 21,197, 6, + 0, 0, 0, 0,104, 20,197, 6, 0, 0, 0, 0,216, 13,197, 6, 0, 0, 0, 0, 40, 15,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72, 21,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184, 21,197, 6, + 0, 0, 0, 0,216, 20,197, 6, 0, 0, 0, 0,216, 13,197, 6, 0, 0, 0, 0,120, 16,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184, 21,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40, 22,197, 6, + 0, 0, 0, 0, 72, 21,197, 6, 0, 0, 0, 0, 40, 15,197, 6, 0, 0, 0, 0,232, 16,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40, 22,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152, 22,197, 6, + 0, 0, 0, 0,184, 21,197, 6, 0, 0, 0, 0,120, 16,197, 6, 0, 0, 0, 0,232, 16,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,152, 22,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8, 23,197, 6, + 0, 0, 0, 0, 40, 22,197, 6, 0, 0, 0, 0,120, 16,197, 6, 0, 0, 0, 0, 88, 17,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 8, 23,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120, 23,197, 6, + 0, 0, 0, 0,152, 22,197, 6, 0, 0, 0, 0,152, 15,197, 6, 0, 0, 0, 0, 88, 17,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,120, 23,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232, 23,197, 6, + 0, 0, 0, 0, 8, 23,197, 6, 0, 0, 0, 0, 8, 16,197, 6, 0, 0, 0, 0,200, 17,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,232, 23,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88, 24,197, 6, + 0, 0, 0, 0,120, 23,197, 6, 0, 0, 0, 0,232, 16,197, 6, 0, 0, 0, 0,200, 17,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88, 24,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200, 24,197, 6, + 0, 0, 0, 0,232, 23,197, 6, 0, 0, 0, 0, 88, 17,197, 6, 0, 0, 0, 0,200, 17,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200, 24,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56, 25,197, 6, + 0, 0, 0, 0, 88, 24,197, 6, 0, 0, 0, 0, 88, 17,197, 6, 0, 0, 0, 0, 56, 18,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56, 25,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168, 25,197, 6, + 0, 0, 0, 0,200, 24,197, 6, 0, 0, 0, 0,200, 17,197, 6, 0, 0, 0, 0, 56, 18,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,168, 25,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24, 26,197, 6, + 0, 0, 0, 0, 56, 25,197, 6, 0, 0, 0, 0,152, 15,197, 6, 0, 0, 0, 0,168, 18,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 24, 26,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,136, 26,197, 6, + 0, 0, 0, 0,168, 25,197, 6, 0, 0, 0, 0, 8, 16,197, 6, 0, 0, 0, 0,168, 18,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136, 26,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 26,197, 6, 0, 0, 0, 0, 56, 18,197, 6, 0, 0, 0, 0,168, 18,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,248, 26,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,200, 30,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 15,197, 6, 0, 0, 0, 0, 72, 14,197, 6, 0, 0, 0, 0,184, 14,197, 6, + 0, 0, 0, 0, 8, 16,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,105, 4, 0, 0, +146, 4, 0, 0, 7, 7,127, 7, 42, 0, 1, 0, 0, 0, 0, 0, 7, 0, 8, 0, 8, 77,163, 6, 0, 0, 0, 0,248, 94,197, 6, + 0, 0, 0, 0,248, 94,197, 6, 0, 0, 0, 0,232, 27,197, 6, 0, 0, 0, 0, 88, 29,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,233, 42, 0, 73,127, 0, 0,104,217,224, 0, 73,127, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,232, 27,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 88, 29,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,163, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,239, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, 0, 0,200, 65, 0,192,239, 68, + 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,127, 7, 26, 0,127, 7, + 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,105, 4, 0, 0, +130, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 26, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 79,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0, 88, 29,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232, 27,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0,192,239, 68, 0, 0, 0, 0, 0, 0, 48, 65, 0, 0, 0, 0, 1,192,237, 68, 0, 0, 0, 0, + 0, 0,128, 65,110, 7, 0, 0,127, 7, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,109, 7, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 2, 2, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, 10, 0,127, 7, 16, 0,110, 7, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,131, 4, 0, 0, +146, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 78,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +160, 0, 0, 0,200, 30,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,184, 35,197, 6, 0, 0, 0, 0,248, 26,197, 6, + 0, 0, 0, 0,216, 13,197, 6, 0, 0, 0, 0,120, 16,197, 6, 0, 0, 0, 0,232, 16,197, 6, 0, 0, 0, 0, 40, 15,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0,123, 0, 0, 0, 15, 15,127, 7, +124, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 28,163, 6, 0, 0, 0, 0,152, 34,197, 6, 0, 0, 0, 0,152, 34,197, 6, + 0, 0, 0, 0,184, 31,197, 6, 0, 0, 0, 0, 40, 33,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24,113,223, 0, 73,127, 0, 0,216,229, 12, 0, 73,127, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,184, 31,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 40, 33,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 96,146, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,239, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, 0, 0,200, 65, 0,192,239, 68, 0, 0,200, 65, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,127, 7, 26, 0,127, 7, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 30,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 40, 33,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 31,197, 6, 0, 0, 0, 0, 0, 0, 64,192, + 0, 0,126, 67, 0, 0, 0, 0, 0, 0, 72, 66, 88,218,103,194, 40,147,141, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0, 18, 0, 0, 0, 97, 0, 0, 0, 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, + 0, 0, 32, 65, 72, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 4, 8, 0,127, 7, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 26, 0, 0, 0,123, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 29,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0,152, 34,197, 6, + 0, 0, 0, 0,190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65, +160, 0, 0, 0,184, 35,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,120, 55,197, 6, 0, 0, 0, 0,200, 30,197, 6, + 0, 0, 0, 0,120, 16,197, 6, 0, 0, 0, 0, 88, 17,197, 6, 0, 0, 0, 0,200, 17,197, 6, 0, 0, 0, 0,232, 16,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,125, 0, 0, 0,167, 3, 0, 0, 20, 20,127, 7, + 43, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,130,163, 6, 0, 0, 0, 0,248, 49,197, 6, 0, 0, 0, 0, 88, 54,197, 6, + 0, 0, 0, 0,168, 36,197, 6, 0, 0, 0, 0,136, 48,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 56,240, 12, 0, 73,127, 0, 0,168,253, 12, 0, 73,127, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168, 36,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 24, 38,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,229, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,239, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, 0, 0,200, 65, 0,192,239, 68, 0, 0,200, 65, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 0, 0, 10, 0,127, 7, 26, 0,127, 7, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,125, 0, 0, 0,150, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,138,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 24, 38,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,136, 39,197, 6, 0, 0, 0, 0,168, 36,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,178, 67, 0, 64, 38,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 64, 38,196, 0, 0, 0, 0,143, 0, 0, 0, +160, 0, 0, 0, 0, 0, 0, 0,152, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +142, 0, 0, 0, 0, 0, 0, 0,152, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,153, 2,143, 0,153, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0, 15, 1, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0,153, 2, 0, 0, 5, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,135,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136, 39,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,152, 42,197, 6, 0, 0, 0, 0, 24, 38,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,178, 67, 0, 0,240,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 0,240,194, 0, 0, 0, 0,143, 0, 0, 0, +160, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +142, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,120, 0,143, 0,120, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0,151, 0, 0, 0, 14, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0,120, 0, 0, 0, 6, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,136,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,248, 40,197, 6, 0, 0, 0, 0,248, 40,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,248, 40,197, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,137,163, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 76, 73, 80, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111, +114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 76, 73, 80, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111, +114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79,112,101,114, 97,116,111,114, 0,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,255,143, 0, 16, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,152, 42,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,168, 45,197, 6, + 0, 0, 0, 0,136, 39,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, 0, 64, 68,196, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 67, 0, 64, 68,196, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, + 6, 0,160, 0, 17, 3,143, 0, 17, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,223, 6, 0, 0, +126, 7, 0, 0,151, 0, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0, 17, 3, + 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,133,163, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 44,197, 6, 0, 0, 0, 0, 8, 44,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 8, 44,197, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,134,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 76, 73, 80, + 95, 80, 84, 95,103,112,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 76, 73, 80, + 95, 80, 84, 95,103,112,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71,114,101, 97, +115,101, 32, 80,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,255, +143, 0, 0, 0, 0, 0, 0, 0, 4, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168, 45,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 24, 47,197, 6, 0, 0, 0, 0,152, 42,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 67, 0, 64,116,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 67, 0,192,111,196, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +159, 0, 0, 0, 18, 0, 0, 0,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 8, 0, 0, 0, 2, 0, 3, 3, 0, 0, 2, 0, 6, 0,160, 0,209, 3,160, 0,191, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0, 0, 0,160, 0, 0, 0,151, 0, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,139,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 24, 47,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,136, 48,197, 6, 0, 0, 0, 0,168, 45,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,122, 67, 0, 0, 32,193, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 32,193, 0, 0, 32, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0,128, 0, 0,124,146, 72,255,255,127,127, 0, 0, 0, 0, + 0, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0, 0, 0,160, 0, 0, 0,151, 0, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,132,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136, 48,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 47,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,255, 0, 0,128,127, 0, 0,128,255, 0, 0,128,127, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63, 6, 0, 0, 0, 0, 0, 0, 17, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,215, 35, 60, + 0, 0,122, 68, 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 4, 10, 0, 63, 6, 17, 3, 63, 6, 17, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0, 0, 0,222, 6, 0, 0,151, 0, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 6, 17, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,131,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 1, 0, 0,248, 49,197, 6, + 0, 0, 0, 0,196, 0, 0, 0, 1, 0, 0, 0, 88, 54,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,120, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17,200, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,120, 51,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,232, 52,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,146, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,239, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, 0, 0,200, 65, 0,192,239, 68, + 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,127, 7, 26, 0,127, 7, + 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,125, 0, 0, 0, +150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,232, 52,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 51,197, 6, + 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67, 0, 0, 0, 0, 0, 0, 72, 66, 88,218,103,194, 40,147,141, 67, 0, 0, 0, 0, + 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 18, 0, 0, 0,208, 3, 0, 0, 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, + 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65, 72, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 4, 8, 0,127, 7,209, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,151, 0, 0, 0, +103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7,209, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +208, 0, 0, 0, 88, 54,197, 6, 0, 0, 0, 0,190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 49,197, 6, + 0, 0, 0, 0,120, 51,197, 6, 0, 0, 0, 0,232, 52,197, 6, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 1, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,120, 55,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 56, 75,197, 6, + 0, 0, 0, 0,184, 35,197, 6, 0, 0, 0, 0, 56, 18,197, 6, 0, 0, 0, 0,168, 18,197, 6, 0, 0, 0, 0, 8, 16,197, 6, + 0, 0, 0, 0,200, 17,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,169, 3, 0, 0,126, 7, 0, 0,169, 3, 0, 0, +103, 4, 0, 0, 20, 20,214, 3,191, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,130,163, 6, 0, 0, 0, 0,184, 69,197, 6, + 0, 0, 0, 0, 24, 74,197, 6, 0, 0, 0, 0,104, 56,197, 6, 0, 0, 0, 0, 72, 68,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,254, 12, 0, 73,127, 0, 0,200, 20, 13, 0, 73,127, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,104, 56,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,216, 57,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,212, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,128,117, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,213, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 64,117, 68, 0, 0,200, 65, 0, 64,117, 68, + 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 0, 0, 10, 0,214, 3, 26, 0,214, 3, + 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,169, 3, 0, 0,126, 7, 0, 0,169, 3, 0, 0, +194, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,214, 3, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,138,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,216, 57,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 72, 59,197, 6, 0, 0, 0, 0,104, 56,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, 0, 0, 52,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 0, 52,194, + 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0, 45, 0,143, 0, + 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,169, 3, 0, 0,169, 3, 0, 0,195, 3, 0, 0, +103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 5, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,135,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0, 72, 59,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 88, 62,197, 6, 0, 0, 0, 0,216, 57,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, 0, 0,240,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 0,240,194, + 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0,120, 0,143, 0, +120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,169, 3, 0, 0,169, 3, 0, 0,195, 3, 0, 0, +103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 6, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,136,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 60,197, 6, 0, 0, 0, 0,184, 60,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 88, 1, 0, 0,184, 60,197, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 76, 73, 80, 95, 80, 84, 95,108, 97,115,116, + 95,111,112,101,114, 97,116,111,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 76, 73, 80, 95, 80, 84, 95,108, 97,115,116, + 95,111,112,101,114, 97,116,111,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78,101,119, 32, 83, 99,114,101,101,110, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,255,143, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88, 62,197, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,104, 65,197, 6, 0, 0, 0, 0, 72, 59,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, 0, 0, 37,195, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 0, 37,195, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, +164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, +164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, + 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0,165, 0,143, 0,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,169, 3, 0, 0,169, 3, 0, 0,195, 3, 0, 0,103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 72,133,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 63,197, 6, + 0, 0, 0, 0,200, 63,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,200, 63,197, 6, 0, 0, 0, 0,213, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67, 76, 73, 80, 95, 80, 84, 95,103,112,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67, 76, 73, 80, 95, 80, 84, 95,103,112,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 71,114,101, 97,115,101, 32, 80,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,232,255,143, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,104, 65,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,216, 66,197, 6, 0, 0, 0, 0, 88, 62,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 0, 37,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 67, 0, 0, 19,195, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0, 18, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 8, 4, 0, 0, 2, 0, 3, 3, 0, 0, 2, 4, 6, 0,160, 0,165, 0,160, 0, +147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,169, 3, 0, 0, 72, 4, 0, 0,195, 3, 0, 0, +103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0,165, 0, 0, 0, 2, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,139,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,216, 66,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 72, 68,197, 6, 0, 0, 0, 0,104, 65,197, 6, + 0, 0, 0, 0, 0, 0, 32,193, 0,128,117, 68,171,170,126,194, 0, 0, 0, 0, 0, 0, 32,193, 0,128,117, 68, 0, 0, 19,195, + 0, 0, 0, 0, 37, 3, 0, 0, 54, 3, 0, 0, 18, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 36, 3, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0, 36, 3, 0, 0, 18, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,124,146, 72, +255,255,127,127, 10,215, 35, 60, 0, 0, 72, 66, 74, 0, 0, 0, 0, 0, 0, 2, 16, 0, 2, 4, 4, 0, 54, 3,165, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 4, 0, 0,126, 7, 0, 0,195, 3, 0, 0, +103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 3,165, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,132,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0, 72, 68,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 66,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,255, 0, 0,128,127, 0, 0,128,255, + 0, 0,128,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,150, 2, 0, 0, 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10,215, 35, 60, 0, 0,122, 68, 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 10, 0,150, 2,165, 0,150, 2, +165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,131,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 48, 1, 0, 0,184, 69,197, 6, 0, 0, 0, 0,196, 0, 0, 0, 1, 0, 0, 0, 24, 74,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17,200, 0, 0, 0, 0, 2, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 56, 71,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,168, 72,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,146, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0,224,239, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, + 0, 0,200, 65, 0,192,239, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, + 10, 0,127, 7, 26, 0,127, 7, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0,125, 0, 0, 0,150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,232,163,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,152,165,217, 3, - 0, 0, 0, 0, 56,162,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 67, 0, 0,112,193, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 72, 67, 0, 0,157,195, 0, 0, 0, 0,200, 0, 0, 0,217, 0, 0, 0, 18, 0, 0, 0, 75, 1, 0, 0, 0, 0, 0, 0, -199, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,199, 0, 0, 0, 18, 0, 0, 0, 75, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 10, 6, 0, 0, 2, 0, 3, 3, 0, 0, 0, 4, - 6, 0,217, 0, 76, 1,200, 0, 58, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -216, 0, 0, 0,119, 1, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,217, 0, 76, 1, - 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168, 72,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 71,197, 6, 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67, 0, 0, 0, 0, 0, 0, 72, 66, 88,218,103,194, + 40,147,141, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 18, 0, 0, 0,208, 3, 0, 0, 0, 0,128, 63, + 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65, 72, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 4, + 8, 0,127, 7,209, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0,151, 0, 0, 0,103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7,209, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0, 24, 74,197, 6, 0, 0, 0, 0,190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,184, 69,197, 6, 0, 0, 0, 0, 56, 71,197, 6, 0, 0, 0, 0,168, 72,197, 6, 0, 0, 0, 0, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 56, 75,197, 6, 0, 0, 0, 0,214, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 55,197, 6, 0, 0, 0, 0, 88, 17,197, 6, 0, 0, 0, 0,152, 15,197, 6, + 0, 0, 0, 0,168, 18,197, 6, 0, 0, 0, 0, 56, 18,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +167, 3, 0, 0,169, 3, 0, 0,103, 4, 0, 0, 20, 20,168, 3,191, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,130,163, 6, + 0, 0, 0, 0,120, 89,197, 6, 0, 0, 0, 0,216, 93,197, 6, 0, 0, 0, 0, 40, 76,197, 6, 0, 0, 0, 0, 8, 88,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 21, 13, 0, 73,127, 0, 0,120, 22, 13, 0, + 73,127, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 40, 76,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,152, 77,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,212, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0,106, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,105, 68, + 0, 0,200, 65, 0,192,105, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 0, 0, + 10, 0,168, 3, 26, 0,168, 3, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +167, 3, 0, 0,169, 3, 0, 0,194, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 3, 26, 0, + 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,138,163, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,152, 77,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 8, 79,197, 6, + 0, 0, 0, 0, 40, 76,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, 0, 0, 52,194, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 67, 0, 0, 52,194, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, + 6, 0,160, 0, 45, 0,143, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,195, 3, 0, 0,103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,135,163, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8, 79,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 24, 82,197, 6, + 0, 0, 0, 0,152, 77,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,178, 67, 0, 0,240,194, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 67, 0, 0,240,194, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, + 6, 0,160, 0,120, 0,143, 0,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,195, 3, 0, 0,103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,136,163, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 80,197, 6, 0, 0, 0, 0,120, 80,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,120, 80,197, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 76, 73, 80, + 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 76, 73, 80, + 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78,101,119, 32, + 83, 99,114,101,101,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,255, +143, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,152,165,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 72,167,217, 3, - 0, 0, 0, 0,232,163,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 24, 82,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 40, 85,197, 6, 0, 0, 0, 0, 8, 79,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,178, 67, 0, 0, 37,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 0, 37,195, 0, 0, 0, 0,143, 0, 0, 0, +160, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +142, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0,165, 0,143, 0,165, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195, 3, 0, 0,103, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,133,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,136, 83,197, 6, 0, 0, 0, 0,136, 83,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,136, 83,197, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 76, 73, 80, 95, 80, 84, 95,103,112,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 76, 73, 80, 95, 80, 84, 95,103,112,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 2, 0, 0, - 47, 2, 0, 0,119, 1, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, - 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71,114,101, 97,115,101, 32, 80,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,255,143, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72,167,217, 3, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,152,165,217, 3, 0, 0, 0, 0, 0, 0, 16,193, 0, 0,130, 67, 0, 0,160,192, 0, 0,160, 64, 0, 0, 0, 0, - 0, 0,122, 67, 0, 0, 16,193, 0, 0, 32, 65, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 75, 1, 0, 0, 18, 0, 0, 0, - 86, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 86, 1, 0, 0, 18, 0, 0, 0, 75, 1, 0, 0,111, 18,131, 58, -111, 18,131, 58, 0,124,146, 72, 0, 80, 67, 71, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, - 0, 0, 87, 1, 76, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,217, 0, 0, 0, - 47, 2, 0, 0,119, 1, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 1, 76, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 40, 85,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,152, 86,197, 6, + 0, 0, 0, 0, 24, 82,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 64,116,196, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32, 67, 0,192,111,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +159, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0, 18, 0, 0, 0,208, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 8, 0, 0, 0, 2, 0, 3, 3, 0, 0, 2, 0, + 6, 0,160, 0,209, 3,160, 0,191, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,195, 3, 0, 0,103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,139,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65,240, 0, 0, 0,232,151,199, 3, 0, 0, 0, 0,178, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,152, 86,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 8, 88,197, 6, + 0, 0, 0, 0, 40, 85,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 32,193, 0, 0, 32, 65, 0, 0, 0, 0, + 0, 0,122, 67, 0, 0, 32,193, 0, 0, 32, 65, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0,164, 0, 0, 0, 18, 0, 0, 0, +167, 3, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0,167, 3, 0, 0, 18, 0, 0, 0,164, 0, 0, 0, 0, 0,128, 0, + 0, 0,128, 0, 0,124,146, 72,255,255,127,127, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0,168, 3,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +167, 3, 0, 0,195, 3, 0, 0,103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 3,165, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,132,163, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8, 88,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,152, 86,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,255, + 0, 0,128,127, 0, 0,128,255, 0, 0,128,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 2, 0, 0, 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,215, 35, 60, 0, 0,122, 68, 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, + 10, 0,104, 2,165, 0,104, 2,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,131,163, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 48, 1, 0, 0,120, 89,197, 6, 0, 0, 0, 0,196, 0, 0, 0, 1, 0, 0, 0,216, 93,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17,200, 0, 0, + 0, 0, 1, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248, 90,197, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0,104, 92,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,146, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0,224,239, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0,192,239, 68, 0, 0,200, 65, 0,192,239, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,127, 7, 26, 0,127, 7, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,125, 0, 0, 0,150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,104, 92,197, 6, 0, 0, 0, 0,215, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 90,197, 6, 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67, 0, 0, 0, 0, + 0, 0, 72, 66, 88,218,103,194, 40,147,141, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 18, 0, 0, 0, +208, 3, 0, 0, 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65, 72, 0, 0, 0, + 0, 0, 0, 2, 4, 0, 0, 4, 8, 0,127, 7,209, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,151, 0, 0, 0,103, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,127, 7,209, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0,216, 93,197, 6, 0, 0, 0, 0,190, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 89,197, 6, 0, 0, 0, 0,248, 90,197, 6, 0, 0, 0, 0,104, 92,197, 6, + 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 24,120,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,112, 0, 0, 0, 24,120,214, 3, 0, 0, 0, 0, 37, 1, 0, 0, - 1, 0, 0, 0,168,194,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,184, 38,215, 3, - 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 37,215, 3, 0, 0, 0, 0,232, 65,201, 3, - 0, 0, 0, 0,168, 64,201, 3, 0, 0, 0, 0,200, 62,201, 3, 0, 0, 0, 0,104, 63,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 2, 0, 0,240, 4, 0, 0, 93, 1, 0, 0,194, 2, 0, 0, 8, 8,192, 2,102, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,153,199, 3, 0, 0, 0, 0, 88,153,199, 3, 0, 0, 0, 0,248,168,217, 3, - 0, 0, 0, 0, 8,174,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,248,168,217, 3, 0, 0, 0, 0,215, 0, 0, 0, - 1, 0, 0, 0,168,170,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,245, 67, 0, 0, 0, 0, - 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 48, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 2, 0, 0, 0, 0, 0, 0, - 25, 0, 0, 0, 0,192, 47, 68, 0, 0,200, 65, 0,192, 47, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,192, 2, 26, 0,192, 2, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 2, 0, 0,240, 4, 0, 0, 93, 1, 0, 0,118, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,192, 2, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168,170,217, 3, 0, 0, 0, 0,215, 0, 0, 0, - 1, 0, 0, 0, 88,172,217, 3, 0, 0, 0, 0,248,168,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,240, 4, 0, 0,240, 4, 0, 0,119, 1, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88,172,217, 3, 0, 0, 0, 0,215, 0, 0, 0, - 1, 0, 0, 0, 8,174,217, 3, 0, 0, 0, 0,168,170,217, 3, 0, 0, 0, 0, 0, 0,240,195, 0, 0,240, 67, 0, 0,135,195, - 0, 0,135, 67,238, 33,143,196,238, 33,143, 68, 0, 0, 7,196, 0, 0, 7, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 2, 0, 0, 0, 0, 0, 0, - 75, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 59, 70, 0,128, 59, 70,172,197, 39, 55, 0, 80,195, 71, 0, 0, 0, 0, - 0, 0, 6, 0, 0, 0, 0, 4, 0, 0,192, 2, 76, 1,192, 2, 76, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 2, 0, 0,240, 4, 0, 0,119, 1, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,192, 2, 76, 1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8,174,217, 3, 0, 0, 0, 0,215, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,172,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 0, 0, - 0, 0, 0, 65, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, - 75, 1, 0, 0, 18, 0, 0, 0,201, 2, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0,201, 2, 0, 0, 18, 0, 0, 0, - 75, 1, 0, 0, 0, 0, 32, 65, 0, 0, 0, 63, 0,124,146, 72, 0, 0, 0, 66, 10,215, 35, 60, 0, 0,200, 66,105, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 8, 0,202, 2, 76, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,240, 0, 0, 0, 88,153,199, 3, 0, 0, 0, 0,180, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 64, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 0, 0,216, 11, 0, 0,168,194,217, 3, - 0, 0, 0, 0,171, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 83, 99,101,110,101, 0,116, 97,103,101, 0, 97,105,110, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,173,200, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,213,217, 3, 0, 0, 0, 0, 24, 51,163, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 40,117,216, 3, 0, 0, 0, 0,136,118,216, 3, 0, 0, 0, 0, 40,117,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,207,217, 3, 0, 0, 0, 0,232,141,214, 15, - 0, 0, 0, 0, 17, 2, 24, 0, 90, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 0, 0, 0, - 68,172, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0,100, 0, 0, 0, 0, 0, 1, 0, 0, 0,128, 63, 0, 0, 0, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 2,224, 1, 60, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, - 6, 0, 50, 0,141, 0,128, 7, 56, 4, 8, 0, 8, 0, 24, 0, 17, 0, 0, 0, 90, 0, 1, 0, 81, 0, 0, 0, 23, 0, 33, 0, - 2, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 8, 0, 24, 0, 10, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 24,174,200, 3, 0, 0, 0, 0, 24,174,200, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 1, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 5, 0, 2, 0, - 1, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47,116,109,112, 92, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 5, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,204, 76, 63, -205,204, 76, 63,205,204, 76, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0,128, 63, 0, 0,128, 63,173, 2, 95, 0,154,153,217, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 1, 0,180, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 76, 69, 78, - 68, 69, 82, 95, 82, 69, 78, 68, 69, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,172, 0, 0, - 0, 0,128, 63,102,166,171, 67, 0, 0,128, 63, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48,209,117, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,149,158, 15, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 88, 87,171, 3, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 2,224, 1, 60, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 1, 0,180, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 0, -205,204,204, 61,154,153,153, 62,205,204, 76, 62,219, 15, 73, 63,102,102,102, 63, 0, 0, 0, 64,154,153, 25, 63, 0, 0, 64, 65, -102,102,166, 63, 0, 0, 0, 65, 0, 0,160, 65, 6, 0, 0, 0, 0, 0,192, 64, 0, 0,128, 63, 0, 0, 0, 0,205,204, 28, 65, - 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 1, 0,128, 0, 5, 0,218, 0, 0, 0, 60, 0, 5, 0, 1, 0, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 64, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195,245, 28,193, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65,128, 0, 0, 0, 24,173,200, 3, 0, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0, 40,117,216, 3, 0, 0, 0, 0,143, 0, 0, 0, 1, 0, 0, 0,216,117,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,232, 1, 20, 1,184,219,217, 3, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0,216,117,216, 3, 0, 0, 0, 0,143, 0, 0, 0, 1, 0, 0, 0,136,118,216, 3, 0, 0, 0, 0, 40,117,216, 3, - 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0,118, 2,238, 1,168,225,217, 3, 0, 0, 0, 0, 68, 65, 84, 65, - 40, 0, 0, 0,136,118,216, 3, 0, 0, 0, 0,143, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,117,216, 3, - 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0,108, 0, 86, 1,200,213,217, 3, 0, 0, 0, 0, 68, 65, 84, 65, -232, 1, 0, 0, 8,207,217, 3, 0, 0, 0, 0,167, 0, 0, 0, 1, 0, 0, 0,216,202,207, 3, 0, 0, 0, 0,152,203,207, 3, - 0, 0, 0, 0,168, 1,211, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 1, 0, 1, 0,205,204, 76, 63, - 0, 0,180, 66, 9, 0, 1, 0, 0, 0,128, 63,111, 18,131, 58,205,204,204, 61, 0, 0, 1, 0, 32, 0, 32, 0, 32, 0, 1, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,232, 10,219, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 80, 0, 0, 2, 0, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 5, 0, 5, 0,255,255, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 72, 66, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 72, 66, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 66, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 72, 66, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 66, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 10,215, 35, 60,205,204,204, 61, - 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 0,205,204,204, 61,205,204,204, 61,102,102,166, 63, 0, 0,192, 63, 0, 0,240, 65, - 72,225,122, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 67, 2, 0, 3, 2, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 35, 0, 0, 0,204,197,121, 63, 0, 0, 0, 63, 35, 0, 0, 0,204,197,121, 63, 0, 0, 0, 63, 17, 0, 0, 0, 68, 65, 84, 65, - 56, 0, 0, 0,216,202,207, 3, 0, 0, 0, 0,164, 0, 0, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,255,255,255,128, 1, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 0, 0, 0,152,203,207, 3, 0, 0, 0, 0,164, 0, 0, 0, - 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,200,255,128, 1, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 96, 0, 0, 0,168, 1,211, 3, 0, 0, 0, 0,162, 0, 0, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0,120, 58,171, 3, - 0, 0, 0, 0,255,100,100,128, 1, 0, 0, 0,128, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,155, 9, 25, 67, -190, 23,237, 64, 75, 1,147, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,120, 0, 0, 0, 24,174,200, 3, - 0, 0, 0, 0,149, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82,101,110,100, -101,114, 76, 97,121,101,114, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255, 15, 0, 0, 0, 0, 0,255,127, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 67, 65, 0, 0,200, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 22, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 65, 67, 97, -109,101,114, 97, 0, 97,109,101,114, 97, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, - 0, 0, 0, 63,205,204,204, 61, 0, 0,200, 66, 0, 0, 12, 66,161, 14,234, 64, 0, 0, 0, 63, 0, 0, 0, 66, 0, 0,144, 65, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 76, 65, 0, 0, 16, 2, 0, 0,120,209,217, 3, 0, 0, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 76, 97, -109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,247,255,239, 65, 0, 0,150, 66,154,153, 25, 62, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 8,212,217, 3, 0, 0, 0, 0, 2, 0, 0, 0, 46, 26,128, 63, 25, 4,240, 65, 0, 0, 52, 66, 0, 0,128, 63, - 0, 0, 64, 64,205,204, 76, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 11, 3, 0, 1, 0, 0, 0, 0, 2, 1, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,111, 18,131, 58, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 64, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,119,216, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 64, 1, 0, 0, 8,212,217, 3, 0, 0, 0, 0,119, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 2, 0, 1, 0, 0, 0,128, 67, 0, 0, 0, 0, - 0, 0,128, 63,243, 4, 53,191,242, 4, 53, 63,242, 4, 53,191,243, 4, 53, 63, 40, 67,201, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 40, 67,201, 3, 0, 0, 0, 0,117, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56,119,216, 3, - 0, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 79, 0, 0, 24, 2, 0, 0, 24, 51,163, 3, - 0, 0, 0, 0,142, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 79, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 1, 0, 0, 0, 83, 78, 0, 0, 8, 1, 0, 0,136, 95,197, 6, + 0, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0,248,174,197, 6, 0, 0, 0, 0,136, 12,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 83, 99,114,105,112,116,105,110,103, 0,103, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114, 99, 80, 61,114, 99, 80, 61,114, 99, 80, 61, -199, 54, 36, 60,199, 54, 36, 60,199, 54, 36, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,205,204, 28, 65, 0, 0, 0, 0, 0, 0, 32, 0, -128, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 64, 0, 0,200, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0,112, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0,128, 63,205,204, 76, 61, 0, 0, 5, 0, 0, 0, 0, 0, 10,215,163, 59, - 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0,216, 96,197, 6, 0, 0, 0, 0,136,102,197, 6, 0, 0, 0, 0,248,102,197, 6, 0, 0, 0, 0, 40,112,197, 6, + 0, 0, 0, 0,152,112,197, 6, 0, 0, 0, 0,168,167,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,216, 96,197, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72, 97,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72, 97,197, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,184, 97,197, 6, 0, 0, 0, 0,216, 96,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,184, 97,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40, 98,197, 6, + 0, 0, 0, 0, 72, 97,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0, 40, 98,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,152, 98,197, 6, 0, 0, 0, 0,184, 97,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,152, 98,197, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 8, 99,197, 6, 0, 0, 0, 0, 40, 98,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,168, 3, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8, 99,197, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0,120, 99,197, 6, 0, 0, 0, 0,152, 98,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,168, 3, + 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,120, 99,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,232, 99,197, 6, + 0, 0, 0, 0, 8, 99,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 5,168, 3, 0, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,232, 99,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 88,100,197, 6, 0, 0, 0, 0,120, 99,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 5, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 88,100,197, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200,100,197, 6, 0, 0, 0, 0,232, 99,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,104, 1, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,200,100,197, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0, 56,101,197, 6, 0, 0, 0, 0, 88,100,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 5,104, 1, + 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 56,101,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,168,101,197, 6, + 0, 0, 0, 0,200,100,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 2,104, 1, 1, 0, 0, 0, 68, 65, 84, 65, + 32, 0, 0, 0,168,101,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 24,102,197, 6, 0, 0, 0, 0, 56,101,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 5,236, 2, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 24,102,197, 6, + 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,136,102,197, 6, 0, 0, 0, 0,168,101,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,126, 7,236, 2, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,136,102,197, 6, 0, 0, 0, 0,211, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,102,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 2,168, 3, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,248,102,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104,103,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 97,197, 6, 0, 0, 0, 0,184, 97,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,104,103,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216,103,197, 6, + 0, 0, 0, 0,248,102,197, 6, 0, 0, 0, 0, 72, 97,197, 6, 0, 0, 0, 0,152, 98,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216,103,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72,104,197, 6, + 0, 0, 0, 0,104,103,197, 6, 0, 0, 0, 0,184, 97,197, 6, 0, 0, 0, 0, 8, 99,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72,104,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184,104,197, 6, + 0, 0, 0, 0,216,103,197, 6, 0, 0, 0, 0,152, 98,197, 6, 0, 0, 0, 0, 8, 99,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184,104,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40,105,197, 6, + 0, 0, 0, 0, 72,104,197, 6, 0, 0, 0, 0, 8, 99,197, 6, 0, 0, 0, 0,120, 99,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40,105,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152,105,197, 6, + 0, 0, 0, 0,184,104,197, 6, 0, 0, 0, 0, 40, 98,197, 6, 0, 0, 0, 0,232, 99,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,152,105,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8,106,197, 6, + 0, 0, 0, 0, 40,105,197, 6, 0, 0, 0, 0,216, 96,197, 6, 0, 0, 0, 0, 88,100,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 8,106,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120,106,197, 6, + 0, 0, 0, 0,152,105,197, 6, 0, 0, 0, 0,152, 98,197, 6, 0, 0, 0, 0, 88,100,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,120,106,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232,106,197, 6, + 0, 0, 0, 0, 8,106,197, 6, 0, 0, 0, 0,120, 99,197, 6, 0, 0, 0, 0,200,100,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,232,106,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88,107,197, 6, + 0, 0, 0, 0,120,106,197, 6, 0, 0, 0, 0,232, 99,197, 6, 0, 0, 0, 0,200,100,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88,107,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200,107,197, 6, + 0, 0, 0, 0,232,106,197, 6, 0, 0, 0, 0, 88,100,197, 6, 0, 0, 0, 0, 56,101,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200,107,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56,108,197, 6, + 0, 0, 0, 0, 88,107,197, 6, 0, 0, 0, 0,200,100,197, 6, 0, 0, 0, 0, 56,101,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56,108,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168,108,197, 6, + 0, 0, 0, 0,200,107,197, 6, 0, 0, 0, 0,232, 99,197, 6, 0, 0, 0, 0,168,101,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,168,108,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24,109,197, 6, + 0, 0, 0, 0, 56,108,197, 6, 0, 0, 0, 0,120, 99,197, 6, 0, 0, 0, 0,168,101,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 24,109,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,136,109,197, 6, + 0, 0, 0, 0,168,108,197, 6, 0, 0, 0, 0, 8, 99,197, 6, 0, 0, 0, 0, 24,102,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136,109,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,248,109,197, 6, + 0, 0, 0, 0, 24,109,197, 6, 0, 0, 0, 0, 40, 98,197, 6, 0, 0, 0, 0, 24,102,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,248,109,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104,110,197, 6, + 0, 0, 0, 0,136,109,197, 6, 0, 0, 0, 0,168,101,197, 6, 0, 0, 0, 0, 24,102,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,104,110,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216,110,197, 6, + 0, 0, 0, 0,248,109,197, 6, 0, 0, 0, 0,152, 98,197, 6, 0, 0, 0, 0,136,102,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216,110,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72,111,197, 6, + 0, 0, 0, 0,104,110,197, 6, 0, 0, 0, 0,120, 99,197, 6, 0, 0, 0, 0,136,102,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72,111,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184,111,197, 6, + 0, 0, 0, 0,216,110,197, 6, 0, 0, 0, 0, 56,101,197, 6, 0, 0, 0, 0,136,102,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184,111,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40,112,197, 6, + 0, 0, 0, 0, 72,111,197, 6, 0, 0, 0, 0, 88,100,197, 6, 0, 0, 0, 0,200,100,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40,112,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,184,111,197, 6, 0, 0, 0, 0,216, 96,197, 6, 0, 0, 0, 0,232, 99,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,152,112,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,104,116,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 98,197, 6, 0, 0, 0, 0, 72, 97,197, 6, 0, 0, 0, 0,184, 97,197, 6, + 0, 0, 0, 0, 8, 99,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,169, 3, 0, 0, + 5, 4, 0, 0, 7, 7,127, 7, 93, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,174,197, 6, + 0, 0, 0, 0,104,174,197, 6, 0, 0, 0, 0,136,113,197, 6, 0, 0, 0, 0,248,114,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,136,113,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,248,114,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,148, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,239, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, 0, 0,200, 65, 0,192,239, 68, + 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,127, 7, 26, 0,127, 7, + 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,236, 3, 0, 0, + 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,248,114,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,113,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0,192,239, 68, 0, 0, 0, 0, 0, 0, 28, 66, 0, 0, 0, 0, 0,192,237, 68, 0, 0, 0, 0, + 0, 0,134, 66,110, 7, 0, 0,127, 7, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,109, 7, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 2, 2, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, 10, 0,127, 7, 67, 0,110, 7, + 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,169, 3, 0, 0, +235, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +160, 0, 0, 0,104,116,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,248,140,197, 6, 0, 0, 0, 0,152,112,197, 6, + 0, 0, 0, 0,232, 99,197, 6, 0, 0, 0, 0,168,101,197, 6, 0, 0, 0, 0, 24,102,197, 6, 0, 0, 0, 0, 40, 98,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241, 5, 0, 0,126, 7, 0, 0, 0, 0, 0, 0,235, 2, 0, 0, 4, 4,142, 1, +236, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,139,197, 6, 0, 0, 0, 0,184,139,197, 6, + 0, 0, 0, 0, 88,117,197, 6, 0, 0, 0, 0,200,118,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 88,117,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,200,118,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,148, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,199, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +141, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,198, 67, 0, 0,200, 65, 0,128,198, 67, 0, 0,200, 65, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,142, 1, 26, 0,142, 1, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241, 5, 0, 0,126, 7, 0, 0,210, 2, 0, 0,235, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 1, 26, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,200,118,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,117,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,198, 67, 0, 0, 61,196, 0, 0, 0, 0, 0, 0, 0, 0,254,127,190, 67,254,127, 52,196, 0, 0, 0, 0,125, 1, 0, 0, +142, 1, 0, 0, 0, 0, 0, 0,209, 2, 0, 0, 0, 0, 0, 0,126, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, +124, 1, 0, 0, 0, 0, 0, 0,209, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 64, 10, 1, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,142, 1,210, 2,125, 1,210, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241, 5, 0, 0,126, 7, 0, 0, 0, 0, 0, 0,209, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 1,210, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 56,120,197, 6, 0, 0, 0, 0, 24,138,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 56,120,197, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,216,121,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 85, 84, 84, 79, 78, 83, 95, 80, 84, 95, 99,111,110,116,101,120,116, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,110,116,101,120,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,255,124, 1, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,216,121,197, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,120,123,197, 6, + 0, 0, 0, 0, 56,120,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,114,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82,101,110,100, +101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,255, +124, 1, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,119,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,232,119,216, 3, 0, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 79, 66, 0, 0,112, 5, 0, 0,200,213,217, 3, 0, 0, 0, 0,129, 0, 0, 0, 1, 0, 0, 0,184,219,217, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 67, 97, -109,101,114, 97, 0, 97,109,101,114, 97, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,120,123,197, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 24,125,197, 6, 0, 0, 0, 0,216,121,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,108, 97,121,101,114,115, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 97,121,101,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111,255,124, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 24,125,197, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,184,126,197, 6, + 0, 0, 0, 0,120,123,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,100,105,109,101,110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,105,109,101, +110,115,105,111,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,254, +124, 1,203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 24, 98,200, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 10, 0, 0, 0, - 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,184,126,197, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 88,128,197, 6, 0, 0, 0, 0, 24,125,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105, +110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105, +110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65,110,116,105, 45, 65,108,105, 97,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58,254,124, 1, 58, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 88,128,197, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,248,129,197, 6, + 0, 0, 0, 0,184,126,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,109,111,116,105,111,110, 95, 98,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 97,109,112, +108,101,100, 32, 77,111,116,105,111,110, 32, 66,108,117,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,254, +124, 1, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,248,129,197, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,152,131,197, 6, 0, 0, 0, 0, 88,128,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,115,104, 97,100,105,110,103, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,104, 97,100,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,254,124, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,152,131,197, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 56,133,197, 6, + 0, 0, 0, 0,248,129,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,101,114,102, +111,114,109, 97,110, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,242,253, +124, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 56,133,197, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,216,134,197, 6, 0, 0, 0, 0,152,131,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101, +115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,112,111,115,116, 95,112,114,111, 99,101, +115,115,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,111,115,116, 32, 80,114,111, 99,101,115,115,105,110,103, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,218,253,124, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,216,134,197, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,120,136,197, 6, + 0, 0, 0, 0, 56,133,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,116, 97,109, +112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194,253, +124, 1, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,120,136,197, 6, + 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 24,138,197, 6, 0, 0, 0, 0,216,134,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, 69, 82, 95, 80, 84, 95,111,117,116,112,117,116, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,253,124, 1,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110,101,239, 64, -150, 62,208,192, 78,255,170, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 42,254,141, 63,192, 57, 49, 60, 34,159, 80, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,222,149, 47, 63, - 53, 70, 58, 63,222, 56, 49,188, 0, 0, 0, 0, 86,126,162,190,227,251,159, 62, 55, 53,101, 63, 0, 0, 0, 0, 7,165, 39, 63, -149, 84, 28,191, 51,247,227, 62, 0, 0, 0, 0,110,101,239, 64,150, 62,208,192, 78,255,170, 64, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 1, 0,128, 63, - 1, 0,128, 51, 1, 0, 0,179, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0,128, 63, 1, 0,128, 51, 0, 0, 0, 0, 2, 0, 0,179, - 2, 0, 0,167, 1, 0,128, 63, 0, 0, 0, 0, 1, 0, 0, 53, 1, 0, 0, 41, 1, 0,128,168, 0, 0,128, 63,221,149, 47, 63, - 86,126,162,190, 8,165, 39, 63, 0, 0, 0, 0, 51, 70, 58, 63,225,251,159, 62,149, 84, 28,191, 0, 0, 0, 0,192, 56, 49,188, - 55, 53,101, 63, 52,247,227, 62, 0, 0, 0, 0, 90, 38,173,190, 0,222,192,190,152, 9, 52,193, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 24,138,197, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,120,136,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 78, 68, + 69, 82, 95, 80, 84, 95, 98, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 97,107,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,253, +124, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,184,139,197, 6, + 0, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 21, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,248,140,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,136,154,197, 6, + 0, 0, 0, 0,104,116,197, 6, 0, 0, 0, 0, 56,101,197, 6, 0, 0, 0, 0,136,102,197, 6, 0, 0, 0, 0,120, 99,197, 6, + 0, 0, 0, 0,200,100,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,249, 2, 0, 0,239, 5, 0, 0,105, 1, 0, 0, +167, 3, 0, 0, 1, 1,247, 2, 63, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,152,197, 6, + 0, 0, 0, 0,216,152,197, 6, 0, 0, 0, 0,232,141,197, 6, 0, 0, 0, 0,168,147,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,232,141,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 88,143,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,113, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,192, 61, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,246, 2, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128, 61, 68, 0, 0,200, 65, 0,128, 61, 68, + 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,247, 2, 26, 0,247, 2, + 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,249, 2, 0, 0,239, 5, 0, 0,105, 1, 0, 0, +130, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,247, 2, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0, 88,143,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,200,144,197, 6, 0, 0, 0, 0,232,141,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0, 64, 70,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67,255,127, 70,196, + 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0, 43, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,160, 0, 44, 3,143, 0, + 26, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,249, 2, 0, 0,249, 2, 0, 0,131, 1, 0, 0, +167, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 37, 2, 0, 0, 5, 0, 3, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,200,144,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 56,146,197, 6, 0, 0, 0, 0, 88,143,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 67, 0, 0,206,194, 0, 0, 0, 0, 0, 0, 0, 0,231,102, 16, 67, 0, 0,206,194, + 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 18, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,120, 0,143, 0, +102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,249, 2, 0, 0,239, 5, 0, 0,131, 1, 0, 0, +131, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 6, 0, 34, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0, 56,146,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,168,147,197, 6, 0, 0, 0, 0,200,144,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, 0,128,142,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, 0, 0, 26,196, + 0, 0, 0, 0,163, 0, 0, 0,180, 0, 0, 0, 18, 0, 0, 0,121, 2, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 18, 0, 0, 0,121, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,180, 0,122, 2,163, 0, +104, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,239, 5, 0, 0,239, 5, 0, 0,131, 1, 0, 0, +167, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 40, 1, 0, 0,168,147,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,146,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,249, 2, 0, 0,239, 5, 0, 0,131, 1, 0, 0, +167, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,247, 2, 37, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,149,197, 6, 0, 0, 0, 0, 68, 65, 84, 65, +112, 3, 0, 0, 24,149,197, 6, 0, 0, 0, 0,173, 0, 0, 0, 1, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 74,141,193, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, + 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,225,215,163,188, 0, 0, 0, 0, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, + 0, 0, 0, 0, 70,119,105, 63,143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,214,211,111,193, 0, 0,128, 63, 69,239,209, 62, 70,119,105, 63,176, 84, 89,188, + 0, 0, 0, 0, 53,177,205,190,142, 74, 70, 62,166, 33,101, 63, 0, 0, 0, 0,185,158, 81, 63, 35, 44,185,190, 43, 61,228, 62, + 0, 0, 0, 0,164, 96, 68, 65,111,121,173,192,248,209,213, 64, 0, 0,128, 63,178,157,229, 62, 30,132, 27,191,222,160, 81,191, +184,158, 81,191,117, 90,127, 63,166,235,149, 62, 9, 46,185, 62, 35, 44,185, 62,145,180,109,188,212, 60,173, 63,129, 63,228,190, + 42, 61,228,190, 0, 0, 0, 0, 0, 0, 0, 0, 96,132,111, 65,214,211,111, 65,217,236,191, 62, 54,117, 85, 63,224,246, 70,188, + 0,160, 32,182,252, 5,136,190, 43, 33, 3, 62,235,135, 23, 63, 0, 0, 96, 53,215,104, 25,196,133,132,135, 67, 37, 9,167,195, +136,252, 71,194, 3, 54, 25, 68,158, 87,135,195,205,209,166, 67,151,254, 71, 66, 68,239,209, 62, 51,177,205,190,184,158, 81, 63, + 0, 0, 0, 0, 70,119,105, 63,143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, 42, 61,228, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,214,211,111,193, 0, 0,128, 63,178,157,229, 62, 30,132, 27,191,222,160, 81,191, +184,158, 81,191,117, 90,127, 63,166,235,149, 62, 9, 46,185, 62, 35, 44,185, 62,145,180,109,188,212, 60,173, 63,129, 63,228,190, + 42, 61,228,190, 0, 0, 0, 0, 0, 0, 0, 0, 96,132,111, 65,214,211,111, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 86, 45, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 46, 86, 45, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 86, 45, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 92, 62, 55, 63, 56,186,224,190,237,203,148,190, + 3,236,234,190,214,211,111, 65,214,211,111, 65, 0, 0, 0, 0, 0, 0, 0, 0,107,227, 29, 59, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 30, 33, 12, 66, 86,152,137, 66,116, 27,126, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 96, 1, 0, 0,216,152,197, 6, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 56,180,150,201, 0, 0,128, 63,187,225, 16, 63, 0, 0,128, 63,205,204,204, 62, -237, 54, 32, 63, 0, 0, 0, 0,143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 2, 0, 1, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 32, 65,205,204, 76, 62, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,200, 67,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 40,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, 8, 8,128, 0, + 0, 0, 12, 66, 0, 0,128, 63, 10,215, 35, 60, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +160, 0, 0, 0,136,154,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,232,160,197, 6, 0, 0, 0, 0,248,140,197, 6, + 0, 0, 0, 0,216, 96,197, 6, 0, 0, 0, 0, 88,100,197, 6, 0, 0, 0, 0,200,100,197, 6, 0, 0, 0, 0,232, 99,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,239, 5, 0, 0, 0, 0, 0, 0,103, 1, 0, 0, 18, 18,240, 5, +104, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,159,197, 6, 0, 0, 0, 0, 24,159,197, 6, + 0, 0, 0, 0,120,155,197, 6, 0, 0, 0, 0,232,156,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,120,155,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,232,156,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,160, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,190, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,152, 0, 0, 0,248, 40,215, 3, 0, 0, 0, 0,132, 0, 0, 0, - 1, 0, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, +239, 5, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,224,189, 68, 0, 0,200, 65, 0,224,189, 68, 0, 0,200, 65, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,240, 5, 26, 0,240, 5, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,239, 5, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 5, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,204,204, 61, -205,204, 76, 62, 10,215,163, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 79, 66, 0, 0, -112, 5, 0, 0,184,219,217, 3, 0, 0, 0, 0,129, 0, 0, 0, 1, 0, 0, 0,168,225,217, 3, 0, 0, 0, 0,200,213,217, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 67,117, 98,101, 0,112,104,101,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,232,156,197, 6, + 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,155,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0,224,189, 68, 0, 0, 0, 0, 0, 0, 51, 67, 0, 0, 0, 0, 0,224,187, 68, 0, 0, 0, 0, 0, 0,167, 67,223, 5, 0, 0, +240, 5, 0, 0, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +222, 5, 0, 0, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 2, 2, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, 10, 0,240, 5, 78, 1,223, 5, 78, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,239, 5, 0, 0, 26, 0, 0, 0,103, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 5, 78, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88,158,197, 6, + 0, 0, 0, 0,193, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0,200,158,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,200,158,197, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,136, 1, 0, 0, 24,159,197, 6, 0, 0, 0, 0, +194, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,158,197, 6, 0, 0, 0, 0, + 88,158,197, 6, 0, 0, 0, 0, 62, 62, 62, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,112,121,116,104,111,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 0, 0, 8, 4, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,232,160,197, 6, 0, 0, 0, 0, +214, 0, 0, 0, 1, 0, 0, 0,168,167,197, 6, 0, 0, 0, 0,136,154,197, 6, 0, 0, 0, 0,168,101,197, 6, 0, 0, 0, 0, +120, 99,197, 6, 0, 0, 0, 0, 8, 99,197, 6, 0, 0, 0, 0, 24,102,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +241, 5, 0, 0,126, 7, 0, 0,237, 2, 0, 0,167, 3, 0, 0, 3, 3,142, 1,187, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,184,164,197, 6, 0, 0, 0, 0,184,164,197, 6, 0, 0, 0, 0,216,161,197, 6, 0, 0, 0, 0, + 72,163,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,216,161,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, + 72,163,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,244, 67, 0, 0, 0, 0, 0, 0,208, 65, + 0, 0, 0, 0, 0, 0,199, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,141, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, + 0,128,198, 67, 0, 0,200, 65, 0,128,198, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, + 4, 0, 12, 0, 10, 0,142, 1, 26, 0,142, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +241, 5, 0, 0,126, 7, 0, 0,237, 2, 0, 0, 6, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +142, 1, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72,163,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,216,161,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,141, 67, 0, 0,244,194, 0, 0, 0, 0, + 0, 0, 0, 0, 0,128,190, 67, 0, 0, 15,195, 0, 0, 0, 0,125, 1, 0, 0,142, 1, 0, 0, 18, 0, 0, 0,160, 0, 0, 0, + 0, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,124, 1, 0, 0, 18, 0, 0, 0,160, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 18, 6, 0, 0, 2, 0, 3, 3, + 0, 0, 12, 4, 6, 0,142, 1,161, 0,125, 1,143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +241, 5, 0, 0,126, 7, 0, 0, 7, 3, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +142, 1,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 1, 0, 0,184,164,197, 6, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,166,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65, 16, 0, 0, 0, + 24,166,197, 6, 0, 0, 0, 0,237, 0, 0, 0, 1, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0,120,166,197, 6, 0, 0, 0, 0, + 68, 65, 84, 65,224, 0, 0, 0,120,166,197, 6, 0, 0, 0, 0,236, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +104, 38,198, 6, 0, 0, 0, 0, 19, 0, 0, 0, 1, 0, 1, 0,104, 38,198, 6, 0, 0, 0, 0, 20, 0, 0, 0, 1, 0, 1, 0, +104, 38,198, 6, 0, 0, 0, 0, 21, 0, 1, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, +248, 64,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,104, 74,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 8,129,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 72, 88,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 88,110,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,168, 81,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 56, 60,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,200, 67,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 40, 59,198, 6, 0, 0, 0, 0, 21, 0, 0, 0, 1, 0, 1, 0,104, 38,198, 6, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, +168,167,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,160,197, 6, 0, 0, 0, 0, + 88,100,197, 6, 0, 0, 0, 0,152, 98,197, 6, 0, 0, 0, 0,136,102,197, 6, 0, 0, 0, 0, 56,101,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,247, 2, 0, 0,105, 1, 0, 0,167, 3, 0, 0, 9, 9,248, 2, 63, 2, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,171,197, 6, 0, 0, 0, 0,120,171,197, 6, 0, 0, 0, 0, +152,168,197, 6, 0, 0, 0, 0, 8,170,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,152,168,197, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0, 8,170,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230, 67, + 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 62, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,247, 2, 0, 0, + 0, 0, 0, 0, 25, 0, 0, 0, 0,192, 61, 68, 0, 0,200, 65, 0,192, 61, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,248, 2, 26, 0,248, 2, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,247, 2, 0, 0,105, 1, 0, 0,130, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,248, 2, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8,170,197, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,168,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,189, 68, + 0, 0, 0, 0, 0,192, 22, 68,248,150, 23, 68, 8, 41,100, 68, 46,224, 62, 67,233, 15,206, 67, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,247, 2, 0, 0, + 0, 0, 0, 0, 36, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,215, 35, 60, 0, 0,122, 68, + 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 4, 10, 0,248, 2, 37, 2,248, 2, 37, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,247, 2, 0, 0,131, 1, 0, 0,167, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,248, 2, 37, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 2, 0, 0,120,171,197, 6, 0, 0, 0, 0, +186, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,205,204,204, 61,231, 1, 0, 0,243, 1, 0, 0,122, 1, 0, 0,124, 1, 0, 0, +231, 1, 0, 0,243, 1, 0, 0, 4, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0, 8, 1, 0, 0,248,174,197, 6, 0, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0, + 24,246,197, 6, 0, 0, 0, 0,136, 95,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 83, 82, 85, 86, 32, 69,100,105,116,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,176,197, 6, 0, 0, 0, 0, + 88,179,197, 6, 0, 0, 0, 0,200,179,197, 6, 0, 0, 0, 0, 40,184,197, 6, 0, 0, 0, 0,152,184,197, 6, 0, 0, 0, 0, +184,228,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72,176,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, +184,176,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 32, 0, 0, 0,184,176,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 40,177,197, 6, 0, 0, 0, 0, + 72,176,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, + 40,177,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,152,177,197, 6, 0, 0, 0, 0,184,176,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 5, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,152,177,197, 6, 0, 0, 0, 0, +211, 0, 0, 0, 1, 0, 0, 0, 8,178,197, 6, 0, 0, 0, 0, 40,177,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +126, 7, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8,178,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, +120,178,197, 6, 0, 0, 0, 0,152,177,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,234, 3, 1, 0, 0, 0, + 68, 65, 84, 65, 32, 0, 0, 0,120,178,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,232,178,197, 6, 0, 0, 0, 0, + 8,178,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, +232,178,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 88,179,197, 6, 0, 0, 0, 0,120,178,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,200, 3,234, 3, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 88,179,197, 6, 0, 0, 0, 0, +211, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,178,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +200, 3, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200,179,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, + 56,180,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,176,197, 6, 0, 0, 0, 0, 40,177,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56,180,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, +168,180,197, 6, 0, 0, 0, 0,200,179,197, 6, 0, 0, 0, 0,184,176,197, 6, 0, 0, 0, 0, 8,178,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,168,180,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, + 24,181,197, 6, 0, 0, 0, 0, 56,180,197, 6, 0, 0, 0, 0, 40,177,197, 6, 0, 0, 0, 0,120,178,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 24,181,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, +136,181,197, 6, 0, 0, 0, 0,168,180,197, 6, 0, 0, 0, 0, 8,178,197, 6, 0, 0, 0, 0,120,178,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,136,181,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, +248,181,197, 6, 0, 0, 0, 0, 24,181,197, 6, 0, 0, 0, 0, 8,178,197, 6, 0, 0, 0, 0,232,178,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,248,181,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, +104,182,197, 6, 0, 0, 0, 0,136,181,197, 6, 0, 0, 0, 0, 72,176,197, 6, 0, 0, 0, 0, 88,179,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,104,182,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, +216,182,197, 6, 0, 0, 0, 0,248,181,197, 6, 0, 0, 0, 0, 72,176,197, 6, 0, 0, 0, 0, 8,178,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,216,182,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, + 72,183,197, 6, 0, 0, 0, 0,104,182,197, 6, 0, 0, 0, 0,232,178,197, 6, 0, 0, 0, 0, 88,179,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72,183,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, +184,183,197, 6, 0, 0, 0, 0,216,182,197, 6, 0, 0, 0, 0,120,178,197, 6, 0, 0, 0, 0,232,178,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,184,183,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, + 40,184,197, 6, 0, 0, 0, 0, 72,183,197, 6, 0, 0, 0, 0,152,177,197, 6, 0, 0, 0, 0, 88,179,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 40,184,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,184,183,197, 6, 0, 0, 0, 0,152,177,197, 6, 0, 0, 0, 0,120,178,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,152,184,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, +104,188,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,178,197, 6, 0, 0, 0, 0,184,176,197, 6, 0, 0, 0, 0, + 40,177,197, 6, 0, 0, 0, 0,120,178,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, +235, 3, 0, 0, 5, 4, 0, 0, 7, 7,127, 7, 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +136,245,197, 6, 0, 0, 0, 0,136,245,197, 6, 0, 0, 0, 0,136,185,197, 6, 0, 0, 0, 0,248,186,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 1, 0, 0,136,185,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,248,186,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,148, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,239, 68, + 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,239, 68, 0, 0,200, 65, + 0,192,239, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,127, 7, + 26, 0,127, 7, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0, +235, 3, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 7, 26, 0, 0, 0, 1, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 1, 0, 0,248,186,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +136,185,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,109, 69, 0, 0,128,192, 0, 0, 0, 0, 0, 0, 0, 0,255,255,109, 69, + 0, 0, 0,192, 0, 0, 0, 0,112, 7, 0, 0,129, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 2, 0, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, 10, 0,129, 7, + 2, 0,112, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 4, 0, 0, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65,160, 0, 0, 0,104,188,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,184,228,197, 6, 0, 0, 0, 0, +152,184,197, 6, 0, 0, 0, 0, 72,176,197, 6, 0, 0, 0, 0, 8,178,197, 6, 0, 0, 0, 0,232,178,197, 6, 0, 0, 0, 0, + 88,179,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,199, 3, 0, 0, 0, 0, 0, 0,233, 3, 0, 0, + 6, 6,200, 3,234, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,195,197, 6, 0, 0, 0, 0, + 72,195,197, 6, 0, 0, 0, 0, 88,189,197, 6, 0, 0, 0, 0,216,193,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, + 88,189,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,200,190,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,215, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,114, 68, 0, 0, 0, 0, 0, 0,208, 65, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,199, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192,113, 68, 0, 0,200, 65, 0,192,113, 68, 0, 0,200, 65, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,200, 3, 26, 0,200, 3, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,199, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 3, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, +200,190,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,216,193,197, 6, 0, 0, 0, 0, 88,189,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 91, 67, 0,192,115,196, 0, 0, 0, 0, 0, 0, 0, 0,254,255, 74, 67,254,255,115,196, 0, 0, 0, 0, +203, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0,207, 3, 0, 0, 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, + 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0,207, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,220, 0,208, 3,203, 0,208, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,219, 0, 0, 0, 26, 0, 0, 0,233, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0,208, 3, 0, 0, 4, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 56,192,197, 6, 0, 0, 0, 0, 56,192,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, + 56,192,197, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 77, 65, 71, 69, 95, 80, 84, 95,103,112,101,110, 99,105,108, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 77, 65, 71, 69, 95, 80, 84, 95,103,112,101,110, 99,105,108, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71,114,101, 97,115,101, 32, 80,101,110, 99,105,108, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,255,202, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,216,193,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,200,190,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 67, + 51, 51, 43,191,154,153,213, 63, 51, 51,131,191,154,153, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,236, 2, 0, 0, 0, 0, 0, 0,208, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +220, 0, 0, 0,199, 3, 0, 0, 26, 0, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +236, 2,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 33, 0, 0, 72,195,197, 6, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 65, 0, 0, 0, 0,154,153,153, 62, 0, 0, 0, 0,100, 0, 0, 0, +154,153,153, 62,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,184,228,197, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,104,188,197, 6, 0, 0, 0, 0, 88,179,197, 6, 0, 0, 0, 0,232,178,197, 6, 0, 0, 0, 0, +120,178,197, 6, 0, 0, 0, 0,152,177,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,201, 3, 0, 0,126, 7, 0, 0, + 0, 0, 0, 0,233, 3, 0, 0, 1, 1,182, 3,234, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +216,243,197, 6, 0, 0, 0, 0,216,243,197, 6, 0, 0, 0, 0,168,229,197, 6, 0, 0, 0, 0,168,238,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 1, 0, 0,168,229,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 24,231,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,113, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,128,109, 68, + 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,181, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 64,109, 68, 0, 0,200, 65, + 0, 64,109, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,182, 3, + 26, 0,182, 3, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,201, 3, 0, 0,126, 7, 0, 0, + 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,182, 3, 26, 0, 0, 0, 1, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 1, 0, 0, 24,231,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 40,234,197, 6, 0, 0, 0, 0, +168,229,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 67, 0, 0, 86,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, + 0, 0, 86,196, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 87, 3, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 87, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0, + 88, 3,143, 0, 88, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,201, 3, 0, 0,104, 4, 0, 0, +146, 0, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0, 88, 3, 0, 0, 5, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,232,197, 6, 0, 0, 0, 0,136,232,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 88, 1, 0, 0,136,232,197, 6, 0, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, + 84, 95,116,111,111,108,115, 95,111, 98,106,101, 99,116,109,111,100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, + 84, 95,116,111,111,108,115, 95,111, 98,106,101, 99,116,109,111,100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 98,106,101, 99,116, 32, 84, +111,111,108,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,233,253,143, 0,255, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 40,234,197, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0, 56,237,197, 6, 0, 0, 0, 0, 24,231,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 67, + 0, 0,242,194, 0, 0, 0, 0, 0, 0, 0, 0,231,102, 16, 67, 91, 90,242,194, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, + 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,142, 0, 0, 0, + 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, + 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,160, 0,120, 0,143, 0,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,201, 3, 0, 0,104, 4, 0, 0, 26, 0, 0, 0,145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,160, 0,120, 0, 0, 0, 6, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +152,235,197, 6, 0, 0, 0, 0,152,235,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,152,235,197, 6, 0, 0, 0, 0, +213, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,108, 97,115,116, 95,111,112,101,114, 97,116,111,114, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 79,112,101,114, 97,116,111,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,255,144, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 1, 0, 0, 56,237,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,168,238,197, 6, 0, 0, 0, 0, + 40,234,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, 0,128,126,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 67, +255,191,126,196, 0, 0, 0, 0,163, 0, 0, 0,180, 0, 0, 0, 18, 0, 0, 0, 12, 4, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 18, 0, 0, 0, 12, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, 18, 0, 0, 0, 6, 0,180, 0, + 13, 4,163, 0,251, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 7, 0, 0,126, 7, 0, 0, + 26, 0, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, + 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 1, 0, 0,168,238,197, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 56,237,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 4, 0, 0,126, 7, 0, 0, + 26, 0, 0, 0,233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 3,208, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,240,197, 6, 0, 0, 0, 0, + 68, 65, 84, 65,112, 3, 0, 0, 24,240,197, 6, 0, 0, 0, 0,173, 0, 0, 0, 1, 0, 0, 0, 72,246,172, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 28, 13,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, 74,215, 76,190, 0, 0, 0, 0, 68,239,209, 62, 51,177,205,190, +184,158, 81, 63, 0, 0, 0, 0, 70,119,105, 63,143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, + 42, 61,228, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 95,192, 0, 0,128, 63, 69,239,209, 62, 70,119,105, 63, +160, 84, 89,188, 0, 0, 0, 0, 52,177,205,190,142, 74, 70, 62,166, 33,101, 63, 0, 0, 0, 0,185,158, 81, 63, 35, 44,185,190, + 43, 61,228, 62, 0, 0, 0, 0,188,173, 54, 64,136, 95,161,191,147,231,198, 63, 0, 0,128, 63,185,214, 13, 63,208,249,224,190, + 48,180, 81,191,184,158, 81,191,189,188,157, 63,140,225, 88, 62, 26, 63,185, 62, 35, 44,185, 62,241,213,146,188,206,156,122, 63, +138, 84,228,190, 42, 61,228,190, 0, 0, 0, 0, 0, 0, 0, 0,100, 98, 82, 64, 0, 25, 95, 64,121, 92,155, 62,151,198, 44, 63, +192,214, 32,188, 0, 0, 40,180,195, 15,188,190,132, 75, 53, 62,216,125, 81, 63, 0, 0,192,179,115, 77,100,193, 17,173,201, 64, +181,148,248,192,203,247,159,192,233, 74, 87, 65,247, 46,190,192, 88,106,234, 64, 45, 8,160, 64, 68,239,209, 62, 51,177,205,190, +184,158, 81, 63, 0, 0, 0, 0, 70,119,105, 63,143, 74, 70, 62, 35, 44,185,190, 0, 0, 0, 0,162, 84, 89,188,166, 33,101, 63, + 42, 61,228, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 95,192, 0, 0,128, 63,185,214, 13, 63,208,249,224,190, + 48,180, 81,191,184,158, 81,191,189,188,157, 63,140,225, 88, 62, 26, 63,185, 62, 35, 44,185, 62,241,213,146,188,206,156,122, 63, +138, 84,228,190, 42, 61,228,190, 0, 0, 0, 0, 0, 0, 0, 0,100, 98, 82, 64, 0, 25, 95, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,201,250, 62, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,201,250, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +248,201,250, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 92, 62, 55, 63, 56,186,224,190, +237,203,148,190, 3,236,234,190, 0, 25, 95, 64, 0, 25, 95, 64, 0, 0, 0, 0, 0, 0, 0, 0,114,145,245, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 30, 33, 12, 66, 85,152,137, 66,116, 27,126, 66, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 1, 0, 0,216,243,197, 6, 0, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65,205,204, 76, 62, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, +200, 67,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 3, 0, + 8, 8,128, 0, 0, 0, 12, 66, 0, 0,128, 63,205,204,204, 61, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 10, 0, 7, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 83, 78, 0, 0, 8, 1, 0, 0, 24,246,197, 6, 0, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +248,174,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 86,105,100,101,111, 32, + 69,100,105,116,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,247,197, 6, 0, 0, 0, 0, 56,252,197, 6, 0, 0, 0, 0, +168,252,197, 6, 0, 0, 0, 0, 24, 4,198, 6, 0, 0, 0, 0,136, 4,198, 6, 0, 0, 0, 0,232, 29,198, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 32, 0, 0, 0,104,247,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,216,247,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, +216,247,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 72,248,197, 6, 0, 0, 0, 0,104,247,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,222, 2, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 72,248,197, 6, 0, 0, 0, 0, +211, 0, 0, 0, 1, 0, 0, 0,184,248,197, 6, 0, 0, 0, 0,216,247,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +240, 4,222, 2, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,184,248,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, + 40,249,197, 6, 0, 0, 0, 0, 72,248,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 32, 0, 0, 0, 40,249,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,152,249,197, 6, 0, 0, 0, 0, +184,248,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, +152,249,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 8,250,197, 6, 0, 0, 0, 0, 40,249,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,240, 4,195, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 8,250,197, 6, 0, 0, 0, 0, +211, 0, 0, 0, 1, 0, 0, 0,120,250,197, 6, 0, 0, 0, 0,152,249,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +240, 4, 92, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,120,250,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, +232,250,197, 6, 0, 0, 0, 0, 8,250,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 32, 0, 0, 0,232,250,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 88,251,197, 6, 0, 0, 0, 0, +120,250,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 2,195, 2, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, + 88,251,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0,200,251,197, 6, 0, 0, 0, 0,232,250,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,200,251,197, 6, 0, 0, 0, 0, +211, 0, 0, 0, 1, 0, 0, 0, 56,252,197, 6, 0, 0, 0, 0, 88,251,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 2, 92, 1, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 56,252,197, 6, 0, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,200,251,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 68, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,168,252,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24,253,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,216,247,197, 6, 0, 0, 0, 0, 72,248,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0, 24,253,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,136,253,197, 6, 0, 0, 0, 0, +168,252,197, 6, 0, 0, 0, 0,216,247,197, 6, 0, 0, 0, 0, 40,249,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,136,253,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,248,253,197, 6, 0, 0, 0, 0, + 24,253,197, 6, 0, 0, 0, 0, 72,248,197, 6, 0, 0, 0, 0,152,249,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,248,253,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,104,254,197, 6, 0, 0, 0, 0, +136,253,197, 6, 0, 0, 0, 0, 40,249,197, 6, 0, 0, 0, 0,152,249,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,104,254,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,216,254,197, 6, 0, 0, 0, 0, +248,253,197, 6, 0, 0, 0, 0,152,249,197, 6, 0, 0, 0, 0, 8,250,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,216,254,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 72,255,197, 6, 0, 0, 0, 0, +104,254,197, 6, 0, 0, 0, 0,104,247,197, 6, 0, 0, 0, 0,120,250,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0, 72,255,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,184,255,197, 6, 0, 0, 0, 0, +216,254,197, 6, 0, 0, 0, 0, 40,249,197, 6, 0, 0, 0, 0,232,250,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,184,255,197, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 40, 0,198, 6, 0, 0, 0, 0, + 72,255,197, 6, 0, 0, 0, 0,120,250,197, 6, 0, 0, 0, 0, 88,251,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0, 40, 0,198, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,152, 0,198, 6, 0, 0, 0, 0, +184,255,197, 6, 0, 0, 0, 0, 88,251,197, 6, 0, 0, 0, 0,200,251,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,152, 0,198, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 8, 1,198, 6, 0, 0, 0, 0, + 40, 0,198, 6, 0, 0, 0, 0,232,250,197, 6, 0, 0, 0, 0,200,251,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0, 8, 1,198, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,120, 1,198, 6, 0, 0, 0, 0, +152, 0,198, 6, 0, 0, 0, 0, 8,250,197, 6, 0, 0, 0, 0, 56,252,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,120, 1,198, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,232, 1,198, 6, 0, 0, 0, 0, + 8, 1,198, 6, 0, 0, 0, 0,184,248,197, 6, 0, 0, 0, 0, 56,252,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,232, 1,198, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 88, 2,198, 6, 0, 0, 0, 0, +120, 1,198, 6, 0, 0, 0, 0,120,250,197, 6, 0, 0, 0, 0, 56,252,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0, 88, 2,198, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,200, 2,198, 6, 0, 0, 0, 0, +232, 1,198, 6, 0, 0, 0, 0,104,247,197, 6, 0, 0, 0, 0,184,248,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,200, 2,198, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 56, 3,198, 6, 0, 0, 0, 0, + 88, 2,198, 6, 0, 0, 0, 0,152,249,197, 6, 0, 0, 0, 0,232,250,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0, 56, 3,198, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0,168, 3,198, 6, 0, 0, 0, 0, +200, 2,198, 6, 0, 0, 0, 0, 8,250,197, 6, 0, 0, 0, 0,200,251,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,168, 3,198, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 24, 4,198, 6, 0, 0, 0, 0, + 56, 3,198, 6, 0, 0, 0, 0, 40,249,197, 6, 0, 0, 0, 0, 88,251,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0, 24, 4,198, 6, 0, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +168, 3,198, 6, 0, 0, 0, 0, 8,250,197, 6, 0, 0, 0, 0, 88,251,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65,160, 0, 0, 0,136, 4,198, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 88, 8,198, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 40,249,197, 6, 0, 0, 0, 0,216,247,197, 6, 0, 0, 0, 0, 72,248,197, 6, 0, 0, 0, 0, +152,249,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0,196, 2, 0, 0,222, 2, 0, 0, + 7, 7,241, 4, 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 37,198, 6, 0, 0, 0, 0, +216, 37,198, 6, 0, 0, 0, 0,120, 5,198, 6, 0, 0, 0, 0,232, 6,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, +120, 5,198, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,232, 6,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,128,148, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 32,158, 68, 0, 0, 0, 0, 0, 0,208, 65, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,240, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0,158, 68, 0, 0,200, 65, 0, 0,158, 68, 0, 0,200, 65, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,241, 4, 26, 0,241, 4, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0,196, 2, 0, 0,221, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241, 4, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, +232, 6,198, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 5,198, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0,240,109, 69, 0, 0,128,192, 0, 0, 0, 0, 0, 0, 0, 0,255,255,109, 69, 0, 0, 0,192, 0, 0, 0, 0, +112, 7, 0, 0,129, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,111, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, + 0, 0, 0, 0,111, 7, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 2, 0, 0, 0, 1, 0, 3, 3, 2, 0, 0, 4, 10, 0,129, 7, 2, 0,112, 7, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,222, 2, 0, 0,222, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, + 88, 8,198, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 72, 13,198, 6, 0, 0, 0, 0,136, 4,198, 6, 0, 0, 0, 0, +104,247,197, 6, 0, 0, 0, 0,120,250,197, 6, 0, 0, 0, 0, 56,252,197, 6, 0, 0, 0, 0,184,248,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 15, 15,241, 4, 68, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 12,198, 6, 0, 0, 0, 0, 40, 12,198, 6, 0, 0, 0, 0, + 72, 9,198, 6, 0, 0, 0, 0,184, 10,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 72, 9,198, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0,184, 10,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,140, 68, + 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 32,158, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, + 0, 0, 0, 0, 25, 0, 0, 0, 0, 0,158, 68, 0, 0,200, 65, 0, 0,158, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,241, 4, 26, 0,241, 4, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,241, 4, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,184, 10,198, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 9,198, 6, 0, 0, 0, 0, 0, 0, 64,192, 0, 0,126, 67, + 0, 0, 0, 0, 0, 0, 72, 66,112,189, 17,192,246, 70,125, 67, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, + 18, 0, 0, 0, 41, 0, 0, 0, 0, 0,128, 63, 0, 0, 72, 66, 0,124,146, 72, 0, 0, 72, 66,205,204,204, 61, 0, 0, 32, 65, + 72, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 4, 8, 0,241, 4, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 26, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,241, 4, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0, 40, 12,198, 6, 0, 0, 0, 0, +190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,107,205, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 48,218, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, + 72, 13,198, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 56, 21,198, 6, 0, 0, 0, 0, 88, 8,198, 6, 0, 0, 0, 0, +120,250,197, 6, 0, 0, 0, 0, 88,251,197, 6, 0, 0, 0, 0, 8,250,197, 6, 0, 0, 0, 0, 56,252,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 69, 0, 0, 0, 91, 1, 0, 0, 8, 8,241, 4, 23, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 19,198, 6, 0, 0, 0, 0,248, 19,198, 6, 0, 0, 0, 0, + 56, 14,198, 6, 0, 0, 0, 0,136, 18,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 56, 14,198, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0,168, 15,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 26, 68, + 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 32,158, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, + 0, 0, 0, 0, 25, 0, 0, 0, 0, 0,158, 68, 0, 0,200, 65, 0, 0,158, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,241, 4, 26, 0,241, 4, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0, 69, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,241, 4, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 12,217, 3, - 0, 0, 0, 0,168,182,117, 3, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,168, 15,198, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0, 24, 17,198, 6, 0, 0, 0, 0, 56, 14,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 67, + 0, 0,125,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 67, 1, 0,125,195, 0, 0, 0, 0,203, 0, 0, 0,220, 0, 0, 0, + 0, 0, 0, 0,252, 0, 0, 0, 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,202, 0, 0, 0, + 0, 0, 0, 0,252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, + 10, 3, 0, 0, 1, 0, 7, 0, 18, 0, 0, 4, 6, 0,220, 0,253, 0,203, 0,253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 21, 4, 0, 0,240, 4, 0, 0, 95, 0, 0, 0, 91, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,220, 0,253, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 68, 0, 0, 0, 7, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, - 0, 0, 0, 0, 56,180,150,201, 0, 0,128, 63,169, 19,208, 60, 0, 0,128, 63,205,204,204, 62,229,208, 34, 62, 0, 0, 0, 0, -143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 0, 1, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 24, 17,198, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0,136, 18,198, 6, 0, 0, 0, 0,168, 15,198, 6, 0, 0, 0, 0, 0, 0,112,196, 0, 0,112, 68, + 0, 0, 7,196, 0, 0, 7, 68, 0, 0,112,196, 0, 0,112, 68, 0, 0, 7,196, 0, 0, 7, 68, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 59, 70, 0,128, 59, 70,172,197, 39, 55, 0, 80,195, 71, + 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 0, 0, 91, 1, 0, 0, 91, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 7, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,136, 18,198, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 17,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 67, + 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 17, 0, 0, 0, + 18, 0, 0, 0,252, 0, 0, 0, 18, 0, 0, 0, 20, 4, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 20, 4, 0, 0, + 18, 0, 0, 0,252, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 63, 0,124,146, 72, 0, 0, 0, 66, 10,215, 35, 60, 0, 0,200, 66, +105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 0, 21, 4,253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 0, 0, 95, 0, 0, 0, 91, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 21, 4,253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,240, 0, 0, 0,248, 19,198, 6, 0, 0, 0, 0, +180, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, + 56, 21,198, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,232, 29,198, 6, 0, 0, 0, 0, 72, 13,198, 6, 0, 0, 0, 0, + 88,251,197, 6, 0, 0, 0, 0, 40,249,197, 6, 0, 0, 0, 0,232,250,197, 6, 0, 0, 0, 0,200,251,197, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 2, 0, 0, 93, 1, 0, 0,194, 2, 0, 0, 2, 2, 48, 2,102, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232, 27,198, 6, 0, 0, 0, 0,232, 27,198, 6, 0, 0, 0, 0, + 40, 22,198, 6, 0, 0, 0, 0,120, 26,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 40, 22,198, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0,152, 23,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 89, 68, + 0, 0, 0, 0, 0, 0,208, 65,154,216, 65, 55, 0, 0, 12, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 2, 0, 0, + 0, 0, 0, 0, 25, 0, 0, 0, 0,192, 11, 68, 0, 0,200, 65, 0,192, 11, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0, 48, 2, 26, 0, 48, 2, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 2, 0, 0, 93, 1, 0, 0,118, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 48, 2, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,152, 23,198, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0, 8, 25,198, 6, 0, 0, 0, 0, 40, 22,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 67, + 0, 0,112,193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 67, 0, 0,157,195, 0, 0, 0, 0,200, 0, 0, 0,217, 0, 0, 0, + 18, 0, 0, 0, 75, 1, 0, 0, 0, 0, 0, 0,199, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,199, 0, 0, 0, + 18, 0, 0, 0, 75, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 10, 6, 0, 0, 2, 0, 3, 3, 0, 0, 0, 4, 6, 0,217, 0, 76, 1,200, 0, 58, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 0, 0, 0,119, 1, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,217, 0, 76, 1, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 8, 25,198, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0,120, 26,198, 6, 0, 0, 0, 0,152, 23,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 47, 2, 0, 0, 47, 2, 0, 0,119, 1, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,120, 26,198, 6, 0, 0, 0, 0, +215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 25,198, 6, 0, 0, 0, 0, 0, 0, 16,193, 0, 0,130, 67, + 0, 0,160,192, 0, 0,160, 64, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 16,193, 0, 0, 32, 65, 0, 0, 0, 0, 17, 0, 0, 0, + 18, 0, 0, 0, 75, 1, 0, 0, 18, 0, 0, 0, 86, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 86, 1, 0, 0, + 18, 0, 0, 0, 75, 1, 0, 0,111, 18,131, 58,111, 18,131, 58, 0,124,146, 72, 0, 80, 67, 71, 0, 0, 0, 0, 0, 0, 0, 0, +105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 87, 1, 76, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,217, 0, 0, 0, 47, 2, 0, 0,119, 1, 0, 0,194, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 87, 1, 76, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,240, 0, 0, 0,232, 27,198, 6, 0, 0, 0, 0, +178, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 29,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,112, 0, 0, 0, + 40, 29,198, 6, 0, 0, 0, 0, 37, 1, 0, 0, 1, 0, 0, 0,104, 38,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65,160, 0, 0, 0,232, 29,198, 6, 0, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 56, 21,198, 6, 0, 0, 0, 0,200,251,197, 6, 0, 0, 0, 0,232,250,197, 6, 0, 0, 0, 0,152,249,197, 6, 0, 0, 0, 0, + 8,250,197, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 2, 0, 0,240, 4, 0, 0, 93, 1, 0, 0,194, 2, 0, 0, + 8, 8,192, 2,102, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 36,198, 6, 0, 0, 0, 0, +152, 36,198, 6, 0, 0, 0, 0,216, 30,198, 6, 0, 0, 0, 0, 40, 35,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, +216, 30,198, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 72, 32,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,245, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 48, 68, 0, 0, 0, 0, 0, 0,208, 65, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,191, 2, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,192, 47, 68, 0, 0,200, 65, 0,192, 47, 68, 0, 0,200, 65, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 0, 10, 0,192, 2, 26, 0,192, 2, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 2, 0, 0,240, 4, 0, 0, 93, 1, 0, 0,118, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 2, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, + 72, 32,198, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,184, 33,198, 6, 0, 0, 0, 0,216, 30,198, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 4, 0, 0,240, 4, 0, 0,119, 1, 0, 0,194, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, +184, 33,198, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 40, 35,198, 6, 0, 0, 0, 0, 72, 32,198, 6, 0, 0, 0, 0, + 0, 0,240,195, 0, 0,240, 67, 0, 0,135,195, 0, 0,135, 67,238, 33,143,196,238, 33,143, 68, 0, 0, 7,196, 0, 0, 7, 68, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,191, 2, 0, 0, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 59, 70, 0,128, 59, 70, +172,197, 39, 55, 0, 80,195, 71, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 4, 0, 0,192, 2, 76, 1,192, 2, 76, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 2, 0, 0,240, 4, 0, 0,119, 1, 0, 0,194, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 2, 76, 1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, + 40, 35,198, 6, 0, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 33,198, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 0, 0, 0, 0, 0, 65, + 0, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 75, 1, 0, 0, 18, 0, 0, 0,201, 2, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, + 18, 0, 0, 0,201, 2, 0, 0, 18, 0, 0, 0, 75, 1, 0, 0, 0, 0, 32, 65, 0, 0, 0, 63, 0,124,146, 72, 0, 0, 0, 66, + 10,215, 35, 60, 0, 0,200, 66,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0,202, 2, 76, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,240, 0, 0, 0, +152, 36,198, 6, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 64, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 83, 67, 0, 0,216, 11, 0, 0,104, 38,198, 6, 0, 0, 0, 0,171, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 83, 99,101,110,101, 0, +116, 97,103,101, 0, 97,105,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,136, 50,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, +248, 64,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 51,198, 6, 0, 0, 0, 0, 56, 52,198, 6, 0, 0, 0, 0, + 88, 51,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +168, 52,198, 6, 0, 0, 0, 0,136, 4,230, 0, 73,127, 0, 0, 17, 2, 24, 0, 90, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,192, 0, 0, 0, 68,172, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0,100, 0, 0, 0, + 0, 0, 1, 0, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 2,224, 1, 60, 0, + 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 6, 0, 50, 0,141, 0,128, 7, 56, 4, 8, 0, 8, 0, 24, 0, 17, 0, 0, 0, + 90, 0, 1, 0, 81, 0, 0, 0, 23, 0, 33, 0, 2, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 8, 0, 24, 0, 10, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 56,198, 6, 0, 0, 0, 0,136, 56,198, 6, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 1, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0, 0, 0, 5, 0, 2, 0, 1, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47,116,109,112, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 31, 5, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,205,204, 76, 63,205,204, 76, 63,205,204, 76, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0,128, 63, 0, 0,128, 63, +173, 2, 95, 0,154,153,217, 63, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0,180, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 66, 76, 69, 78, 68, 69, 82, 95, 82, 69, 78, 68, 69, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68,172, 0, 0, 0, 0,128, 63,102,166,171, 67, 0, 0,128, 63, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,128,155,194, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +128,230, 81, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,183,159, 6, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 2,224, 1, 60, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0,180, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 0,205,204,204, 61,154,153,153, 62,205,204, 76, 62,219, 15, 73, 63,102,102,102, 63, + 0, 0, 0, 64,154,153, 25, 63, 0, 0, 64, 65,102,102,166, 63, 0, 0, 0, 65, 0, 0,160, 65, 6, 0, 0, 0, 0, 0,192, 64, + 0, 0,128, 63, 0, 0, 0, 0,205,204, 28, 65, 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 1, 0,128, 0, 5, 0,218, 0, 0, 0, + 60, 0, 5, 0, 1, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,195,245, 28,193, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,128, 0, 0, 0,136, 50,198, 6, 0, 0, 0, 0, + 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88, 51,198, 6, 0, 0, 0, 0,143, 0, 0, 0, 1, 0, 0, 0, +200, 51,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,216, 2,222, 1, +104, 74,198, 6, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,200, 51,198, 6, 0, 0, 0, 0,143, 0, 0, 0, 1, 0, 0, 0, + 56, 52,198, 6, 0, 0, 0, 0, 88, 51,198, 6, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0,173, 3, 35, 3, +168, 81,198, 6, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 56, 52,198, 6, 0, 0, 0, 0,143, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,200, 51,198, 6, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0,161, 0, 65, 2, +200, 67,198, 6, 0, 0, 0, 0, 68, 65, 84, 65,232, 1, 0, 0,168, 52,198, 6, 0, 0, 0, 0,167, 0, 0, 0, 1, 0, 0, 0, +216, 54,198, 6, 0, 0, 0, 0, 88, 55,198, 6, 0, 0, 0, 0,216, 55,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 1, 0, 1, 0,205,204, 76, 63, 0, 0,180, 66, 9, 0, 1, 0, 0, 0,128, 63,111, 18,131, 58,205,204,204, 61, + 0, 0, 1, 0, 32, 0, 32, 0, 32, 0, 1, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 80, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 5, 0, 5, 0,255,255, + 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 66, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, + 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 66, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 66, + 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 66, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 66, + 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 10,215, 35, 60,205,204,204, 61, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 0,205,204,204, 61,205,204,204, 61, +102,102,166, 63, 0, 0,192, 63, 0, 0,240, 65, 72,225,122, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 67, 2, 0, 3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 35, 0, 0, 0,204,197,121, 63, 0, 0, 0, 63, 35, 0, 0, 0,204,197,121, 63, + 0, 0, 0, 63, 17, 0, 0, 0, 68, 65, 84, 65, 56, 0, 0, 0,216, 54,198, 6, 0, 0, 0, 0,164, 0, 0, 0, 1, 0, 0, 0, +152,227,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 1, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 0, 0, 0, + 88, 55,198, 6, 0, 0, 0, 0,164, 0, 0, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +200,200,255,128, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 0, 0, 0,216, 55,198, 6, 0, 0, 0, 0,162, 0, 0, 0, 1, 0, 0, 0, +136, 84,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,100,100,128, 1, 0, 0, 0,128, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0,155, 9, 25, 67,190, 23,237, 64, 75, 1,147, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65,120, 0, 0, 0,136, 56,198, 6, 0, 0, 0, 0,149, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 82,101,110,100,101,114, 76, 97,121,101,114, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255, 15, 0, 0, 0, 0, 0, +255,127, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 67, 65, 0, 0,200, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, + 22, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 67, 65, 67, 97,109,101,114, 97, 0, 97,109,101,114, 97, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 24, 42,215, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,243,206, 3, 0, 0, 0, 0,136,250,206, 3, 0, 0, 0, 0, 25, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 63,205,204,204, 61, 0, 0,200, 66, 0, 0, 12, 66,161, 14,234, 64, + 0, 0, 0, 63, 0, 0, 0, 66, 0, 0,144, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 0, 0, 16, 2, 0, 0, 56, 60,198, 6, 0, 0, 0, 0, + 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 8, 0, 0, 0,136, 12,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,168,182,117, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65,152, 0, 0, 0, 24, 42,215, 3, 0, 0, 0, 0,132, 0, 0, 0, 1, 0, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,247,255,239, 65, 0, 0,150, 66, +154,153, 25, 62, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,152, 62,198, 6, 0, 0, 0, 0, 2, 0, 0, 0, 46, 26,128, 63, + 25, 4,240, 65, 0, 0, 52, 66, 0, 0,128, 63, 0, 0, 64, 64,205,204, 76, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 64, 11, 3, 0, 1, 0, 0, 0, 0, 2, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, +111, 18,131, 58, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,204,204, 61,205,204, 76, 62, 10,215,163, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 79, 66, 0, 0,112, 5, 0, 0,168,225,217, 3, 0, 0, 0, 0, -129, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,219,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,136, 64,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 64, 1, 0, 0, +152, 62,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 2, 0, 1, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,243, 4, 53,191,242, 4, 53, 63,242, 4, 53,191,243, 4, 53, 63, + 40, 64,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 40, 64,198, 6, 0, 0, 0, 0, +117, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 40, 0, 0, 0,136, 64,198, 6, 0, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 87, 79, 0, 0, 24, 2, 0, 0,248, 64,198, 6, 0, 0, 0, 0,142, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 79, 87,111,114,108,100, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +114, 99, 80, 61,114, 99, 80, 61,114, 99, 80, 61,199, 54, 36, 60,199, 54, 36, 60,199, 54, 36, 60, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, +205,204, 28, 65, 0, 0, 0, 0, 0, 0, 32, 0,128, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 64, + 0, 0,200, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, + 0, 0,112, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0,128, 63,205,204, 76, 61, + 0, 0, 5, 0, 0, 0, 0, 0, 10,215,163, 59, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 88, 67,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 88, 67,198, 6, 0, 0, 0, 0, + 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0,112, 5, 0, 0,200, 67,198, 6, 0, 0, 0, 0, +129, 0, 0, 0, 1, 0, 0, 0,104, 74,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 67, 97,109,101,114, 97, 0, 97,109,101,114, 97, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,209,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 59,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,154,112,130, 64,183,178,128, 63,112,236,188, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,110,101,239, 64,150, 62,208,192, 78,255,170, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,229,123, 38, 63, 87, 43, 98, 61,229,229,238, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 42,254,141, 63,192, 57, 49, 60, 34,159, 80, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 54,236,148,190, 25,134,116, 63,236, 13, 98,189, 0, 0, 0, 0,221,102, 69,191, 57,174, 76,190, - 34,194, 26, 63, 0, 0, 0, 0, 37,255, 16, 63,241,161, 95, 62,164,111, 75, 63, 0, 0, 0, 0,154,112,130, 64,183,178,128, 63, -112,236,188, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0,222,149, 47, 63, 53, 70, 58, 63,222, 56, 49,188, 0, 0, 0, 0, 86,126,162,190,227,251,159, 62, + 55, 53,101, 63, 0, 0, 0, 0, 7,165, 39, 63,149, 84, 28,191, 51,247,227, 62, 0, 0, 0, 0,110,101,239, 64,150, 62,208,192, + 78,255,170, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 1, 0,128, 50, 0, 0, 0,179, 0, 0, 0, 0, 1, 0,128, 50, 1, 0,128, 63, - 1, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 0, 39, 1, 0, 0, 52, - 1, 0,128, 39, 0, 0,128, 63, 54,236,148,190,221,102, 69,191, 38,255, 16, 63, 0, 0, 0, 0, 24,134,116, 63, 57,174, 76,190, -239,161, 95, 62, 0, 0, 0, 0,237, 13, 98,189, 35,194, 26, 63,166,111, 75, 63, 0, 0, 0, 0,209, 19, 13, 63,241, 65,102,190, - 10, 10,231,192, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 1, 0,128, 63, 1, 0,128, 51, 1, 0, 0,179, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0,128, 63, + 1, 0,128, 51, 0, 0, 0, 0, 2, 0, 0,179, 2, 0, 0,167, 1, 0,128, 63, 0, 0, 0, 0, 1, 0, 0, 53, 1, 0, 0, 41, + 1, 0,128,168, 0, 0,128, 63,221,149, 47, 63, 86,126,162,190, 8,165, 39, 63, 0, 0, 0, 0, 51, 70, 58, 63,225,251,159, 62, +149, 84, 28,191, 0, 0, 0, 0,192, 56, 49,188, 55, 53,101, 63, 52,247,227, 62, 0, 0, 0, 0, 90, 38,173,190, 0,222,192,190, +152, 9, 52,193, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 68, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 56,180,150,201, 0, 0,128, 63, -169, 19,208, 60, 0, 0,128, 63,205,204,204, 62,229,208, 34, 62, 0, 0, 0, 0,143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 0, 1, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, +187,225, 16, 63, 0, 0,128, 63,205,204,204, 62,237, 54, 32, 63, 0, 0, 0, 0,143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 1, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,231,217, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 73,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,152, 0, 0, 0, -200,231,217, 3, 0, 0, 0, 0,132, 0, 0, 0, 1, 0, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +136, 73,198, 6, 0, 0, 0, 0,132, 0, 0, 0, 1, 0, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,204,204, 61,205,204, 76, 62, 10,215,163, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 0, 0, 77, 65, 0, 0,128, 3, 0, 0,152, 7,218, 3, 0, 0, 0, 0, 39, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 77, 65, 77, 97,116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 79, 66, 0, 0,112, 5, 0, 0,104, 74,198, 6, 0, 0, 0, 0,129, 0, 0, 0, 1, 0, 0, 0, +168, 81,198, 6, 0, 0, 0, 0,200, 67,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 79, 66, 67,117, 98,101, 0,112,104,101,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0,205,204, 76, 63,205,204, 76, 63,205,204, 76, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,205,204, 76, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 10,215, 35, 60, 0, 0, 0, 0, - 0, 0, 8, 0, 1, 0, 50, 0,205,204, 76, 62, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 16, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 63, 0, 0, 0, 0, 0, 0,160, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 2, 0, 2, 0, 50, 0, 0, 6, 0, 0,128, 63, 0, 0,128, 63, 18, 0, 18, 0, 10,215,163, 59, 10,215,163, 59, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 4, 0, 67, 0, 64, 3, 67, 0, 64, 3, 1, 0, 4, 0, 12, 0, 4, 0, 0, 0, 0, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 63, 0, 0,128, 64, 0, 0, 0, 63,205,204,204, 61, 0, 0, 0, 63,205,204,204, 61,205,204,204, 61, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,104,112,223, 0, 73,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, + 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 40, 80,198, 6, 0, 0, 0, 0,120, 80,198, 6, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 68, 0, 0, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 56,180,150,201, 0, 0,128, 63,169, 19,208, 60, 0, 0,128, 63, +205,204,204, 62,229,208, 34, 62, 0, 0, 0, 0,143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 5, 0, 1, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 80,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 63,225, 0, 73,127, 0, 0, +248, 81,225, 0, 73,127, 0, 0, 25, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 8, 0, 0, 0, 40, 80,198, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,120, 80,198, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,152, 0, 0, 0,200, 80,198, 6, 0, 0, 0, 0,132, 0, 0, 0, + 1, 0, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,204,204, 61, +205,204, 76, 62, 10,215,163, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 79, 66, 0, 0, +112, 5, 0, 0,168, 81,198, 6, 0, 0, 0, 0,129, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 74,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 60,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154,112,130, 64,183,178,128, 63,112,236,188, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,229,123, 38, 63, + 87, 43, 98, 61,229,229,238, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,236,148,190, 25,134,116, 63,236, 13, 98,189, + 0, 0, 0, 0,221,102, 69,191, 57,174, 76,190, 34,194, 26, 63, 0, 0, 0, 0, 37,255, 16, 63,241,161, 95, 62,164,111, 75, 63, + 0, 0, 0, 0,154,112,130, 64,183,178,128, 63,112,236,188, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 1, 0,128, 50, 0, 0, 0,179, + 0, 0, 0, 0, 1, 0,128, 50, 1, 0,128, 63, 1, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 1, 0, 0, 39, 1, 0, 0, 52, 1, 0,128, 39, 0, 0,128, 63, 54,236,148,190,221,102, 69,191, 38,255, 16, 63, + 0, 0, 0, 0, 24,134,116, 63, 57,174, 76,190,239,161, 95, 62, 0, 0, 0, 0,237, 13, 98,189, 35,194, 26, 63,166,111, 75, 63, + 0, 0, 0, 0,209, 19, 13, 63,241, 65,102,190, 10, 10,231,192, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 68, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, + 0, 0, 0, 0, 56,180,150,201, 0, 0,128, 63,169, 19,208, 60, 0, 0,128, 63,205,204,204, 62,229,208, 34, 62, 0, 0, 0, 0, +143,194,117, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 0, 1, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63,152, 11,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,104, 87,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,120,216, 3, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,111,148, 26, 63, -111,148, 26, 63,111,148, 26, 63,205,204, 76, 61,205,204,204, 61,102,102,166, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0,152, 11,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 68, 65, 84, 65,152, 0, 0, 0,104, 87,198, 6, 0, 0, 0, 0,132, 0, 0, 0, 1, 0, 0, 0, 0,192, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,204,204, 61,205,204, 76, 62, 10,215,163, 60, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 77, 65, 0, 0,128, 3, 0, 0, 72, 88,198, 6, + 0, 0, 0, 0, 39, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 90, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 65, 77, 97,116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,205,204, 76, 63,205,204, 76, 63,205,204, 76, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,205,204, 76, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 40, 0, 0, 0,152,120,216, 3, 0, 0, 0, 0, - 12, 0, 0, 0, 1, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 53, 0, 53, 0, - 88, 13,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 16, 0, 0, 88, 13,218, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 51, 2, 2, 2, 51, - 6, 6, 6,153, 6, 6, 6,153, 6, 6, 6,153, 4, 4, 4,102, 3, 3, 3,102, 2, 2, 2, 51, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 51, 8, 8, 8,153, 11, 11, 11,204, 13, 13, 13,255, 12, 12, 12,255, - 12, 12, 12,255, 11, 11, 11,255, 10, 10, 10,255, 10, 10, 10,255, 9, 9, 9,255, 9, 9, 9,255, 9, 9, 9,255, 4, 4, 4,102, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 3, 3, 51, 10, 10, 10,153, 18, 18, 18,255, 20, 20, 20,255, 22, 22, 22,255, 23, 23, 23,255, 22, 22, 22,255, - 20, 20, 20,255, 19, 19, 19,255, 16, 16, 16,255, 14, 14, 14,255, 11, 11, 11,255, 10, 10, 10,255, 9, 9, 9,255, 9, 9, 9,255, - 9, 9, 9,255, 8, 8, 8,204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 7, 7,102, 19, 19, 19,204, 27, 27, 27,255, 31, 31, 31,255, 32, 32, 32,255, 33, 33, 33,255, 33, 33, 33,255, 31, 31, 31,255, - 30, 30, 30,255, 27, 27, 27,255, 25, 25, 25,255, 22, 22, 22,255, 19, 19, 19,255, 16, 16, 16,255, 12, 12, 12,255, 10, 10, 10,255, - 10, 10, 10,255, 10, 10, 10,255, 10, 10, 10,255, 4, 4, 4,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13,153, - 29, 29, 29,255, 37, 37, 37,255, 40, 40, 40,255, 42, 42, 42,255, 42, 42, 42,255, 43, 43, 43,255, 41, 41, 41,255, 40, 40, 40,255, - 38, 38, 38,255, 36, 36, 36,255, 33, 33, 33,255, 30, 30, 30,255, 27, 27, 27,255, 24, 24, 24,255, 20, 20, 20,255, 16, 16, 16,255, - 12, 12, 12,255, 10, 10, 10,255, 10, 10, 10,255, 10, 10, 10,255, 7, 7, 7,153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13,102, 37, 37, 37,255, - 44, 44, 44,255, 48, 48, 48,255, 50, 50, 50,255, 51, 51, 51,255, 51, 51, 51,255, 50, 50, 50,255, 49, 49, 49,255, 48, 48, 48,255, - 45, 45, 45,255, 43, 43, 43,255, 41, 41, 41,255, 37, 37, 37,255, 34, 34, 34,255, 31, 31, 31,255, 28, 28, 28,255, 24, 24, 24,255, - 20, 20, 20,255, 15, 15, 15,255, 11, 11, 11,255, 10, 10, 10,255, 11, 11, 11,255, 7, 7, 7,153, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13,102, 41, 41, 41,255, 50, 50, 50,255, - 54, 54, 54,255, 57, 57, 57,255, 58, 58, 58,255, 59, 59, 59,255, 59, 59, 59,255, 58, 58, 58,255, 57, 57, 57,255, 55, 55, 55,255, - 53, 53, 53,255, 51, 51, 51,255, 48, 48, 48,255, 45, 45, 45,255, 41, 41, 41,255, 38, 38, 38,255, 35, 35, 35,255, 31, 31, 31,255, - 27, 27, 27,255, 23, 23, 23,255, 17, 17, 17,255, 12, 12, 12,255, 11, 11, 11,255, 11, 11, 11,255, 5, 5, 5,102, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, 36,204, 53, 53, 53,255, 59, 59, 59,255, - 63, 63, 63,255, 65, 65, 65,255, 66, 66, 66,255, 66, 66, 66,255, 66, 66, 66,255, 65, 65, 65,255, 64, 64, 64,255, 62, 62, 62,255, - 60, 60, 60,255, 57, 57, 57,255, 54, 54, 54,255, 51, 51, 51,255, 48, 48, 48,255, 44, 44, 44,255, 41, 41, 41,255, 37, 37, 37,255, - 33, 33, 33,255, 29, 29, 29,255, 24, 24, 24,255, 19, 19, 19,255, 13, 13, 13,255, 11, 11, 11,255, 12, 12, 12,255, 3, 3, 3, 51, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19,102, 56, 56, 56,255, 64, 64, 64,255, 68, 68, 68,255, - 71, 71, 71,255, 73, 73, 73,255, 74, 74, 74,255, 74, 74, 74,255, 73, 73, 73,255, 72, 72, 72,255, 71, 71, 71,255, 69, 69, 69,255, - 67, 67, 67,255, 64, 64, 64,255, 61, 61, 61,255, 58, 58, 58,255, 54, 54, 54,255, 50, 50, 50,255, 47, 47, 47,255, 43, 43, 43,255, - 39, 39, 39,255, 34, 34, 34,255, 30, 30, 30,255, 25, 25, 25,255, 19, 19, 19,255, 13, 13, 13,255, 12, 12, 12,255, 10, 10, 10,204, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54,255, 66, 66, 66,255, 72, 72, 72,255, 77, 77, 77,255, - 79, 79, 79,255, 81, 81, 81,255, 81, 81, 81,255, 81, 81, 81,255, 80, 80, 80,255, 79, 79, 79,255, 77, 77, 77,255, 75, 75, 75,255, - 73, 73, 73,255, 70, 70, 70,255, 67, 67, 67,255, 63, 63, 63,255, 60, 60, 60,255, 56, 56, 56,255, 52, 52, 52,255, 49, 49, 49,255, - 44, 44, 44,255, 40, 40, 40,255, 35, 35, 35,255, 30, 30, 30,255, 24, 24, 24,255, 18, 18, 18,255, 12, 12, 12,255, 12, 12, 12,255, - 6, 6, 6,102, 0, 0, 0, 0, 0, 0, 0, 0, 22, 22, 22,102, 67, 67, 67,255, 76, 76, 76,255, 81, 81, 81,255, 84, 84, 84,255, - 87, 87, 87,255, 88, 88, 88,255, 88, 88, 88,255, 88, 88, 88,255, 87, 87, 87,255, 86, 86, 86,255, 84, 84, 84,255, 82, 82, 82,255, - 79, 79, 79,255, 76, 76, 76,255, 73, 73, 73,255, 69, 69, 69,255, 65, 65, 65,255, 62, 62, 62,255, 58, 58, 58,255, 54, 54, 54,255, - 49, 49, 49,255, 45, 45, 45,255, 40, 40, 40,255, 35, 35, 35,255, 29, 29, 29,255, 23, 23, 23,255, 16, 16, 16,255, 12, 12, 12,255, - 12, 12, 12,204, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49,204, 76, 76, 76,255, 84, 84, 84,255, 89, 89, 89,255, 92, 92, 92,255, - 94, 94, 94,255, 95, 95, 95,255, 95, 95, 95,255, 95, 95, 95,255, 94, 94, 94,255, 93, 93, 93,255, 91, 91, 91,255, 88, 88, 88,255, - 85, 85, 85,255, 82, 82, 82,255, 79, 79, 79,255, 75, 75, 75,255, 71, 71, 71,255, 67, 67, 67,255, 63, 63, 63,255, 59, 59, 59,255, - 55, 55, 55,255, 50, 50, 50,255, 45, 45, 45,255, 40, 40, 40,255, 34, 34, 34,255, 28, 28, 28,255, 21, 21, 21,255, 13, 13, 13,255, - 14, 14, 14,255, 0, 0, 0, 0, 14, 14, 14,102, 70, 70, 70,255, 85, 85, 85,255, 92, 92, 92,255, 97, 97, 97,255,100,100,100,255, -102,102,102,255,102,102,102,255,103,103,103,255,102,102,102,255,101,101,101,255, 99, 99, 99,255, 97, 97, 97,255, 94, 94, 94,255, - 91, 91, 91,255, 88, 88, 88,255, 84, 84, 84,255, 81, 81, 81,255, 77, 77, 77,255, 72, 72, 72,255, 68, 68, 68,255, 64, 64, 64,255, - 59, 59, 59,255, 55, 55, 55,255, 50, 50, 50,255, 44, 44, 44,255, 39, 39, 39,255, 32, 32, 32,255, 25, 25, 25,255, 17, 17, 17,255, - 13, 13, 13,255, 7, 7, 7,102, 24, 24, 24,102, 80, 80, 80,255, 93, 93, 93,255,100,100,100,255,104,104,104,255,107,107,107,255, -109,109,109,255,109,109,109,255,109,109,109,255,109,109,109,255,107,107,107,255,106,106,106,255,103,103,103,255,100,100,100,255, - 97, 97, 97,255, 94, 94, 94,255, 90, 90, 90,255, 86, 86, 86,255, 82, 82, 82,255, 77, 77, 77,255, 73, 73, 73,255, 69, 69, 69,255, - 64, 64, 64,255, 59, 59, 59,255, 54, 54, 54,255, 49, 49, 49,255, 43, 43, 43,255, 36, 36, 36,255, 29, 29, 29,255, 21, 21, 21,255, - 14, 14, 14,255, 10, 10, 10,153, 29, 29, 29,102, 89, 89, 89,255,100,100,100,255,107,107,107,255,112,112,112,255,114,114,114,255, -116,116,116,255,116,116,116,255,116,116,116,255,115,115,115,255,114,114,114,255,112,112,112,255,110,110,110,255,107,107,107,255, -104,104,104,255,100,100,100,255, 96, 96, 96,255, 92, 92, 92,255, 87, 87, 87,255, 83, 83, 83,255, 78, 78, 78,255, 73, 73, 73,255, - 68, 68, 68,255, 63, 63, 63,255, 58, 58, 58,255, 52, 52, 52,255, 46, 46, 46,255, 40, 40, 40,255, 33, 33, 33,255, 24, 24, 24,255, - 17, 17, 17,255, 13, 13, 13,204, 46, 46, 46,153, 95, 95, 95,255,107,107,107,255,114,114,114,255,118,118,118,255,121,121,121,255, -122,122,122,255,123,123,123,255,123,123,123,255,122,122,122,255,122,122,122,255,120,120,120,255,118,118,118,255,114,114,114,255, -110,110,110,255,106,106,106,255,101,101,101,255, 97, 97, 97,255, 92, 92, 92,255, 87, 87, 87,255, 83, 83, 83,255, 78, 78, 78,255, - 73, 73, 73,255, 68, 68, 68,255, 62, 62, 62,255, 56, 56, 56,255, 50, 50, 50,255, 44, 44, 44,255, 36, 36, 36,255, 28, 28, 28,255, - 19, 19, 19,255, 12, 12, 12,204, 47, 47, 47,153,101,101,101,255,113,113,113,255,120,120,120,255,125,125,125,255,127,127,127,255, -129,129,129,255,130,130,130,255,130,130,130,255,131,131,131,255,131,131,131,255,131,131,131,255,129,129,129,255,125,125,125,255, -120,120,120,255,113,113,113,255,108,108,108,255,103,103,103,255, 97, 97, 97,255, 92, 92, 92,255, 87, 87, 87,255, 82, 82, 82,255, - 77, 77, 77,255, 72, 72, 72,255, 66, 66, 66,255, 60, 60, 60,255, 54, 54, 54,255, 47, 47, 47,255, 39, 39, 39,255, 31, 31, 31,255, - 22, 22, 22,255, 12, 12, 12,204, 48, 48, 48,153,106,106,106,255,118,118,118,255,126,126,126,255,131,131,131,255,134,134,134,255, -135,135,135,255,137,137,137,255,138,138,138,255,142,142,142,255,147,147,147,255,149,149,149,255,148,148,148,255,142,142,142,255, -133,133,133,255,124,124,124,255,115,115,115,255,108,108,108,255,102,102,102,255, 97, 97, 97,255, 92, 92, 92,255, 87, 87, 87,255, - 81, 81, 81,255, 75, 75, 75,255, 69, 69, 69,255, 63, 63, 63,255, 57, 57, 57,255, 49, 49, 49,255, 42, 42, 42,255, 33, 33, 33,255, - 24, 24, 24,255, 9, 9, 9,153, 32, 32, 32,102,109,109,109,255,123,123,123,255,131,131,131,255,136,136,136,255,140,140,140,255, -142,142,142,255,144,144,144,255,148,148,148,255,156,156,156,255,168,168,168,255,176,176,176,255,177,177,177,255,168,168,168,255, -153,153,153,255,137,137,137,255,124,124,124,255,114,114,114,255,107,107,107,255,101,101,101,255, 96, 96, 96,255, 90, 90, 90,255, - 85, 85, 85,255, 79, 79, 79,255, 72, 72, 72,255, 66, 66, 66,255, 59, 59, 59,255, 52, 52, 52,255, 44, 44, 44,255, 35, 35, 35,255, - 26, 26, 26,255, 10, 10, 10,153, 17, 17, 17, 51,110,110,110,255,127,127,127,255,136,136,136,255,142,142,142,255,145,145,145,255, -148,148,148,255,151,151,151,255,159,159,159,255,174,174,174,255,195,195,195,255,212,212,212,255,216,216,216,255,204,204,204,255, -179,179,179,255,154,154,154,255,135,135,135,255,121,121,121,255,112,112,112,255,106,106,106,255, 99, 99, 99,255, 94, 94, 94,255, - 88, 88, 88,255, 82, 82, 82,255, 76, 76, 76,255, 69, 69, 69,255, 62, 62, 62,255, 54, 54, 54,255, 46, 46, 46,255, 37, 37, 37,255, - 26, 26, 26,255, 6, 6, 6,102, 0, 0, 0, 0,107,107,107,255,130,130,130,255,140,140,140,255,146,146,146,255,150,150,150,255, -153,153,153,255,158,158,158,255,169,169,169,255,191,191,191,255,219,219,219,255,246,246,246,255,254,254,254,255,237,237,237,255, -204,204,204,255,170,170,170,255,145,145,145,255,127,127,127,255,117,117,117,255,110,110,110,255,103,103,103,255, 97, 97, 97,255, - 91, 91, 91,255, 85, 85, 85,255, 78, 78, 78,255, 71, 71, 71,255, 64, 64, 64,255, 55, 55, 55,255, 47, 47, 47,255, 37, 37, 37,255, - 25, 25, 25,255, 3, 3, 3, 51, 0, 0, 0, 0, 65, 65, 65,153,129,129,129,255,142,142,142,255,149,149,149,255,154,154,154,255, -158,158,158,255,163,163,163,255,176,176,176,255,199,199,199,255,232,232,232,255,255,255,255,255,255,255,255,255,255,255,255,255, -220,220,220,255,181,181,181,255,151,151,151,255,132,132,132,255,121,121,121,255,113,113,113,255,106,106,106,255,100,100,100,255, - 94, 94, 94,255, 87, 87, 87,255, 80, 80, 80,255, 73, 73, 73,255, 65, 65, 65,255, 57, 57, 57,255, 48, 48, 48,255, 38, 38, 38,255, - 16, 16, 16,153, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 51,127,127,127,255,143,143,143,255,152,152,152,255,157,157,157,255, -161,161,161,255,165,165,165,255,177,177,177,255,198,198,198,255,227,227,227,255,253,253,253,255,255,255,255,255,250,250,250,255, -217,217,217,255,181,181,181,255,153,153,153,255,135,135,135,255,124,124,124,255,117,117,117,255,110,110,110,255,103,103,103,255, - 96, 96, 96,255, 89, 89, 89,255, 82, 82, 82,255, 74, 74, 74,255, 66, 66, 66,255, 57, 57, 57,255, 48, 48, 48,255, 35, 35, 35,255, - 10, 10, 10,153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 93, 93,204,141,141,141,255,153,153,153,255,159,159,159,255, -163,163,163,255,167,167,167,255,174,174,174,255,188,188,188,255,209,209,209,255,228,228,228,255,234,234,234,255,224,224,224,255, -200,200,200,255,173,173,173,255,151,151,151,255,136,136,136,255,127,127,127,255,119,119,119,255,112,112,112,255,105,105,105,255, - 98, 98, 98,255, 90, 90, 90,255, 83, 83, 83,255, 75, 75, 75,255, 66, 66, 66,255, 57, 57, 57,255, 46, 46, 46,255, 24, 24, 24,204, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 51,134,134,134,255,151,151,151,255,160,160,160,255, -164,164,164,255,167,167,167,255,171,171,171,255,178,178,178,255,189,189,189,255,200,200,200,255,202,202,202,255,195,195,195,255, -180,180,180,255,163,163,163,255,148,148,148,255,137,137,137,255,129,129,129,255,121,121,121,255,114,114,114,255,107,107,107,255, - 99, 99, 99,255, 91, 91, 91,255, 83, 83, 83,255, 74, 74, 74,255, 65, 65, 65,255, 55, 55, 55,255, 41, 41, 41,255, 7, 7, 7, 51, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49,102,145,145,145,255,157,157,157,255, -164,164,164,255,167,167,167,255,170,170,170,255,172,172,172,255,176,176,176,255,180,180,180,255,179,179,179,255,174,174,174,255, -165,165,165,255,155,155,155,255,145,145,145,255,137,137,137,255,130,130,130,255,122,122,122,255,115,115,115,255,107,107,107,255, - 99, 99, 99,255, 91, 91, 91,255, 82, 82, 82,255, 73, 73, 73,255, 63, 63, 63,255, 50, 50, 50,255, 22, 22, 22,153, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 78, 78,153,149,149,149,255, -160,160,160,255,166,166,166,255,168,168,168,255,169,169,169,255,170,170,170,255,169,169,169,255,167,167,167,255,164,164,164,255, -158,158,158,255,151,151,151,255,144,144,144,255,137,137,137,255,130,130,130,255,123,123,123,255,115,115,115,255,106,106,106,255, - 98, 98, 98,255, 89, 89, 89,255, 80, 80, 80,255, 70, 70, 70,255, 58, 58, 58,255, 27, 27, 27,153, 3, 3, 3, 51, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80,153, -150,150,150,255,160,160,160,255,165,165,165,255,167,167,167,255,167,167,167,255,166,166,166,255,163,163,163,255,160,160,160,255, -155,155,155,255,149,149,149,255,143,143,143,255,137,137,137,255,129,129,129,255,121,121,121,255,113,113,113,255,105,105,105,255, - 96, 96, 96,255, 86, 86, 86,255, 76, 76, 76,255, 63, 63, 63,255, 38, 38, 38,204, 7, 7, 7, 51, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 10,215, 35, 60, 0, 0, 0, 0, 0, 0, 8, 0, 1, 0, 50, 0,205,204, 76, 62, 0, 0,128, 63, 0, 0,128, 63, +205,204, 76, 62, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 63, 0, 0, 0, 0, + 0, 0,160, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 2, 0, 2, 0, 50, 0, 0, 6, 0, 0,128, 63, 0, 0,128, 63, + 18, 0, 18, 0, 10,215,163, 59, 10,215,163, 59, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 4, 0, 67, 0, 64, 3, 67, 0, 64, 3, + 1, 0, 4, 0, 12, 0, 4, 0, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0,128, 64, 0, 0, 0, 63,205,204,204, 61, + 0, 0, 0, 63,205,204,204, 61,205,204,204, 61, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 24, 92,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 93,198, 6, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63,111,148, 26, 63,111,148, 26, 63,111,148, 26, 63,205,204, 76, 61,205,204,204, 61,102,102,166, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 24, 92,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,110,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 40, 0, 0, 0,152, 93,198, 6, 0, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, 53, 0, 53, 0, 8, 94,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 16, 0, 0, 8, 94,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 2, 51, 2, 2, 2, 51, 6, 6, 6,153, 6, 6, 6,153, 6, 6, 6,153, 4, 4, 4,102, 3, 3, 3,102, + 2, 2, 2, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 51, 8, 8, 8,153, + 11, 11, 11,204, 13, 13, 13,255, 12, 12, 12,255, 12, 12, 12,255, 11, 11, 11,255, 10, 10, 10,255, 10, 10, 10,255, 9, 9, 9,255, + 9, 9, 9,255, 9, 9, 9,255, 4, 4, 4,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 51, 10, 10, 10,153, 18, 18, 18,255, 20, 20, 20,255, + 22, 22, 22,255, 23, 23, 23,255, 22, 22, 22,255, 20, 20, 20,255, 19, 19, 19,255, 16, 16, 16,255, 14, 14, 14,255, 11, 11, 11,255, + 10, 10, 10,255, 9, 9, 9,255, 9, 9, 9,255, 9, 9, 9,255, 8, 8, 8,204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7,102, 19, 19, 19,204, 27, 27, 27,255, 31, 31, 31,255, 32, 32, 32,255, + 33, 33, 33,255, 33, 33, 33,255, 31, 31, 31,255, 30, 30, 30,255, 27, 27, 27,255, 25, 25, 25,255, 22, 22, 22,255, 19, 19, 19,255, + 16, 16, 16,255, 12, 12, 12,255, 10, 10, 10,255, 10, 10, 10,255, 10, 10, 10,255, 10, 10, 10,255, 4, 4, 4,102, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13,153, 29, 29, 29,255, 37, 37, 37,255, 40, 40, 40,255, 42, 42, 42,255, 42, 42, 42,255, + 43, 43, 43,255, 41, 41, 41,255, 40, 40, 40,255, 38, 38, 38,255, 36, 36, 36,255, 33, 33, 33,255, 30, 30, 30,255, 27, 27, 27,255, + 24, 24, 24,255, 20, 20, 20,255, 16, 16, 16,255, 12, 12, 12,255, 10, 10, 10,255, 10, 10, 10,255, 10, 10, 10,255, 7, 7, 7,153, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 13, 13, 13,102, 37, 37, 37,255, 44, 44, 44,255, 48, 48, 48,255, 50, 50, 50,255, 51, 51, 51,255, 51, 51, 51,255, + 50, 50, 50,255, 49, 49, 49,255, 48, 48, 48,255, 45, 45, 45,255, 43, 43, 43,255, 41, 41, 41,255, 37, 37, 37,255, 34, 34, 34,255, + 31, 31, 31,255, 28, 28, 28,255, 24, 24, 24,255, 20, 20, 20,255, 15, 15, 15,255, 11, 11, 11,255, 10, 10, 10,255, 11, 11, 11,255, + 7, 7, 7,153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13, 13, 13,102, 41, 41, 41,255, 50, 50, 50,255, 54, 54, 54,255, 57, 57, 57,255, 58, 58, 58,255, 59, 59, 59,255, 59, 59, 59,255, + 58, 58, 58,255, 57, 57, 57,255, 55, 55, 55,255, 53, 53, 53,255, 51, 51, 51,255, 48, 48, 48,255, 45, 45, 45,255, 41, 41, 41,255, + 38, 38, 38,255, 35, 35, 35,255, 31, 31, 31,255, 27, 27, 27,255, 23, 23, 23,255, 17, 17, 17,255, 12, 12, 12,255, 11, 11, 11,255, + 11, 11, 11,255, 5, 5, 5,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 36, 36,204, 53, 53, 53,255, 59, 59, 59,255, 63, 63, 63,255, 65, 65, 65,255, 66, 66, 66,255, 66, 66, 66,255, 66, 66, 66,255, + 65, 65, 65,255, 64, 64, 64,255, 62, 62, 62,255, 60, 60, 60,255, 57, 57, 57,255, 54, 54, 54,255, 51, 51, 51,255, 48, 48, 48,255, + 44, 44, 44,255, 41, 41, 41,255, 37, 37, 37,255, 33, 33, 33,255, 29, 29, 29,255, 24, 24, 24,255, 19, 19, 19,255, 13, 13, 13,255, + 11, 11, 11,255, 12, 12, 12,255, 3, 3, 3, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19,102, + 56, 56, 56,255, 64, 64, 64,255, 68, 68, 68,255, 71, 71, 71,255, 73, 73, 73,255, 74, 74, 74,255, 74, 74, 74,255, 73, 73, 73,255, + 72, 72, 72,255, 71, 71, 71,255, 69, 69, 69,255, 67, 67, 67,255, 64, 64, 64,255, 61, 61, 61,255, 58, 58, 58,255, 54, 54, 54,255, + 50, 50, 50,255, 47, 47, 47,255, 43, 43, 43,255, 39, 39, 39,255, 34, 34, 34,255, 30, 30, 30,255, 25, 25, 25,255, 19, 19, 19,255, + 13, 13, 13,255, 12, 12, 12,255, 10, 10, 10,204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54,255, + 66, 66, 66,255, 72, 72, 72,255, 77, 77, 77,255, 79, 79, 79,255, 81, 81, 81,255, 81, 81, 81,255, 81, 81, 81,255, 80, 80, 80,255, + 79, 79, 79,255, 77, 77, 77,255, 75, 75, 75,255, 73, 73, 73,255, 70, 70, 70,255, 67, 67, 67,255, 63, 63, 63,255, 60, 60, 60,255, + 56, 56, 56,255, 52, 52, 52,255, 49, 49, 49,255, 44, 44, 44,255, 40, 40, 40,255, 35, 35, 35,255, 30, 30, 30,255, 24, 24, 24,255, + 18, 18, 18,255, 12, 12, 12,255, 12, 12, 12,255, 6, 6, 6,102, 0, 0, 0, 0, 0, 0, 0, 0, 22, 22, 22,102, 67, 67, 67,255, + 76, 76, 76,255, 81, 81, 81,255, 84, 84, 84,255, 87, 87, 87,255, 88, 88, 88,255, 88, 88, 88,255, 88, 88, 88,255, 87, 87, 87,255, + 86, 86, 86,255, 84, 84, 84,255, 82, 82, 82,255, 79, 79, 79,255, 76, 76, 76,255, 73, 73, 73,255, 69, 69, 69,255, 65, 65, 65,255, + 62, 62, 62,255, 58, 58, 58,255, 54, 54, 54,255, 49, 49, 49,255, 45, 45, 45,255, 40, 40, 40,255, 35, 35, 35,255, 29, 29, 29,255, + 23, 23, 23,255, 16, 16, 16,255, 12, 12, 12,255, 12, 12, 12,204, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49,204, 76, 76, 76,255, + 84, 84, 84,255, 89, 89, 89,255, 92, 92, 92,255, 94, 94, 94,255, 95, 95, 95,255, 95, 95, 95,255, 95, 95, 95,255, 94, 94, 94,255, + 93, 93, 93,255, 91, 91, 91,255, 88, 88, 88,255, 85, 85, 85,255, 82, 82, 82,255, 79, 79, 79,255, 75, 75, 75,255, 71, 71, 71,255, + 67, 67, 67,255, 63, 63, 63,255, 59, 59, 59,255, 55, 55, 55,255, 50, 50, 50,255, 45, 45, 45,255, 40, 40, 40,255, 34, 34, 34,255, + 28, 28, 28,255, 21, 21, 21,255, 13, 13, 13,255, 14, 14, 14,255, 0, 0, 0, 0, 14, 14, 14,102, 70, 70, 70,255, 85, 85, 85,255, + 92, 92, 92,255, 97, 97, 97,255,100,100,100,255,102,102,102,255,102,102,102,255,103,103,103,255,102,102,102,255,101,101,101,255, + 99, 99, 99,255, 97, 97, 97,255, 94, 94, 94,255, 91, 91, 91,255, 88, 88, 88,255, 84, 84, 84,255, 81, 81, 81,255, 77, 77, 77,255, + 72, 72, 72,255, 68, 68, 68,255, 64, 64, 64,255, 59, 59, 59,255, 55, 55, 55,255, 50, 50, 50,255, 44, 44, 44,255, 39, 39, 39,255, + 32, 32, 32,255, 25, 25, 25,255, 17, 17, 17,255, 13, 13, 13,255, 7, 7, 7,102, 24, 24, 24,102, 80, 80, 80,255, 93, 93, 93,255, +100,100,100,255,104,104,104,255,107,107,107,255,109,109,109,255,109,109,109,255,109,109,109,255,109,109,109,255,107,107,107,255, +106,106,106,255,103,103,103,255,100,100,100,255, 97, 97, 97,255, 94, 94, 94,255, 90, 90, 90,255, 86, 86, 86,255, 82, 82, 82,255, + 77, 77, 77,255, 73, 73, 73,255, 69, 69, 69,255, 64, 64, 64,255, 59, 59, 59,255, 54, 54, 54,255, 49, 49, 49,255, 43, 43, 43,255, + 36, 36, 36,255, 29, 29, 29,255, 21, 21, 21,255, 14, 14, 14,255, 10, 10, 10,153, 29, 29, 29,102, 89, 89, 89,255,100,100,100,255, +107,107,107,255,112,112,112,255,114,114,114,255,116,116,116,255,116,116,116,255,116,116,116,255,115,115,115,255,114,114,114,255, +112,112,112,255,110,110,110,255,107,107,107,255,104,104,104,255,100,100,100,255, 96, 96, 96,255, 92, 92, 92,255, 87, 87, 87,255, + 83, 83, 83,255, 78, 78, 78,255, 73, 73, 73,255, 68, 68, 68,255, 63, 63, 63,255, 58, 58, 58,255, 52, 52, 52,255, 46, 46, 46,255, + 40, 40, 40,255, 33, 33, 33,255, 24, 24, 24,255, 17, 17, 17,255, 13, 13, 13,204, 46, 46, 46,153, 95, 95, 95,255,107,107,107,255, +114,114,114,255,118,118,118,255,121,121,121,255,122,122,122,255,123,123,123,255,123,123,123,255,122,122,122,255,122,122,122,255, +120,120,120,255,118,118,118,255,114,114,114,255,110,110,110,255,106,106,106,255,101,101,101,255, 97, 97, 97,255, 92, 92, 92,255, + 87, 87, 87,255, 83, 83, 83,255, 78, 78, 78,255, 73, 73, 73,255, 68, 68, 68,255, 62, 62, 62,255, 56, 56, 56,255, 50, 50, 50,255, + 44, 44, 44,255, 36, 36, 36,255, 28, 28, 28,255, 19, 19, 19,255, 12, 12, 12,204, 47, 47, 47,153,101,101,101,255,113,113,113,255, +120,120,120,255,125,125,125,255,127,127,127,255,129,129,129,255,130,130,130,255,130,130,130,255,131,131,131,255,131,131,131,255, +131,131,131,255,129,129,129,255,125,125,125,255,120,120,120,255,113,113,113,255,108,108,108,255,103,103,103,255, 97, 97, 97,255, + 92, 92, 92,255, 87, 87, 87,255, 82, 82, 82,255, 77, 77, 77,255, 72, 72, 72,255, 66, 66, 66,255, 60, 60, 60,255, 54, 54, 54,255, + 47, 47, 47,255, 39, 39, 39,255, 31, 31, 31,255, 22, 22, 22,255, 12, 12, 12,204, 48, 48, 48,153,106,106,106,255,118,118,118,255, +126,126,126,255,131,131,131,255,134,134,134,255,135,135,135,255,137,137,137,255,138,138,138,255,142,142,142,255,147,147,147,255, +149,149,149,255,148,148,148,255,142,142,142,255,133,133,133,255,124,124,124,255,115,115,115,255,108,108,108,255,102,102,102,255, + 97, 97, 97,255, 92, 92, 92,255, 87, 87, 87,255, 81, 81, 81,255, 75, 75, 75,255, 69, 69, 69,255, 63, 63, 63,255, 57, 57, 57,255, + 49, 49, 49,255, 42, 42, 42,255, 33, 33, 33,255, 24, 24, 24,255, 9, 9, 9,153, 32, 32, 32,102,109,109,109,255,123,123,123,255, +131,131,131,255,136,136,136,255,140,140,140,255,142,142,142,255,144,144,144,255,148,148,148,255,156,156,156,255,168,168,168,255, +176,176,176,255,177,177,177,255,168,168,168,255,153,153,153,255,137,137,137,255,124,124,124,255,114,114,114,255,107,107,107,255, +101,101,101,255, 96, 96, 96,255, 90, 90, 90,255, 85, 85, 85,255, 79, 79, 79,255, 72, 72, 72,255, 66, 66, 66,255, 59, 59, 59,255, + 52, 52, 52,255, 44, 44, 44,255, 35, 35, 35,255, 26, 26, 26,255, 10, 10, 10,153, 17, 17, 17, 51,110,110,110,255,127,127,127,255, +136,136,136,255,142,142,142,255,145,145,145,255,148,148,148,255,151,151,151,255,159,159,159,255,174,174,174,255,195,195,195,255, +212,212,212,255,216,216,216,255,204,204,204,255,179,179,179,255,154,154,154,255,135,135,135,255,121,121,121,255,112,112,112,255, +106,106,106,255, 99, 99, 99,255, 94, 94, 94,255, 88, 88, 88,255, 82, 82, 82,255, 76, 76, 76,255, 69, 69, 69,255, 62, 62, 62,255, + 54, 54, 54,255, 46, 46, 46,255, 37, 37, 37,255, 26, 26, 26,255, 6, 6, 6,102, 0, 0, 0, 0,107,107,107,255,130,130,130,255, +140,140,140,255,146,146,146,255,150,150,150,255,153,153,153,255,158,158,158,255,169,169,169,255,191,191,191,255,219,219,219,255, +246,246,246,255,254,254,254,255,237,237,237,255,204,204,204,255,170,170,170,255,145,145,145,255,127,127,127,255,117,117,117,255, +110,110,110,255,103,103,103,255, 97, 97, 97,255, 91, 91, 91,255, 85, 85, 85,255, 78, 78, 78,255, 71, 71, 71,255, 64, 64, 64,255, + 55, 55, 55,255, 47, 47, 47,255, 37, 37, 37,255, 25, 25, 25,255, 3, 3, 3, 51, 0, 0, 0, 0, 65, 65, 65,153,129,129,129,255, +142,142,142,255,149,149,149,255,154,154,154,255,158,158,158,255,163,163,163,255,176,176,176,255,199,199,199,255,232,232,232,255, +255,255,255,255,255,255,255,255,255,255,255,255,220,220,220,255,181,181,181,255,151,151,151,255,132,132,132,255,121,121,121,255, +113,113,113,255,106,106,106,255,100,100,100,255, 94, 94, 94,255, 87, 87, 87,255, 80, 80, 80,255, 73, 73, 73,255, 65, 65, 65,255, + 57, 57, 57,255, 48, 48, 48,255, 38, 38, 38,255, 16, 16, 16,153, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 51,127,127,127,255, +143,143,143,255,152,152,152,255,157,157,157,255,161,161,161,255,165,165,165,255,177,177,177,255,198,198,198,255,227,227,227,255, +253,253,253,255,255,255,255,255,250,250,250,255,217,217,217,255,181,181,181,255,153,153,153,255,135,135,135,255,124,124,124,255, +117,117,117,255,110,110,110,255,103,103,103,255, 96, 96, 96,255, 89, 89, 89,255, 82, 82, 82,255, 74, 74, 74,255, 66, 66, 66,255, + 57, 57, 57,255, 48, 48, 48,255, 35, 35, 35,255, 10, 10, 10,153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 93, 93,204, +141,141,141,255,153,153,153,255,159,159,159,255,163,163,163,255,167,167,167,255,174,174,174,255,188,188,188,255,209,209,209,255, +228,228,228,255,234,234,234,255,224,224,224,255,200,200,200,255,173,173,173,255,151,151,151,255,136,136,136,255,127,127,127,255, +119,119,119,255,112,112,112,255,105,105,105,255, 98, 98, 98,255, 90, 90, 90,255, 83, 83, 83,255, 75, 75, 75,255, 66, 66, 66,255, + 57, 57, 57,255, 46, 46, 46,255, 24, 24, 24,204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 51, +134,134,134,255,151,151,151,255,160,160,160,255,164,164,164,255,167,167,167,255,171,171,171,255,178,178,178,255,189,189,189,255, +200,200,200,255,202,202,202,255,195,195,195,255,180,180,180,255,163,163,163,255,148,148,148,255,137,137,137,255,129,129,129,255, +121,121,121,255,114,114,114,255,107,107,107,255, 99, 99, 99,255, 91, 91, 91,255, 83, 83, 83,255, 74, 74, 74,255, 65, 65, 65,255, + 55, 55, 55,255, 41, 41, 41,255, 7, 7, 7, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 49, 49, 49,102,145,145,145,255,157,157,157,255,164,164,164,255,167,167,167,255,170,170,170,255,172,172,172,255,176,176,176,255, +180,180,180,255,179,179,179,255,174,174,174,255,165,165,165,255,155,155,155,255,145,145,145,255,137,137,137,255,130,130,130,255, +122,122,122,255,115,115,115,255,107,107,107,255, 99, 99, 99,255, 91, 91, 91,255, 82, 82, 82,255, 73, 73, 73,255, 63, 63, 63,255, + 50, 50, 50,255, 22, 22, 22,153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 78, 78, 78,153,149,149,149,255,160,160,160,255,166,166,166,255,168,168,168,255,169,169,169,255,170,170,170,255, +169,169,169,255,167,167,167,255,164,164,164,255,158,158,158,255,151,151,151,255,144,144,144,255,137,137,137,255,130,130,130,255, +123,123,123,255,115,115,115,255,106,106,106,255, 98, 98, 98,255, 89, 89, 89,255, 80, 80, 80,255, 70, 70, 70,255, 58, 58, 58,255, + 27, 27, 27,153, 3, 3, 3, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80,153,150,150,150,255,160,160,160,255,165,165,165,255,167,167,167,255,167,167,167,255, +166,166,166,255,163,163,163,255,160,160,160,255,155,155,155,255,149,149,149,255,143,143,143,255,137,137,137,255,129,129,129,255, +121,121,121,255,113,113,113,255,105,105,105,255, 96, 96, 96,255, 86, 86, 86,255, 76, 76, 76,255, 63, 63, 63,255, 38, 38, 38,204, + 7, 7, 7, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 78, 78,153,147,147,147,255,157,157,157,255,161,161,161,255,163,163,163,255, +162,162,162,255,160,160,160,255,157,157,157,255,152,152,152,255,147,147,147,255,141,141,141,255,135,135,135,255,127,127,127,255, +119,119,119,255,110,110,110,255,101,101,101,255, 91, 91, 91,255, 80, 80, 80,255, 66, 66, 66,255, 32, 32, 32,153, 7, 7, 7, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 78, 78, 78,153,147,147,147,255,157,157,157,255,161,161,161,255,163,163,163,255,162,162,162,255,160,160,160,255,157,157,157,255, -152,152,152,255,147,147,147,255,141,141,141,255,135,135,135,255,127,127,127,255,119,119,119,255,110,110,110,255,101,101,101,255, - 91, 91, 91,255, 80, 80, 80,255, 66, 66, 66,255, 32, 32, 32,153, 7, 7, 7, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,134,134,134,255,148,148,148,255,154,154,154,255, +155,155,155,255,154,154,154,255,152,152,152,255,147,147,147,255,142,142,142,255,136,136,136,255,130,130,130,255,122,122,122,255, +114,114,114,255,104,104,104,255, 93, 93, 93,255, 81, 81, 81,255, 54, 54, 54,204, 22, 22, 22,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,134,134,134,255,148,148,148,255,154,154,154,255,155,155,155,255,154,154,154,255,152,152,152,255, -147,147,147,255,142,142,142,255,136,136,136,255,130,130,130,255,122,122,122,255,114,114,114,255,104,104,104,255, 93, 93, 93,255, - 81, 81, 81,255, 54, 54, 54,204, 22, 22, 22,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 73, 73,153,103,103,103,204, +137,137,137,255,140,140,140,255,140,140,140,255,137,137,137,255,133,133,133,255,127,127,127,255,120,120,120,255,113,113,113,255, +102,102,102,255, 91, 91, 91,255, 64, 64, 64,204, 28, 28, 28,102, 6, 6, 6, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 73, 73,153,103,103,103,204,137,137,137,255,140,140,140,255,140,140,140,255, -137,137,137,255,133,133,133,255,127,127,127,255,120,120,120,255,113,113,113,255,102,102,102,255, 91, 91, 91,255, 64, 64, 64,204, - 28, 28, 28,102, 6, 6, 6, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46,102, 72, 72, 72,153, - 72, 72, 72,153, 92, 92, 92,204, 88, 88, 88,204, 81, 81, 81,204, 54, 54, 54,153, 35, 35, 35,102, 16, 16, 16, 51, 0, 0, 0, 0, + 0, 0, 0, 0, 46, 46, 46,102, 72, 72, 72,153, 72, 72, 72,153, 92, 92, 92,204, 88, 88, 88,204, 81, 81, 81,204, 54, 54, 54,153, + 35, 35, 35,102, 16, 16, 16, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 0, 0,168, 1, 0, 0, 88,110,198, 6, + 0, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 84,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 0, 0,168, 1, 0, 0,216, 29,218, 3, 0, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0,160, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 64, 0, 0, 0, 64, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 7, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 8, 0, 0, 0, 1, 0, 1, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,205,204,204, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 84, 69, 84,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,112,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72,112,198, 6, + 0, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 16, 0, 15, 0,184,112,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 16, 0, 0,184,112,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 62, 0, 0,160, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 64, 0, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 8, 0, 0, 0, 1, 0, 1, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -205,204,204, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 72,121,216, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 72,121,216, 3, 0, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, - 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 16, 0, 15, 0, 8, 32,218, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 16, 0, 0, 8, 32,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6008,54 +6544,125 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 0, 0,232, 4, 0, 0, 8,129,198, 6, 0, 0, 0, 0, 50, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 69, 67,117, 98,101, 0,112,104,101,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,134,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,147,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,143,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,143,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,136,198, 6, 0, 0, 0, 0, 24,140,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,136,134,198, 6, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 0, 5, 0, 0, 0, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,137,198, 6, 0, 0, 0, 0,255,255,255,255, +255,255,255,255,255,255,255,255, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 77, 69, 0, 0,232, 4, 0, 0,136, 48,218, 3, 0, 0, 0, 0, 50, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 67,117, 98,101, 0,112, -104,101,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 13,217, 3, 0, 0, 0, 0,200,218,208, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 56, 98,198, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 2,211, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,232,217, 3, 0, 0, 0, 0, - 24, 7,163, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,122,209, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 53,218, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,145,198, 6, 0, 0, 0, 0,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,248,140,198, 6, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 0,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 2, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 51, 0, 0, 0,180, 0, 0, 0, 0, 4, 0,128, 63, + 4, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 67, 0, 30, 0, 6, 0, 1, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 8, 0, 0, 0, 56,134,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 72, 88,198, 6, 0, 0, 0, 0, 68, 65, 84, 65, 8, 2, 0, 0,136,134,198, 6, 0, 0, 0, 0,124, 1, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,216,136,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,216,136,198, 6, 0, 0, 0, 0, 56, 0, 0, 0, + 8, 0, 0, 0, 0, 0,128, 63,255,255,127, 63, 0, 0,128,191,230, 73,230, 73, 26,182, 1, 0, 0, 0,128, 63, 0, 0,128,191, + 0, 0,128,191,230, 73, 26,182, 26,182, 1, 0, 1, 0,128,191,253,255,127,191, 0, 0,128,191, 26,182, 26,182, 26,182, 1, 0, +250,255,127,191, 3, 0,128, 63, 0, 0,128,191, 26,182,230, 73, 26,182, 1, 0, 4, 0,128, 63,247,255,127, 63, 0, 0,128, 63, +230, 73,230, 73,230, 73, 1, 0,245,255,127, 63, 5, 0,128,191, 0, 0,128, 63,230, 73, 26,182,230, 73, 1, 0, 3, 0,128,191, +250,255,127,191, 0, 0,128, 63, 26,182, 26,182,230, 73, 1, 0,255,255,127,191, 0, 0,128, 63, 0, 0,128, 63, 26,182,230, 73, +230, 73, 1, 0, 68, 65, 84, 65, 8, 2, 0, 0,200,137,198, 6, 0, 0, 0, 0,124, 1, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,140,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,144, 0, 0, 0, 24,140,198, 6, 0, 0, 0, 0, 53, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 35, 0, + 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 35, 0, 1, 0, 0, 0, 5, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 35, 0, 2, 0, 0, 0, 6, 0, 0, 0, 0, 0, 35, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 35, 0, + 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0, 68, 65, 84, 65, 8, 2, 0, 0,248,140,198, 6, 0, 0, 0, 0,124, 1, 0, 0, + 5, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67,111,108, 0, 32, 70, 97, 99,101, 45, 86,101,114,116,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 72,143,198, 6, 0, 0, 0, 0, 26, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 71,111,110, 32, 70, 97, 99,101, 45, 86,101,114,116,101,120, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,143,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 0, 0, 0, 72,143,198, 6, 0, 0, 0, 0, 62, 0, 0, 0, + 24, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255, 1, 0, 0, 0, 5, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,136, 56,218, 3, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 0, 5, 0, 0, 0, - 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,156,173, 15, 0, 0, 0, 0, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,255,255,255,255, 1, 0, 0, 0,255,255,255,255, -255,255,255,255, 2, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255, 3, 0, 0, 0, 5, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 56, 64,218, 3, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 0, 5, 0, 0, 0, - 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 61,218, 3, 0, 0, 0, 0, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255, 1, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255, 2, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 51, 0, 0, 0,180, 0, 0, 0, 0, 4, 0,128, 63, 4, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 67, 0, 30, 0, 6, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 8, 0, 0, 0, 24, 13,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,152, 7,218, 3, 0, 0, 0, 0, - 68, 65, 84, 65, 8, 2, 0, 0,248, 53,218, 3, 0, 0, 0, 0,124, 1, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255,255,255,255, 68, 65, 84, 65,192, 0, 0, 0,248,143,198, 6, 0, 0, 0, 0, 59, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, + 9, 0, 0, 0, 7, 0, 0, 0, 11, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, + 6, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 68, 65, 84, 65, + 8, 2, 0, 0, 8,145,198, 6, 0, 0, 0, 0,124, 1, 0, 0, 5, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 71,111,110, 32, 70, 97, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,147,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,232,217, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6067,117 +6674,26 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 72, 0, 0, 0, 88,147,198, 6, 0, 0, 0, 0, 58, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 2, 0, + 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 12, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 2, 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 66, 82, 0, 0, + 88, 6, 0, 0,232,147,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 24,158,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 65,100,100, 0,104, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 8,156,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65,160, 0, 0, 0,232,232,217, 3, 0, 0, 0, 0, 56, 0, 0, 0, 8, 0, 0, 0, 0, 0,128, 63,255,255,127, 63, - 0, 0,128,191,230, 73,230, 73, 26,182, 1, 0, 0, 0,128, 63, 0, 0,128,191, 0, 0,128,191,230, 73, 26,182, 26,182, 1, 0, - 1, 0,128,191,253,255,127,191, 0, 0,128,191, 26,182, 26,182, 26,182, 1, 0,250,255,127,191, 3, 0,128, 63, 0, 0,128,191, - 26,182,230, 73, 26,182, 1, 0, 4, 0,128, 63,247,255,127, 63, 0, 0,128, 63,230, 73,230, 73,230, 73, 1, 0,245,255,127, 63, - 5, 0,128,191, 0, 0,128, 63,230, 73, 26,182,230, 73, 1, 0, 3, 0,128,191,250,255,127,191, 0, 0,128, 63, 26,182, 26,182, -230, 73, 1, 0,255,255,127,191, 0, 0,128, 63, 0, 0,128, 63, 26,182,230, 73,230, 73, 1, 0, 68, 65, 84, 65, 8, 2, 0, 0, -136, 56,218, 3, 0, 0, 0, 0,124, 1, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 7,163, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,144, 0, 0, 0, - 24, 7,163, 3, 0, 0, 0, 0, 53, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 35, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 35, 0, - 1, 0, 0, 0, 5, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 35, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 35, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0, - 68, 65, 84, 65, 8, 2, 0, 0, 72,156,173, 15, 0, 0, 0, 0,124, 1, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,205,203, 15, 0, 0, 0, 0, - 6, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 67,111,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184,122,209, 15, 0, 0, 0, 0, 9, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,200,136,205, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 8, 2, 0, 0,168, 61,218, 3, 0, 0, 0, 0,124, 1, 0, 0, 5, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,108, 0, 32, 70, 97, 99, -101, 45, 86,101,114,116,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 2,211, 3, 0, 0, 0, 0, - 26, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 78, 71,111,110, 32, 70, 97, 99,101, 45, 86,101,114,116,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 56, 98,198, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 96, 0, 0, 0,136, 2,211, 3, 0, 0, 0, 0, 62, 0, 0, 0, 24, 0, 0, 0,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 68, 65, 84, 65,192, 0, 0, 0, - 56, 98,198, 3, 0, 0, 0, 0, 59, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, - 2, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 7, 0, 0, 0, 11, 0, 0, 0, - 6, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, - 5, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, - 6, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, - 7, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 3, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 68, 65, 84, 65, 8, 2, 0, 0, 56, 64,218, 3, 0, 0, 0, 0, -124, 1, 0, 0, 5, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 78, 71,111,110, 32, 70, 97, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,200,218,208, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 72, 0, 0, 0,200,218,208, 3, 0, 0, 0, 0, - 58, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 2, 0, - 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 16, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 2, 0, 20, 0, 0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 66, 82, 0, 0, 88, 6, 0, 0,200, 66,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 65,100,100, 0,104, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,104, 75,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6209,49 +6725,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 96, 67,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, + 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,128,148,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,104, 75,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, 46,189,194, 61,248,121,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0, 8,156,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, + 46,189,194, 61,152,157,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,152,157,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, + 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 24,158,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,200,166,198, 6, 0, 0, 0, 0,232,147,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 66,108,111, 98, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,248,121,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0,200, 66,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 66,108,111, 98, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,184,164,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 13, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 8, 84,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6283,52 +6800,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, + 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0,176,158,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0,192, 77,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 8, 84,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,168,122,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,184,164,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186, 72,166,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 72,166,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,200,166,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,120,175,198, 6, 0, 0, 0, 0, 24,158,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 66,108,117,114, 0, 46, 48, 48, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,168,122,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,200, 85,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 40, 77,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 66,108,117,114, 0, 46, 48, 48, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,104,173,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,168, 92,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6359,50 +6874,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 96, 86,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, + 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 96,167,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,168, 92,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, 46,189,194, 61, 88,123,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,104,173,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, + 46,189,194, 61,248,174,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,248,174,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, + 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,120,175,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 40,184,198, 6, 0, 0, 0, 0,200,166,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 66,114,117,115,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 88,123,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,104, 94,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0,200, 85,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 66,114,117,115,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 24,182,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 31, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 72,101,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6434,51 +6950,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 35, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0, 0, 95,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 35, 0, 0, 0, + 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, + 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0, 16,176,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 72,101,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186, 8,124,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0, 24,182,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186,168,183,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,168,183,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 40,184,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,216,192,198, 6, 0, 0, 0, 0,120,175,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 67,108, 97,121, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 8,124,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0, 8,103,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,168,205,210, 3, 0, 0, 0, 0,104, 94,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 67,108, 97,121, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,200,190,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,232,109,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6509,49 +7024,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 8, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0,160,103,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 8, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, + 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0,192,184,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,232,109,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,184,124,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,200,190,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186, 88,192,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,184,124,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,168,205,210, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 8,103,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 67,108, 97,121, 32, 83,116,114,105,112,115, 0, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 88,192,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,216,192,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,136,201,198, 6, 0, 0, 0, 0, 40,184,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 67,108, 97,121, 32, 83,116,114,105,112, +115, 0, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,120,199,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 24,114,219, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6583,52 +7100,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0,160,119, 78, 63, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, + 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0,112,193,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0,160,119, 78, 63, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0, 64,206,210, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 24,114,219, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,152, 62,171, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,120,199,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186, 8,201,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 8,201,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,136,201,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 56,210,198, 6, 0, 0, 0, 0,216,192,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 67,108,111,110,101, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,152, 62,171, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,168,111,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0,168,205,210, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 67,108,111,110,101, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 40,208,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,136,118,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6659,49 +7174,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 35, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 51, 51, 51, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 64,112,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 35, 0, 0, 0, + 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 32,202,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,136,118,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, 46,189,194, 61,104,125,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0, 40,208,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, + 46,189,194, 61,184,209,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,184,209,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, + 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 56,210,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,232,218,198, 6, 0, 0, 0, 0,136,201,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 67,114,101, 97,115,101, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,104,125,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0, 72,120,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0,168,111,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 67,114,101, 97,115,101, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,216,216,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 18, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 40,127,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6733,52 +7250,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 6, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 62, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, + 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0,208,210,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 6, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0,224,120,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 40,127,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,228, 97,175,190, 50,131,112, 63,218,243,127,191, 10,183,157,188, 24,126,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,216,216,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,228, 97,175,190, 50,131,112, 63,218,243,127,191, + 10,183,157,188,104,218,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,104,218,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 64, 63, 10,215, 35, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,232,218,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,152,227,198, 6, 0, 0, 0, 0, 56,210,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 68, 97,114,107,101,110, 0, 48, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 24,126,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 64, 63, 10,215, 35, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,232,128,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 72,120,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 68, 97,114,107,101,110, 0, 48, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,136,225,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,200,135,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6809,50 +7324,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0,128,129,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, + 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,128,219,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,200,135,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, 46,189,194, 61,200,126,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,136,225,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, + 46,189,194, 61, 24,227,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 24,227,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, + 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,152,227,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 72,236,198, 6, 0, 0, 0, 0,232,218,198, 6, + 0, 0, 0, 0, 0, 20, 1,160,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 68,114, 97,119, 0, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,200,126,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,136,137,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0,232,128,218, 3, 0, 0, 0, 0, 0, 20, 1,160,255,255,255,255, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 68,114, 97,119, 0, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 56,234,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 31, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 88,146,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6884,50 +7400,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 35, 0, 0, 0, 0, 4, 0, 8, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0, 32,138,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 35, 0, 0, 0, + 0, 4, 0, 8, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, + 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0, 48,228,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 88,146,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,120,127,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0, 56,234,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186,200,235,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,120,127,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,104,176,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0,136,137,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 70,105,108,108, 47, 68,101,101,112,101,110, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,200,235,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 72,236,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,248,244,198, 6, 0, 0, 0, 0,152,227,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 70,105,108,108, 47, 68,101,101,112,101, +110, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,232,242,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 20, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 24,148,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6959,51 +7475,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 20,174,199, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0, 0,177,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 20,174,199, 62, + 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0,224,236,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 24,148,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186, 40,128,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,232,242,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186,120,244,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 40,128,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0, 72,183,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0,104,176,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 70,108, 97,116,116,101,110, 47, 67,111,110,116,114, 97,115,116, 0, 48, 48, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,120,244,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,248,244,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,168,253,198, 6, 0, 0, 0, 0, 72,236,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 70,108, 97,116,116,101,110, 47, 67,111, +110,116,114, 97,115,116, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,152,251,198, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 21, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,216,149,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7034,50 +7549,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 20,174,199, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0,224,183,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 20,174,199, 62, + 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0,144,245,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,216,149,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,216,128,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,152,251,198, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186, 40,253,198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 40,253,198, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,168,253,198, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 88, 6,199, 6, 0, 0, 0, 0,248,244,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 71,114, 97, 98, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,216,128,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0, 40,190,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 72,183,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 71,114, 97, 98, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 72, 4,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 22, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,152,151,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7109,51 +7625,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0,192,190,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 75, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 64,254,198, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,152,151,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,136,129,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0, 72, 4,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186,216, 5,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,136,129,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0, 8,197,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 40,190,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 73,110,102,108, 97,116,101, 47, 68,101,102,108, 97,116,101, 0, 48, 48, 49, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,216, 5,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 88, 6,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 8, 15,199, 6, 0, 0, 0, 0,168,253,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 73,110,102,108, 97,116,101, 47, 68,101, +102,108, 97,116,101, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,248, 12,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 23, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 88,153,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7184,50 +7699,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0, 64, 63, 0, 0, 64, 63, 0, 0, 64, 63, 0, 0,128, 62, 0, 0,128, 62, 0, 0,128, 62, - 68, 65, 84, 65, 56, 1, 0, 0,160,197,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0, 64, 63, 0, 0, 64, 63, 0, 0, 64, 63, + 0, 0,128, 62, 0, 0,128, 62, 0, 0,128, 62, 68, 65, 84, 65, 56, 1, 0, 0,240, 6,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 88,153,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186, 56,130,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,248, 12,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186,136, 14,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,136, 14,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 8, 15,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,184, 23,199, 6, 0, 0, 0, 0, 88, 6,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 76, 97,121,101,114, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 56,130,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,232,203,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 8,197,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 76, 97,121,101,114, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,168, 21,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 24,155,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7259,51 +7775,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0,128,204,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,160, 15,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 24,155,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,232,130,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,168, 21,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186, 56, 23,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 56, 23,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,184, 23,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,104, 32,199, 6, 0, 0, 0, 0, 8, 15,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 76,105,103,104,116,101,110, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,232,130,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,200,210,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0,232,203,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 76,105,103,104,116,101,110, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 88, 30,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,216,156,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7334,50 +7849,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 96,211,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, + 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 80, 24,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,216,156,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, 46,189,194, 61,152,131,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0, 88, 30,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, + 46,189,194, 61,232, 31,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,232, 31,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, + 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,104, 32,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 24, 41,199, 6, 0, 0, 0, 0,184, 23,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 77,105,120, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,152,131,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,168,217,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0,200,210,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 77,105,120, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 8, 39,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,152,158,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7409,51 +7925,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 51, 51, 51, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 64,218,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, + 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 0, 33,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,152,158,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, 46,189,194, 61, 72,132,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0, 8, 39,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, + 46,189,194, 61,152, 40,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,152, 40,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, + 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 24, 41,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,200, 49,199, 6, 0, 0, 0, 0,104, 32,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 77,117,108,116,105,112,108,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 72,132,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,136,224,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0,168,217,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 77,117,108,116,105,112,108,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,184, 47,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 88,160,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7484,50 +7999,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 32,225,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, + 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,176, 41,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 88,160,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, 46,189,194, 61,248,132,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,184, 47,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, + 46,189,194, 61, 72, 49,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 72, 49,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, + 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,200, 49,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,120, 58,199, 6, 0, 0, 0, 0, 24, 41,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 78,117,100,103,101, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,248,132,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,184,212,210, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0,136,224,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 78,117,100,103,101, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,104, 56,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 28, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 24,162,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7559,51 +8075,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 80,213,210, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 96, 50,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 24,162,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,168,133,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,104, 56,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186,248, 57,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,168,133,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,200,219,210, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0,184,212,210, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 80,105,110, 99,104, 47, 77, 97,103,110,105,102,121, 0, 48, 48, 49, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,248, 57,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,120, 58,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 40, 67,199, 6, 0, 0, 0, 0,200, 49,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 80,105,110, 99,104, 47, 77, 97,103,110, +105,102,121, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 24, 65,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 29, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,216,163,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7634,49 +8149,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0, 64, 63, 0, 0, 64, 63, 0, 0, 64, 63, 0, 0,128, 62, 0, 0,128, 62, 0, 0,128, 62, - 68, 65, 84, 65, 56, 1, 0, 0, 96,220,210, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0, 64, 63, 0, 0, 64, 63, 0, 0, 64, 63, + 0, 0,128, 62, 0, 0,128, 62, 0, 0,128, 62, 68, 65, 84, 65, 56, 1, 0, 0, 16, 59,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,216,163,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186, 88,134,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0, 24, 65,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186,168, 66,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,168, 66,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 40, 67,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,216, 75,199, 6, 0, 0, 0, 0,120, 58,199, 6, + 0, 0, 0, 0,253, 21,192, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 80,111,108,105,115,104, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 88,134,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,216,226,210, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0,200,219,210, 3, 0, 0, 0, 0,253, 21,192, 32, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 80,111,108,105,115,104, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,200, 73,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 21, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,152,165,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7708,51 +8225,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 1, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 20,174,199, 62, + 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0,192, 67,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 1, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 20,174,199, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0,112,227,210, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,152,165,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186, 8,135,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,200, 73,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186, 88, 75,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 8,135,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,232,233,210, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0,216,226,210, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83, 99,114, 97,112,101, 47, 80,101, 97,107,115, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 88, 75,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,216, 75,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,136, 84,199, 6, 0, 0, 0, 0, 40, 67,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83, 99,114, 97,112,101, 47, 80,101, 97, +107,115, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,120, 82,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 30, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 88,167,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7784,49 +8300,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 20,174,199, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0,128,234,210, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 20,174,199, 62, + 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0,112, 76,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 88,167,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,184,135,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,120, 82,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186, 8, 84,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 8, 84,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,136, 84,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 56, 93,199, 6, 0, 0, 0, 0,216, 75,199, 6, + 0, 0, 0, 0,168,205,210, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83, 99,117,108,112,116, 68,114, 97,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,184,135,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,248,240,210, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0,232,233,210, 3, 0, 0, 0, 0,168,205,210, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83, 99,117,108,112,116, 68,114, 97,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 40, 91,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 31, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 24,169,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7858,52 +8375,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0,160,119, 78, 63, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, + 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0, 32, 85,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0,160,119, 78, 63, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0,144,241,210, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 24,169,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,104,136,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0, 40, 91,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186,184, 92,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,184, 92,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 56, 93,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,232,101,199, 6, 0, 0, 0, 0,136, 84,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83,109,101, 97,114, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,104,136,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,152,231,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0,248,240,210, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83,109,101, 97,114, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,216, 99,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,216,170,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7934,50 +8449,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 35, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 48,232,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 35, 0, 0, 0, + 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,208, 93,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,216,170,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, 46,189,194, 61, 24,137,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,216, 99,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, + 46,189,194, 61,104,101,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,104,101,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, + 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,232,101,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,152,110,199, 6, 0, 0, 0, 0, 56, 93,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83,109,111,111,116,104, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 24,137,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,168,238,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0,152,231,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83,109,111,111,116,104, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,136,108,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,152,172,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8009,50 +8525,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0, 64, 63, 0, 0, 64, 63, 0, 0, 64, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 64,239,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 35, 0, 0, 0, + 4, 4, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0, 64, 63, 0, 0, 64, 63, 0, 0, 64, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,128,102,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,152,172,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,200,137,216, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,136,108,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186, 24,110,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,200,137,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,184,245,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0,168,238,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83,110, 97,107,101, 32, 72,111,111,107, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 24,110,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,152,110,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 72,119,199, 6, 0, 0, 0, 0,232,101,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83,110, 97,107,101, 32, 72,111,111,107, + 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 56,117,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 34, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 88,174,218, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8084,49 +8600,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 80,246,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 75, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 48,111,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 88,174,218, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,120,138,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0, 56,117,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186,200,118,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,200,118,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 72,119,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,248,127,199, 6, 0, 0, 0, 0,152,110,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83,111,102,116,101,110, 0, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,120,138,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,200,252,218, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0,184,245,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83,111,102,116,101,110, 0, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,232,125,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,152,103,219, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8158,52 +8675,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 35, 0, 0, 0, + 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,224,119,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 35, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 96,253,218, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,152,103,219, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, 46,189,194, 61, 40,139,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,232,125,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, + 46,189,194, 61,120,127,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,120,127,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, + 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,248,127,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0,168,136,199, 6, 0, 0, 0, 0, 72,119,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83,117, 98,116,114, 97, 99,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 40,139,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,216, 3,219, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0,200,252,218, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 83,117, 98,116,114, 97, 99,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,152,134,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 88,105,219, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8234,49 +8749,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0,112, 4,219, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 35, 0, 0, 0, + 4, 4, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,144,128,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 88,105,219, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, 46,189,194, 61,216,139,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,152,134,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63, 14,215,126,191, 54,189,194, 61, 14,215,126,191, + 46,189,194, 61, 40,136,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 40,136,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, + 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0,168,136,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 88,145,199, 6, 0, 0, 0, 0,248,127,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 84,101,120, 68,114, 97,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,216,139,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62, 31,133,107, 63, 0, 0, 0, 0, 0, 0, 64, 63, 10,215,163, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,232, 10,219, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0,216, 3,219, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 84,101,120, 68,114, 97,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 72,143,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 24,107,219, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8308,52 +8825,50 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 35, 0, 0, 0, + 4, 4, 0, 8, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 51, 51, 51, 63, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, 68, 65, 84, 65, 56, 1, 0, 0, 64,137,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 35, 0, 0, 0, 4, 4, 0, 8, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 51, 51, 51, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 20,174,199, 62, 20,174,199, 62, 0, 0,128, 63, - 68, 65, 84, 65, 56, 1, 0, 0,128, 11,219, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0, 24,107,219, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,136,140,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0, 72,143,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186,216,144,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,216,144,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 88,145,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 8,154,199, 6, 0, 0, 0, 0,168,136,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 84,104,117,109, 98, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,136,140,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0,248, 17,219, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0, 8, 25,219, 3, 0, 0, 0, 0,232, 10,219, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 84,104,117,109, 98, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,248,151,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 38, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,216,108,219, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8384,50 +8899,51 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 75, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0,144, 18,219, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 75, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,240,145,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,216,108,219, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186, 56,141,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,248,151,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186,136,153,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,136,153,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, + 88, 6, 0, 0, 8,154,199, 6, 0, 0, 0, 0,123, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,145,199, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 84,119,105,115,116, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 56,141,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 0, 0, 88, 6, 0, 0, 8, 25,219, 3, 0, 0, 0, 0, -123, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 17,219, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 82, 84,119,105,115,116, 0, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0,168,160,199, 6, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 39, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0,152,110,219, 3, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8459,36 +8975,38 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 75, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, - 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0,160, 25,219, 3, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 75, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0,102,102,102, 63,205,204,204, 61, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63,205,204,204, 62, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 62, 0, 0,128, 62, 0, 0,128, 63, 0, 0,128, 62, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,160,154,199, 6, 0, 0, 0, 0, 25, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 64, 1, 0, 0,152,110,219, 3, 0, 0, 0, 0, -119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, - 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191,114, 97,255,186,232,141,216, 3, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, + 64, 1, 0, 0,168,160,199, 6, 0, 0, 0, 0,119, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0,128, 63, 4, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63,224,255,127,191, 46, 95,255,186,224,255,127,191, +114, 97,255,186, 56,162,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0, 56,162,199, 6, + 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, + 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 85, 83, 69, 82, +112, 38, 0, 0, 0,182, 22, 5, 0, 0, 0, 0,209, 0, 0, 0, 1, 0, 0, 0, 1, 8, 17, 1, 63, 6, 0, 0, 5, 0, 0, 0, + 47,116,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,232,141,216, 3, 0, 0, 0, 0,117, 1, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 62,215,163,112, 63, 0, 0, 0, 0, 0, 0, 64, 63,143,194,117, 61, - 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 85, 83, 69, 82,112, 38, 0, 0, 96, 41,141, 67, 1, 0, 0, 0, -209, 0, 0, 0, 1, 0, 0, 0, 1, 8, 17, 1, 63, 6, 0, 0, 5, 0, 0, 0, 47,116,109,112, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8510,10 +9028,9 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 0, 85,115,101,114,115, 47,116,111,110, 47, 68,101,115,107,116,111,112, 47, 0, 45,112,111,119,101,114,112, 99, 47, 98, +105,110, 47, 98,108,101,110,100,101,114, 46, 97,112,112, 47, 67,111,110,116,101,110,116,115, 47, 82,101,115,111,117,114, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 85,115,101,114,115, 47,116,111,110, - 47, 68,101,115,107,116,111,112, 47, 0, 45,112,111,119,101,114,112, 99, 47, 98,105,110, 47, 98,108,101,110,100,101,114, 46, 97, -112,112, 47, 67,111,110,116,101,110,116,115, 47, 82,101,115,111,117,114, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8535,7 +9052,7 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8567,7 +9084,7 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8663,7 +9180,7 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8751,71 +9268,70 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 2, 0, 94, 1, - 8, 0, 0, 0, 3, 0, 0, 0, 56, 52, 39, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 8, 0, 0, 2, 0, 0, 0, 68,172, 0, 0, - 36, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 72, 0, 0, 0, 0, 0, 64, 0, 5, 0, 2, 0, 88,174,219, 3, 0, 0, 0, 0, - 88,174,219, 3, 0, 0, 0, 0,200,152,170, 3, 0, 0, 0, 0,200,152,170, 3, 0, 0, 0, 0,200,154,199, 3, 0, 0, 0, 0, -200,154,199, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,184,211,219, 3, 0, 0, 0, 0, 8,219,219, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 35, 0, 0, 0, 2, 0, 94, 1, 8, 0, 0, 0, 3, 0, 0, 0, 56, 52, 39, 0, 0, 0, 0, 0, 1, 0, 2, 0, + 0, 8, 0, 0, 2, 0, 0, 0, 68,172, 0, 0, 36, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 72, 0, 0, 0, 0, 0, 64, 0, + 5, 0, 2, 0,120,201,199, 6, 0, 0, 0, 0,120,201,199, 6, 0, 0, 0, 0,248,176,199, 6, 0, 0, 0, 0,248,176,199, 6, + 0, 0, 0, 0,104,243,199, 6, 0, 0, 0, 0,104,243,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,154,198, 6, 0, 0, 0, 0,200,242,199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 1, 0, 2, 0, - 25, 0, 0, 0, 20, 0, 20, 0, 1, 0, 0, 0, 0, 0, 0, 0,205,204, 76, 63,205,204, 76, 63,205,204, 76, 63, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 30, 90,100,191,154,153,153, 62,102,102,102, 63, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 31,250,254, 62, 9, 0, 0, 63,156,153, 25, 63, 0, 0, 0, 0,205,204, 76, 62,205,204, 76, 62, -205,204, 76, 62, 0, 0,128, 63, 44,135, 22, 63, 32,133,235, 62,184,243,125, 62, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -195, 73, 76, 63, 42,135, 86, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 43,135, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, - 16, 47, 93, 62, 58,180,200,190, 24, 47, 93,190, 0, 0, 0, 0, 14, 0, 1, 0, 25, 0, 15, 0,120, 0, 60, 0, 3, 0, 5, 0, -128, 0, 0, 0, 0, 0, 0, 0,144, 31, 15, 0, 6, 0, 25, 0, 8, 0, 10, 0,200, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, - 10, 0, 50, 0, 20, 0, 2, 0, 1, 0, 0, 0, 0, 0,128, 63, 60, 0, 0, 0, 0, 0, 2, 0, 2, 0, 8, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, - 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, - 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, - 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, - 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, - 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, - 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, - 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, - 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, - 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, - 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, - 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, - 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, - 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, - 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, - 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, - 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32, 0, 0, 0, 1, 0, 2, 0, 25, 0, 0, 0, 20, 0, 20, 0, 1, 0, 0, 0, 0, 0, 0, 0,205,204, 76, 63, +205,204, 76, 63,205,204, 76, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 30, 90,100,191, +154,153,153, 62,102,102,102, 63, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 31,250,254, 62, 9, 0, 0, 63,156,153, 25, 63, + 0, 0, 0, 0,205,204, 76, 62,205,204, 76, 62,205,204, 76, 62, 0, 0,128, 63, 44,135, 22, 63, 32,133,235, 62,184,243,125, 62, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,195, 73, 76, 63, 42,135, 86, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 43,135, 61, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 16, 47, 93, 62, 58,180,200,190, 24, 47, 93,190, 0, 0, 0, 0, 14, 0, 1, 0, + 25, 0, 15, 0,120, 0, 60, 0, 3, 0, 5, 0,128, 0, 0, 0, 0, 0, 0, 0,144, 31, 15, 0, 6, 0, 25, 0, 8, 0, 10, 0, +200, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 10, 0, 50, 0, 20, 0, 2, 0, 1, 0, 0, 0, 0, 0,128, 63, 60, 0, 0, 0, + 0, 0, 2, 0, 2, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, + 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 68, 65, 84, 65,168, 36, 0, 0, - 88,174,219, 3, 0, 0, 0, 0,206, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68,101,102, 97,117,108,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, - 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255, 1, 0, 15, 0,241,255, 0, 0, - 25, 25, 25,255,153,153,153,255,153,153,153,255, 90, 90, 90,255, 0, 0, 0,255,255,255,255,255, 1, 0, 0, 0, 25, 0, 0, 0, - 0, 0, 0,255, 70, 70, 70,255, 86,128,194,255,255,255,255,255,255,255,255,255, 0, 0, 0,255, 1, 0, 15, 0,241,255, 0, 0, - 0, 0, 0,255, 70, 70, 70,255, 70, 70, 70,255,255,255,255,255, 0, 0, 0,255,255,255,255,255, 1, 0, 15, 0,241,255, 0, 0, - 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, - 25, 25, 25,255,180,180,180,255,153,153,153,255, 90, 90, 90,255, 0, 0, 0,255,255,255,255,255, 1, 0,236,255, 0, 0, 0, 0, - 25, 25, 25,255,180,180,180,255,153,153,153,255,128,128,128,255, 0, 0, 0,255,255,255,255,255, 1, 0,236,255, 0, 0, 0, 0, - 0, 0, 0,255, 70, 70, 70,255, 70, 70, 70,255,255,255,255,255,255,255,255,255,204,204,204,255, 1, 0, 15, 0,241,255, 0, 0, - 0, 0, 0,255, 63, 63, 63,255, 86,128,194,255,255,255,255,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 25, 0,236,255, 0, 0, - 0, 0, 0,255, 25, 25, 25,230, 45, 45, 45,230,100,100,100,255,160,160,160,255,255,255,255,255, 0, 0, 25, 0,236,255, 0, 0, - 0, 0, 0,255, 0, 0, 0, 0, 86,128,194,255,172,172,172,128,255,255,255,255, 0, 0, 0,255, 1, 0, 38, 0, 0, 0, 0, 0, - 0, 0, 0,255, 25, 25, 25,230, 45, 45, 45,230,100,100,100,255,255,255,255,255,255,255,255,255, 0, 0, 25, 0,236,255, 0, 0, - 25, 25, 25,255,128,128,128,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 50, 50,180, 80, 80, 80,180,100,100,100,180,128,128,128,255, 0, 0, 0,255,255,255,255,255, 1, 0, 5, 0,251,255, 0, 0, - 0, 0, 0,255,190,190,190,255,100,100,100,180, 68, 68, 68,255, 0, 0, 0,255,255,255,255,255, 0, 0, 5, 0,251,255, 0, 0, - 0, 0, 0,255, 0, 0, 0, 0, 86,128,194,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, -115,190, 76,255, 90,166, 51,255,240,235,100,255,215,211, 75,255,180, 0,255,255,153, 0,230,255, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, + 0, 0, 0, 0, 68, 65, 84, 65,168, 36, 0, 0,120,201,199, 6, 0, 0, 0, 0,206, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,101,102, 97,117,108,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255, +255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255, +255,255,255,255, 1, 0, 15, 0,241,255, 0, 0, 25, 25, 25,255,153,153,153,255,153,153,153,255, 90, 90, 90,255, 0, 0, 0,255, +255,255,255,255, 1, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0,255, 70, 70, 70,255, 86,128,194,255,255,255,255,255,255,255,255,255, + 0, 0, 0,255, 1, 0, 15, 0,241,255, 0, 0, 0, 0, 0,255, 70, 70, 70,255, 70, 70, 70,255,255,255,255,255, 0, 0, 0,255, +255,255,255,255, 1, 0, 15, 0,241,255, 0, 0, 25, 25, 25,255,153,153,153,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255, +255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25,255,180,180,180,255,153,153,153,255, 90, 90, 90,255, 0, 0, 0,255, +255,255,255,255, 1, 0,236,255, 0, 0, 0, 0, 25, 25, 25,255,180,180,180,255,153,153,153,255,128,128,128,255, 0, 0, 0,255, +255,255,255,255, 1, 0,236,255, 0, 0, 0, 0, 0, 0, 0,255, 70, 70, 70,255, 70, 70, 70,255,255,255,255,255,255,255,255,255, +204,204,204,255, 1, 0, 15, 0,241,255, 0, 0, 0, 0, 0,255, 63, 63, 63,255, 86,128,194,255,255,255,255,255, 0, 0, 0,255, + 0, 0, 0,255, 0, 0, 25, 0,236,255, 0, 0, 0, 0, 0,255, 25, 25, 25,230, 45, 45, 45,230,100,100,100,255,160,160,160,255, +255,255,255,255, 0, 0, 25, 0,236,255, 0, 0, 0, 0, 0,255, 0, 0, 0, 0, 86,128,194,255,172,172,172,128,255,255,255,255, + 0, 0, 0,255, 1, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0,255, 25, 25, 25,230, 45, 45, 45,230,100,100,100,255,255,255,255,255, +255,255,255,255, 0, 0, 25, 0,236,255, 0, 0, 25, 25, 25,255,128,128,128,255,100,100,100,255, 25, 25, 25,255, 0, 0, 0,255, +255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50,180, 80, 80, 80,180,100,100,100,180,128,128,128,255, 0, 0, 0,255, +255,255,255,255, 1, 0, 5, 0,251,255, 0, 0, 0, 0, 0,255,190,190,190,255,100,100,100,180, 68, 68, 68,255, 0, 0, 0,255, +255,255,255,255, 0, 0, 5, 0,251,255, 0, 0, 0, 0, 0,255, 0, 0, 0, 0, 86,128,194,255, 0, 0, 0,255, 0, 0, 0,255, + 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0,115,190, 76,255, 90,166, 51,255,240,235,100,255,215,211, 75,255,180, 0,255,255, +153, 0,230,255, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8823,2397 +9339,2398 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,130,130,130,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 57, 57,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0,255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,170, 64,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, 32,255,255,255, 75, 75, 75,255,204, 0,153,255, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 32, 0, 0,255, 0, 32, 0,255, 0, 0,128,255, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255,255,255,255,255, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,200,200,255, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76,255, 0, 0, 0, 0,250,250,250,255, 15, 15, 15,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100,255,140, 25,255,250,250,250,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130,130,130,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250,250,250,255, 0, 0, 0, 0,250,250,250,255,250,250,250,255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,255,255,255,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -150,150,150,100,112,112,112,100, 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 79,101, 73,255,135,177,125,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, -153, 64, 48,255, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255,240,175,144,255, 82, 96,110,255,124,137,150,255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,255,255,255,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -150,150,150,100,112,112,112,100, 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 79,101, 73,255,135,177,125,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 82, 96,110,255,124,137,150,255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 3, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,255,255,255,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -150,150,150,100,112,112,112,100, 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 79,101, 73,255,135,177,125,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 82, 96,110,255,124,137,150,255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 3, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,116,116,116,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81,105,135,255, 32, 32,143,255,109, 88,129,255, 78,152, 62,255, 46,143,143,255, -169, 84,124,255,126,126, 80,255,162, 95,111,255,109,145,131,255,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 53, 53,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, -255,255,255, 10,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 18, 66,176, 38,255,133, 0,178,255,133, 0,127, 0,255, 0,255, -255, 0, 0,255,225,210,195, 35, 0, 0, 0, 0, 0, 0, 0, 0,153,153,153,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -143,143,143,255,198,119,119,255,255, 0, 0,255, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0,100, 0, 0,255, 0, 0,200,255, -128, 0, 80,255, 95, 95, 0,255, 0,100, 50,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 51,127, 51, 76,130,135,140, 76,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -173,173,173,255,127,112,112,100, 0, 0, 0, 0, 91, 91, 91,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 57, 57,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,255,255,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 5,155,155,155,160,100,104,111,255, -111,106,100,255,104,106,117,255,105,117,110,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,100,100,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96,128,255,255,255,255,255,255, 0,170, 0,255,220, 96, 96,255,220, 96, 96,255, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 57, 57,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0,255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,170, 64,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, - 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, 32,255,255,255, 75, 75, 75,255,204, 0,153,255, - 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 32, 0, 0,255, 0, 32, 0,255, 0, 0,128,255, 0, 0, 0, 0, 34,221,221,255, - 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255, -219, 37, 18,255,240,255, 64,255,240,144,160,255,255,255,255,255, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, - 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, 0, 0, 0,255,255,255, 0,255, 4, 0, 0, 0, -255,127,127, 0,255,255,255,255,255,255,255, 0,255,127, 0, 0,255,127,127,127,255,200,200,200,255,255, 0, 0,255, 0, 0,255, -255, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154, 0, 0,255,189, 17, 17,255,247, 10, 10,255, 0, 0, 0, 0, -247, 64, 24,255,246,105, 19,255,250,153, 0,255, 0, 0, 0, 0, 30,145, 9,255, 89,183, 11,255,131,239, 29,255, 0, 0, 0, 0, - 10, 54,148,255, 54,103,223,255, 94,193,239,255, 0, 0, 0, 0,169, 41, 78,255,193, 65,106,255,240, 93,145,255, 0, 0, 0, 0, - 67, 12,120,255, 84, 58,163,255,135,100,213,255, 0, 0, 0, 0, 36,120, 90,255, 60,149,121,255,111,182,171,255, 0, 0, 0, 0, - 75,112,124,255,106,134,145,255,155,194,205,255, 0, 0, 0, 0,244,201, 12,255,238,194, 54,255,243,255, 0,255, 0, 0, 0, 0, - 30, 32, 36,255, 72, 76, 86,255,255,255,255,255, 0, 0, 0, 0,111, 47,106,255,152, 69,190,255,211, 48,214,255, 0, 0, 0, 0, -108,142, 34,255,127,176, 34,255,187,239, 91,255, 0, 0, 0, 0,141,141,141,255,176,176,176,255,222,222,222,255, 0, 0, 0, 0, -131, 67, 38,255,139, 88, 17,255,189,106, 17,255, 0, 0, 0, 0, 8, 49, 14,255, 28, 67, 11,255, 52, 98, 43,255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0, -184,211,219, 3, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0,136,212,219, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -105,111, 95,115, 99,101,110,101, 95, 51,100,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 80, 0, 0, 0,136,212,219, 3, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0, 88,213,219, 3, 0, 0, 0, 0, -184,211,219, 3, 0, 0, 0, 0,105,111, 95,115, 99,101,110,101, 95,102, 98,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0, 88,213,219, 3, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0, - 40,214,219, 3, 0, 0, 0, 0,136,212,219, 3, 0, 0, 0, 0,105,111, 95, 97,110,105,109, 95, 98,118,104, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0, 40,214,219, 3, 0, 0, 0, 0, -207, 0, 0, 0, 1, 0, 0, 0,248,214,219, 3, 0, 0, 0, 0, 88,213,219, 3, 0, 0, 0, 0,105,111, 95,109,101,115,104, 95, -112,108,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0, -248,214,219, 3, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0,200,215,219, 3, 0, 0, 0, 0, 40,214,219, 3, 0, 0, 0, 0, -105,111, 95,115, 99,101,110,101, 95,111, 98,106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 80, 0, 0, 0,200,215,219, 3, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0,152,216,219, 3, 0, 0, 0, 0, -248,214,219, 3, 0, 0, 0, 0,105,111, 95,115, 99,101,110,101, 95,120, 51,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0,152,216,219, 3, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0, -104,217,219, 3, 0, 0, 0, 0,200,215,219, 3, 0, 0, 0, 0,105,111, 95,109,101,115,104, 95,115,116,108, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0,104,217,219, 3, 0, 0, 0, 0, -207, 0, 0, 0, 1, 0, 0, 0, 56,218,219, 3, 0, 0, 0, 0,152,216,219, 3, 0, 0, 0, 0,105,111, 95,109,101,115,104, 95, -117,118, 95,108, 97,121,111,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0, - 56,218,219, 3, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0, 8,219,219, 3, 0, 0, 0, 0,104,217,219, 3, 0, 0, 0, 0, -105,111, 95, 99,117,114,118,101, 95,115,118,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 80, 0, 0, 0, 8,219,219, 3, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 56,218,219, 3, 0, 0, 0, 0, 99,121, 99,108,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,232, 0, 0, 0,200,154,199, 3, 0, 0, 0, 0,199, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,101,102, 97,117,108,116, 32, 83,116,121,108,101, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0,255,255, 0, 0,154,153, 25, 62, 0, 0,128, 63, 0, 0, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0,255,255, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 0, 0, 11, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0,255,255, 0, 0,154,153, 25, 62, 0, 0,128, 63, 0, 0, 11, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 8, 0, 5, 0, 5, 0, 8, 0, - 2, 0, 8, 0, 4, 0, 0, 0, 68, 78, 65, 49,136, 4, 1, 0,200,254,218, 15, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 83, 68, 78, 65, 78, 65, 77, 69, 58, 13, 0, 0, 42,110,101,120,116, 0, 42,112,114,101,118, 0, 42,100, 97,116, 97, 0, 42,102, -105,114,115,116, 0, 42,108, 97,115,116, 0,120, 0,121, 0,122, 0,120,109,105,110, 0,120,109, 97,120, 0,121,109,105,110, 0, -121,109, 97,120, 0, 42,112,111,105,110,116,101,114, 0,103,114,111,117,112, 0,118, 97,108, 0,118, 97,108, 50, 0,116,121,112, -101, 0,115,117, 98,116,121,112,101, 0,102,108, 97,103, 0,110, 97,109,101, 91, 54, 52, 93, 0,115, 97,118,101,100, 0,100, 97, -116, 97, 0,108,101,110, 0,116,111,116, 97,108,108,101,110, 0, 42,110,101,119,105,100, 0, 42,108,105, 98, 0,110, 97,109,101, - 91, 54, 54, 93, 0,112, 97,100, 0,117,115, 0,105, 99,111,110, 95,105,100, 0,112, 97,100, 50, 0, 42,112,114,111,112,101,114, -116,105,101,115, 0,105,100, 0, 42,105,100, 98,108,111, 99,107, 0, 42,102,105,108,101,100, 97,116, 97, 0,110, 97,109,101, 91, - 49, 48, 50, 52, 93, 0,102,105,108,101,112, 97,116,104, 91, 49, 48, 50, 52, 93, 0,116,111,116, 0, 42,112, 97,114,101,110,116, - 0,119, 91, 50, 93, 0,104, 91, 50, 93, 0, 99,104, 97,110,103,101,100, 91, 50, 93, 0, 99,104, 97,110,103,101,100, 95,116,105, -109,101,115,116, 97,109,112, 91, 50, 93, 0, 42,114,101, 99,116, 91, 50, 93, 0, 42,111, 98, 0, 98,108,111, 99,107,116,121,112, -101, 0, 97,100,114, 99,111,100,101, 0,110, 97,109,101, 91, 49, 50, 56, 93, 0, 42, 98,112, 0, 42, 98,101,122,116, 0,109, 97, -120,114, 99,116, 0,116,111,116,114, 99,116, 0,118, 97,114,116,121,112,101, 0,116,111,116,118,101,114,116, 0,105,112,111, 0, -101,120,116,114, 97,112, 0,114,116, 0, 98,105,116,109, 97,115,107, 0,115,108,105,100,101, 95,109,105,110, 0,115,108,105,100, -101, 95,109, 97,120, 0, 99,117,114,118, 97,108, 0, 42,100,114,105,118,101,114, 0, 99,117,114,118,101, 0, 99,117,114, 0,115, -104,111,119,107,101,121, 0,109,117,116,101,105,112,111, 0,112,111,115, 0,114,101,108, 97,116,105,118,101, 0,116,111,116,101, -108,101,109, 0, 42,119,101,105,103,104,116,115, 0,118,103,114,111,117,112, 91, 54, 52, 93, 0,115,108,105,100,101,114,109,105, -110, 0,115,108,105,100,101,114,109, 97,120, 0,117,105,100, 0,112, 97,100, 51, 0, 42, 97,100,116, 0, 42,114,101,102,107,101, -121, 0,101,108,101,109,115,116,114, 91, 54, 52, 93, 0,101,108,101,109,115,105,122,101, 0, 98,108,111, 99,107, 0, 42,105,112, -111, 0, 42,102,114,111,109, 0,116,111,116,107,101,121, 0,115,108,117,114,112,104, 0,117,105,100,103,101,110, 0, 42,108,105, -110,101, 0, 42,102,111,114,109, 97,116, 0, 98,108,101,110, 0,108,105,110,101,110,111, 0,115,116, 97,114,116, 0,101,110,100, - 0,112, 97,100, 49, 0,102,108, 97,103,115, 0, 99,111,108,111,114, 91, 52, 93, 0,112, 97,100, 91, 52, 93, 0, 42,110, 97,109, -101, 0,110,108,105,110,101,115, 0,108,105,110,101,115, 0, 42, 99,117,114,108, 0, 42,115,101,108,108, 0, 99,117,114, 99, 0, -115,101,108, 99, 0,109, 97,114,107,101,114,115, 0, 42,117,110,100,111, 95, 98,117,102, 0,117,110,100,111, 95,112,111,115, 0, -117,110,100,111, 95,108,101,110, 0, 42, 99,111,109,112,105,108,101,100, 0,109,116,105,109,101, 0,115,105,122,101, 0,115,101, -101,107, 0,100,116,120, 0,112, 97,115,115,101,112, 97,114,116, 97,108,112,104, 97, 0, 99,108,105,112,115,116, 97, 0, 99,108, -105,112,101,110,100, 0,108,101,110,115, 0,111,114,116,104,111, 95,115, 99, 97,108,101, 0,100,114, 97,119,115,105,122,101, 0, -115,101,110,115,111,114, 95,120, 0,115,101,110,115,111,114, 95,121, 0,115,104,105,102,116,120, 0,115,104,105,102,116,121, 0, - 89, 70, 95,100,111,102,100,105,115,116, 0, 42,100,111,102, 95,111, 98, 0,115,101,110,115,111,114, 95,102,105,116, 0,112, 97, -100, 91, 55, 93, 0, 42,115, 99,101,110,101, 0,102,114, 97,109,101,110,114, 0,102,114, 97,109,101,115, 0,111,102,102,115,101, -116, 0,115,102,114, 97, 0,102,105,101, 95,105,109, 97, 0, 99,121, 99,108, 0,111,107, 0,109,117,108,116,105, 95,105,110,100, -101,120, 0,108, 97,121,101,114, 0,112, 97,115,115, 0,105, 98,117,102,115, 0, 42,103,112,117,116,101,120,116,117,114,101, 0, - 42, 97,110,105,109, 0, 42,114,114, 0, 42,114,101,110,100,101,114,115, 91, 56, 93, 0,114,101,110,100,101,114, 95,115,108,111, -116, 0,108, 97,115,116, 95,114,101,110,100,101,114, 95,115,108,111,116, 0,115,111,117,114, 99,101, 0,108, 97,115,116,102,114, - 97,109,101, 0,116,112, 97,103,101,102,108, 97,103, 0,116,111,116, 98,105,110,100, 0,120,114,101,112, 0,121,114,101,112, 0, -116,119,115,116, 97, 0,116,119,101,110,100, 0, 98,105,110,100, 99,111,100,101, 0, 42,114,101,112, 98,105,110,100, 0, 42,112, - 97, 99,107,101,100,102,105,108,101, 0, 42,112,114,101,118,105,101,119, 0,108, 97,115,116,117,112,100, 97,116,101, 0,108, 97, -115,116,117,115,101,100, 0, 97,110,105,109,115,112,101,101,100, 0,103,101,110, 95,120, 0,103,101,110, 95,121, 0,103,101,110, - 95,116,121,112,101, 0,103,101,110, 95,102,108, 97,103, 0, 97,115,112,120, 0, 97,115,112,121, 0,116,101,120, 99,111, 0,109, - 97,112,116,111, 0,109, 97,112,116,111,110,101,103, 0, 98,108,101,110,100,116,121,112,101, 0, 42,111, 98,106,101, 99,116, 0, - 42,116,101,120, 0,117,118,110, 97,109,101, 91, 54, 52, 93, 0,112,114,111,106,120, 0,112,114,111,106,121, 0,112,114,111,106, -122, 0,109, 97,112,112,105,110,103, 0,111,102,115, 91, 51, 93, 0,115,105,122,101, 91, 51, 93, 0,114,111,116, 0,116,101,120, -102,108, 97,103, 0, 99,111,108,111,114,109,111,100,101,108, 0,112,109, 97,112,116,111, 0,112,109, 97,112,116,111,110,101,103, - 0,110,111,114,109, 97,112,115,112, 97, 99,101, 0,119,104,105, 99,104, 95,111,117,116,112,117,116, 0, 98,114,117,115,104, 95, -109, 97,112, 95,109,111,100,101, 0,114, 0,103, 0, 98, 0,107, 0,100,101,102, 95,118, 97,114, 0, 99,111,108,102, 97, 99, 0, -118, 97,114,102, 97, 99, 0,110,111,114,102, 97, 99, 0,100,105,115,112,102, 97, 99, 0,119, 97,114,112,102, 97, 99, 0, 99,111, -108,115,112,101, 99,102, 97, 99, 0,109,105,114,114,102, 97, 99, 0, 97,108,112,104, 97,102, 97, 99, 0,100,105,102,102,102, 97, - 99, 0,115,112,101, 99,102, 97, 99, 0,101,109,105,116,102, 97, 99, 0,104, 97,114,100,102, 97, 99, 0,114, 97,121,109,105,114, -114,102, 97, 99, 0,116,114, 97,110,115,108,102, 97, 99, 0, 97,109, 98,102, 97, 99, 0, 99,111,108,101,109,105,116,102, 97, 99, - 0, 99,111,108,114,101,102,108,102, 97, 99, 0, 99,111,108,116,114, 97,110,115,102, 97, 99, 0,100,101,110,115,102, 97, 99, 0, -115, 99, 97,116,116,101,114,102, 97, 99, 0,114,101,102,108,102, 97, 99, 0,116,105,109,101,102, 97, 99, 0,108,101,110,103,116, -104,102, 97, 99, 0, 99,108,117,109,112,102, 97, 99, 0,100, 97,109,112,102, 97, 99, 0,107,105,110,107,102, 97, 99, 0,114,111, -117,103,104,102, 97, 99, 0,112, 97,100,101,110,115,102, 97, 99, 0,103,114, 97,118,105,116,121,102, 97, 99, 0,108,105,102,101, -102, 97, 99, 0,115,105,122,101,102, 97, 99, 0,105,118,101,108,102, 97, 99, 0,102,105,101,108,100,102, 97, 99, 0,115,104, 97, -100,111,119,102, 97, 99, 0,122,101,110,117,112,102, 97, 99, 0,122,101,110,100,111,119,110,102, 97, 99, 0, 98,108,101,110,100, -102, 97, 99, 0, 42,104, 97,110,100,108,101, 0, 42,112,110, 97,109,101, 0, 42,115,116,110, 97,109,101,115, 0,115,116,121,112, -101,115, 0,118, 97,114,115, 0, 42,118, 97,114,115,116,114, 0, 42,114,101,115,117,108,116, 0, 42, 99,102,114, 97, 0,100, 97, -116, 97, 91, 51, 50, 93, 0, 40, 42,100,111,105,116, 41, 40, 41, 0, 40, 42,105,110,115,116, 97,110, 99,101, 95,105,110,105,116, - 41, 40, 41, 0, 40, 42, 99, 97,108,108, 98, 97, 99,107, 41, 40, 41, 0,118,101,114,115,105,111,110, 0, 97, 0,105,112,111,116, -121,112,101, 0, 42,105,109, 97, 0, 42, 99,117, 98,101, 91, 54, 93, 0,105,109, 97,116, 91, 52, 93, 91, 52, 93, 0,111, 98,105, -109, 97,116, 91, 51, 93, 91, 51, 93, 0,115,116,121,112,101, 0,118,105,101,119,115, 99, 97,108,101, 0,110,111,116,108, 97,121, - 0, 99,117, 98,101,114,101,115, 0,100,101,112,116,104, 0,114,101, 99, 97,108, 99, 0,108, 97,115,116,115,105,122,101, 0,102, - 97,108,108,111,102,102, 95,116,121,112,101, 0,102, 97,108,108,111,102,102, 95,115,111,102,116,110,101,115,115, 0,114, 97,100, -105,117,115, 0, 99,111,108,111,114, 95,115,111,117,114, 99,101, 0,116,111,116,112,111,105,110,116,115, 0,112,100,112, 97,100, - 0,112,115,121,115, 0,112,115,121,115, 95, 99, 97, 99,104,101, 95,115,112, 97, 99,101, 0,111, 98, 95, 99, 97, 99,104,101, 95, -115,112, 97, 99,101, 0, 42,112,111,105,110,116, 95,116,114,101,101, 0, 42,112,111,105,110,116, 95,100, 97,116, 97, 0,110,111, -105,115,101, 95,115,105,122,101, 0,110,111,105,115,101, 95,100,101,112,116,104, 0,110,111,105,115,101, 95,105,110,102,108,117, -101,110, 99,101, 0,110,111,105,115,101, 95, 98, 97,115,105,115, 0,112,100,112, 97,100, 51, 91, 51, 93, 0,110,111,105,115,101, - 95,102, 97, 99, 0,115,112,101,101,100, 95,115, 99, 97,108,101, 0,102, 97,108,108,111,102,102, 95,115,112,101,101,100, 95,115, - 99, 97,108,101, 0,112,100,112, 97,100, 50, 0, 42, 99,111, 98, 97, 0, 42,102, 97,108,108,111,102,102, 95, 99,117,114,118,101, - 0,114,101,115,111,108, 91, 51, 93, 0,105,110,116,101,114,112, 95,116,121,112,101, 0,102,105,108,101, 95,102,111,114,109, 97, -116, 0,101,120,116,101,110,100, 0,115,109,111,107,101,100, 95,116,121,112,101, 0,105,110,116, 95,109,117,108,116,105,112,108, -105,101,114, 0,115,116,105,108,108, 95,102,114, 97,109,101, 0,115,111,117,114, 99,101, 95,112, 97,116,104, 91, 49, 48, 50, 52, - 93, 0, 42,100, 97,116, 97,115,101,116, 0, 99, 97, 99,104,101,100,102,114, 97,109,101, 0,111, 99,101, 97,110,109,111,100, 91, - 54, 52, 93, 0,111,117,116,112,117,116, 0,110,111,105,115,101,115,105,122,101, 0,116,117,114, 98,117,108, 0, 98,114,105,103, -104,116, 0, 99,111,110,116,114, 97,115,116, 0,115, 97,116,117,114, 97,116,105,111,110, 0,114,102, 97, 99, 0,103,102, 97, 99, - 0, 98,102, 97, 99, 0,102,105,108,116,101,114,115,105,122,101, 0,109,103, 95, 72, 0,109,103, 95,108, 97, 99,117,110, 97,114, -105,116,121, 0,109,103, 95,111, 99,116, 97,118,101,115, 0,109,103, 95,111,102,102,115,101,116, 0,109,103, 95,103, 97,105,110, - 0,100,105,115,116, 95, 97,109,111,117,110,116, 0,110,115, 95,111,117,116,115, 99, 97,108,101, 0,118,110, 95,119, 49, 0,118, -110, 95,119, 50, 0,118,110, 95,119, 51, 0,118,110, 95,119, 52, 0,118,110, 95,109,101,120,112, 0,118,110, 95,100,105,115,116, -109, 0,118,110, 95, 99,111,108,116,121,112,101, 0,110,111,105,115,101,100,101,112,116,104, 0,110,111,105,115,101,116,121,112, -101, 0,110,111,105,115,101, 98, 97,115,105,115, 0,110,111,105,115,101, 98, 97,115,105,115, 50, 0,105,109, 97,102,108, 97,103, - 0, 99,114,111,112,120,109,105,110, 0, 99,114,111,112,121,109,105,110, 0, 99,114,111,112,120,109, 97,120, 0, 99,114,111,112, -121,109, 97,120, 0,116,101,120,102,105,108,116,101,114, 0, 97,102,109, 97,120, 0,120,114,101,112,101, 97,116, 0,121,114,101, -112,101, 97,116, 0, 99,104,101, 99,107,101,114,100,105,115,116, 0,110, 97, 98,108, 97, 0,105,117,115,101,114, 0, 42,110,111, -100,101,116,114,101,101, 0, 42,112,108,117,103,105,110, 0, 42,101,110,118, 0, 42,112,100, 0, 42,118,100, 0, 42,111,116, 0, -117,115,101, 95,110,111,100,101,115, 0,108,111, 99, 91, 51, 93, 0,114,111,116, 91, 51, 93, 0,109, 97,116, 91, 52, 93, 91, 52, - 93, 0,109,105,110, 91, 51, 93, 0,109, 97,120, 91, 51, 93, 0, 99,111, 98, 97, 0, 98,108,101,110,100, 95, 99,111,108,111,114, - 91, 51, 93, 0, 98,108,101,110,100, 95,102, 97, 99,116,111,114, 0, 98,108,101,110,100, 95,116,121,112,101, 0,112, 97,100, 91, - 51, 93, 0,109,111,100,101, 0,116,111,116,101,120, 0,115,104,100,119,114, 0,115,104,100,119,103, 0,115,104,100,119, 98, 0, -115,104,100,119,112, 97,100, 0,101,110,101,114,103,121, 0,100,105,115,116, 0,115,112,111,116,115,105,122,101, 0,115,112,111, -116, 98,108,101,110,100, 0,104, 97,105,110,116, 0, 97,116,116, 49, 0, 97,116,116, 50, 0, 42, 99,117,114,102, 97,108,108,111, -102,102, 0,115,104, 97,100,115,112,111,116,115,105,122,101, 0, 98,105, 97,115, 0,115,111,102,116, 0, 99,111,109,112,114,101, -115,115,116,104,114,101,115,104, 0,112, 97,100, 53, 91, 51, 93, 0, 98,117,102,115,105,122,101, 0,115, 97,109,112, 0, 98,117, -102,102,101,114,115, 0,102,105,108,116,101,114,116,121,112,101, 0, 98,117,102,102,108, 97,103, 0, 98,117,102,116,121,112,101, - 0,114, 97,121, 95,115, 97,109,112, 0,114, 97,121, 95,115, 97,109,112,121, 0,114, 97,121, 95,115, 97,109,112,122, 0,114, 97, -121, 95,115, 97,109,112, 95,116,121,112,101, 0, 97,114,101, 97, 95,115,104, 97,112,101, 0, 97,114,101, 97, 95,115,105,122,101, - 0, 97,114,101, 97, 95,115,105,122,101,121, 0, 97,114,101, 97, 95,115,105,122,101,122, 0, 97,100, 97,112,116, 95,116,104,114, -101,115,104, 0,114, 97,121, 95,115, 97,109,112, 95,109,101,116,104,111,100, 0,116,101,120, 97, 99,116, 0,115,104, 97,100,104, - 97,108,111,115,116,101,112, 0,115,117,110, 95,101,102,102,101, 99,116, 95,116,121,112,101, 0,115,107,121, 98,108,101,110,100, -116,121,112,101, 0,104,111,114,105,122,111,110, 95, 98,114,105,103,104,116,110,101,115,115, 0,115,112,114,101, 97,100, 0,115, -117,110, 95, 98,114,105,103,104,116,110,101,115,115, 0,115,117,110, 95,115,105,122,101, 0, 98, 97, 99,107,115, 99, 97,116,116, -101,114,101,100, 95,108,105,103,104,116, 0,115,117,110, 95,105,110,116,101,110,115,105,116,121, 0, 97,116,109, 95,116,117,114, - 98,105,100,105,116,121, 0, 97,116,109, 95,105,110,115, 99, 97,116,116,101,114,105,110,103, 95,102, 97, 99,116,111,114, 0, 97, -116,109, 95,101,120,116,105,110, 99,116,105,111,110, 95,102, 97, 99,116,111,114, 0, 97,116,109, 95,100,105,115,116, 97,110, 99, -101, 95,102, 97, 99,116,111,114, 0,115,107,121, 98,108,101,110,100,102, 97, 99, 0,115,107,121, 95,101,120,112,111,115,117,114, -101, 0,115,107,121, 95, 99,111,108,111,114,115,112, 97, 99,101, 0,112, 97,100, 52, 91, 54, 93, 0, 42,109,116,101,120, 91, 49, - 56, 93, 0,112,114, 95,116,101,120,116,117,114,101, 0,112, 97,100, 54, 91, 52, 93, 0,100,101,110,115,105,116,121, 0,101,109, -105,115,115,105,111,110, 0,115, 99, 97,116,116,101,114,105,110,103, 0,114,101,102,108,101, 99,116,105,111,110, 0,101,109,105, -115,115,105,111,110, 95, 99,111,108, 91, 51, 93, 0,116,114, 97,110,115,109,105,115,115,105,111,110, 95, 99,111,108, 91, 51, 93, - 0,114,101,102,108,101, 99,116,105,111,110, 95, 99,111,108, 91, 51, 93, 0,100,101,110,115,105,116,121, 95,115, 99, 97,108,101, - 0,100,101,112,116,104, 95, 99,117,116,111,102,102, 0, 97,115,121,109,109,101,116,114,121, 0,115,116,101,112,115,105,122,101, - 95,116,121,112,101, 0,115,104, 97,100,101,102,108, 97,103, 0,115,104, 97,100,101, 95,116,121,112,101, 0,112,114,101, 99, 97, - 99,104,101, 95,114,101,115,111,108,117,116,105,111,110, 0,115,116,101,112,115,105,122,101, 0,109,115, 95,100,105,102,102, 0, -109,115, 95,105,110,116,101,110,115,105,116,121, 0,109,115, 95,115,112,114,101, 97,100, 0, 97,108,112,104, 97, 95, 98,108,101, -110,100, 0,102, 97, 99,101, 95,111,114,105,101,110,116, 97,116,105,111,110, 0,109, 97,116,101,114,105, 97,108, 95,116,121,112, -101, 0,115,112,101, 99,114, 0,115,112,101, 99,103, 0,115,112,101, 99, 98, 0,109,105,114,114, 0,109,105,114,103, 0,109,105, -114, 98, 0, 97,109, 98,114, 0, 97,109, 98, 98, 0, 97,109, 98,103, 0, 97,109, 98, 0,101,109,105,116, 0, 97,110,103, 0,115, -112,101, 99,116,114, 97, 0,114, 97,121, 95,109,105,114,114,111,114, 0, 97,108,112,104, 97, 0,114,101,102, 0,115,112,101, 99, - 0,122,111,102,102,115, 0, 97,100,100, 0,116,114, 97,110,115,108,117, 99,101,110, 99,121, 0,118,111,108, 0,103, 97,109,101, - 0,102,114,101,115,110,101,108, 95,109,105,114, 0,102,114,101,115,110,101,108, 95,109,105,114, 95,105, 0,102,114,101,115,110, -101,108, 95,116,114, 97, 0,102,114,101,115,110,101,108, 95,116,114, 97, 95,105, 0,102,105,108,116,101,114, 0,116,120, 95,108, -105,109,105,116, 0,116,120, 95,102, 97,108,108,111,102,102, 0,114, 97,121, 95,100,101,112,116,104, 0,114, 97,121, 95,100,101, -112,116,104, 95,116,114, 97, 0,104, 97,114, 0,115,101,101,100, 49, 0,115,101,101,100, 50, 0,103,108,111,115,115, 95,109,105, -114, 0,103,108,111,115,115, 95,116,114, 97, 0,115, 97,109,112, 95,103,108,111,115,115, 95,109,105,114, 0,115, 97,109,112, 95, -103,108,111,115,115, 95,116,114, 97, 0, 97,100, 97,112,116, 95,116,104,114,101,115,104, 95,109,105,114, 0, 97,100, 97,112,116, - 95,116,104,114,101,115,104, 95,116,114, 97, 0, 97,110,105,115,111, 95,103,108,111,115,115, 95,109,105,114, 0,100,105,115,116, - 95,109,105,114, 0,102, 97,100,101,116,111, 95,109,105,114, 0,115,104, 97,100,101, 95,102,108, 97,103, 0,109,111,100,101, 95, -108, 0,102,108, 97,114,101, 99, 0,115,116, 97,114, 99, 0,108,105,110,101, 99, 0,114,105,110,103, 99, 0,104, 97,115,105,122, -101, 0,102,108, 97,114,101,115,105,122,101, 0,115,117, 98,115,105,122,101, 0,102,108, 97,114,101, 98,111,111,115,116, 0,115, -116,114, 97,110,100, 95,115,116, 97, 0,115,116,114, 97,110,100, 95,101,110,100, 0,115,116,114, 97,110,100, 95,101, 97,115,101, - 0,115,116,114, 97,110,100, 95,115,117,114,102,110,111,114, 0,115,116,114, 97,110,100, 95,109,105,110, 0,115,116,114, 97,110, -100, 95,119,105,100,116,104,102, 97,100,101, 0,115,116,114, 97,110,100, 95,117,118,110, 97,109,101, 91, 54, 52, 93, 0,115, 98, -105, 97,115, 0,108, 98,105, 97,115, 0,115,104, 97,100, 95, 97,108,112,104, 97, 0,115,101,112,116,101,120, 0,114,103, 98,115, -101,108, 0,112,114, 95,116,121,112,101, 0,112,114, 95, 98, 97, 99,107, 0,112,114, 95,108, 97,109,112, 0,109,108, 95,102,108, - 97,103, 0,100,105,102,102, 95,115,104, 97,100,101,114, 0,115,112,101, 99, 95,115,104, 97,100,101,114, 0,114,111,117,103,104, -110,101,115,115, 0,114,101,102,114, 97, 99, 0,112, 97,114, 97,109, 91, 52, 93, 0,114,109,115, 0,100, 97,114,107,110,101,115, -115, 0, 42,114, 97,109,112, 95, 99,111,108, 0, 42,114, 97,109,112, 95,115,112,101, 99, 0,114, 97,109,112,105,110, 95, 99,111, -108, 0,114, 97,109,112,105,110, 95,115,112,101, 99, 0,114, 97,109,112, 98,108,101,110,100, 95, 99,111,108, 0,114, 97,109,112, - 98,108,101,110,100, 95,115,112,101, 99, 0,114, 97,109,112, 95,115,104,111,119, 0,114, 97,109,112,102, 97, 99, 95, 99,111,108, - 0,114, 97,109,112,102, 97, 99, 95,115,112,101, 99, 0, 42,103,114,111,117,112, 0,102,114,105, 99,116,105,111,110, 0,102,104, - 0,114,101,102,108,101, 99,116, 0,102,104,100,105,115,116, 0,120,121,102,114,105, 99,116, 0,100,121,110, 97,109,111,100,101, - 0,115,115,115, 95,114, 97,100,105,117,115, 91, 51, 93, 0,115,115,115, 95, 99,111,108, 91, 51, 93, 0,115,115,115, 95,101,114, -114,111,114, 0,115,115,115, 95,115, 99, 97,108,101, 0,115,115,115, 95,105,111,114, 0,115,115,115, 95, 99,111,108,102, 97, 99, - 0,115,115,115, 95,116,101,120,102, 97, 99, 0,115,115,115, 95,102,114,111,110,116, 0,115,115,115, 95, 98, 97, 99,107, 0,115, -115,115, 95,102,108, 97,103, 0,115,115,115, 95,112,114,101,115,101,116, 0,109, 97,112,116,111, 95,116,101,120,116,117,114,101, -100, 0,115,104, 97,100,111,119,111,110,108,121, 95,102,108, 97,103, 0,105,110,100,101,120, 0,103,112,117,109, 97,116,101,114, -105, 97,108, 0, 42, 98, 98, 0,115,101,108, 99,111,108, 49, 0,115,101,108, 99,111,108, 50, 0,113,117, 97,116, 91, 52, 93, 0, -101,120,112,120, 0,101,120,112,121, 0,101,120,112,122, 0,114, 97,100, 0,114, 97,100, 50, 0,115, 0, 42,109, 97,116, 0, 42, -105,109, 97,116, 0,101,108,101,109,115, 0,100,105,115,112, 0, 42,101,100,105,116,101,108,101,109,115, 0, 42, 42,109, 97,116, - 0,102,108, 97,103, 50, 0,116,111,116, 99,111,108, 0,119,105,114,101,115,105,122,101, 0,114,101,110,100,101,114,115,105,122, -101, 0,116,104,114,101,115,104, 0, 42,108, 97,115,116,101,108,101,109, 0,118,101, 99, 91, 51, 93, 91, 51, 93, 0, 97,108,102, - 97, 0,119,101,105,103,104,116, 0,104, 49, 0,104, 50, 0,102, 49, 0,102, 50, 0,102, 51, 0,104,105,100,101, 0,118,101, 99, - 91, 52, 93, 0,109, 97,116, 95,110,114, 0,112,110,116,115,117, 0,112,110,116,115,118, 0,114,101,115,111,108,117, 0,114,101, -115,111,108,118, 0,111,114,100,101,114,117, 0,111,114,100,101,114,118, 0,102,108, 97,103,117, 0,102,108, 97,103,118, 0, 42, -107,110,111,116,115,117, 0, 42,107,110,111,116,115,118, 0,116,105,108,116, 95,105,110,116,101,114,112, 0,114, 97,100,105,117, -115, 95,105,110,116,101,114,112, 0, 99,104, 97,114,105,100,120, 0,107,101,114,110, 0,119, 0,104, 0,110,117,114, 98,115, 0, - 42,107,101,121,105,110,100,101,120, 0,115,104, 97,112,101,110,114, 0,110,117,114, 98, 0, 42,101,100,105,116,110,117,114, 98, - 0, 42, 98,101,118,111, 98,106, 0, 42,116, 97,112,101,114,111, 98,106, 0, 42,116,101,120,116,111,110, 99,117,114,118,101, 0, - 42,112, 97,116,104, 0, 42,107,101,121, 0, 98,101,118, 0,100,114, 97,119,102,108, 97,103, 0,116,119,105,115,116, 95,109,111, -100,101, 0,116,119,105,115,116, 95,115,109,111,111,116,104, 0,115,109, 97,108,108, 99, 97,112,115, 95,115, 99, 97,108,101, 0, -112, 97,116,104,108,101,110, 0, 98,101,118,114,101,115,111,108, 0,119,105,100,116,104, 0,101,120,116, 49, 0,101,120,116, 50, - 0,114,101,115,111,108,117, 95,114,101,110, 0,114,101,115,111,108,118, 95,114,101,110, 0, 97, 99,116,110,117, 0, 42,108, 97, -115,116,115,101,108, 0,115,112, 97, 99,101,109,111,100,101, 0,115,112, 97, 99,105,110,103, 0,108,105,110,101,100,105,115,116, - 0,115,104,101, 97,114, 0,102,115,105,122,101, 0,119,111,114,100,115,112, 97, 99,101, 0,117,108,112,111,115, 0,117,108,104, -101,105,103,104,116, 0,120,111,102, 0,121,111,102, 0,108,105,110,101,119,105,100,116,104, 0, 42,115,116,114, 0, 42,115,101, -108, 98,111,120,101,115, 0, 42,101,100,105,116,102,111,110,116, 0,102, 97,109,105,108,121, 91, 50, 52, 93, 0, 42,118,102,111, -110,116, 0, 42,118,102,111,110,116, 98, 0, 42,118,102,111,110,116,105, 0, 42,118,102,111,110,116, 98,105, 0,115,101,112, 99, -104, 97,114, 0, 99,116,105,109,101, 0,116,111,116, 98,111,120, 0, 97, 99,116, 98,111,120, 0, 42,116, 98, 0,115,101,108,115, -116, 97,114,116, 0,115,101,108,101,110,100, 0, 42,115,116,114,105,110,102,111, 0, 99,117,114,105,110,102,111, 0, 42,109,112, -111,108,121, 0, 42,109,116,112,111,108,121, 0, 42,109,108,111,111,112, 0, 42,109,108,111,111,112,117,118, 0, 42,109,108,111, -111,112, 99,111,108, 0, 42,109,102, 97, 99,101, 0, 42,109,116,102, 97, 99,101, 0, 42,116,102, 97, 99,101, 0, 42,109,118,101, -114,116, 0, 42,109,101,100,103,101, 0, 42,100,118,101,114,116, 0, 42,109, 99,111,108, 0, 42,109,115,116,105, 99,107,121, 0, - 42,116,101,120, 99,111,109,101,115,104, 0, 42,109,115,101,108,101, 99,116, 0, 42,101,100,105,116, 95, 98,116,109,101,115,104, - 0,118,100, 97,116, 97, 0,101,100, 97,116, 97, 0,102,100, 97,116, 97, 0,112,100, 97,116, 97, 0,108,100, 97,116, 97, 0,116, -111,116,101,100,103,101, 0,116,111,116,102, 97, 99,101, 0,116,111,116,115,101,108,101, 99,116, 0,116,111,116,112,111,108,121, - 0,116,111,116,108,111,111,112, 0, 97, 99,116, 95,102, 97, 99,101, 0,115,109,111,111,116,104,114,101,115,104, 0,115,117, 98, -100,105,118, 0,115,117, 98,100,105,118,114, 0,115,117, 98,115,117,114,102,116,121,112,101, 0,101,100,105,116,102,108, 97,103, - 0, 42,109,114, 0, 42,116,112, 97,103,101, 0,117,118, 91, 52, 93, 91, 50, 93, 0, 99,111,108, 91, 52, 93, 0,116,114, 97,110, -115,112, 0,116,105,108,101, 0,117,110,119,114, 97,112, 0,118, 49, 0,118, 50, 0,118, 51, 0,118, 52, 0,101,100, 99,111,100, -101, 0, 99,114,101, 97,115,101, 0, 98,119,101,105,103,104,116, 0,100,101,102, 95,110,114, 0, 42,100,119, 0,116,111,116,119, -101,105,103,104,116, 0, 99,111, 91, 51, 93, 0,110,111, 91, 51, 93, 0,108,111,111,112,115,116, 97,114,116, 0,118, 0,101, 0, -117,118, 91, 50, 93, 0, 99,111, 91, 50, 93, 0,102, 0,105, 0,115, 91, 50, 53, 54, 93, 0,116,111,116,100,105,115,112, 0,108, -101,118,101,108, 0, 40, 42,100,105,115,112,115, 41, 40, 41, 0, 42,104,105,100,100,101,110, 0,118, 91, 52, 93, 0,109,105,100, - 0,112, 97,100, 91, 50, 93, 0,118, 91, 50, 93, 0, 42,102, 97, 99,101,115, 0, 42, 99,111,108,102, 97, 99,101,115, 0, 42,101, -100,103,101,115, 0, 42,118,101,114,116,115, 0,108,101,118,101,108,115, 0,108,101,118,101,108, 95, 99,111,117,110,116, 0, 99, -117,114,114,101,110,116, 0,110,101,119,108,118,108, 0,101,100,103,101,108,118,108, 0,112,105,110,108,118,108, 0,114,101,110, -100,101,114,108,118,108, 0,117,115,101, 95, 99,111,108, 0, 42,101,100,103,101, 95,102,108, 97,103,115, 0, 42,101,100,103,101, - 95, 99,114,101, 97,115,101,115, 0,115,116, 97, 99,107,105,110,100,101,120, 0, 42,101,114,114,111,114, 0,109,111,100,105,102, -105,101,114, 0, 42,116,101,120,116,117,114,101, 0, 42,109, 97,112, 95,111, 98,106,101, 99,116, 0,117,118,108, 97,121,101,114, - 95,110, 97,109,101, 91, 54, 52, 93, 0,117,118,108, 97,121,101,114, 95,116,109,112, 0,116,101,120,109, 97,112,112,105,110,103, - 0,115,117, 98,100,105,118, 84,121,112,101, 0,114,101,110,100,101,114, 76,101,118,101,108,115, 0, 42,101,109, 67, 97, 99,104, -101, 0, 42,109, 67, 97, 99,104,101, 0,115,116,114,101,110,103,116,104, 0,100,101,102, 97,120,105,115, 0,112, 97,100, 91, 54, - 93, 0,108,101,110,103,116,104, 0,114, 97,110,100,111,109,105,122,101, 0,115,101,101,100, 0, 42,111, 98, 95, 97,114,109, 0, - 42,115,116, 97,114,116, 95, 99, 97,112, 0, 42,101,110,100, 95, 99, 97,112, 0, 42, 99,117,114,118,101, 95,111, 98, 0, 42,111, -102,102,115,101,116, 95,111, 98, 0,111,102,102,115,101,116, 91, 51, 93, 0,115, 99, 97,108,101, 91, 51, 93, 0,109,101,114,103, -101, 95,100,105,115,116, 0,102,105,116, 95,116,121,112,101, 0,111,102,102,115,101,116, 95,116,121,112,101, 0, 99,111,117,110, -116, 0, 97,120,105,115, 0,116,111,108,101,114, 97,110, 99,101, 0, 42,109,105,114,114,111,114, 95,111, 98, 0,115,112,108,105, -116, 95, 97,110,103,108,101, 0,118, 97,108,117,101, 0,114,101,115, 0,118, 97,108, 95,102,108, 97,103,115, 0,108,105,109, 95, -102,108, 97,103,115, 0,101, 95,102,108, 97,103,115, 0, 98,101,118,101,108, 95, 97,110,103,108,101, 0,100,101,102,103,114,112, - 95,110, 97,109,101, 91, 54, 52, 93, 0, 42,100,111,109, 97,105,110, 0, 42,102,108,111,119, 0, 42, 99,111,108,108, 0,116,105, -109,101, 0,100,105,114,101, 99,116,105,111,110, 0,109,105,100,108,101,118,101,108, 0, 42,112,114,111,106,101, 99,116,111,114, -115, 91, 49, 48, 93, 0, 42,105,109, 97,103,101, 0,110,117,109, 95,112,114,111,106,101, 99,116,111,114,115, 0, 97,115,112,101, - 99,116,120, 0, 97,115,112,101, 99,116,121, 0,115, 99, 97,108,101,120, 0,115, 99, 97,108,101,121, 0,112,101,114, 99,101,110, -116, 0,102, 97, 99,101, 67,111,117,110,116, 0,102, 97, 99, 0,114,101,112,101, 97,116, 0, 42,111, 98,106,101, 99,116, 99,101, -110,116,101,114, 0,115,116, 97,114,116,120, 0,115,116, 97,114,116,121, 0,104,101,105,103,104,116, 0,110, 97,114,114,111,119, - 0,115,112,101,101,100, 0,100, 97,109,112, 0,102, 97,108,108,111,102,102, 0,116,105,109,101,111,102,102,115, 0,108,105,102, -101,116,105,109,101, 0,100,101,102,111,114,109,102,108, 97,103, 0,109,117,108,116,105, 0, 42,112,114,101,118, 67,111,115, 0, -115,117, 98,116, 97,114,103,101,116, 91, 54, 52, 93, 0,112, 97,114,101,110,116,105,110,118, 91, 52, 93, 91, 52, 93, 0, 99,101, -110,116, 91, 51, 93, 0, 42,105,110,100,101,120, 97,114, 0,116,111,116,105,110,100,101,120, 0,102,111,114, 99,101, 0, 42, 99, -108,111,116,104, 79, 98,106,101, 99,116, 0, 42,115,105,109, 95,112, 97,114,109,115, 0, 42, 99,111,108,108, 95,112, 97,114,109, -115, 0, 42,112,111,105,110,116, 95, 99, 97, 99,104,101, 0,112,116, 99, 97, 99,104,101,115, 0, 42,120, 0, 42,120,110,101,119, - 0, 42,120,111,108,100, 0, 42, 99,117,114,114,101,110,116, 95,120,110,101,119, 0, 42, 99,117,114,114,101,110,116, 95,120, 0, - 42, 99,117,114,114,101,110,116, 95,118, 0, 42,109,102, 97, 99,101,115, 0,110,117,109,118,101,114,116,115, 0,110,117,109,102, - 97, 99,101,115, 0,116,105,109,101, 95,120, 0,116,105,109,101, 95,120,110,101,119, 0, 42, 98,118,104,116,114,101,101, 0, 42, -118, 0, 42,100,109, 0, 99,102,114, 97, 0,111,112,101,114, 97,116,105,111,110, 0,118,101,114,116,101,120, 0,116,111,116,105, -110,102,108,117,101,110, 99,101, 0,103,114,105,100,115,105,122,101, 0, 42, 98,105,110,100,105,110,102,108,117,101,110, 99,101, -115, 0, 42, 98,105,110,100,111,102,102,115,101,116,115, 0, 42, 98,105,110,100, 99, 97,103,101, 99,111,115, 0,116,111,116, 99, - 97,103,101,118,101,114,116, 0, 42,100,121,110,103,114,105,100, 0, 42,100,121,110,105,110,102,108,117,101,110, 99,101,115, 0, - 42,100,121,110,118,101,114,116,115, 0, 42,112, 97,100, 50, 0,100,121,110,103,114,105,100,115,105,122,101, 0,100,121,110, 99, -101,108,108,109,105,110, 91, 51, 93, 0,100,121,110, 99,101,108,108,119,105,100,116,104, 0, 98,105,110,100,109, 97,116, 91, 52, - 93, 91, 52, 93, 0, 42, 98,105,110,100,119,101,105,103,104,116,115, 0, 42, 98,105,110,100, 99,111,115, 0, 40, 42, 98,105,110, -100,102,117,110, 99, 41, 40, 41, 0, 42,112,115,121,115, 0,116,111,116,100,109,118,101,114,116, 0,116,111,116,100,109,101,100, -103,101, 0,116,111,116,100,109,102, 97, 99,101, 0,112,111,115,105,116,105,111,110, 0,114, 97,110,100,111,109, 95,112,111,115, -105,116,105,111,110, 0, 42,102, 97, 99,101,112, 97, 0,118,103,114,111,117,112, 0,112,114,111,116,101, 99,116, 0,108,118,108, - 0,115, 99,117,108,112,116,108,118,108, 0,116,111,116,108,118,108, 0,115,105,109,112,108,101, 0, 42,102,115,115, 0, 42,116, - 97,114,103,101,116, 0, 42, 97,117,120, 84, 97,114,103,101,116, 0,118,103,114,111,117,112, 95,110, 97,109,101, 91, 54, 52, 93, - 0,107,101,101,112, 68,105,115,116, 0,115,104,114,105,110,107, 84,121,112,101, 0,115,104,114,105,110,107, 79,112,116,115, 0, -112,114,111,106, 65,120,105,115, 0,115,117, 98,115,117,114,102, 76,101,118,101,108,115, 0, 42,111,114,105,103,105,110, 0,102, - 97, 99,116,111,114, 0,108,105,109,105,116, 91, 50, 93, 0,111,114,105,103,105,110, 79,112,116,115, 0,111,102,102,115,101,116, - 95,102, 97, 99, 0,111,102,102,115,101,116, 95,102, 97, 99, 95,118,103, 0, 99,114,101, 97,115,101, 95,105,110,110,101,114, 0, - 99,114,101, 97,115,101, 95,111,117,116,101,114, 0, 99,114,101, 97,115,101, 95,114,105,109, 0,109, 97,116, 95,111,102,115, 0, -109, 97,116, 95,111,102,115, 95,114,105,109, 0, 42,111, 98, 95, 97,120,105,115, 0,115,116,101,112,115, 0,114,101,110,100,101, -114, 95,115,116,101,112,115, 0,105,116,101,114, 0,115, 99,114,101,119, 95,111,102,115, 0, 97,110,103,108,101, 0, 42,111, 99, -101, 97,110, 0, 42,111, 99,101, 97,110, 99, 97, 99,104,101, 0,114,101,115,111,108,117,116,105,111,110, 0,115,112, 97,116,105, - 97,108, 95,115,105,122,101, 0,119,105,110,100, 95,118,101,108,111, 99,105,116,121, 0,115,109, 97,108,108,101,115,116, 95,119, - 97,118,101, 0,119, 97,118,101, 95, 97,108,105,103,110,109,101,110,116, 0,119, 97,118,101, 95,100,105,114,101, 99,116,105,111, -110, 0,119, 97,118,101, 95,115, 99, 97,108,101, 0, 99,104,111,112, 95, 97,109,111,117,110,116, 0,102,111, 97,109, 95, 99,111, -118,101,114, 97,103,101, 0, 98, 97,107,101,115,116, 97,114,116, 0, 98, 97,107,101,101,110,100, 0, 99, 97, 99,104,101,112, 97, -116,104, 91, 49, 48, 50, 52, 93, 0,102,111, 97,109,108, 97,121,101,114,110, 97,109,101, 91, 54, 52, 93, 0, 99, 97, 99,104,101, -100, 0,103,101,111,109,101,116,114,121, 95,109,111,100,101, 0,114,101,102,114,101,115,104, 0,114,101,112,101, 97,116, 95,120, - 0,114,101,112,101, 97,116, 95,121, 0,102,111, 97,109, 95,102, 97,100,101, 0, 42,111, 98,106,101, 99,116, 95,102,114,111,109, - 0, 42,111, 98,106,101, 99,116, 95,116,111, 0,102, 97,108,108,111,102,102, 95,114, 97,100,105,117,115, 0,101,100,105,116, 95, -102,108, 97,103,115, 0,100,101,102, 97,117,108,116, 95,119,101,105,103,104,116, 0, 42, 99,109, 97,112, 95, 99,117,114,118,101, - 0, 97,100,100, 95,116,104,114,101,115,104,111,108,100, 0,114,101,109, 95,116,104,114,101,115,104,111,108,100, 0,109, 97,115, -107, 95, 99,111,110,115,116, 97,110,116, 0,109, 97,115,107, 95,100,101,102,103,114,112, 95,110, 97,109,101, 91, 54, 52, 93, 0, -109, 97,115,107, 95,116,101,120, 95,117,115,101, 95, 99,104, 97,110,110,101,108, 0, 42,109, 97,115,107, 95,116,101,120,116,117, -114,101, 0, 42,109, 97,115,107, 95,116,101,120, 95,109, 97,112, 95,111, 98,106, 0,109, 97,115,107, 95,116,101,120, 95,109, 97, -112,112,105,110,103, 0,109, 97,115,107, 95,116,101,120, 95,117,118,108, 97,121,101,114, 95,110, 97,109,101, 91, 54, 52, 93, 0, -112, 97,100, 95,105, 49, 0,100,101,102,103,114,112, 95,110, 97,109,101, 95, 97, 91, 54, 52, 93, 0,100,101,102,103,114,112, 95, -110, 97,109,101, 95, 98, 91, 54, 52, 93, 0,100,101,102, 97,117,108,116, 95,119,101,105,103,104,116, 95, 97, 0,100,101,102, 97, -117,108,116, 95,119,101,105,103,104,116, 95, 98, 0,109,105,120, 95,109,111,100,101, 0,109,105,120, 95,115,101,116, 0,112, 97, -100, 95, 99, 49, 91, 54, 93, 0,112,114,111,120,105,109,105,116,121, 95,109,111,100,101, 0,112,114,111,120,105,109,105,116,121, - 95,102,108, 97,103,115, 0, 42,112,114,111,120,105,109,105,116,121, 95,111, 98, 95,116, 97,114,103,101,116, 0,109,105,110, 95, -100,105,115,116, 0,109, 97,120, 95,100,105,115,116, 0,112, 97,100, 95,115, 49, 0, 42, 99, 97,110,118, 97,115, 0, 42, 98,114, -117,115,104, 0,116,104,114,101,115,104,111,108,100, 0,115, 99, 97,108,101, 0,104,101,114,109,105,116,101, 95,110,117,109, 0, - 42,108, 97,116,116, 0,112,110,116,115,119, 0,111,112,110,116,115,117, 0,111,112,110,116,115,118, 0,111,112,110,116,115,119, - 0,116,121,112,101,117, 0,116,121,112,101,118, 0,116,121,112,101,119, 0,102,117, 0,102,118, 0,102,119, 0,100,117, 0,100, -118, 0,100,119, 0, 42,100,101,102, 0, 42,108, 97,116,116,105, 99,101,100, 97,116, 97, 0,108, 97,116,109, 97,116, 91, 52, 93, - 91, 52, 93, 0, 42,101,100,105,116,108, 97,116,116, 0,118,101, 99, 91, 56, 93, 91, 51, 93, 0, 42,115, 99,117,108,112,116, 0, -112, 97,114,116,121,112,101, 0,112, 97,114, 49, 0,112, 97,114, 50, 0,112, 97,114, 51, 0,112, 97,114,115,117, 98,115,116,114, - 91, 54, 52, 93, 0, 42,116,114, 97, 99,107, 0, 42,112,114,111,120,121, 0, 42,112,114,111,120,121, 95,103,114,111,117,112, 0, - 42,112,114,111,120,121, 95,102,114,111,109, 0, 42, 97, 99,116,105,111,110, 0, 42,112,111,115,101,108,105, 98, 0, 42,112,111, -115,101, 0, 42,103,112,100, 0, 97,118,115, 0, 42,109,112, 97,116,104, 0, 99,111,110,115,116,114, 97,105,110,116, 67,104, 97, -110,110,101,108,115, 0,101,102,102,101, 99,116, 0,100,101,102, 98, 97,115,101, 0,109,111,100,105,102,105,101,114,115, 0,114, -101,115,116,111,114,101, 95,109,111,100,101, 0, 42,109, 97,116, 98,105,116,115, 0, 97, 99,116, 99,111,108, 0,100,108,111, 99, - 91, 51, 93, 0,111,114,105,103, 91, 51, 93, 0,100,115,105,122,101, 91, 51, 93, 0,100,115, 99, 97,108,101, 91, 51, 93, 0,100, -114,111,116, 91, 51, 93, 0,100,113,117, 97,116, 91, 52, 93, 0,114,111,116, 65,120,105,115, 91, 51, 93, 0,100,114,111,116, 65, -120,105,115, 91, 51, 93, 0,114,111,116, 65,110,103,108,101, 0,100,114,111,116, 65,110,103,108,101, 0,111, 98,109, 97,116, 91, - 52, 93, 91, 52, 93, 0, 99,111,110,115,116,105,110,118, 91, 52, 93, 91, 52, 93, 0,105,109, 97,116, 95,114,101,110, 91, 52, 93, - 91, 52, 93, 0,108, 97,121, 0,112, 97,100, 54, 0, 99,111,108, 98,105,116,115, 0,116,114, 97,110,115,102,108, 97,103, 0,112, -114,111,116,101, 99,116,102,108, 97,103, 0,116,114, 97, 99,107,102,108, 97,103, 0,117,112,102,108, 97,103, 0,110,108, 97,102, -108, 97,103, 0,105,112,111,102,108, 97,103, 0,115, 99, 97,102,108, 97,103, 0,115, 99, 97,118,105,115,102,108, 97,103, 0,112, - 97,100, 53, 0,100,117,112,111,110, 0,100,117,112,111,102,102, 0,100,117,112,115,116, 97, 0,100,117,112,101,110,100, 0,115, -102, 0,109, 97,115,115, 0,100, 97,109,112,105,110,103, 0,105,110,101,114,116,105, 97, 0,102,111,114,109,102, 97, 99,116,111, -114, 0,114,100, 97,109,112,105,110,103, 0,109, 97,114,103,105,110, 0,109, 97,120, 95,118,101,108, 0,109,105,110, 95,118,101, -108, 0,109, 95, 99,111,110,116, 97, 99,116, 80,114,111, 99,101,115,115,105,110,103, 84,104,114,101,115,104,111,108,100, 0,111, - 98,115,116, 97, 99,108,101, 82, 97,100, 0,114,111,116,109,111,100,101, 0, 98,111,117,110,100,116,121,112,101, 0, 99,111,108, -108,105,115,105,111,110, 95, 98,111,117,110,100,116,121,112,101, 0,114,101,115,116,114,105, 99,116,102,108, 97,103, 0,100,116, - 0,101,109,112,116,121, 95,100,114, 97,119,116,121,112,101, 0,101,109,112,116,121, 95,100,114, 97,119,115,105,122,101, 0,100, -117,112,102, 97, 99,101,115, 99, 97, 0,112,114,111,112, 0,115,101,110,115,111,114,115, 0, 99,111,110,116,114,111,108,108,101, -114,115, 0, 97, 99,116,117, 97,116,111,114,115, 0, 98, 98,115,105,122,101, 91, 51, 93, 0, 97, 99,116,100,101,102, 0,103, 97, -109,101,102,108, 97,103, 0,103, 97,109,101,102,108, 97,103, 50, 0, 42, 98,115,111,102,116, 0,115,111,102,116,102,108, 97,103, - 0, 97,110,105,115,111,116,114,111,112,105, 99, 70,114,105, 99,116,105,111,110, 91, 51, 93, 0, 99,111,110,115,116,114, 97,105, -110,116,115, 0,110,108, 97,115,116,114,105,112,115, 0,104,111,111,107,115, 0,112, 97,114,116,105, 99,108,101,115,121,115,116, -101,109, 0, 42,115,111,102,116, 0, 42,100,117,112, 95,103,114,111,117,112, 0, 98,111,100,121, 95,116,121,112,101, 0,115,104, - 97,112,101,102,108, 97,103, 0, 42,102,108,117,105,100,115,105,109, 83,101,116,116,105,110,103,115, 0, 42,100,101,114,105,118, -101,100, 68,101,102,111,114,109, 0, 42,100,101,114,105,118,101,100, 70,105,110, 97,108, 0,108, 97,115,116, 68, 97,116, 97, 77, - 97,115,107, 0, 99,117,115,116,111,109,100, 97,116, 97, 95,109, 97,115,107, 0,115,116, 97,116,101, 0,105,110,105,116, 95,115, -116, 97,116,101, 0,103,112,117,108, 97,109,112, 0,112, 99, 95,105,100,115, 0, 42,100,117,112,108,105,108,105,115,116, 0,105, -109, 97, 95,111,102,115, 91, 50, 93, 0, 99,117,114,105,110,100,101,120, 0, 97, 99,116,105,118,101, 0,111,114,105,103,108, 97, -121, 0,111,109, 97,116, 91, 52, 93, 91, 52, 93, 0,111,114, 99,111, 91, 51, 93, 0,110,111, 95,100,114, 97,119, 0, 97,110,105, -109, 97,116,101,100, 0,100,101,102,108,101, 99,116, 0,102,111,114, 99,101,102,105,101,108,100, 0,115,104, 97,112,101, 0,116, -101,120, 95,109,111,100,101, 0,107,105,110,107, 0,107,105,110,107, 95, 97,120,105,115, 0,122,100,105,114, 0,102, 95,115,116, -114,101,110,103,116,104, 0,102, 95,100, 97,109,112, 0,102, 95,102,108,111,119, 0,102, 95,115,105,122,101, 0,102, 95,112,111, -119,101,114, 0,109, 97,120,100,105,115,116, 0,109,105,110,100,105,115,116, 0,102, 95,112,111,119,101,114, 95,114, 0,109, 97, -120,114, 97,100, 0,109,105,110,114, 97,100, 0,112,100,101,102, 95,100, 97,109,112, 0,112,100,101,102, 95,114,100, 97,109,112, - 0,112,100,101,102, 95,112,101,114,109, 0,112,100,101,102, 95,102,114,105, 99,116, 0,112,100,101,102, 95,114,102,114,105, 99, -116, 0,112,100,101,102, 95,115,116,105, 99,107,110,101,115,115, 0, 97, 98,115,111,114,112,116,105,111,110, 0,112,100,101,102, - 95,115, 98,100, 97,109,112, 0,112,100,101,102, 95,115, 98,105,102,116, 0,112,100,101,102, 95,115, 98,111,102,116, 0, 99,108, -117,109,112, 95,102, 97, 99, 0, 99,108,117,109,112, 95,112,111,119, 0,107,105,110,107, 95,102,114,101,113, 0,107,105,110,107, - 95,115,104, 97,112,101, 0,107,105,110,107, 95, 97,109,112, 0,102,114,101,101, 95,101,110,100, 0,116,101,120, 95,110, 97, 98, -108, 97, 0, 42,114,110,103, 0,102, 95,110,111,105,115,101, 0,119,101,105,103,104,116, 91, 49, 51, 93, 0,103,108,111, 98, 97, -108, 95,103,114, 97,118,105,116,121, 0,114,116, 91, 51, 93, 0,116,111,116,100, 97,116, 97, 0,102,114, 97,109,101, 0,116,111, -116,112,111,105,110,116, 0,100, 97,116, 97, 95,116,121,112,101,115, 0, 42,100, 97,116, 97, 91, 56, 93, 0, 42, 99,117,114, 91, - 56, 93, 0,101,120,116,114, 97,100, 97,116, 97, 0,115,116,101,112, 0,115,105,109,102,114, 97,109,101, 0,115,116, 97,114,116, -102,114, 97,109,101, 0,101,110,100,102,114, 97,109,101, 0,101,100,105,116,102,114, 97,109,101, 0,108, 97,115,116, 95,101,120, - 97, 99,116, 0,108, 97,115,116, 95,118, 97,108,105,100, 0, 99,111,109,112,114,101,115,115,105,111,110, 0,112,114,101,118, 95, -110, 97,109,101, 91, 54, 52, 93, 0,105,110,102,111, 91, 54, 52, 93, 0,112, 97,116,104, 91, 49, 48, 50, 52, 93, 0, 42, 99, 97, - 99,104,101,100, 95,102,114, 97,109,101,115, 0,109,101,109, 95, 99, 97, 99,104,101, 0, 42,101,100,105,116, 0, 40, 42,102,114, -101,101, 95,101,100,105,116, 41, 40, 41, 0,108,105,110, 83,116,105,102,102, 0, 97,110,103, 83,116,105,102,102, 0,118,111,108, -117,109,101, 0,118,105,116,101,114, 97,116,105,111,110,115, 0,112,105,116,101,114, 97,116,105,111,110,115, 0,100,105,116,101, -114, 97,116,105,111,110,115, 0, 99,105,116,101,114, 97,116,105,111,110,115, 0,107, 83, 82, 72, 82, 95, 67, 76, 0,107, 83, 75, - 72, 82, 95, 67, 76, 0,107, 83, 83, 72, 82, 95, 67, 76, 0,107, 83, 82, 95, 83, 80, 76, 84, 95, 67, 76, 0,107, 83, 75, 95, 83, - 80, 76, 84, 95, 67, 76, 0,107, 83, 83, 95, 83, 80, 76, 84, 95, 67, 76, 0,107, 86, 67, 70, 0,107, 68, 80, 0,107, 68, 71, 0, -107, 76, 70, 0,107, 80, 82, 0,107, 86, 67, 0,107, 68, 70, 0,107, 77, 84, 0,107, 67, 72, 82, 0,107, 75, 72, 82, 0,107, 83, - 72, 82, 0,107, 65, 72, 82, 0, 99,111,108,108,105,115,105,111,110,102,108, 97,103,115, 0,110,117,109, 99,108,117,115,116,101, -114,105,116,101,114, 97,116,105,111,110,115, 0,119,101,108,100,105,110,103, 0,116,111,116,115,112,114,105,110,103, 0, 42, 98, -112,111,105,110,116, 0, 42, 98,115,112,114,105,110,103, 0,109,115,103, 95,108,111, 99,107, 0,109,115,103, 95,118, 97,108,117, -101, 0,110,111,100,101,109, 97,115,115, 0,110, 97,109,101,100, 86, 71, 95, 77, 97,115,115, 91, 54, 52, 93, 0,103,114, 97,118, - 0,109,101,100,105, 97,102,114,105, 99,116, 0,114,107,108,105,109,105,116, 0,112,104,121,115,105, 99,115, 95,115,112,101,101, -100, 0,103,111, 97,108,115,112,114,105,110,103, 0,103,111, 97,108,102,114,105, 99,116, 0,109,105,110,103,111, 97,108, 0,109, - 97,120,103,111, 97,108, 0,100,101,102,103,111, 97,108, 0,118,101,114,116,103,114,111,117,112, 0,110, 97,109,101,100, 86, 71, - 95, 83,111,102,116,103,111, 97,108, 91, 54, 52, 93, 0,102,117,122,122,121,110,101,115,115, 0,105,110,115,112,114,105,110,103, - 0,105,110,102,114,105, 99,116, 0,110, 97,109,101,100, 86, 71, 95, 83,112,114,105,110,103, 95, 75, 91, 54, 52, 93, 0,101,102, -114, 97, 0,105,110,116,101,114,118, 97,108, 0,108,111, 99, 97,108, 0,115,111,108,118,101,114,102,108, 97,103,115, 0, 42, 42, -107,101,121,115, 0,116,111,116,112,111,105,110,116,107,101,121, 0,115,101, 99,111,110,100,115,112,114,105,110,103, 0, 99,111, -108, 98, 97,108,108, 0, 98, 97,108,108,100, 97,109,112, 0, 98, 97,108,108,115,116,105,102,102, 0,115, 98, 99, 95,109,111,100, -101, 0, 97,101,114,111,101,100,103,101, 0,109,105,110,108,111,111,112,115, 0,109, 97,120,108,111,111,112,115, 0, 99,104,111, -107,101, 0,115,111,108,118,101,114, 95, 73, 68, 0,112,108, 97,115,116,105, 99, 0,115,112,114,105,110,103,112,114,101,108,111, - 97,100, 0, 42,115, 99,114, 97,116, 99,104, 0,115,104,101, 97,114,115,116,105,102,102, 0,105,110,112,117,115,104, 0, 42,112, -111,105,110,116, 99, 97, 99,104,101, 0, 42,101,102,102,101, 99,116,111,114, 95,119,101,105,103,104,116,115, 0,108, 99,111,109, - 91, 51, 93, 0,108,114,111,116, 91, 51, 93, 91, 51, 93, 0,108,115, 99, 97,108,101, 91, 51, 93, 91, 51, 93, 0,108, 97,115,116, - 95,102,114, 97,109,101, 0,118,101,108, 91, 51, 93, 0, 42,102,109,100, 0,115,104,111,119, 95, 97,100,118, 97,110, 99,101,100, -111,112,116,105,111,110,115, 0,114,101,115,111,108,117,116,105,111,110,120,121,122, 0,112,114,101,118,105,101,119,114,101,115, -120,121,122, 0,114,101, 97,108,115,105,122,101, 0,103,117,105, 68,105,115,112,108, 97,121, 77,111,100,101, 0,114,101,110,100, -101,114, 68,105,115,112,108, 97,121, 77,111,100,101, 0,118,105,115, 99,111,115,105,116,121, 86, 97,108,117,101, 0,118,105,115, - 99,111,115,105,116,121, 77,111,100,101, 0,118,105,115, 99,111,115,105,116,121, 69,120,112,111,110,101,110,116, 0,103,114, 97, -118, 91, 51, 93, 0, 97,110,105,109, 83,116, 97,114,116, 0, 97,110,105,109, 69,110,100, 0, 98, 97,107,101, 83,116, 97,114,116, - 0, 98, 97,107,101, 69,110,100, 0,102,114, 97,109,101, 79,102,102,115,101,116, 0,103,115,116, 97,114, 0,109, 97,120, 82,101, -102,105,110,101, 0,105,110,105, 86,101,108,120, 0,105,110,105, 86,101,108,121, 0,105,110,105, 86,101,108,122, 0, 42,111,114, -103, 77,101,115,104, 0, 42,109,101,115,104, 66, 66, 0,115,117,114,102,100, 97,116, 97, 80, 97,116,104, 91, 49, 48, 50, 52, 93, - 0, 98, 98, 83,116, 97,114,116, 91, 51, 93, 0, 98, 98, 83,105,122,101, 91, 51, 93, 0,116,121,112,101, 70,108, 97,103,115, 0, -100,111,109, 97,105,110, 78,111,118,101, 99,103,101,110, 0,118,111,108,117,109,101, 73,110,105,116, 84,121,112,101, 0,112, 97, -114,116, 83,108,105,112, 86, 97,108,117,101, 0,103,101,110,101,114, 97,116,101, 84,114, 97, 99,101,114,115, 0,103,101,110,101, -114, 97,116,101, 80, 97,114,116,105, 99,108,101,115, 0,115,117,114,102, 97, 99,101, 83,109,111,111,116,104,105,110,103, 0,115, -117,114,102, 97, 99,101, 83,117, 98,100,105,118,115, 0,112, 97,114,116,105, 99,108,101, 73,110,102, 83,105,122,101, 0,112, 97, -114,116,105, 99,108,101, 73,110,102, 65,108,112,104, 97, 0,102, 97,114, 70,105,101,108,100, 83,105,122,101, 0, 42,109,101,115, -104, 86,101,108,111, 99,105,116,105,101,115, 0, 99,112,115, 84,105,109,101, 83,116, 97,114,116, 0, 99,112,115, 84,105,109,101, - 69,110,100, 0, 99,112,115, 81,117, 97,108,105,116,121, 0, 97,116,116,114, 97, 99,116,102,111,114, 99,101, 83,116,114,101,110, -103,116,104, 0, 97,116,116,114, 97, 99,116,102,111,114, 99,101, 82, 97,100,105,117,115, 0,118,101,108,111, 99,105,116,121,102, -111,114, 99,101, 83,116,114,101,110,103,116,104, 0,118,101,108,111, 99,105,116,121,102,111,114, 99,101, 82, 97,100,105,117,115, - 0,108, 97,115,116,103,111,111,100,102,114, 97,109,101, 0, 97,110,105,109, 82, 97,116,101, 0,109,105,115,116,121,112,101, 0, -104,111,114,114, 0,104,111,114,103, 0,104,111,114, 98, 0,122,101,110,114, 0,122,101,110,103, 0,122,101,110, 98, 0,102, 97, -115,116, 99,111,108, 0,101,120,112,111,115,117,114,101, 0,101,120,112, 0,114, 97,110,103,101, 0,108,105,110,102, 97, 99, 0, -108,111,103,102, 97, 99, 0,103,114, 97,118,105,116,121, 0, 97, 99,116,105,118,105,116,121, 66,111,120, 82, 97,100,105,117,115, - 0,115,107,121,116,121,112,101, 0,111, 99, 99,108,117,115,105,111,110, 82,101,115, 0,112,104,121,115,105, 99,115, 69,110,103, -105,110,101, 0,116,105, 99,114, 97,116,101, 0,109, 97,120,108,111,103,105, 99,115,116,101,112, 0,112,104,121,115,117, 98,115, -116,101,112, 0,109, 97,120,112,104,121,115,116,101,112, 0,109,105,115,105, 0,109,105,115,116,115,116, 97, 0,109,105,115,116, -100,105,115,116, 0,109,105,115,116,104,105, 0,115,116, 97,114,114, 0,115,116, 97,114,103, 0,115,116, 97,114, 98, 0,115,116, - 97,114,107, 0,115,116, 97,114,115,105,122,101, 0,115,116, 97,114,109,105,110,100,105,115,116, 0,115,116, 97,114,100,105,115, -116, 0,115,116, 97,114, 99,111,108,110,111,105,115,101, 0,100,111,102,115,116, 97, 0,100,111,102,101,110,100, 0,100,111,102, -109,105,110, 0,100,111,102,109, 97,120, 0, 97,111,100,105,115,116, 0, 97,111,100,105,115,116,102, 97, 99, 0, 97,111,101,110, -101,114,103,121, 0, 97,111, 98,105, 97,115, 0, 97,111,109,111,100,101, 0, 97,111,115, 97,109,112, 0, 97,111,109,105,120, 0, - 97,111, 99,111,108,111,114, 0, 97,111, 95, 97,100, 97,112,116, 95,116,104,114,101,115,104, 0, 97,111, 95, 97,100, 97,112,116, - 95,115,112,101,101,100, 95,102, 97, 99, 0, 97,111, 95, 97,112,112,114,111,120, 95,101,114,114,111,114, 0, 97,111, 95, 97,112, -112,114,111,120, 95, 99,111,114,114,101, 99,116,105,111,110, 0, 97,111, 95,105,110,100,105,114,101, 99,116, 95,101,110,101,114, -103,121, 0, 97,111, 95,101,110,118, 95,101,110,101,114,103,121, 0, 97,111, 95,112, 97,100, 50, 0, 97,111, 95,105,110,100,105, -114,101, 99,116, 95, 98,111,117,110, 99,101,115, 0, 97,111, 95,112, 97,100, 0, 97,111, 95,115, 97,109,112, 95,109,101,116,104, -111,100, 0, 97,111, 95,103, 97,116,104,101,114, 95,109,101,116,104,111,100, 0, 97,111, 95, 97,112,112,114,111,120, 95,112, 97, -115,115,101,115, 0, 42, 97,111,115,112,104,101,114,101, 0, 42, 97,111,116, 97, 98,108,101,115, 0,115,101,108, 99,111,108, 0, -115,120, 0,115,121, 0, 42,108,112, 70,111,114,109, 97,116, 0, 42,108,112, 80, 97,114,109,115, 0, 99, 98, 70,111,114,109, 97, -116, 0, 99, 98, 80, 97,114,109,115, 0,102, 99, 99, 84,121,112,101, 0,102, 99, 99, 72, 97,110,100,108,101,114, 0,100,119, 75, -101,121, 70,114, 97,109,101, 69,118,101,114,121, 0,100,119, 81,117, 97,108,105,116,121, 0,100,119, 66,121,116,101,115, 80,101, -114, 83,101, 99,111,110,100, 0,100,119, 70,108, 97,103,115, 0,100,119, 73,110,116,101,114,108,101, 97,118,101, 69,118,101,114, -121, 0, 97,118,105, 99,111,100,101, 99,110, 97,109,101, 91, 49, 50, 56, 93, 0, 42, 99,100, 80, 97,114,109,115, 0, 42,112, 97, -100, 0, 99,100, 83,105,122,101, 0,113,116, 99,111,100,101, 99,110, 97,109,101, 91, 49, 50, 56, 93, 0, 99,111,100,101, 99, 84, -121,112,101, 0, 99,111,100,101, 99, 83,112, 97,116,105, 97,108, 81,117, 97,108,105,116,121, 0, 99,111,100,101, 99, 0, 99,111, -100,101, 99, 70,108, 97,103,115, 0, 99,111,108,111,114, 68,101,112,116,104, 0, 99,111,100,101, 99, 84,101,109,112,111,114, 97, -108, 81,117, 97,108,105,116,121, 0,109,105,110, 83,112, 97,116,105, 97,108, 81,117, 97,108,105,116,121, 0,109,105,110, 84,101, -109,112,111,114, 97,108, 81,117, 97,108,105,116,121, 0,107,101,121, 70,114, 97,109,101, 82, 97,116,101, 0, 98,105,116, 82, 97, -116,101, 0, 97,117,100,105,111, 99,111,100,101, 99, 84,121,112,101, 0, 97,117,100,105,111, 83, 97,109,112,108,101, 82, 97,116, -101, 0, 97,117,100,105,111, 66,105,116, 68,101,112,116,104, 0, 97,117,100,105,111, 67,104, 97,110,110,101,108,115, 0, 97,117, -100,105,111, 67,111,100,101, 99, 70,108, 97,103,115, 0, 97,117,100,105,111, 66,105,116, 82, 97,116,101, 0, 97,117,100,105,111, - 95, 99,111,100,101, 99, 0,118,105,100,101,111, 95, 98,105,116,114, 97,116,101, 0, 97,117,100,105,111, 95, 98,105,116,114, 97, -116,101, 0, 97,117,100,105,111, 95,109,105,120,114, 97,116,101, 0, 97,117,100,105,111, 95, 99,104, 97,110,110,101,108,115, 0, - 97,117,100,105,111, 95,112, 97,100, 0, 97,117,100,105,111, 95,118,111,108,117,109,101, 0,103,111,112, 95,115,105,122,101, 0, -114, 99, 95,109,105,110, 95,114, 97,116,101, 0,114, 99, 95,109, 97,120, 95,114, 97,116,101, 0,114, 99, 95, 98,117,102,102,101, -114, 95,115,105,122,101, 0,109,117,120, 95,112, 97, 99,107,101,116, 95,115,105,122,101, 0,109,117,120, 95,114, 97,116,101, 0, -109,105,120,114, 97,116,101, 0,109, 97,105,110, 0,115,112,101,101,100, 95,111,102, 95,115,111,117,110,100, 0,100,111,112,112, -108,101,114, 95,102, 97, 99,116,111,114, 0,100,105,115,116, 97,110, 99,101, 95,109,111,100,101,108, 0, 42,109, 97,116, 95,111, -118,101,114,114,105,100,101, 0, 42,108,105,103,104,116, 95,111,118,101,114,114,105,100,101, 0,108, 97,121, 95,122,109, 97,115, -107, 0,108, 97,121,102,108, 97,103, 0,112, 97,115,115,102,108, 97,103, 0,112, 97,115,115, 95,120,111,114, 0,105,109,116,121, -112,101, 0,112,108, 97,110,101,115, 0,113,117, 97,108,105,116,121, 0, 99,111,109,112,114,101,115,115, 0,101,120,114, 95, 99, -111,100,101, 99, 0, 99,105,110,101,111,110, 95,102,108, 97,103, 0, 99,105,110,101,111,110, 95,119,104,105,116,101, 0, 99,105, -110,101,111,110, 95, 98,108, 97, 99,107, 0, 99,105,110,101,111,110, 95,103, 97,109,109, 97, 0,106,112, 50, 95,102,108, 97,103, - 0,105,109, 95,102,111,114,109, 97,116, 0, 42, 97,118,105, 99,111,100,101, 99,100, 97,116, 97, 0, 42,113,116, 99,111,100,101, - 99,100, 97,116, 97, 0,113,116, 99,111,100,101, 99,115,101,116,116,105,110,103,115, 0,102,102, 99,111,100,101, 99,100, 97,116, - 97, 0,115,117, 98,102,114, 97,109,101, 0,112,115,102,114, 97, 0,112,101,102,114, 97, 0,105,109, 97,103,101,115, 0,102,114, - 97,109, 97,112,116,111, 0,116,104,114,101, 97,100,115, 0,102,114, 97,109,101,108,101,110, 0, 98,108,117,114,102, 97, 99, 0, -101,100,103,101, 82, 0,101,100,103,101, 71, 0,101,100,103,101, 66, 0,102,117,108,108,115, 99,114,101,101,110, 0,120,112,108, - 97,121, 0,121,112,108, 97,121, 0,102,114,101,113,112,108, 97,121, 0, 97,116,116,114,105, 98, 0,102,114, 97,109,101, 95,115, -116,101,112, 0,115,116,101,114,101,111,109,111,100,101, 0,100,105,109,101,110,115,105,111,110,115,112,114,101,115,101,116, 0, -109, 97,120,105,109,115,105,122,101, 0,120,115, 99,104, 0,121,115, 99,104, 0,120,112, 97,114,116,115, 0,121,112, 97,114,116, -115, 0,115,117, 98,105,109,116,121,112,101, 0,100,105,115,112,108, 97,121,109,111,100,101, 0,115, 99,101,109,111,100,101, 0, -114, 97,121,116,114, 97, 99,101, 95,111,112,116,105,111,110,115, 0,114, 97,121,116,114, 97, 99,101, 95,115,116,114,117, 99,116, -117,114,101, 0,111, 99,114,101,115, 0,112, 97,100, 52, 0, 97,108,112,104, 97,109,111,100,101, 0,111,115, 97, 0,102,114,115, - 95,115,101, 99, 0,101,100,103,101,105,110,116, 0,115, 97,102,101,116,121, 0, 98,111,114,100,101,114, 0,100,105,115,112,114, -101, 99,116, 0,108, 97,121,101,114,115, 0, 97, 99,116,108, 97,121, 0,109, 98,108,117,114, 95,115, 97,109,112,108,101,115, 0, -120, 97,115,112, 0,121, 97,115,112, 0,102,114,115, 95,115,101, 99, 95, 98, 97,115,101, 0,103, 97,117,115,115, 0, 99,111,108, -111,114, 95,109,103,116, 95,102,108, 97,103, 0,112,111,115,116,103, 97,109,109, 97, 0,112,111,115,116,104,117,101, 0,112,111, -115,116,115, 97,116, 0,100,105,116,104,101,114, 95,105,110,116,101,110,115,105,116,121, 0, 98, 97,107,101, 95,111,115, 97, 0, - 98, 97,107,101, 95,102,105,108,116,101,114, 0, 98, 97,107,101, 95,109,111,100,101, 0, 98, 97,107,101, 95,102,108, 97,103, 0, - 98, 97,107,101, 95,110,111,114,109, 97,108, 95,115,112, 97, 99,101, 0, 98, 97,107,101, 95,113,117, 97,100, 95,115,112,108,105, -116, 0, 98, 97,107,101, 95,109, 97,120,100,105,115,116, 0, 98, 97,107,101, 95, 98,105, 97,115,100,105,115,116, 0, 98, 97,107, -101, 95,112, 97,100, 0,112,105, 99, 91, 49, 48, 50, 52, 93, 0,115,116, 97,109,112, 0,115,116, 97,109,112, 95,102,111,110,116, - 95,105,100, 0,115,116, 97,109,112, 95,117,100, 97,116, 97, 91, 55, 54, 56, 93, 0,102,103, 95,115,116, 97,109,112, 91, 52, 93, - 0, 98,103, 95,115,116, 97,109,112, 91, 52, 93, 0,115,101,113, 95,112,114,101,118, 95,116,121,112,101, 0,115,101,113, 95,114, -101,110,100, 95,116,121,112,101, 0,115,101,113, 95,102,108, 97,103, 0,112, 97,100, 53, 91, 53, 93, 0,115,105,109,112,108,105, -102,121, 95,102,108, 97,103, 0,115,105,109,112,108,105,102,121, 95,115,117, 98,115,117,114,102, 0,115,105,109,112,108,105,102, -121, 95,115,104, 97,100,111,119,115, 97,109,112,108,101,115, 0,115,105,109,112,108,105,102,121, 95,112, 97,114,116,105, 99,108, -101,115, 0,115,105,109,112,108,105,102,121, 95, 97,111,115,115,115, 0, 99,105,110,101,111,110,119,104,105,116,101, 0, 99,105, -110,101,111,110, 98,108, 97, 99,107, 0, 99,105,110,101,111,110,103, 97,109,109, 97, 0,106,112, 50, 95,112,114,101,115,101,116, - 0,106,112, 50, 95,100,101,112,116,104, 0,114,112, 97,100, 51, 0,100,111,109,101,114,101,115, 0,100,111,109,101,109,111,100, -101, 0,100,111,109,101, 97,110,103,108,101, 0,100,111,109,101,116,105,108,116, 0,100,111,109,101,114,101,115, 98,117,102, 0, - 42,100,111,109,101,116,101,120,116, 0,101,110,103,105,110,101, 91, 51, 50, 93, 0,110, 97,109,101, 91, 51, 50, 93, 0,112, 97, -114,116,105, 99,108,101, 95,112,101,114, 99, 0,115,117, 98,115,117,114,102, 95,109, 97,120, 0,115,104, 97,100, 98,117,102,115, - 97,109,112,108,101, 95,109, 97,120, 0, 97,111, 95,101,114,114,111,114, 0,116,105,108,116, 0,114,101,115, 98,117,102, 0, 42, -119, 97,114,112,116,101,120,116, 0, 99,111,108, 91, 51, 93, 0, 99,101,108,108,115,105,122,101, 0, 99,101,108,108,104,101,105, -103,104,116, 0, 97,103,101,110,116,109, 97,120,115,108,111,112,101, 0, 97,103,101,110,116,109, 97,120, 99,108,105,109, 98, 0, - 97,103,101,110,116,104,101,105,103,104,116, 0, 97,103,101,110,116,114, 97,100,105,117,115, 0,101,100,103,101,109, 97,120,108, -101,110, 0,101,100,103,101,109, 97,120,101,114,114,111,114, 0,114,101,103,105,111,110,109,105,110,115,105,122,101, 0,114,101, -103,105,111,110,109,101,114,103,101,115,105,122,101, 0,118,101,114,116,115,112,101,114,112,111,108,121, 0,100,101,116, 97,105, -108,115, 97,109,112,108,101,100,105,115,116, 0,100,101,116, 97,105,108,115, 97,109,112,108,101,109, 97,120,101,114,114,111,114, - 0,102,114, 97,109,105,110,103, 0,112,108, 97,121,101,114,102,108, 97,103, 0,114,116, 49, 0,114,116, 50, 0, 97, 97,115, 97, -109,112,108,101,115, 0,112, 97,100, 52, 91, 51, 93, 0,100,111,109,101, 0,115,116,101,114,101,111,102,108, 97,103, 0,101,121, -101,115,101,112, 97,114, 97,116,105,111,110, 0,114,101, 99, 97,115,116, 68, 97,116, 97, 0,109, 97,116,109,111,100,101, 0,101, -120,105,116,107,101,121, 0,111, 98,115,116, 97, 99,108,101, 83,105,109,117,108, 97,116,105,111,110, 0,108,101,118,101,108, 72, -101,105,103,104,116, 0, 42, 99, 97,109,101,114, 97, 0, 42,112, 97,105,110,116, 95, 99,117,114,115,111,114, 0,112, 97,105,110, -116, 95, 99,117,114,115,111,114, 95, 99,111,108, 91, 52, 93, 0,112, 97,105,110,116, 0,115,101, 97,109, 95, 98,108,101,101,100, - 0,110,111,114,109, 97,108, 95, 97,110,103,108,101, 0,115, 99,114,101,101,110, 95,103,114, 97, 98, 95,115,105,122,101, 91, 50, - 93, 0, 42,112, 97,105,110,116, 99,117,114,115,111,114, 0,105,110,118,101,114,116, 0,116,111,116,114,101,107,101,121, 0,116, -111,116, 97,100,100,107,101,121, 0, 98,114,117,115,104,116,121,112,101, 0, 98,114,117,115,104, 91, 55, 93, 0,101,109,105,116, -116,101,114,100,105,115,116, 0,115,101,108,101, 99,116,109,111,100,101, 0,101,100,105,116,116,121,112,101, 0,100,114, 97,119, - 95,115,116,101,112, 0,102, 97,100,101, 95,102,114, 97,109,101,115, 0,114, 97,100,105, 97,108, 95,115,121,109,109, 91, 51, 93, - 0,108, 97,115,116, 95,120, 0,108, 97,115,116, 95,121, 0,108, 97,115,116, 95, 97,110,103,108,101, 0,100,114, 97,119, 95, 97, -110, 99,104,111,114,101,100, 0, 97,110, 99,104,111,114,101,100, 95,115,105,122,101, 0, 97,110, 99,104,111,114,101,100, 95,108, -111, 99, 97,116,105,111,110, 91, 51, 93, 0, 97,110, 99,104,111,114,101,100, 95,105,110,105,116,105, 97,108, 95,109,111,117,115, -101, 91, 50, 93, 0,100,114, 97,119, 95,112,114,101,115,115,117,114,101, 0,112,114,101,115,115,117,114,101, 95,118, 97,108,117, -101, 0,115,112,101, 99,105, 97,108, 95,114,111,116, 97,116,105,111,110, 0, 42,118,112, 97,105,110,116, 95,112,114,101,118, 0, - 42,119,112, 97,105,110,116, 95,112,114,101,118, 0,109, 97,116, 91, 51, 93, 91, 51, 93, 0,117,110,112,114,111,106,101, 99,116, -101,100, 95,114, 97,100,105,117,115, 0, 42,118,112, 97,105,110,116, 0, 42,119,112, 97,105,110,116, 0, 42,117,118,115, 99,117, -108,112,116, 0,118,103,114,111,117,112, 95,119,101,105,103,104,116, 0, 99,111,114,110,101,114,116,121,112,101, 0,101,100,105, -116, 98,117,116,102,108, 97,103, 0,106,111,105,110,116,114,105,108,105,109,105,116, 0,100,101,103,114, 0,116,117,114,110, 0, -101,120,116,114, 95,111,102,102,115, 0,100,111,117, 98,108,105,109,105,116, 0,110,111,114,109, 97,108,115,105,122,101, 0, 97, -117,116,111,109,101,114,103,101, 0,115,101,103,109,101,110,116,115, 0,114,105,110,103,115, 0,118,101,114,116,105, 99,101,115, - 0,117,110,119,114, 97,112,112,101,114, 0,117,118, 99, 97,108, 99, 95,114, 97,100,105,117,115, 0,117,118, 99, 97,108, 99, 95, - 99,117, 98,101,115,105,122,101, 0,117,118, 99, 97,108, 99, 95,109, 97,114,103,105,110, 0,117,118, 99, 97,108, 99, 95,109, 97, -112,100,105,114, 0,117,118, 99, 97,108, 99, 95,109, 97,112, 97,108,105,103,110, 0,117,118, 99, 97,108, 99, 95,102,108, 97,103, - 0,117,118, 95,102,108, 97,103, 0,117,118, 95,115,101,108,101, 99,116,109,111,100,101, 0,117,118, 95,115,117, 98,115,117,114, -102, 95,108,101,118,101,108, 0,103,112,101,110, 99,105,108, 95,102,108, 97,103,115, 0, 97,117,116,111,105,107, 95, 99,104, 97, -105,110,108,101,110, 0,105,109, 97,112, 97,105,110,116, 0,112, 97,114,116,105, 99,108,101, 0,112,114,111,112,111,114,116,105, -111,110, 97,108, 95,115,105,122,101, 0,115,101,108,101, 99,116, 95,116,104,114,101,115,104, 0, 99,108,101, 97,110, 95,116,104, -114,101,115,104, 0, 97,117,116,111,107,101,121, 95,109,111,100,101, 0, 97,117,116,111,107,101,121, 95,102,108, 97,103, 0,109, -117,108,116,105,114,101,115, 95,115,117, 98,100,105,118, 95,116,121,112,101, 0,112, 97,100, 50, 91, 53, 93, 0,115,107,103,101, -110, 95,114,101,115,111,108,117,116,105,111,110, 0,115,107,103,101,110, 95,116,104,114,101,115,104,111,108,100, 95,105,110,116, -101,114,110, 97,108, 0,115,107,103,101,110, 95,116,104,114,101,115,104,111,108,100, 95,101,120,116,101,114,110, 97,108, 0,115, -107,103,101,110, 95,108,101,110,103,116,104, 95,114, 97,116,105,111, 0,115,107,103,101,110, 95,108,101,110,103,116,104, 95,108, -105,109,105,116, 0,115,107,103,101,110, 95, 97,110,103,108,101, 95,108,105,109,105,116, 0,115,107,103,101,110, 95, 99,111,114, -114,101,108, 97,116,105,111,110, 95,108,105,109,105,116, 0,115,107,103,101,110, 95,115,121,109,109,101,116,114,121, 95,108,105, -109,105,116, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,101,116, 95, 97,110,103,108,101, 95,119,101,105,103,104,116, 0, -115,107,103,101,110, 95,114,101,116, 97,114,103,101,116, 95,108,101,110,103,116,104, 95,119,101,105,103,104,116, 0,115,107,103, -101,110, 95,114,101,116, 97,114,103,101,116, 95,100,105,115,116, 97,110, 99,101, 95,119,101,105,103,104,116, 0,115,107,103,101, -110, 95,111,112,116,105,111,110,115, 0,115,107,103,101,110, 95,112,111,115,116,112,114,111, 0,115,107,103,101,110, 95,112,111, -115,116,112,114,111, 95,112, 97,115,115,101,115, 0,115,107,103,101,110, 95,115,117, 98,100,105,118,105,115,105,111,110,115, 91, - 51, 93, 0,115,107,103,101,110, 95,109,117,108,116,105, 95,108,101,118,101,108, 0, 42,115,107,103,101,110, 95,116,101,109,112, -108, 97,116,101, 0, 98,111,110,101, 95,115,107,101,116, 99,104,105,110,103, 0, 98,111,110,101, 95,115,107,101,116, 99,104,105, -110,103, 95, 99,111,110,118,101,114,116, 0,115,107,103,101,110, 95,115,117, 98,100,105,118,105,115,105,111,110, 95,110,117,109, - 98,101,114, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,101,116, 95,111,112,116,105,111,110,115, 0,115,107,103,101,110, - 95,114,101,116, 97,114,103,101,116, 95,114,111,108,108, 0,115,107,103,101,110, 95,115,105,100,101, 95,115,116,114,105,110,103, - 91, 56, 93, 0,115,107,103,101,110, 95,110,117,109, 95,115,116,114,105,110,103, 91, 56, 93, 0,101,100,103,101, 95,109,111,100, -101, 0,101,100,103,101, 95,109,111,100,101, 95,108,105,118,101, 95,117,110,119,114, 97,112, 0,115,110, 97,112, 95,109,111,100, -101, 0,115,110, 97,112, 95,102,108, 97,103, 0,115,110, 97,112, 95,116, 97,114,103,101,116, 0,112,114,111,112,111,114,116,105, -111,110, 97,108, 0,112,114,111,112, 95,109,111,100,101, 0,112,114,111,112,111,114,116,105,111,110, 97,108, 95,111, 98,106,101, - 99,116,115, 0,112, 97,100, 91, 53, 93, 0, 97,117,116,111, 95,110,111,114,109, 97,108,105,122,101, 0,109,117,108,116,105,112, - 97,105,110,116, 0,117,115,101, 95,117,118, 95,115, 99,117,108,112,116, 0,117,118, 95,115, 99,117,108,112,116, 95,115,101,116, -116,105,110,103,115, 0,117,118, 95,115, 99,117,108,112,116, 95,116,111,111,108, 0,117,118, 95,114,101,108, 97,120, 95,109,101, -116,104,111,100, 0,115, 99,117,108,112,116, 95,112, 97,105,110,116, 95,115,101,116,116,105,110,103,115, 0,115, 99,117,108,112, -116, 95,112, 97,105,110,116, 95,117,110,105,102,105,101,100, 95,115,105,122,101, 0,115, 99,117,108,112,116, 95,112, 97,105,110, -116, 95,117,110,105,102,105,101,100, 95,117,110,112,114,111,106,101, 99,116,101,100, 95,114, 97,100,105,117,115, 0,115, 99,117, -108,112,116, 95,112, 97,105,110,116, 95,117,110,105,102,105,101,100, 95, 97,108,112,104, 97, 0,117,110,105,102,105,101,100, 95, -112, 97,105,110,116, 95,115,101,116,116,105,110,103,115, 0,116,111,116,111, 98,106, 0,116,111,116,108, 97,109,112, 0,116,111, -116,111, 98,106,115,101,108, 0,116,111,116, 99,117,114,118,101, 0,116,111,116,109,101,115,104, 0,116,111,116, 97,114,109, 97, -116,117,114,101, 0,115, 99, 97,108,101, 95,108,101,110,103,116,104, 0,115,121,115,116,101,109, 0,115,121,115,116,101,109, 95, -114,111,116, 97,116,105,111,110, 0,103,114, 97,118,105,116,121, 91, 51, 93, 0,113,117,105, 99,107, 95, 99, 97, 99,104,101, 95, -115,116,101,112, 0, 42,119,111,114,108,100, 0, 42,115,101,116, 0, 98, 97,115,101, 0, 42, 98, 97,115, 97, 99,116, 0, 42,111, - 98,101,100,105,116, 0, 99,117,114,115,111,114, 91, 51, 93, 0,116,119, 99,101,110,116, 91, 51, 93, 0,116,119,109,105,110, 91, - 51, 93, 0,116,119,109, 97,120, 91, 51, 93, 0,108, 97,121, 97, 99,116, 0,108, 97,121, 95,117,112,100, 97,116,101,100, 0, 42, -101,100, 0, 42,116,111,111,108,115,101,116,116,105,110,103,115, 0, 42,115,116, 97,116,115, 0, 97,117,100,105,111, 0,116,114, - 97,110,115,102,111,114,109, 95,115,112, 97, 99,101,115, 0, 42,115,111,117,110,100, 95,115, 99,101,110,101, 0, 42,115,111,117, -110,100, 95,115, 99,101,110,101, 95,104, 97,110,100,108,101, 0, 42,115,111,117,110,100, 95,115, 99,114,117, 98, 95,104, 97,110, -100,108,101, 0, 42,115,112,101, 97,107,101,114, 95,104, 97,110,100,108,101,115, 0, 42,102,112,115, 95,105,110,102,111, 0, 42, -116,104,101, 68, 97,103, 0,100, 97,103,105,115,118, 97,108,105,100, 0,100, 97,103,102,108, 97,103,115, 0, 97, 99,116,105,118, -101, 95,107,101,121,105,110,103,115,101,116, 0,107,101,121,105,110,103,115,101,116,115, 0,103,109, 0,117,110,105,116, 0,112, -104,121,115,105, 99,115, 95,115,101,116,116,105,110,103,115, 0, 42, 99,108,105,112, 0, 99,117,115,116,111,109,100, 97,116, 97, - 95,109, 97,115,107, 95,109,111,100, 97,108, 0, 99,117,115,101,114, 0, 98,108,101,110,100, 0,118,105,101,119, 0,119,105,110, -109, 97,116, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,109, 97,116, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,105,110,118, 91, - 52, 93, 91, 52, 93, 0,112,101,114,115,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,101,114,115,105,110,118, 91, 52, 93, 91, 52, - 93, 0,118,105,101,119,109, 97,116,111, 98, 91, 52, 93, 91, 52, 93, 0,112,101,114,115,109, 97,116,111, 98, 91, 52, 93, 91, 52, - 93, 0, 99,108,105,112, 91, 54, 93, 91, 52, 93, 0, 99,108,105,112, 95,108,111, 99, 97,108, 91, 54, 93, 91, 52, 93, 0, 42, 99, -108,105,112, 98, 98, 0, 42,108,111, 99, 97,108,118,100, 0, 42,114,105, 0, 42,114,101,110,100,101,114, 95,101,110,103,105,110, -101, 0, 42,100,101,112,116,104,115, 0, 42,115,109,115, 0, 42,115,109,111,111,116,104, 95,116,105,109,101,114, 0,116,119,109, - 97,116, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,113,117, 97,116, 91, 52, 93, 0,122,102, 97, 99, 0, 99, 97,109,100,120, 0, - 99, 97,109,100,121, 0,112,105,120,115,105,122,101, 0, 99, 97,109,122,111,111,109, 0,105,115, 95,112,101,114,115,112, 0,112, -101,114,115,112, 0,118,105,101,119,108,111, 99,107, 0,116,119,100,114, 97,119,102,108, 97,103, 0,114,102,108, 97,103, 0,108, -118,105,101,119,113,117, 97,116, 91, 52, 93, 0,108,112,101,114,115,112, 0,108,118,105,101,119, 0,103,114,105,100,118,105,101, -119, 0,116,119, 97,110,103,108,101, 91, 51, 93, 0,114,111,116, 95, 97,110,103,108,101, 0,114,111,116, 95, 97,120,105,115, 91, - 51, 93, 0,114,101,103,105,111,110, 98, 97,115,101, 0,115,112, 97, 99,101,116,121,112,101, 0, 98,108,111, 99,107,115, 99, 97, -108,101, 0, 98,108,111, 99,107,104, 97,110,100,108,101,114, 91, 56, 93, 0, 98,117,110,100,108,101, 95,115,105,122,101, 0, 98, -117,110,100,108,101, 95,100,114, 97,119,116,121,112,101, 0,108, 97,121, 95,117,115,101,100, 0, 42,111, 98, 95, 99,101,110,116, -114,101, 0, 98,103,112,105, 99, 98, 97,115,101, 0, 42, 98,103,112,105, 99, 0,111, 98, 95, 99,101,110,116,114,101, 95, 98,111, -110,101, 91, 54, 52, 93, 0,100,114, 97,119,116,121,112,101, 0,111, 98, 95, 99,101,110,116,114,101, 95, 99,117,114,115,111,114, - 0,115, 99,101,110,101,108,111, 99,107, 0, 97,114,111,117,110,100, 0,103,114,105,100, 0,110,101, 97,114, 0,102, 97,114, 0, -109,111,100,101,115,101,108,101, 99,116, 0,103,114,105,100,108,105,110,101,115, 0,103,114,105,100,115,117, 98,100,105,118, 0, -103,114,105,100,102,108, 97,103, 0,116,119,116,121,112,101, 0,116,119,109,111,100,101, 0,116,119,102,108, 97,103, 0,112, 97, -100, 50, 91, 50, 93, 0, 97,102,116,101,114,100,114, 97,119, 95,116,114, 97,110,115,112, 0, 97,102,116,101,114,100,114, 97,119, - 95,120,114, 97,121, 0, 97,102,116,101,114,100,114, 97,119, 95,120,114, 97,121,116,114, 97,110,115,112, 0,122, 98,117,102, 0, -120,114, 97,121, 0,112, 97,100, 51, 91, 50, 93, 0, 42,112,114,111,112,101,114,116,105,101,115, 95,115,116,111,114, 97,103,101, - 0,118,101,114,116, 0,104,111,114, 0,109, 97,115,107, 0,109,105,110, 91, 50, 93, 0,109, 97,120, 91, 50, 93, 0,109,105,110, -122,111,111,109, 0,109, 97,120,122,111,111,109, 0,115, 99,114,111,108,108, 0,115, 99,114,111,108,108, 95,117,105, 0,107,101, -101,112,116,111,116, 0,107,101,101,112,122,111,111,109, 0,107,101,101,112,111,102,115, 0, 97,108,105,103,110, 0,119,105,110, -120, 0,119,105,110,121, 0,111,108,100,119,105,110,120, 0,111,108,100,119,105,110,121, 0, 42,116, 97, 98, 95,111,102,102,115, -101,116, 0,116, 97, 98, 95,110,117,109, 0,116, 97, 98, 95, 99,117,114, 0,114,112,116, 95,109, 97,115,107, 0,118, 50,100, 0, - 42, 97,100,115, 0,103,104,111,115,116, 67,117,114,118,101,115, 0, 97,117,116,111,115,110, 97,112, 0, 99,117,114,115,111,114, - 86, 97,108, 0,109, 97,105,110, 98, 0,109, 97,105,110, 98,111, 0,109, 97,105,110, 98,117,115,101,114, 0,114,101, 95, 97,108, -105,103,110, 0,112,114,101,118,105,101,119, 0,116,101,120,116,117,114,101, 95, 99,111,110,116,101,120,116, 0,112, 97,116,104, -102,108, 97,103, 0,100, 97,116, 97,105, 99,111,110, 0, 42,112,105,110,105,100, 0, 42,116,101,120,117,115,101,114, 0,114,101, -110,100,101,114, 95,115,105,122,101, 0, 99,104, 97,110,115,104,111,119,110, 0,122,101, 98,114, 97, 0,122,111,111,109, 0,116, -105,116,108,101, 91, 51, 50, 93, 0,100,105,114, 91, 49, 48, 53, 54, 93, 0,102,105,108,101, 91, 50, 53, 54, 93, 0,114,101,110, - 97,109,101,102,105,108,101, 91, 50, 53, 54, 93, 0,114,101,110, 97,109,101,101,100,105,116, 91, 50, 53, 54, 93, 0,102,105,108, -116,101,114, 95,103,108,111, 98, 91, 54, 52, 93, 0, 97, 99,116,105,118,101, 95,102,105,108,101, 0,115,101,108, 95,102,105,114, -115,116, 0,115,101,108, 95,108, 97,115,116, 0,115,111,114,116, 0,100,105,115,112,108, 97,121, 0,102, 95,102,112, 0,102,112, - 95,115,116,114, 91, 56, 93, 0,115, 99,114,111,108,108, 95,111,102,102,115,101,116, 0, 42,112, 97,114, 97,109,115, 0, 42,102, -105,108,101,115, 0, 42,102,111,108,100,101,114,115, 95,112,114,101,118, 0, 42,102,111,108,100,101,114,115, 95,110,101,120,116, - 0, 42,111,112, 0, 42,115,109,111,111,116,104,115, 99,114,111,108,108, 95,116,105,109,101,114, 0, 42,108, 97,121,111,117,116, - 0,114,101, 99,101,110,116,110,114, 0, 98,111,111,107,109, 97,114,107,110,114, 0,115,121,115,116,101,109,110,114, 0,116,114, -101,101, 0, 42,116,114,101,101,115,116,111,114,101, 0,115,101, 97,114, 99,104, 95,115,116,114,105,110,103, 91, 51, 50, 93, 0, -115,101, 97,114, 99,104, 95,116,115,101, 0,111,117,116,108,105,110,101,118,105,115, 0,115,116,111,114,101,102,108, 97,103, 0, -115,101, 97,114, 99,104, 95,102,108, 97,103,115, 0, 42, 99,117,109, 97,112, 0,115, 99,111,112,101,115, 0,115, 97,109,112,108, -101, 95,108,105,110,101, 95,104,105,115,116, 0, 99,117,114,115,111,114, 91, 50, 93, 0, 99,101,110,116,120, 0, 99,101,110,116, -121, 0, 99,117,114,116,105,108,101, 0,108,111, 99,107, 0,112,105,110, 0,100,116, 95,117,118, 0,115,116,105, 99,107,121, 0, -100,116, 95,117,118,115,116,114,101,116, 99,104, 0, 42,116,101,120,116, 0,116,111,112, 0,118,105,101,119,108,105,110,101,115, - 0,109,101,110,117,110,114, 0,108,104,101,105,103,104,116, 0, 99,119,105,100,116,104, 0,108,105,110,101,110,114,115, 95,116, -111,116, 0,108,101,102,116, 0,115,104,111,119,108,105,110,101,110,114,115, 0,116, 97, 98,110,117,109, 98,101,114, 0,115,104, -111,119,115,121,110,116, 97,120, 0,108,105,110,101, 95,104,108,105,103,104,116, 0,111,118,101,114,119,114,105,116,101, 0,108, -105,118,101, 95,101,100,105,116, 0,112,105,120, 95,112,101,114, 95,108,105,110,101, 0,116,120,116,115, 99,114,111,108,108, 0, -116,120,116, 98, 97,114, 0,119,111,114,100,119,114, 97,112, 0,100,111,112,108,117,103,105,110,115, 0,102,105,110,100,115,116, -114, 91, 50, 53, 54, 93, 0,114,101,112,108, 97, 99,101,115,116,114, 91, 50, 53, 54, 93, 0,109, 97,114,103,105,110, 95, 99,111, -108,117,109,110, 0, 42,100,114, 97,119, 99, 97, 99,104,101, 0, 42,112,121, 95,100,114, 97,119, 0, 42,112,121, 95,101,118,101, -110,116, 0, 42,112,121, 95, 98,117,116,116,111,110, 0, 42,112,121, 95, 98,114,111,119,115,101,114, 99, 97,108,108, 98, 97, 99, -107, 0, 42,112,121, 95,103,108,111, 98, 97,108,100,105, 99,116, 0,108, 97,115,116,115,112, 97, 99,101, 0,115, 99,114,105,112, -116,110, 97,109,101, 91, 49, 48, 50, 52, 93, 0,115, 99,114,105,112,116, 97,114,103, 91, 50, 53, 54, 93, 0, 42,115, 99,114,105, -112,116, 0, 42, 98,117,116, 95,114,101,102,115, 0, 42, 97,114,114, 97,121, 0, 99, 97, 99,104,101,115, 0, 99, 97, 99,104,101, - 95,100,105,115,112,108, 97,121, 0, 42,105,100, 0, 97,115,112,101, 99,116, 0,112, 97,100,102, 0,109,120, 0,109,121, 0, 42, -101,100,105,116,116,114,101,101, 0,116,114,101,101,116,121,112,101, 0,116,101,120,102,114,111,109, 0,115,104, 97,100,101,114, -102,114,111,109, 0,108,105,110,107,100,114, 97,103, 0,108,101,110, 95, 97,108,108,111, 99, 0, 99,117,114,115,111,114, 0,115, - 99,114,111,108,108, 98, 97, 99,107, 0,104,105,115,116,111,114,121, 0,112,114,111,109,112,116, 91, 50, 53, 54, 93, 0,108, 97, -110,103,117, 97,103,101, 91, 51, 50, 93, 0,115,101,108, 95,115,116, 97,114,116, 0,115,101,108, 95,101,110,100, 0,102,105,108, -116,101,114, 91, 54, 52, 93, 0,120,108,111, 99,107,111,102, 0,121,108,111, 99,107,111,102, 0,117,115,101,114, 0,112, 97,116, -104, 95,108,101,110,103,116,104, 0,108,111, 99, 91, 50, 93, 0,115,116, 97, 98,109, 97,116, 91, 52, 93, 91, 52, 93, 0,117,110, -105,115,116, 97, 98,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,111,115,116,112,114,111, 99, 95,102,108, 97,103, 0,114,117,110, -116,105,109,101, 95,102,108, 97,103, 0,102,105,108,101,110, 97,109,101, 91, 49, 48, 50, 52, 93, 0, 98,108,102, 95,105,100, 0, -117,105,102,111,110,116, 95,105,100, 0,114, 95,116,111, 95,108, 0,112,111,105,110,116,115, 0,107,101,114,110,105,110,103, 0, -105,116, 97,108,105, 99, 0, 98,111,108,100, 0,115,104, 97,100,111,119, 0,115,104, 97,100,120, 0,115,104, 97,100,121, 0,115, -104, 97,100,111,119, 97,108,112,104, 97, 0,115,104, 97,100,111,119, 99,111,108,111,114, 0,112, 97,110,101,108,116,105,116,108, -101, 0,103,114,111,117,112,108, 97, 98,101,108, 0,119,105,100,103,101,116,108, 97, 98,101,108, 0,119,105,100,103,101,116, 0, -112, 97,110,101,108,122,111,111,109, 0,109,105,110,108, 97, 98,101,108, 99,104, 97,114,115, 0,109,105,110,119,105,100,103,101, -116, 99,104, 97,114,115, 0, 99,111,108,117,109,110,115,112, 97, 99,101, 0,116,101,109,112,108, 97,116,101,115,112, 97, 99,101, - 0, 98,111,120,115,112, 97, 99,101, 0, 98,117,116,116,111,110,115,112, 97, 99,101,120, 0, 98,117,116,116,111,110,115,112, 97, - 99,101,121, 0,112, 97,110,101,108,115,112, 97, 99,101, 0,112, 97,110,101,108,111,117,116,101,114, 0,111,117,116,108,105,110, -101, 91, 52, 93, 0,105,110,110,101,114, 91, 52, 93, 0,105,110,110,101,114, 95,115,101,108, 91, 52, 93, 0,105,116,101,109, 91, - 52, 93, 0,116,101,120,116, 91, 52, 93, 0,116,101,120,116, 95,115,101,108, 91, 52, 93, 0,115,104, 97,100,101,100, 0,115,104, - 97,100,101,116,111,112, 0,115,104, 97,100,101,100,111,119,110, 0, 97,108,112,104, 97, 95, 99,104,101, 99,107, 0,105,110,110, -101,114, 95, 97,110,105,109, 91, 52, 93, 0,105,110,110,101,114, 95, 97,110,105,109, 95,115,101,108, 91, 52, 93, 0,105,110,110, -101,114, 95,107,101,121, 91, 52, 93, 0,105,110,110,101,114, 95,107,101,121, 95,115,101,108, 91, 52, 93, 0,105,110,110,101,114, - 95,100,114,105,118,101,110, 91, 52, 93, 0,105,110,110,101,114, 95,100,114,105,118,101,110, 95,115,101,108, 91, 52, 93, 0,104, -101, 97,100,101,114, 91, 52, 93, 0,115,104,111,119, 95,104,101, 97,100,101,114, 0,119, 99,111,108, 95,114,101,103,117,108, 97, -114, 0,119, 99,111,108, 95,116,111,111,108, 0,119, 99,111,108, 95,116,101,120,116, 0,119, 99,111,108, 95,114, 97,100,105,111, - 0,119, 99,111,108, 95,111,112,116,105,111,110, 0,119, 99,111,108, 95,116,111,103,103,108,101, 0,119, 99,111,108, 95,110,117, -109, 0,119, 99,111,108, 95,110,117,109,115,108,105,100,101,114, 0,119, 99,111,108, 95,109,101,110,117, 0,119, 99,111,108, 95, -112,117,108,108,100,111,119,110, 0,119, 99,111,108, 95,109,101,110,117, 95, 98, 97, 99,107, 0,119, 99,111,108, 95,109,101,110, -117, 95,105,116,101,109, 0,119, 99,111,108, 95,116,111,111,108,116,105,112, 0,119, 99,111,108, 95, 98,111,120, 0,119, 99,111, -108, 95,115, 99,114,111,108,108, 0,119, 99,111,108, 95,112,114,111,103,114,101,115,115, 0,119, 99,111,108, 95,108,105,115,116, - 95,105,116,101,109, 0,119, 99,111,108, 95,115,116, 97,116,101, 0,112, 97,110,101,108, 0,105, 99,111,110,102,105,108,101, 91, - 50, 53, 54, 93, 0,105, 99,111,110, 95, 97,108,112,104, 97, 0, 98, 97, 99,107, 91, 52, 93, 0,116,105,116,108,101, 91, 52, 93, - 0,116,101,120,116, 95,104,105, 91, 52, 93, 0,104,101, 97,100,101,114, 95,116,105,116,108,101, 91, 52, 93, 0,104,101, 97,100, -101,114, 95,116,101,120,116, 91, 52, 93, 0,104,101, 97,100,101,114, 95,116,101,120,116, 95,104,105, 91, 52, 93, 0, 98,117,116, -116,111,110, 91, 52, 93, 0, 98,117,116,116,111,110, 95,116,105,116,108,101, 91, 52, 93, 0, 98,117,116,116,111,110, 95,116,101, -120,116, 91, 52, 93, 0, 98,117,116,116,111,110, 95,116,101,120,116, 95,104,105, 91, 52, 93, 0,108,105,115,116, 91, 52, 93, 0, -108,105,115,116, 95,116,105,116,108,101, 91, 52, 93, 0,108,105,115,116, 95,116,101,120,116, 91, 52, 93, 0,108,105,115,116, 95, -116,101,120,116, 95,104,105, 91, 52, 93, 0,112, 97,110,101,108, 91, 52, 93, 0,112, 97,110,101,108, 95,116,105,116,108,101, 91, - 52, 93, 0,112, 97,110,101,108, 95,116,101,120,116, 91, 52, 93, 0,112, 97,110,101,108, 95,116,101,120,116, 95,104,105, 91, 52, - 93, 0,115,104, 97,100,101, 49, 91, 52, 93, 0,115,104, 97,100,101, 50, 91, 52, 93, 0,104,105,108,105,116,101, 91, 52, 93, 0, -103,114,105,100, 91, 52, 93, 0,119,105,114,101, 91, 52, 93, 0,115,101,108,101, 99,116, 91, 52, 93, 0,108, 97,109,112, 91, 52, - 93, 0,115,112,101, 97,107,101,114, 91, 52, 93, 0,101,109,112,116,121, 91, 52, 93, 0, 99, 97,109,101,114, 97, 91, 52, 93, 0, -112, 97,100, 91, 56, 93, 0, 97, 99,116,105,118,101, 91, 52, 93, 0,103,114,111,117,112, 91, 52, 93, 0,103,114,111,117,112, 95, - 97, 99,116,105,118,101, 91, 52, 93, 0,116,114, 97,110,115,102,111,114,109, 91, 52, 93, 0,118,101,114,116,101,120, 91, 52, 93, - 0,118,101,114,116,101,120, 95,115,101,108,101, 99,116, 91, 52, 93, 0,101,100,103,101, 91, 52, 93, 0,101,100,103,101, 95,115, -101,108,101, 99,116, 91, 52, 93, 0,101,100,103,101, 95,115,101, 97,109, 91, 52, 93, 0,101,100,103,101, 95,115,104, 97,114,112, - 91, 52, 93, 0,101,100,103,101, 95,102, 97, 99,101,115,101,108, 91, 52, 93, 0,101,100,103,101, 95, 99,114,101, 97,115,101, 91, - 52, 93, 0,102, 97, 99,101, 91, 52, 93, 0,102, 97, 99,101, 95,115,101,108,101, 99,116, 91, 52, 93, 0,102, 97, 99,101, 95,100, -111,116, 91, 52, 93, 0,101,120,116,114, 97, 95,101,100,103,101, 95,108,101,110, 91, 52, 93, 0,101,120,116,114, 97, 95,102, 97, - 99,101, 95, 97,110,103,108,101, 91, 52, 93, 0,101,120,116,114, 97, 95,102, 97, 99,101, 95, 97,114,101, 97, 91, 52, 93, 0,112, - 97,100, 51, 91, 52, 93, 0,110,111,114,109, 97,108, 91, 52, 93, 0,118,101,114,116,101,120, 95,110,111,114,109, 97,108, 91, 52, - 93, 0, 98,111,110,101, 95,115,111,108,105,100, 91, 52, 93, 0, 98,111,110,101, 95,112,111,115,101, 91, 52, 93, 0,115,116,114, -105,112, 91, 52, 93, 0,115,116,114,105,112, 95,115,101,108,101, 99,116, 91, 52, 93, 0, 99,102,114, 97,109,101, 91, 52, 93, 0, -110,117,114, 98, 95,117,108,105,110,101, 91, 52, 93, 0,110,117,114, 98, 95,118,108,105,110,101, 91, 52, 93, 0, 97, 99,116, 95, -115,112,108,105,110,101, 91, 52, 93, 0,110,117,114, 98, 95,115,101,108, 95,117,108,105,110,101, 91, 52, 93, 0,110,117,114, 98, - 95,115,101,108, 95,118,108,105,110,101, 91, 52, 93, 0,108, 97,115,116,115,101,108, 95,112,111,105,110,116, 91, 52, 93, 0,104, - 97,110,100,108,101, 95,102,114,101,101, 91, 52, 93, 0,104, 97,110,100,108,101, 95, 97,117,116,111, 91, 52, 93, 0,104, 97,110, -100,108,101, 95,118,101, 99,116, 91, 52, 93, 0,104, 97,110,100,108,101, 95, 97,108,105,103,110, 91, 52, 93, 0,104, 97,110,100, -108,101, 95, 97,117,116,111, 95, 99,108, 97,109,112,101,100, 91, 52, 93, 0,104, 97,110,100,108,101, 95,115,101,108, 95,102,114, -101,101, 91, 52, 93, 0,104, 97,110,100,108,101, 95,115,101,108, 95, 97,117,116,111, 91, 52, 93, 0,104, 97,110,100,108,101, 95, -115,101,108, 95,118,101, 99,116, 91, 52, 93, 0,104, 97,110,100,108,101, 95,115,101,108, 95, 97,108,105,103,110, 91, 52, 93, 0, -104, 97,110,100,108,101, 95,115,101,108, 95, 97,117,116,111, 95, 99,108, 97,109,112,101,100, 91, 52, 93, 0,100,115, 95, 99,104, - 97,110,110,101,108, 91, 52, 93, 0,100,115, 95,115,117, 98, 99,104, 97,110,110,101,108, 91, 52, 93, 0, 99,111,110,115,111,108, -101, 95,111,117,116,112,117,116, 91, 52, 93, 0, 99,111,110,115,111,108,101, 95,105,110,112,117,116, 91, 52, 93, 0, 99,111,110, -115,111,108,101, 95,105,110,102,111, 91, 52, 93, 0, 99,111,110,115,111,108,101, 95,101,114,114,111,114, 91, 52, 93, 0, 99,111, -110,115,111,108,101, 95, 99,117,114,115,111,114, 91, 52, 93, 0,118,101,114,116,101,120, 95,115,105,122,101, 0,111,117,116,108, -105,110,101, 95,119,105,100,116,104, 0,102, 97, 99,101,100,111,116, 95,115,105,122,101, 0,110,111,111,100,108,101, 95, 99,117, -114,118,105,110,103, 0,115,121,110,116, 97,120,108, 91, 52, 93, 0,115,121,110,116, 97,120,110, 91, 52, 93, 0,115,121,110,116, - 97,120, 98, 91, 52, 93, 0,115,121,110,116, 97,120,118, 91, 52, 93, 0,115,121,110,116, 97,120, 99, 91, 52, 93, 0,109,111,118, -105,101, 91, 52, 93, 0,109,111,118,105,101, 99,108,105,112, 91, 52, 93, 0,105,109, 97,103,101, 91, 52, 93, 0,115, 99,101,110, -101, 91, 52, 93, 0, 97,117,100,105,111, 91, 52, 93, 0,101,102,102,101, 99,116, 91, 52, 93, 0,112,108,117,103,105,110, 91, 52, - 93, 0,116,114, 97,110,115,105,116,105,111,110, 91, 52, 93, 0,109,101,116, 97, 91, 52, 93, 0,101,100,105,116,109,101,115,104, - 95, 97, 99,116,105,118,101, 91, 52, 93, 0,104, 97,110,100,108,101, 95,118,101,114,116,101,120, 91, 52, 93, 0,104, 97,110,100, -108,101, 95,118,101,114,116,101,120, 95,115,101,108,101, 99,116, 91, 52, 93, 0,104, 97,110,100,108,101, 95,118,101,114,116,101, -120, 95,115,105,122,101, 0,109, 97,114,107,101,114, 95,111,117,116,108,105,110,101, 91, 52, 93, 0,109, 97,114,107,101,114, 91, - 52, 93, 0, 97, 99,116, 95,109, 97,114,107,101,114, 91, 52, 93, 0,115,101,108, 95,109, 97,114,107,101,114, 91, 52, 93, 0,100, -105,115, 95,109, 97,114,107,101,114, 91, 52, 93, 0,108,111, 99,107, 95,109, 97,114,107,101,114, 91, 52, 93, 0, 98,117,110,100, -108,101, 95,115,111,108,105,100, 91, 52, 93, 0,112, 97,116,104, 95, 98,101,102,111,114,101, 91, 52, 93, 0,112, 97,116,104, 95, - 97,102,116,101,114, 91, 52, 93, 0, 99, 97,109,101,114, 97, 95,112, 97,116,104, 91, 52, 93, 0,104,112, 97,100, 91, 55, 93, 0, -112,114,101,118,105,101,119, 95, 98, 97, 99,107, 91, 52, 93, 0,112,114,101,118,105,101,119, 95,115,116,105,116, 99,104, 95,102, - 97, 99,101, 91, 52, 93, 0,112,114,101,118,105,101,119, 95,115,116,105,116, 99,104, 95,101,100,103,101, 91, 52, 93, 0,112,114, -101,118,105,101,119, 95,115,116,105,116, 99,104, 95,118,101,114,116, 91, 52, 93, 0,112,114,101,118,105,101,119, 95,115,116,105, -116, 99,104, 95,115,116,105,116, 99,104, 97, 98,108,101, 91, 52, 93, 0,112,114,101,118,105,101,119, 95,115,116,105,116, 99,104, - 95,117,110,115,116,105,116, 99,104, 97, 98,108,101, 91, 52, 93, 0,112,114,101,118,105,101,119, 95,115,116,105,116, 99,104, 95, - 97, 99,116,105,118,101, 91, 52, 93, 0,109, 97,116, 99,104, 91, 52, 93, 0,115,101,108,101, 99,116,101,100, 95,104,105,103,104, -108,105,103,104,116, 91, 52, 93, 0,115,111,108,105,100, 91, 52, 93, 0,116,117,105, 0,116, 98,117,116,115, 0,116,118, 51,100, - 0,116,102,105,108,101, 0,116,105,112,111, 0,116,105,110,102,111, 0,116, 97, 99,116, 0,116,110,108, 97, 0,116,115,101,113, - 0,116,105,109, 97, 0,116,101,120,116, 0,116,111,111,112,115, 0,116,116,105,109,101, 0,116,110,111,100,101, 0,116,108,111, -103,105, 99, 0,116,117,115,101,114,112,114,101,102, 0,116, 99,111,110,115,111,108,101, 0,116, 99,108,105,112, 0,116, 97,114, -109, 91, 50, 48, 93, 0, 97, 99,116,105,118,101, 95,116,104,101,109,101, 95, 97,114,101, 97, 0,109,111,100,117,108,101, 91, 54, - 52, 93, 0,115,112,101, 99, 91, 52, 93, 0,100,117,112,102,108, 97,103, 0,115, 97,118,101,116,105,109,101, 0,116,101,109,112, -100,105,114, 91, 55, 54, 56, 93, 0,102,111,110,116,100,105,114, 91, 55, 54, 56, 93, 0,114,101,110,100,101,114,100,105,114, 91, - 49, 48, 50, 52, 93, 0,116,101,120,116,117,100,105,114, 91, 55, 54, 56, 93, 0,112,108,117,103,116,101,120,100,105,114, 91, 55, - 54, 56, 93, 0,112,108,117,103,115,101,113,100,105,114, 91, 55, 54, 56, 93, 0,112,121,116,104,111,110,100,105,114, 91, 55, 54, - 56, 93, 0,115,111,117,110,100,100,105,114, 91, 55, 54, 56, 93, 0,105,109, 97,103,101, 95,101,100,105,116,111,114, 91, 49, 48, - 50, 52, 93, 0, 97,110,105,109, 95,112,108, 97,121,101,114, 91, 49, 48, 50, 52, 93, 0, 97,110,105,109, 95,112,108, 97,121,101, -114, 95,112,114,101,115,101,116, 0,118, 50,100, 95,109,105,110, 95,103,114,105,100,115,105,122,101, 0,116,105,109,101, 99,111, -100,101, 95,115,116,121,108,101, 0,118,101,114,115,105,111,110,115, 0,100, 98,108, 95, 99,108,105, 99,107, 95,116,105,109,101, - 0,103, 97,109,101,102,108, 97,103,115, 0,119,104,101,101,108,108,105,110,101,115, 99,114,111,108,108, 0,117,105,102,108, 97, -103, 0,108, 97,110,103,117, 97,103,101, 0,117,115,101,114,112,114,101,102, 0,118,105,101,119,122,111,111,109, 0,109,105,120, - 98,117,102,115,105,122,101, 0, 97,117,100,105,111,100,101,118,105, 99,101, 0, 97,117,100,105,111,114, 97,116,101, 0, 97,117, -100,105,111,102,111,114,109, 97,116, 0, 97,117,100,105,111, 99,104, 97,110,110,101,108,115, 0,100,112,105, 0,101,110, 99,111, -100,105,110,103, 0,116,114, 97,110,115,111,112,116,115, 0,109,101,110,117,116,104,114,101,115,104,111,108,100, 49, 0,109,101, -110,117,116,104,114,101,115,104,111,108,100, 50, 0,116,104,101,109,101,115, 0,117,105,102,111,110,116,115, 0,117,105,115,116, -121,108,101,115, 0,107,101,121,109, 97,112,115, 0,117,115,101,114, 95,107,101,121,109, 97,112,115, 0, 97,100,100,111,110,115, - 0,107,101,121, 99,111,110,102,105,103,115,116,114, 91, 54, 52, 93, 0,117,110,100,111,115,116,101,112,115, 0,117,110,100,111, -109,101,109,111,114,121, 0,103,112, 95,109, 97,110,104, 97,116,116,101,110,100,105,115,116, 0,103,112, 95,101,117, 99,108,105, -100,101, 97,110,100,105,115,116, 0,103,112, 95,101,114, 97,115,101,114, 0,103,112, 95,115,101,116,116,105,110,103,115, 0,116, - 98, 95,108,101,102,116,109,111,117,115,101, 0,116, 98, 95,114,105,103,104,116,109,111,117,115,101, 0,108,105,103,104,116, 91, - 51, 93, 0,116,119, 95,104,111,116,115,112,111,116, 0,116,119, 95,102,108, 97,103, 0,116,119, 95,104, 97,110,100,108,101,115, -105,122,101, 0,116,119, 95,115,105,122,101, 0,116,101,120,116,105,109,101,111,117,116, 0,116,101,120, 99,111,108,108,101, 99, -116,114, 97,116,101, 0,119,109,100,114, 97,119,109,101,116,104,111,100, 0,100,114, 97,103,116,104,114,101,115,104,111,108,100, - 0,109,101,109, 99, 97, 99,104,101,108,105,109,105,116, 0,112,114,101,102,101,116, 99,104,102,114, 97,109,101,115, 0,102,114, - 97,109,101,115,101,114,118,101,114,112,111,114,116, 0,112, 97,100, 95,114,111,116, 95, 97,110,103,108,101, 0,111, 98, 99,101, -110,116,101,114, 95,100,105, 97, 0,114,118,105,115,105,122,101, 0,114,118,105, 98,114,105,103,104,116, 0,114,101, 99,101,110, -116, 95,102,105,108,101,115, 0,115,109,111,111,116,104, 95,118,105,101,119,116,120, 0,103,108,114,101,115,108,105,109,105,116, - 0, 99,117,114,115,115,105,122,101, 0, 99,111,108,111,114, 95,112,105, 99,107,101,114, 95,116,121,112,101, 0,105,112,111, 95, -110,101,119, 0,107,101,121,104, 97,110,100,108,101,115, 95,110,101,119, 0,115, 99,114, 99, 97,115,116,102,112,115, 0,115, 99, -114, 99, 97,115,116,119, 97,105,116, 0,119,105,100,103,101,116, 95,117,110,105,116, 0, 97,110,105,115,111,116,114,111,112,105, - 99, 95,102,105,108,116,101,114, 0,117,115,101, 95, 49, 54, 98,105,116, 95,116,101,120,116,117,114,101,115, 0,112, 97,100, 56, - 0,110,100,111,102, 95,115,101,110,115,105,116,105,118,105,116,121, 0,110,100,111,102, 95,102,108, 97,103, 0,103,108, 97,108, -112,104, 97, 99,108,105,112, 0,116,101,120,116, 95,114,101,110,100,101,114, 0,112, 97,100, 57, 0, 99,111, 98, 97, 95,119,101, -105,103,104,116, 0,115, 99,117,108,112,116, 95,112, 97,105,110,116, 95,111,118,101,114,108, 97,121, 95, 99,111,108, 91, 51, 93, - 0,116,119,101, 97,107, 95,116,104,114,101,115,104,111,108,100, 0, 97,117,116,104,111,114, 91, 56, 48, 93, 0, 99,111,109,112, -117,116,101, 95,100,101,118,105, 99,101, 95,116,121,112,101, 0, 99,111,109,112,117,116,101, 95,100,101,118,105, 99,101, 95,105, -100, 0,102, 99,117, 95,105,110, 97, 99,116,105,118,101, 95, 97,108,112,104, 97, 0,118,101,114,116, 98, 97,115,101, 0,101,100, -103,101, 98, 97,115,101, 0, 97,114,101, 97, 98, 97,115,101, 0, 42,110,101,119,115, 99,101,110,101, 0,114,101,100,114, 97,119, -115, 95,102,108, 97,103, 0,102,117,108,108, 0,116,101,109,112, 0,119,105,110,105,100, 0,100,111, 95,100,114, 97,119, 0,100, -111, 95,114,101,102,114,101,115,104, 0,100,111, 95,100,114, 97,119, 95,103,101,115,116,117,114,101, 0,100,111, 95,100,114, 97, -119, 95,112, 97,105,110,116, 99,117,114,115,111,114, 0,100,111, 95,100,114, 97,119, 95,100,114, 97,103, 0,115,119, 97,112, 0, -109, 97,105,110,119,105,110, 0,115,117, 98,119,105,110, 97, 99,116,105,118,101, 0, 42, 97,110,105,109,116,105,109,101,114, 0, - 42, 99,111,110,116,101,120,116, 0,104, 97,110,100,108,101,114, 91, 56, 93, 0, 42,110,101,119,118, 0,118,101, 99, 0, 42,118, - 49, 0, 42,118, 50, 0, 42,116,121,112,101, 0,112, 97,110,101,108,110, 97,109,101, 91, 54, 52, 93, 0,116, 97, 98,110, 97,109, -101, 91, 54, 52, 93, 0,100,114, 97,119,110, 97,109,101, 91, 54, 52, 93, 0,111,102,115,120, 0,111,102,115,121, 0,115,105,122, -101,120, 0,115,105,122,101,121, 0,108, 97, 98,101,108,111,102,115, 0, 99,111,110,116,114,111,108, 0,115,110, 97,112, 0,115, -111,114,116,111,114,100,101,114, 0, 42,112, 97,110,101,108,116, 97, 98, 0, 42, 97, 99,116,105,118,101,100, 97,116, 97, 0,108, -105,115,116, 95,115, 99,114,111,108,108, 0,108,105,115,116, 95,115,105,122,101, 0,108,105,115,116, 95,108, 97,115,116, 95,108, -101,110, 0,108,105,115,116, 95,103,114,105,112, 95,115,105,122,101, 0,108,105,115,116, 95,115,101, 97,114, 99,104, 91, 54, 52, - 93, 0, 42,118, 51, 0, 42,118, 52, 0, 42,102,117,108,108, 0, 98,117,116,115,112, 97, 99,101,116,121,112,101, 0,104,101, 97, -100,101,114,116,121,112,101, 0,115,112, 97, 99,101,100, 97,116, 97, 0,104, 97,110,100,108,101,114,115, 0, 97, 99,116,105,111, -110,122,111,110,101,115, 0,119,105,110,114, 99,116, 0,100,114, 97,119,114, 99,116, 0,115,119,105,110,105,100, 0,114,101,103, -105,111,110,116,121,112,101, 0, 97,108,105,103,110,109,101,110,116, 0,100,111, 95,100,114, 97,119, 95,111,118,101,114,108, 97, -121, 0,117,105, 98,108,111, 99,107,115, 0,112, 97,110,101,108,115, 0, 42,104,101, 97,100,101,114,115,116,114, 0, 42,114,101, -103,105,111,110,100, 97,116, 97, 0,115,117, 98,118,115,116,114, 91, 52, 93, 0,115,117, 98,118,101,114,115,105,111,110, 0,112, - 97,100,115, 0,109,105,110,118,101,114,115,105,111,110, 0,109,105,110,115,117, 98,118,101,114,115,105,111,110, 0,119,105,110, -112,111,115, 0, 42, 99,117,114,115, 99,114,101,101,110, 0, 42, 99,117,114,115, 99,101,110,101, 0,102,105,108,101,102,108, 97, -103,115, 0,103,108,111, 98, 97,108,102, 0,114,101,118,105,115,105,111,110, 0,110, 97,109,101, 91, 50, 53, 54, 93, 0,111,114, -105,103, 95,119,105,100,116,104, 0,111,114,105,103, 95,104,101,105,103,104,116, 0, 98,111,116,116,111,109, 0,114,105,103,104, -116, 0,120,111,102,115, 0,121,111,102,115, 0,108,105,102,116, 91, 51, 93, 0,103, 97,109,109, 97, 91, 51, 93, 0,103, 97,105, -110, 91, 51, 93, 0,100,105,114, 91, 55, 54, 56, 93, 0,116, 99, 0, 98,117,105,108,100, 95,115,105,122,101, 95,102,108, 97,103, -115, 0, 98,117,105,108,100, 95,116, 99, 95,102,108, 97,103,115, 0,100,111,110,101, 0,115,116, 97,114,116,115,116,105,108,108, - 0,101,110,100,115,116,105,108,108, 0, 42,115,116,114,105,112,100, 97,116, 97, 0, 42, 99,114,111,112, 0, 42,116,114, 97,110, -115,102,111,114,109, 0, 42, 99,111,108,111,114, 95, 98, 97,108, 97,110, 99,101, 0, 42,105,110,115,116, 97,110, 99,101, 95,112, -114,105,118, 97,116,101, 95,100, 97,116, 97, 0, 42, 42, 99,117,114,114,101,110,116, 95,112,114,105,118, 97,116,101, 95,100, 97, -116, 97, 0, 42,116,109,112, 0,115,116, 97,114,116,111,102,115, 0,101,110,100,111,102,115, 0,109, 97, 99,104,105,110,101, 0, -115,116, 97,114,116,100,105,115,112, 0,101,110,100,100,105,115,112, 0,115, 97,116, 0,109,117,108, 0,104, 97,110,100,115,105, -122,101, 0, 97,110,105,109, 95,112,114,101,115,101,101,107, 0,115,116,114,101, 97,109,105,110,100,101,120, 0,109,117,108,116, -105, 99, 97,109, 95,115,111,117,114, 99,101, 0, 99,108,105,112, 95,102,108, 97,103, 0, 42,115,116,114,105,112, 0, 42,115, 99, -101,110,101, 95, 99, 97,109,101,114, 97, 0,101,102,102,101, 99,116, 95,102, 97,100,101,114, 0,115,112,101,101,100, 95,102, 97, -100,101,114, 0, 42,115,101,113, 49, 0, 42,115,101,113, 50, 0, 42,115,101,113, 51, 0,115,101,113, 98, 97,115,101, 0, 42,115, -111,117,110,100, 0, 42,115, 99,101,110,101, 95,115,111,117,110,100, 0,112,105,116, 99,104, 0,112, 97,110, 0,115,116,114,111, - 98,101, 0, 42,101,102,102,101, 99,116,100, 97,116, 97, 0, 97,110,105,109, 95,115,116, 97,114,116,111,102,115, 0, 97,110,105, -109, 95,101,110,100,111,102,115, 0, 98,108,101,110,100, 95,109,111,100,101, 0, 98,108,101,110,100, 95,111,112, 97, 99,105,116, -121, 0, 42,111,108,100, 98, 97,115,101,112, 0, 42,112, 97,114,115,101,113, 0, 42,115,101,113, 98, 97,115,101,112, 0,109,101, -116, 97,115,116, 97, 99,107, 0, 42, 97, 99,116, 95,115,101,113, 0, 97, 99,116, 95,105,109, 97,103,101,100,105,114, 91, 49, 48, - 50, 52, 93, 0, 97, 99,116, 95,115,111,117,110,100,100,105,114, 91, 49, 48, 50, 52, 93, 0,111,118,101,114, 95,111,102,115, 0, -111,118,101,114, 95, 99,102,114, 97, 0,111,118,101,114, 95,102,108, 97,103, 0,111,118,101,114, 95, 98,111,114,100,101,114, 0, -101,100,103,101, 87,105,100,116,104, 0,102,111,114,119, 97,114,100, 0,119,105,112,101,116,121,112,101, 0,102, 77,105,110,105, - 0,102, 67,108, 97,109,112, 0,102, 66,111,111,115,116, 0,100, 68,105,115,116, 0,100, 81,117, 97,108,105,116,121, 0, 98, 78, -111, 67,111,109,112, 0, 83, 99, 97,108,101,120, 73,110,105, 0, 83, 99, 97,108,101,121, 73,110,105, 0,120, 73,110,105, 0,121, - 73,110,105, 0,114,111,116, 73,110,105, 0,105,110,116,101,114,112,111,108, 97,116,105,111,110, 0,117,110,105,102,111,114,109, - 95,115, 99, 97,108,101, 0, 42,102,114, 97,109,101, 77, 97,112, 0,103,108,111, 98, 97,108, 83,112,101,101,100, 0,108, 97,115, -116, 86, 97,108,105,100, 70,114, 97,109,101, 0, 98,117,116,116,121,112,101, 0,117,115,101,114,106,105,116, 0,115,116, 97, 0, -116,111,116,112, 97,114,116, 0,110,111,114,109,102, 97, 99, 0,111, 98,102, 97, 99, 0,114, 97,110,100,102, 97, 99, 0,116,101, -120,102, 97, 99, 0,114, 97,110,100,108,105,102,101, 0,102,111,114, 99,101, 91, 51, 93, 0,118,101, 99,116,115,105,122,101, 0, -109, 97,120,108,101,110, 0,100,101,102,118,101, 99, 91, 51, 93, 0,109,117,108,116, 91, 52, 93, 0,108,105,102,101, 91, 52, 93, - 0, 99,104,105,108,100, 91, 52, 93, 0,109, 97,116, 91, 52, 93, 0,116,101,120,109, 97,112, 0, 99,117,114,109,117,108,116, 0, -115,116, 97,116,105, 99,115,116,101,112, 0,111,109, 97,116, 0,116,105,109,101,116,101,120, 0,115,112,101,101,100,116,101,120, - 0,102,108, 97,103, 50,110,101,103, 0,118,101,114,116,103,114,111,117,112, 95,118, 0,118,103,114,111,117,112,110, 97,109,101, - 91, 54, 52, 93, 0,118,103,114,111,117,112,110, 97,109,101, 95,118, 91, 54, 52, 93, 0, 42,107,101,121,115, 0,109,105,110,102, - 97, 99, 0,110,114, 0,117,115,101,100, 0,117,115,101,100,101,108,101,109, 0, 42,112,111,105,110, 0,114,101,115,101,116,100, -105,115,116, 0,108, 97,115,116,118, 97,108, 0, 42,109, 97, 0,107,101,121, 0,113,117, 97,108, 0,113,117, 97,108, 50, 0,116, - 97,114,103,101,116, 78, 97,109,101, 91, 54, 52, 93, 0,116,111,103,103,108,101, 78, 97,109,101, 91, 54, 52, 93, 0,118, 97,108, -117,101, 91, 54, 52, 93, 0,109, 97,120,118, 97,108,117,101, 91, 54, 52, 93, 0,100,101,108, 97,121, 0,100,117,114, 97,116,105, -111,110, 0,109, 97,116,101,114,105, 97,108, 78, 97,109,101, 91, 54, 52, 93, 0,100, 97,109,112,116,105,109,101,114, 0,112,114, -111,112,110, 97,109,101, 91, 54, 52, 93, 0,109, 97,116,110, 97,109,101, 91, 54, 52, 93, 0, 97,120,105,115,102,108, 97,103, 0, -112,111,115,101, 99,104, 97,110,110,101,108, 91, 54, 52, 93, 0, 99,111,110,115,116,114, 97,105,110,116, 91, 54, 52, 93, 0, 42, -102,114,111,109, 79, 98,106,101, 99,116, 0,115,117, 98,106,101, 99,116, 91, 54, 52, 93, 0, 98,111,100,121, 91, 54, 52, 93, 0, -111,116,121,112,101, 0,112,117,108,115,101, 0,102,114,101,113, 0,116,111,116,108,105,110,107,115, 0, 42, 42,108,105,110,107, -115, 0,116, 97,112, 0,106,111,121,105,110,100,101,120, 0, 97,120,105,115, 95,115,105,110,103,108,101, 0, 97,120,105,115,102, - 0, 98,117,116,116,111,110, 0,104, 97,116, 0,104, 97,116,102, 0,112,114,101, 99,105,115,105,111,110, 0,115,116,114, 91, 49, - 50, 56, 93, 0, 42,109,121,110,101,119, 0,105,110,112,117,116,115, 0,116,111,116,115,108,105,110,107,115, 0, 42, 42,115,108, -105,110,107,115, 0,118, 97,108,111, 0,115,116, 97,116,101, 95,109, 97,115,107, 0, 42, 97, 99,116, 0,102,114, 97,109,101, 80, -114,111,112, 91, 54, 52, 93, 0, 98,108,101,110,100,105,110, 0,112,114,105,111,114,105,116,121, 0,101,110,100, 95,114,101,115, -101,116, 0,115,116,114,105,100,101, 97,120,105,115, 0,115,116,114,105,100,101,108,101,110,103,116,104, 0,108, 97,121,101,114, - 95,119,101,105,103,104,116, 0,109,105,110, 95,103, 97,105,110, 0,109, 97,120, 95,103, 97,105,110, 0,114,101,102,101,114,101, -110, 99,101, 95,100,105,115,116, 97,110, 99,101, 0,109, 97,120, 95,100,105,115,116, 97,110, 99,101, 0,114,111,108,108,111,102, -102, 95,102, 97, 99,116,111,114, 0, 99,111,110,101, 95,105,110,110,101,114, 95, 97,110,103,108,101, 0, 99,111,110,101, 95,111, -117,116,101,114, 95, 97,110,103,108,101, 0, 99,111,110,101, 95,111,117,116,101,114, 95,103, 97,105,110, 0,115,110,100,110,114, - 0,115,111,117,110,100, 51, 68, 0,112, 97,100, 54, 91, 49, 93, 0, 42,109,101, 0,108,105,110, 86,101,108,111, 99,105,116,121, - 91, 51, 93, 0, 97,110,103, 86,101,108,111, 99,105,116,121, 91, 51, 93, 0,108,111, 99, 97,108,102,108, 97,103, 0,100,121,110, - 95,111,112,101,114, 97,116,105,111,110, 0,102,111,114, 99,101,108,111, 99, 91, 51, 93, 0,102,111,114, 99,101,114,111,116, 91, - 51, 93, 0,112, 97,100, 49, 91, 51, 93, 0,108,105,110,101, 97,114,118,101,108,111, 99,105,116,121, 91, 51, 93, 0, 97,110,103, -117,108, 97,114,118,101,108,111, 99,105,116,121, 91, 51, 93, 0, 42,114,101,102,101,114,101,110, 99,101, 0,109,105,110, 0,109, - 97,120, 0,114,111,116,100, 97,109,112, 0,109,105,110,108,111, 99, 91, 51, 93, 0,109, 97,120,108,111, 99, 91, 51, 93, 0,109, -105,110,114,111,116, 91, 51, 93, 0,109, 97,120,114,111,116, 91, 51, 93, 0,109, 97,116,112,114,111,112, 91, 54, 52, 93, 0, 98, -117,116,115,116, 97, 0, 98,117,116,101,110,100, 0,100,105,115,116,114,105, 98,117,116,105,111,110, 0,105,110,116, 95, 97,114, -103, 95, 49, 0,105,110,116, 95, 97,114,103, 95, 50, 0,102,108,111, 97,116, 95, 97,114,103, 95, 49, 0,102,108,111, 97,116, 95, - 97,114,103, 95, 50, 0,116,111, 80,114,111,112, 78, 97,109,101, 91, 54, 52, 93, 0, 42,116,111, 79, 98,106,101, 99,116, 0, 98, -111,100,121, 84,121,112,101, 0,102,105,108,101,110, 97,109,101, 91, 54, 52, 93, 0,108,111, 97,100, 97,110,105,110, 97,109,101, - 91, 54, 52, 93, 0,105,110,116, 95, 97,114,103, 0,102,108,111, 97,116, 95, 97,114,103, 0,105,110,102,108,117,101,110, 99,101, - 0, 42,115,117, 98,116, 97,114,103,101,116, 0,102, 97, 99,105,110,103, 97,120,105,115, 0,118,101,108,111, 99,105,116,121, 0, - 97, 99, 99,101,108,101,114, 97,116,105,111,110, 0,116,117,114,110,115,112,101,101,100, 0,117,112,100, 97,116,101, 84,105,109, -101, 0, 42,110, 97,118,109,101,115,104, 0,103,111, 0, 42,110,101,119,112, 97, 99,107,101,100,102,105,108,101, 0, 97,116,116, -101,110,117, 97,116,105,111,110, 0,100,105,115,116, 97,110, 99,101, 0, 42, 99, 97, 99,104,101, 0, 42,119, 97,118,101,102,111, -114,109, 0, 42,112,108, 97,121, 98, 97, 99,107, 95,104, 97,110,100,108,101, 0, 42,108, 97,109,112,114,101,110, 0,103,111, 98, -106,101, 99,116, 0,100,117,112,108,105, 95,111,102,115, 91, 51, 93, 0, 42,112,114,111,112, 0, 99,104,105,108,100, 98, 97,115, -101, 0,114,111,108,108, 0,104,101, 97,100, 91, 51, 93, 0,116, 97,105,108, 91, 51, 93, 0, 98,111,110,101, 95,109, 97,116, 91, - 51, 93, 91, 51, 93, 0, 97,114,109, 95,104,101, 97,100, 91, 51, 93, 0, 97,114,109, 95,116, 97,105,108, 91, 51, 93, 0, 97,114, -109, 95,109, 97,116, 91, 52, 93, 91, 52, 93, 0, 97,114,109, 95,114,111,108,108, 0,120,119,105,100,116,104, 0,122,119,105,100, -116,104, 0,101, 97,115,101, 49, 0,101, 97,115,101, 50, 0,114, 97,100, 95,104,101, 97,100, 0,114, 97,100, 95,116, 97,105,108, - 0,112, 97,100, 91, 49, 93, 0, 98,111,110,101, 98, 97,115,101, 0, 99,104, 97,105,110, 98, 97,115,101, 0, 42,101,100, 98,111, - 0, 42, 97, 99,116, 95, 98,111,110,101, 0, 42, 97, 99,116, 95,101,100, 98,111,110,101, 0, 42,115,107,101,116, 99,104, 0,103, -101,118,101,114,116,100,101,102,111,114,109,101,114, 0,108, 97,121,101,114, 95,117,115,101,100, 0,108, 97,121,101,114, 95,112, -114,111,116,101, 99,116,101,100, 0,103,104,111,115,116,101,112, 0,103,104,111,115,116,115,105,122,101, 0,103,104,111,115,116, -116,121,112,101, 0,112, 97,116,104,115,105,122,101, 0,103,104,111,115,116,115,102, 0,103,104,111,115,116,101,102, 0,112, 97, -116,104,115,102, 0,112, 97,116,104,101,102, 0,112, 97,116,104, 98, 99, 0,112, 97,116,104, 97, 99, 0, 42,112,111,105,110,116, -115, 0,115,116, 97,114,116, 95,102,114, 97,109,101, 0,101,110,100, 95,102,114, 97,109,101, 0,103,104,111,115,116, 95,115,102, - 0,103,104,111,115,116, 95,101,102, 0,103,104,111,115,116, 95, 98, 99, 0,103,104,111,115,116, 95, 97, 99, 0,103,104,111,115, -116, 95,116,121,112,101, 0,103,104,111,115,116, 95,115,116,101,112, 0,103,104,111,115,116, 95,102,108, 97,103, 0,112, 97,116, -104, 95,116,121,112,101, 0,112, 97,116,104, 95,115,116,101,112, 0,112, 97,116,104, 95,118,105,101,119,102,108, 97,103, 0,112, - 97,116,104, 95, 98, 97,107,101,102,108, 97,103, 0,112, 97,116,104, 95,115,102, 0,112, 97,116,104, 95,101,102, 0,112, 97,116, -104, 95, 98, 99, 0,112, 97,116,104, 95, 97, 99, 0,105,107,102,108, 97,103, 0, 97,103,114,112, 95,105,110,100,101,120, 0, 99, -111,110,115,116,102,108, 97,103, 0,115,101,108,101, 99,116,102,108, 97,103, 0,112, 97,100, 48, 91, 54, 93, 0, 42, 98,111,110, -101, 0, 42, 99,104,105,108,100, 0,105,107,116,114,101,101, 0,115,105,107,116,114,101,101, 0, 42, 99,117,115,116,111,109, 0, - 42, 99,117,115,116,111,109, 95,116,120, 0,101,117,108, 91, 51, 93, 0, 99,104, 97,110, 95,109, 97,116, 91, 52, 93, 91, 52, 93, - 0,112,111,115,101, 95,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,111,115,101, 95,104,101, 97,100, 91, 51, 93, 0,112,111,115, -101, 95,116, 97,105,108, 91, 51, 93, 0,108,105,109,105,116,109,105,110, 91, 51, 93, 0,108,105,109,105,116,109, 97,120, 91, 51, - 93, 0,115,116,105,102,102,110,101,115,115, 91, 51, 93, 0,105,107,115,116,114,101,116, 99,104, 0,105,107,114,111,116,119,101, -105,103,104,116, 0,105,107,108,105,110,119,101,105,103,104,116, 0, 42,116,101,109,112, 0, 99,104, 97,110, 98, 97,115,101, 0, - 42, 99,104, 97,110,104, 97,115,104, 0,112,114,111,120,121, 95,108, 97,121,101,114, 0,115,116,114,105,100,101, 95,111,102,102, -115,101,116, 91, 51, 93, 0, 99,121, 99,108,105, 99, 95,111,102,102,115,101,116, 91, 51, 93, 0, 97,103,114,111,117,112,115, 0, - 97, 99,116,105,118,101, 95,103,114,111,117,112, 0,105,107,115,111,108,118,101,114, 0, 42,105,107,100, 97,116, 97, 0, 42,105, -107,112, 97,114, 97,109, 0,112,114,111,120,121, 95, 97, 99,116, 95, 98,111,110,101, 91, 54, 52, 93, 0,110,117,109,105,116,101, -114, 0,110,117,109,115,116,101,112, 0,109,105,110,115,116,101,112, 0,109, 97,120,115,116,101,112, 0,115,111,108,118,101,114, - 0,102,101,101,100, 98, 97, 99,107, 0,109, 97,120,118,101,108, 0,100, 97,109,112,109, 97,120, 0,100, 97,109,112,101,112,115, - 0, 99,104, 97,110,110,101,108,115, 0, 99,117,115,116,111,109, 67,111,108, 0, 99,115, 0, 99,117,114,118,101,115, 0,103,114, -111,117,112,115, 0, 97, 99,116,105,118,101, 95,109, 97,114,107,101,114, 0,105,100,114,111,111,116, 0, 42,115,111,117,114, 99, -101, 0, 42,102,105,108,116,101,114, 95,103,114,112, 0,115,101, 97,114, 99,104,115,116,114, 91, 54, 52, 93, 0,102,105,108,116, -101,114,102,108, 97,103, 0,114,101,110, 97,109,101, 73,110,100,101,120, 0, 97,100,115, 0,116,105,109,101,115,108,105,100,101, - 0, 42,103,114,112, 0,110, 97,109,101, 91, 51, 48, 93, 0,111,119,110,115,112, 97, 99,101, 0,116, 97,114,115,112, 97, 99,101, - 0,101,110,102,111,114, 99,101, 0,104,101, 97,100,116, 97,105,108, 0,108,105,110, 95,101,114,114,111,114, 0,114,111,116, 95, -101,114,114,111,114, 0, 42,116, 97,114, 0,109, 97,116,114,105,120, 91, 52, 93, 91, 52, 93, 0,115,112, 97, 99,101, 0,114,111, -116, 79,114,100,101,114, 0,116, 97,114,110,117,109, 0,116, 97,114,103,101,116,115, 0,105,116,101,114, 97,116,105,111,110,115, - 0,114,111,111,116, 98,111,110,101, 0,109, 97,120, 95,114,111,111,116, 98,111,110,101, 0, 42,112,111,108,101,116, 97,114, 0, -112,111,108,101,115,117, 98,116, 97,114,103,101,116, 91, 54, 52, 93, 0,112,111,108,101, 97,110,103,108,101, 0,111,114,105,101, -110,116,119,101,105,103,104,116, 0,103,114, 97, 98,116, 97,114,103,101,116, 91, 51, 93, 0,110,117,109,112,111,105,110,116,115, - 0, 99,104, 97,105,110,108,101,110, 0,120,122, 83, 99, 97,108,101, 77,111,100,101, 0,114,101,115,101,114,118,101,100, 49, 0, -114,101,115,101,114,118,101,100, 50, 0,109,105,110,109, 97,120,102,108, 97,103, 0,115,116,117, 99,107, 0, 99, 97, 99,104,101, - 91, 51, 93, 0,108,111, 99,107,102,108, 97,103, 0,102,111,108,108,111,119,102,108, 97,103, 0,118,111,108,109,111,100,101, 0, -112,108, 97,110,101, 0,111,114,103,108,101,110,103,116,104, 0, 98,117,108,103,101, 0,112,105,118, 88, 0,112,105,118, 89, 0, -112,105,118, 90, 0, 97,120, 88, 0, 97,120, 89, 0, 97,120, 90, 0,109,105,110, 76,105,109,105,116, 91, 54, 93, 0,109, 97,120, - 76,105,109,105,116, 91, 54, 93, 0,101,120,116,114, 97, 70,122, 0,105,110,118,109, 97,116, 91, 52, 93, 91, 52, 93, 0,102,114, -111,109, 0,116,111, 0,109, 97,112, 91, 51, 93, 0,101,120,112,111, 0,102,114,111,109, 95,109,105,110, 91, 51, 93, 0,102,114, -111,109, 95,109, 97,120, 91, 51, 93, 0,116,111, 95,109,105,110, 91, 51, 93, 0,116,111, 95,109, 97,120, 91, 51, 93, 0,114,111, -116, 65,120,105,115, 0,122,109,105,110, 0,122,109, 97,120, 0,112, 97,100, 91, 57, 93, 0,116,114, 97, 99,107, 91, 54, 52, 93, - 0,111, 98,106,101, 99,116, 91, 54, 52, 93, 0, 42,100,101,112,116,104, 95,111, 98, 0, 99,104, 97,110,110,101,108, 91, 51, 50, - 93, 0,110,111, 95,114,111,116, 95, 97,120,105,115, 0,115,116,114,105,100,101, 95, 97,120,105,115, 0, 99,117,114,109,111,100, - 0, 97, 99,116,115,116, 97,114,116, 0, 97, 99,116,101,110,100, 0, 97, 99,116,111,102,102,115, 0,115,116,114,105,100,101,108, -101,110, 0, 98,108,101,110,100,111,117,116, 0,115,116,114,105,100,101, 99,104, 97,110,110,101,108, 91, 51, 50, 93, 0,111,102, -102,115, 95, 98,111,110,101, 91, 51, 50, 93, 0,104, 97,115,105,110,112,117,116, 0,104, 97,115,111,117,116,112,117,116, 0,100, - 97,116, 97,116,121,112,101, 0,115,111, 99,107,101,116,116,121,112,101, 0,105,115, 95, 99,111,112,121, 0,101,120,116,101,114, -110, 97,108, 0, 42,110,101,119, 95,115,111, 99,107, 0, 42,115,116,111,114, 97,103,101, 0,108,105,109,105,116, 0,115,116,114, -117, 99,116, 95,116,121,112,101, 0,108,111, 99,120, 0,108,111, 99,121, 0, 42,100,101,102, 97,117,108,116, 95,118, 97,108,117, -101, 0,115,116, 97, 99,107, 95,105,110,100,101,120, 0,115,116, 97, 99,107, 95,116,121,112,101, 0,111,119,110, 95,105,110,100, -101,120, 0,116,111, 95,105,110,100,101,120, 0, 42,103,114,111,117,112,115,111, 99,107, 0, 42,108,105,110,107, 0,110,115, 0, - 42,114,101, 99,116, 0,120,115,105,122,101, 0,121,115,105,122,101, 0, 42,110,101,119, 95,110,111,100,101, 0,108, 97,115,116, -121, 0,111,117,116,112,117,116,115, 0,109,105,110,105,119,105,100,116,104, 0,117,112,100, 97,116,101, 0,108, 97, 98,101,108, - 91, 54, 52, 93, 0, 99,117,115,116,111,109, 49, 0, 99,117,115,116,111,109, 50, 0, 99,117,115,116,111,109, 51, 0, 99,117,115, -116,111,109, 52, 0,110,101,101,100, 95,101,120,101, 99, 0,101,120,101, 99, 0, 42,116,104,114,101, 97,100,100, 97,116, 97, 0, -116,111,116,114, 0, 98,117,116,114, 0,112,114,118,114, 0, 42, 98,108,111, 99,107, 0, 42,116,121,112,101,105,110,102,111, 0, - 42,102,114,111,109,110,111,100,101, 0, 42,116,111,110,111,100,101, 0, 42,102,114,111,109,115,111, 99,107, 0, 42,116,111,115, -111, 99,107, 0,110,111,100,101,115, 0,108,105,110,107,115, 0,105,110,105,116, 0, 99,117,114, 95,105,110,100,101,120, 0,110, -111,100,101,116,121,112,101, 0, 42,101,120,101, 99,100, 97,116, 97, 0, 40, 42,112,114,111,103,114,101,115,115, 41, 40, 41, 0, - 40, 42,115,116, 97,116,115, 95,100,114, 97,119, 41, 40, 41, 0, 40, 42,116,101,115,116, 95, 98,114,101, 97,107, 41, 40, 41, 0, - 42,116, 98,104, 0, 42,112,114,104, 0, 42,115,100,104, 0,118, 97,108,117,101, 91, 51, 93, 0,118, 97,108,117,101, 91, 52, 93, - 0, 99,121, 99,108,105, 99, 0,109,111,118,105,101, 0,115, 97,109,112,108,101,115, 0,109, 97,120,115,112,101,101,100, 0,109, -105,110,115,112,101,101,100, 0, 99,117,114,118,101,100, 0,112,101,114, 99,101,110,116,120, 0,112,101,114, 99,101,110,116,121, - 0, 98,111,107,101,104, 0,103, 97,109,109, 97, 0,105,109, 97,103,101, 95,105,110, 95,119,105,100,116,104, 0,105,109, 97,103, -101, 95,105,110, 95,104,101,105,103,104,116, 0, 99,101,110,116,101,114, 95,120, 0, 99,101,110,116,101,114, 95,121, 0,115,112, -105,110, 0,119,114, 97,112, 0,115,105,103,109, 97, 95, 99,111,108,111,114, 0,115,105,103,109, 97, 95,115,112, 97, 99,101, 0, -104,117,101, 0, 98, 97,115,101, 95,112, 97,116,104, 91, 49, 48, 50, 52, 93, 0,102,111,114,109, 97,116, 0, 97, 99,116,105,118, -101, 95,105,110,112,117,116, 0,117,115,101, 95,114,101,110,100,101,114, 95,102,111,114,109, 97,116, 0,117,115,101, 95,110,111, -100,101, 95,102,111,114,109, 97,116, 0,116, 49, 0,116, 50, 0,116, 51, 0,102,115,116,114,101,110,103,116,104, 0,102, 97,108, -112,104, 97, 0,107,101,121, 91, 52, 93, 0, 97,108,103,111,114,105,116,104,109, 0, 99,104, 97,110,110,101,108, 0,120, 49, 0, -120, 50, 0,121, 49, 0,121, 50, 0,102, 97, 99, 95,120, 49, 0,102, 97, 99, 95,120, 50, 0,102, 97, 99, 95,121, 49, 0,102, 97, - 99, 95,121, 50, 0, 99,111,108,110, 97,109,101, 91, 54, 52, 93, 0, 98,107,116,121,112,101, 0,112, 97,100, 95, 99, 49, 0,103, - 97,109, 99,111, 0,110,111, 95,122, 98,117,102, 0,102,115,116,111,112, 0,109, 97,120, 98,108,117,114, 0, 98,116,104,114,101, -115,104, 0,114,111,116, 97,116,105,111,110, 0,112, 97,100, 95,102, 49, 0, 42,100,105, 99,116, 0, 42,110,111,100,101, 0, 99, -111,108,109,111,100, 0,109,105,120, 0,102, 97,100,101, 0, 97,110,103,108,101, 95,111,102,115, 0,109, 0, 99, 0,106,105,116, - 0,112,114,111,106, 0,102,105,116, 0,115,108,111,112,101, 91, 51, 93, 0,112,111,119,101,114, 91, 51, 93, 0,108,105,102,116, - 95,108,103,103, 91, 51, 93, 0,103, 97,109,109, 97, 95,105,110,118, 91, 51, 93, 0,108,105,109, 99,104, 97,110, 0,117,110,115, -112,105,108,108, 0,108,105,109,115, 99, 97,108,101, 0,117,115,112,105,108,108,114, 0,117,115,112,105,108,108,103, 0,117,115, -112,105,108,108, 98, 0,116,101,120, 95,109, 97,112,112,105,110,103, 0, 99,111,108,111,114, 95,109, 97,112,112,105,110,103, 0, -115,117,110, 95,100,105,114,101, 99,116,105,111,110, 91, 51, 93, 0,116,117,114, 98,105,100,105,116,121, 0, 99,111,108,111,114, - 95,115,112, 97, 99,101, 0,112,114,111,106,101, 99,116,105,111,110, 0,103,114, 97,100,105,101,110,116, 95,116,121,112,101, 0, - 99,111,108,111,114,105,110,103, 0,109,117,115,103,114, 97,118,101, 95,116,121,112,101, 0,119, 97,118,101, 95,116,121,112,101, - 0,115,104,111,114,116,121, 0,109,105,110,116, 97, 98,108,101, 0,109, 97,120,116, 97, 98,108,101, 0,101,120,116, 95,105,110, - 91, 50, 93, 0,101,120,116, 95,111,117,116, 91, 50, 93, 0, 42, 99,117,114,118,101, 0, 42,116, 97, 98,108,101, 0, 42,112,114, -101,109,117,108,116, 97, 98,108,101, 0,112,114,101,115,101,116, 0, 99,104, 97,110,103,101,100, 95,116,105,109,101,115,116, 97, -109,112, 0, 99,117,114,114, 0, 99,108,105,112,114, 0, 99,109, 91, 52, 93, 0, 98,108, 97, 99,107, 91, 51, 93, 0,119,104,105, -116,101, 91, 51, 93, 0, 98,119,109,117,108, 91, 51, 93, 0,115, 97,109,112,108,101, 91, 51, 93, 0,120, 95,114,101,115,111,108, -117,116,105,111,110, 0,100, 97,116, 97, 95,114, 91, 50, 53, 54, 93, 0,100, 97,116, 97, 95,103, 91, 50, 53, 54, 93, 0,100, 97, -116, 97, 95, 98, 91, 50, 53, 54, 93, 0,100, 97,116, 97, 95,108,117,109, 97, 91, 50, 53, 54, 93, 0,115, 97,109,112,108,101, 95, -102,117,108,108, 0,115, 97,109,112,108,101, 95,108,105,110,101,115, 0, 97, 99, 99,117,114, 97, 99,121, 0,119, 97,118,101,102, -114,109, 95,109,111,100,101, 0,119, 97,118,101,102,114,109, 95, 97,108,112,104, 97, 0,119, 97,118,101,102,114,109, 95,121,102, - 97, 99, 0,119, 97,118,101,102,114,109, 95,104,101,105,103,104,116, 0,118,101, 99,115, 99,111,112,101, 95, 97,108,112,104, 97, - 0,118,101, 99,115, 99,111,112,101, 95,104,101,105,103,104,116, 0,109,105,110,109, 97,120, 91, 51, 93, 91, 50, 93, 0,104,105, -115,116, 0, 42,119, 97,118,101,102,111,114,109, 95, 49, 0, 42,119, 97,118,101,102,111,114,109, 95, 50, 0, 42,119, 97,118,101, -102,111,114,109, 95, 51, 0, 42,118,101, 99,115, 99,111,112,101, 0,119, 97,118,101,102,111,114,109, 95,116,111,116, 0,111,102, -102,115,101,116, 91, 50, 93, 0, 99,108,111,110,101, 0,109,116,101,120, 0, 42,105, 99,111,110, 95,105,109, 98,117,102, 0,105, - 99,111,110, 95,102,105,108,101,112, 97,116,104, 91, 49, 48, 50, 52, 93, 0,110,111,114,109, 97,108, 95,119,101,105,103,104,116, - 0,111, 98, 95,109,111,100,101, 0,106,105,116,116,101,114, 0,115,109,111,111,116,104, 95,115,116,114,111,107,101, 95,114, 97, -100,105,117,115, 0,115,109,111,111,116,104, 95,115,116,114,111,107,101, 95,102, 97, 99,116,111,114, 0,114, 97,116,101, 0,114, -103, 98, 91, 51, 93, 0,115, 99,117,108,112,116, 95,112,108, 97,110,101, 0,112,108, 97,110,101, 95,111,102,102,115,101,116, 0, -115, 99,117,108,112,116, 95,116,111,111,108, 0,118,101,114,116,101,120,112, 97,105,110,116, 95,116,111,111,108, 0,105,109, 97, -103,101,112, 97,105,110,116, 95,116,111,111,108, 0,112, 97,100, 51, 91, 53, 93, 0, 97,117,116,111,115,109,111,111,116,104, 95, -102, 97, 99,116,111,114, 0, 99,114,101, 97,115,101, 95,112,105,110, 99,104, 95,102, 97, 99,116,111,114, 0,112,108, 97,110,101, - 95,116,114,105,109, 0,116,101,120,116,117,114,101, 95,115, 97,109,112,108,101, 95, 98,105, 97,115, 0,116,101,120,116,117,114, -101, 95,111,118,101,114,108, 97,121, 95, 97,108,112,104, 97, 0, 97,100,100, 95, 99,111,108, 91, 51, 93, 0,115,117, 98, 95, 99, -111,108, 91, 51, 93, 0, 97, 99,116,105,118,101, 95,114,110,100, 0, 97, 99,116,105,118,101, 95, 99,108,111,110,101, 0, 97, 99, -116,105,118,101, 95,109, 97,115,107, 0, 42,108, 97,121,101,114,115, 0,116,121,112,101,109, 97,112, 91, 51, 52, 93, 0,116,111, -116,108, 97,121,101,114, 0,109, 97,120,108, 97,121,101,114, 0,116,111,116,115,105,122,101, 0, 42,112,111,111,108, 0, 42,101, -120,116,101,114,110, 97,108, 0,114,111,116, 91, 52, 93, 0, 97,118,101, 91, 51, 93, 0, 42,103,114,111,117,110,100, 0,119, 97, -110,100,101,114, 91, 51, 93, 0,114,101,115,116, 95,108,101,110,103,116,104, 0,112, 97,114,116,105, 99,108,101, 95,105,110,100, -101,120, 91, 50, 93, 0,100,101,108,101,116,101, 95,102,108, 97,103, 0,110,117,109, 0,112, 97,114,101,110,116, 0,112, 97, 91, - 52, 93, 0,119, 91, 52, 93, 0,102,117,118, 91, 52, 93, 0,102,111,102,102,115,101,116, 0,112,114,101,118, 95,115,116, 97,116, -101, 0, 42,104, 97,105,114, 0, 42, 98,111,105,100, 0,100,105,101,116,105,109,101, 0,110,117,109, 95,100,109, 99, 97, 99,104, -101, 0,104, 97,105,114, 95,105,110,100,101,120, 0, 97,108,105,118,101, 0,115,112,114,105,110,103, 95,107, 0,112,108, 97,115, -116,105, 99,105,116,121, 95, 99,111,110,115,116, 97,110,116, 0,121,105,101,108,100, 95,114, 97,116,105,111, 0,112,108, 97,115, -116,105, 99,105,116,121, 95, 98, 97,108, 97,110, 99,101, 0,121,105,101,108,100, 95, 98, 97,108, 97,110, 99,101, 0,118,105,115, - 99,111,115,105,116,121, 95,111,109,101,103, 97, 0,118,105,115, 99,111,115,105,116,121, 95, 98,101,116, 97, 0,115,116,105,102, -102,110,101,115,115, 95,107, 0,115,116,105,102,102,110,101,115,115, 95,107,110,101, 97,114, 0,114,101,115,116, 95,100,101,110, -115,105,116,121, 0, 98,117,111,121, 97,110, 99,121, 0,115,112,114,105,110,103, 95,102,114, 97,109,101,115, 0, 42, 98,111,105, -100,115, 0, 42,102,108,117,105,100, 0,100,105,115,116,114, 0,112,104,121,115,116,121,112,101, 0, 97,118,101,109,111,100,101, - 0,114,101, 97, 99,116,101,118,101,110,116, 0,100,114, 97,119, 0,100,114, 97,119, 95, 97,115, 0,100,114, 97,119, 95,115,105, -122,101, 0, 99,104,105,108,100,116,121,112,101, 0,114,101,110, 95, 97,115, 0,115,117, 98,102,114, 97,109,101,115, 0,100,114, - 97,119, 95, 99,111,108, 0,114,101,110, 95,115,116,101,112, 0,104, 97,105,114, 95,115,116,101,112, 0,107,101,121,115, 95,115, -116,101,112, 0, 97,100, 97,112,116, 95, 97,110,103,108,101, 0, 97,100, 97,112,116, 95,112,105,120, 0,114,111,116,102,114,111, -109, 0,105,110,116,101,103,114, 97,116,111,114, 0, 98, 98, 95, 97,108,105,103,110, 0, 98, 98, 95,117,118, 95,115,112,108,105, -116, 0, 98, 98, 95, 97,110,105,109, 0, 98, 98, 95,115,112,108,105,116, 95,111,102,102,115,101,116, 0, 98, 98, 95,116,105,108, -116, 0, 98, 98, 95,114, 97,110,100, 95,116,105,108,116, 0, 98, 98, 95,111,102,102,115,101,116, 91, 50, 93, 0, 98, 98, 95,115, -105,122,101, 91, 50, 93, 0, 98, 98, 95,118,101,108, 95,104,101, 97,100, 0, 98, 98, 95,118,101,108, 95,116, 97,105,108, 0, 99, -111,108,111,114, 95,118,101, 99, 95,109, 97,120, 0,115,105,109,112,108,105,102,121, 95,114,101,102,115,105,122,101, 0,115,105, -109,112,108,105,102,121, 95,114, 97,116,101, 0,115,105,109,112,108,105,102,121, 95,116,114, 97,110,115,105,116,105,111,110, 0, -115,105,109,112,108,105,102,121, 95,118,105,101,119,112,111,114,116, 0,116,105,109,101,116,119,101, 97,107, 0, 99,111,117,114, - 97,110,116, 95,116, 97,114,103,101,116, 0,106,105,116,102, 97, 99, 0,101,102,102, 95,104, 97,105,114, 0,103,114,105,100, 95, -114, 97,110,100, 0,112,115, 95,111,102,102,115,101,116, 91, 49, 93, 0,103,114,105,100, 95,114,101,115, 0,101,102,102,101, 99, -116,111,114, 95, 97,109,111,117,110,116, 0,116,105,109,101, 95,102,108, 97,103, 0,116,105,109,101, 95,112, 97,100, 91, 51, 93, - 0,112, 97,114,116,102, 97, 99, 0,116, 97,110,102, 97, 99, 0,116, 97,110,112,104, 97,115,101, 0,114,101, 97, 99,116,102, 97, - 99, 0,111, 98, 95,118,101,108, 91, 51, 93, 0, 97,118,101,102, 97, 99, 0,112,104, 97,115,101,102, 97, 99, 0,114, 97,110,100, -114,111,116,102, 97, 99, 0,114, 97,110,100,112,104, 97,115,101,102, 97, 99, 0,114, 97,110,100,115,105,122,101, 0, 97, 99, 99, - 91, 51, 93, 0,100,114, 97,103,102, 97, 99, 0, 98,114,111,119,110,102, 97, 99, 0,114, 97,110,100,108,101,110,103,116,104, 0, - 99,104,105,108,100, 95,110, 98,114, 0,114,101,110, 95, 99,104,105,108,100, 95,110, 98,114, 0,112, 97,114,101,110,116,115, 0, - 99,104,105,108,100,115,105,122,101, 0, 99,104,105,108,100,114, 97,110,100,115,105,122,101, 0, 99,104,105,108,100,114, 97,100, - 0, 99,104,105,108,100,102,108, 97,116, 0, 99,108,117,109,112,112,111,119, 0,107,105,110,107, 95,102,108, 97,116, 0,107,105, -110,107, 95, 97,109,112, 95, 99,108,117,109,112, 0,114,111,117,103,104, 49, 0,114,111,117,103,104, 49, 95,115,105,122,101, 0, -114,111,117,103,104, 50, 0,114,111,117,103,104, 50, 95,115,105,122,101, 0,114,111,117,103,104, 50, 95,116,104,114,101,115, 0, -114,111,117,103,104, 95,101,110,100, 0,114,111,117,103,104, 95,101,110,100, 95,115,104, 97,112,101, 0, 99,108,101,110,103,116, -104, 0, 99,108,101,110,103,116,104, 95,116,104,114,101,115, 0,112, 97,114,116,105,110,103, 95,102, 97, 99, 0,112, 97,114,116, -105,110,103, 95,109,105,110, 0,112, 97,114,116,105,110,103, 95,109, 97,120, 0, 98,114, 97,110, 99,104, 95,116,104,114,101,115, - 0,100,114, 97,119, 95,108,105,110,101, 91, 50, 93, 0,112, 97,116,104, 95,115,116, 97,114,116, 0,112, 97,116,104, 95,101,110, -100, 0,116,114, 97,105,108, 95, 99,111,117,110,116, 0,107,101,121,101,100, 95,108,111,111,112,115, 0,100,117,112,108,105,119, -101,105,103,104,116,115, 0, 42,101,102,102, 95,103,114,111,117,112, 0, 42,100,117,112, 95,111, 98, 0, 42, 98, 98, 95,111, 98, - 0, 42,112,100, 50, 0, 42,112, 97,114,116, 0, 42,112, 97,114,116,105, 99,108,101,115, 0, 42, 42,112, 97,116,104, 99, 97, 99, -104,101, 0, 42, 42, 99,104,105,108,100, 99, 97, 99,104,101, 0,112, 97,116,104, 99, 97, 99,104,101, 98,117,102,115, 0, 99,104, -105,108,100, 99, 97, 99,104,101, 98,117,102,115, 0, 42, 99,108,109,100, 0, 42,104, 97,105,114, 95,105,110, 95,100,109, 0, 42, -104, 97,105,114, 95,111,117,116, 95,100,109, 0, 42,116, 97,114,103,101,116, 95,111, 98, 0, 42,108, 97,116,116,105, 99,101, 0, -116,114,101,101, 95,102,114, 97,109,101, 0, 98,118,104,116,114,101,101, 95,102,114, 97,109,101, 0, 99,104,105,108,100, 95,115, -101,101,100, 0,116,111,116,117,110,101,120,105,115,116, 0,116,111,116, 99,104,105,108,100, 0,116,111,116, 99, 97, 99,104,101, -100, 0,116,111,116, 99,104,105,108,100, 99, 97, 99,104,101, 0,116, 97,114,103,101,116, 95,112,115,121,115, 0,116,111,116,107, -101,121,101,100, 0, 98, 97,107,101,115,112, 97, 99,101, 0, 98, 98, 95,117,118,110, 97,109,101, 91, 51, 93, 91, 54, 52, 93, 0, -118,103,114,111,117,112, 91, 49, 50, 93, 0,118,103, 95,110,101,103, 0,114,116, 51, 0, 42,114,101,110,100,101,114,100, 97,116, - 97, 0, 42,101,102,102,101, 99,116,111,114,115, 0, 42,102,108,117,105,100, 95,115,112,114,105,110,103,115, 0,116,111,116, 95, -102,108,117,105,100,115,112,114,105,110,103,115, 0, 97,108,108,111, 99, 95,102,108,117,105,100,115,112,114,105,110,103,115, 0, - 42,116,114,101,101, 0, 42,112,100,100, 0, 42,102,114, 97,110,100, 0,100,116, 95,102,114, 97, 99, 0, 95,112, 97,100, 0, 67, -100,105,115, 0, 67,118,105, 0,115,116,114,117, 99,116,117,114, 97,108, 0, 98,101,110,100,105,110,103, 0,109, 97,120, 95, 98, -101,110,100, 0,109, 97,120, 95,115,116,114,117, 99,116, 0,109, 97,120, 95,115,104,101, 97,114, 0, 97,118,103, 95,115,112,114, -105,110,103, 95,108,101,110, 0,116,105,109,101,115, 99, 97,108,101, 0,101,102,102, 95,102,111,114, 99,101, 95,115, 99, 97,108, -101, 0,101,102,102, 95,119,105,110,100, 95,115, 99, 97,108,101, 0,115,105,109, 95,116,105,109,101, 95,111,108,100, 0,118,101, -108,111, 99,105,116,121, 95,115,109,111,111,116,104, 0, 99,111,108,108,105,100,101,114, 95,102,114,105, 99,116,105,111,110, 0, -118,101,108, 95,100, 97,109,112,105,110,103, 0,115,116,101,112,115, 80,101,114, 70,114, 97,109,101, 0,112,114,101,114,111,108, -108, 0,109, 97,120,115,112,114,105,110,103,108,101,110, 0,115,111,108,118,101,114, 95,116,121,112,101, 0,118,103,114,111,117, -112, 95, 98,101,110,100, 0,118,103,114,111,117,112, 95,109, 97,115,115, 0,118,103,114,111,117,112, 95,115,116,114,117, 99,116, - 0,115,104, 97,112,101,107,101,121, 95,114,101,115,116, 0,112,114,101,115,101,116,115, 0,114,101,115,101,116, 0, 42, 99,111, -108,108,105,115,105,111,110, 95,108,105,115,116, 0,101,112,115,105,108,111,110, 0,115,101,108,102, 95,102,114,105, 99,116,105, -111,110, 0,115,101,108,102,101,112,115,105,108,111,110, 0,114,101,112,101,108, 95,102,111,114, 99,101, 0,100,105,115,116, 97, -110, 99,101, 95,114,101,112,101,108, 0,115,101,108,102, 95,108,111,111,112, 95, 99,111,117,110,116, 0,108,111,111,112, 95, 99, -111,117,110,116, 0,112,114,101,115,115,117,114,101, 0,116,104,105, 99,107,110,101,115,115, 0,115,116,114,111,107,101,115, 0, -102,114, 97,109,101,110,117,109, 0, 42, 97, 99,116,102,114, 97,109,101, 0,103,115,116,101,112, 0,105,110,102,111, 91, 49, 50, - 56, 93, 0,115, 98,117,102,102,101,114, 95,115,105,122,101, 0,115, 98,117,102,102,101,114, 95,115,102,108, 97,103, 0, 42,115, - 98,117,102,102,101,114, 0,108,105,115,116, 0,112,114,105,110,116,108,101,118,101,108, 0,115,116,111,114,101,108,101,118,101, -108, 0, 42,114,101,112,111,114,116,116,105,109,101,114, 0, 42,119,105,110,100,114, 97,119, 97, 98,108,101, 0, 42,119,105,110, - 97, 99,116,105,118,101, 0,119,105,110,100,111,119,115, 0,105,110,105,116,105, 97,108,105,122,101,100, 0,102,105,108,101, 95, -115, 97,118,101,100, 0,111,112, 95,117,110,100,111, 95,100,101,112,116,104, 0,111,112,101,114, 97,116,111,114,115, 0,113,117, -101,117,101, 0,114,101,112,111,114,116,115, 0,106,111, 98,115, 0,112, 97,105,110,116, 99,117,114,115,111,114,115, 0,100,114, - 97,103,115, 0,107,101,121, 99,111,110,102,105,103,115, 0, 42,100,101,102, 97,117,108,116, 99,111,110,102, 0, 42, 97,100,100, -111,110, 99,111,110,102, 0, 42,117,115,101,114, 99,111,110,102, 0,116,105,109,101,114,115, 0, 42, 97,117,116,111,115, 97,118, -101,116,105,109,101,114, 0, 42,103,104,111,115,116,119,105,110, 0,103,114, 97, 98, 99,117,114,115,111,114, 0, 42,115, 99,114, -101,101,110, 0, 42,110,101,119,115, 99,114,101,101,110, 0,115, 99,114,101,101,110,110, 97,109,101, 91, 54, 52, 93, 0,112,111, -115,120, 0,112,111,115,121, 0,119,105,110,100,111,119,115,116, 97,116,101, 0,109,111,110,105,116,111,114, 0,108, 97,115,116, - 99,117,114,115,111,114, 0,109,111,100, 97,108, 99,117,114,115,111,114, 0, 97,100,100,109,111,117,115,101,109,111,118,101, 0, - 42,101,118,101,110,116,115,116, 97,116,101, 0, 42, 99,117,114,115,119,105,110, 0, 42,116,119,101, 97,107, 0,100,114, 97,119, -109,101,116,104,111,100, 0,100,114, 97,119,102, 97,105,108, 0, 42,100,114, 97,119,100, 97,116, 97, 0,109,111,100, 97,108,104, - 97,110,100,108,101,114,115, 0,115,117, 98,119,105,110,100,111,119,115, 0,103,101,115,116,117,114,101, 0,105,100,110, 97,109, -101, 91, 54, 52, 93, 0,112,114,111,112,118, 97,108,117,101, 0,115,104,105,102,116, 0, 99,116,114,108, 0, 97,108,116, 0,111, -115,107,101,121, 0,107,101,121,109,111,100,105,102,105,101,114, 0,109, 97,112,116,121,112,101, 0, 42,112,116,114, 0, 42,114, -101,109,111,118,101, 95,105,116,101,109, 0, 42, 97,100,100, 95,105,116,101,109, 0,105,116,101,109,115, 0,100,105,102,102, 95, -105,116,101,109,115, 0,115,112, 97, 99,101,105,100, 0,114,101,103,105,111,110,105,100, 0,107,109,105, 95,105,100, 0, 40, 42, -112,111,108,108, 41, 40, 41, 0, 42,109,111,100, 97,108, 95,105,116,101,109,115, 0, 98, 97,115,101,110, 97,109,101, 91, 54, 52, - 93, 0, 97, 99,116,107,101,121,109, 97,112, 0, 42, 99,117,115,116,111,109,100, 97,116, 97, 0, 42,112,121, 95,105,110,115,116, - 97,110, 99,101, 0, 42,114,101,112,111,114,116,115, 0,109, 97, 99,114,111, 0, 42,111,112,109, 0, 42,101,100, 97,116, 97, 0, - 42, 99,111,101,102,102,105, 99,105,101,110,116,115, 0, 97,114,114, 97,121,115,105,122,101, 0,112,111,108,121, 95,111,114,100, -101,114, 0, 97,109,112,108,105,116,117,100,101, 0,112,104, 97,115,101, 95,109,117,108,116,105,112,108,105,101,114, 0,112,104, - 97,115,101, 95,111,102,102,115,101,116, 0,118, 97,108,117,101, 95,111,102,102,115,101,116, 0,109,105,100,118, 97,108, 0, 98, -101,102,111,114,101, 95,109,111,100,101, 0, 97,102,116,101,114, 95,109,111,100,101, 0, 98,101,102,111,114,101, 95, 99,121, 99, -108,101,115, 0, 97,102,116,101,114, 95, 99,121, 99,108,101,115, 0,114,101, 99,116, 0,112,104, 97,115,101, 0,109,111,100,105, -102,105, 99, 97,116,105,111,110, 0,115,116,101,112, 95,115,105,122,101, 0, 42,114,110, 97, 95,112, 97,116,104, 0,112, 99,104, - 97,110, 95,110, 97,109,101, 91, 51, 50, 93, 0,116,114, 97,110,115, 67,104, 97,110, 0,105,100,116,121,112,101, 0,116, 97,114, -103,101,116,115, 91, 56, 93, 0,110,117,109, 95,116, 97,114,103,101,116,115, 0,118, 97,114,105, 97, 98,108,101,115, 0,101,120, -112,114,101,115,115,105,111,110, 91, 50, 53, 54, 93, 0, 42,101,120,112,114, 95, 99,111,109,112, 0,118,101, 99, 91, 50, 93, 0, - 42,102,112,116, 0, 97,114,114, 97,121, 95,105,110,100,101,120, 0, 99,111,108,111,114, 95,109,111,100,101, 0, 99,111,108,111, -114, 91, 51, 93, 0,102,114,111,109, 91, 49, 50, 56, 93, 0,116,111, 91, 49, 50, 56, 93, 0,109, 97,112,112,105,110,103,115, 0, -115,116,114,105,112,115, 0, 42,114,101,109, 97,112, 0,102, 99,117,114,118,101,115, 0,115,116,114,105,112, 95,116,105,109,101, - 0, 98,108,101,110,100,109,111,100,101, 0,101,120,116,101,110,100,109,111,100,101, 0, 42,115,112,101, 97,107,101,114, 95,104, - 97,110,100,108,101, 0,103,114,111,117,112, 91, 54, 52, 93, 0,103,114,111,117,112,109,111,100,101, 0,107,101,121,105,110,103, -102,108, 97,103, 0,112, 97,116,104,115, 0,100,101,115, 99,114,105,112,116,105,111,110, 91, 50, 52, 48, 93, 0,116,121,112,101, -105,110,102,111, 91, 54, 52, 93, 0, 97, 99,116,105,118,101, 95,112, 97,116,104, 0, 42,116,109,112, 97, 99,116, 0,110,108, 97, - 95,116,114, 97, 99,107,115, 0, 42, 97, 99,116,115,116,114,105,112, 0,100,114,105,118,101,114,115, 0,111,118,101,114,114,105, -100,101,115, 0, 97, 99,116, 95, 98,108,101,110,100,109,111,100,101, 0, 97, 99,116, 95,101,120,116,101,110,100,109,111,100,101, - 0, 97, 99,116, 95,105,110,102,108,117,101,110, 99,101, 0,114,117,108,101, 0,111,112,116,105,111,110,115, 0,102,101, 97,114, - 95,102, 97, 99,116,111,114, 0,115,105,103,110, 97,108, 95,105,100, 0,108,111,111,107, 95, 97,104,101, 97,100, 0,111,108,111, - 99, 91, 51, 93, 0,113,117,101,117,101, 95,115,105,122,101, 0,119, 97,110,100,101,114, 0,102,108,101,101, 95,100,105,115,116, - 97,110, 99,101, 0,104,101, 97,108,116,104, 0,115,116, 97,116,101, 95,105,100, 0,114,117,108,101,115, 0, 99,111,110,100,105, -116,105,111,110,115, 0, 97, 99,116,105,111,110,115, 0,114,117,108,101,115,101,116, 95,116,121,112,101, 0,114,117,108,101, 95, -102,117,122,122,105,110,101,115,115, 0,108, 97,115,116, 95,115,116, 97,116,101, 95,105,100, 0,108, 97,110,100,105,110,103, 95, -115,109,111,111,116,104,110,101,115,115, 0, 98, 97,110,107,105,110,103, 0, 97,103,103,114,101,115,115,105,111,110, 0, 97,105, -114, 95,109,105,110, 95,115,112,101,101,100, 0, 97,105,114, 95,109, 97,120, 95,115,112,101,101,100, 0, 97,105,114, 95,109, 97, -120, 95, 97, 99, 99, 0, 97,105,114, 95,109, 97,120, 95, 97,118,101, 0, 97,105,114, 95,112,101,114,115,111,110, 97,108, 95,115, -112, 97, 99,101, 0,108, 97,110,100, 95,106,117,109,112, 95,115,112,101,101,100, 0,108, 97,110,100, 95,109, 97,120, 95,115,112, -101,101,100, 0,108, 97,110,100, 95,109, 97,120, 95, 97, 99, 99, 0,108, 97,110,100, 95,109, 97,120, 95, 97,118,101, 0,108, 97, -110,100, 95,112,101,114,115,111,110, 97,108, 95,115,112, 97, 99,101, 0,108, 97,110,100, 95,115,116,105, 99,107, 95,102,111,114, - 99,101, 0,115,116, 97,116,101,115, 0, 42,115,109,100, 0, 42,102,108,117,105,100, 95,103,114,111,117,112, 0, 42, 99,111,108, -108, 95,103,114,111,117,112, 0, 42,119,116, 0, 42,116,101,120, 95,119,116, 0, 42,116,101,120, 95,115,104, 97,100,111,119, 0, - 42,115,104, 97,100,111,119, 0,112, 48, 91, 51, 93, 0,112, 49, 91, 51, 93, 0,100,120, 0,111,109,101,103, 97, 0,116,101,109, -112, 65,109, 98, 0, 98,101,116, 97, 0,114,101,115, 91, 51, 93, 0, 97,109,112,108,105,102,121, 0,109, 97,120,114,101,115, 0, -118,105,101,119,115,101,116,116,105,110,103,115, 0,110,111,105,115,101, 0,100,105,115,115, 95,112,101,114, 99,101,110,116, 0, -100,105,115,115, 95,115,112,101,101,100, 0,114,101,115, 95,119,116, 91, 51, 93, 0,100,120, 95,119,116, 0,118, 51,100,110,117, -109, 0, 99, 97, 99,104,101, 95, 99,111,109,112, 0, 99, 97, 99,104,101, 95,104,105,103,104, 95, 99,111,109,112, 0, 42,112,111, -105,110,116, 95, 99, 97, 99,104,101, 91, 50, 93, 0,112,116, 99, 97, 99,104,101,115, 91, 50, 93, 0, 98,111,114,100,101,114, 95, - 99,111,108,108,105,115,105,111,110,115, 0,116,105,109,101, 95,115, 99, 97,108,101, 0,118,111,114,116,105, 99,105,116,121, 0, -118,101,108,111, 99,105,116,121, 91, 50, 93, 0,118,101,108, 95,109,117,108,116,105, 0,118,103,114,112, 95,104,101, 97,116, 95, -115, 99, 97,108,101, 91, 50, 93, 0,118,103,114,111,117,112, 95,102,108,111,119, 0,118,103,114,111,117,112, 95,100,101,110,115, -105,116,121, 0,118,103,114,111,117,112, 95,104,101, 97,116, 0, 42,112,111,105,110,116,115, 95,111,108,100, 0, 42,118,101,108, - 0,109, 97,116, 95,111,108,100, 91, 52, 93, 91, 52, 93, 0,118,111,108,117,109,101, 95,109, 97,120, 0,118,111,108,117,109,101, - 95,109,105,110, 0,100,105,115,116, 97,110, 99,101, 95,109, 97,120, 0,100,105,115,116, 97,110, 99,101, 95,114,101,102,101,114, -101,110, 99,101, 0, 99,111,110,101, 95, 97,110,103,108,101, 95,111,117,116,101,114, 0, 99,111,110,101, 95, 97,110,103,108,101, - 95,105,110,110,101,114, 0, 99,111,110,101, 95,118,111,108,117,109,101, 95,111,117,116,101,114, 0,114,101,110,100,101,114, 95, -102,108, 97,103, 0, 98,117,105,108,100, 95,115,105,122,101, 95,102,108, 97,103, 0, 98,117,105,108,100, 95,116, 99, 95,102,108, - 97,103, 0,108, 97,115,116,115,105,122,101, 91, 50, 93, 0,116,114, 97, 99,107,105,110,103, 0, 42,116,114, 97, 99,107,105,110, -103, 95, 99,111,110,116,101,120,116, 0,112,114,111,120,121, 0,116,114, 97, 99,107, 95,112,114,101,118,105,101,119, 95,104,101, -105,103,104,116, 0, 42,116,114, 97, 99,107, 95,112,114,101,118,105,101,119, 0,116,114, 97, 99,107, 95,112,111,115, 91, 50, 93, - 0,116,114, 97, 99,107, 95,100,105,115, 97, 98,108,101,100, 0, 42,109, 97,114,107,101,114, 0,115,108,105,100,101, 95,115, 99, - 97,108,101, 91, 50, 93, 0,101,114,114,111,114, 0, 42,105,110,116,114,105,110,115,105, 99,115, 0,115,101,110,115,111,114, 95, -119,105,100,116,104, 0,112,105,120,101,108, 95, 97,115,112,101, 99,116, 0,102,111, 99, 97,108, 0,117,110,105,116,115, 0,112, -114,105,110, 99,105,112, 97,108, 91, 50, 93, 0,107, 49, 0,107, 50, 0,107, 51, 0,112,111,115, 91, 50, 93, 0,112, 97,116, 95, -109,105,110, 91, 50, 93, 0,112, 97,116, 95,109, 97,120, 91, 50, 93, 0,115,101, 97,114, 99,104, 95,109,105,110, 91, 50, 93, 0, -115,101, 97,114, 99,104, 95,109, 97,120, 91, 50, 93, 0,109, 97,114,107,101,114,115,110,114, 0,108, 97,115,116, 95,109, 97,114, -107,101,114, 0, 42,109, 97,114,107,101,114,115, 0, 98,117,110,100,108,101, 95,112,111,115, 91, 51, 93, 0,112, 97,116, 95,102, -108, 97,103, 0,115,101, 97,114, 99,104, 95,102,108, 97,103, 0,102,114, 97,109,101,115, 95,108,105,109,105,116, 0,112, 97,116, -116,101,114,110, 95,109, 97,116, 99,104, 0,116,114, 97, 99,107,101,114, 0,112,121,114, 97,109,105,100, 95,108,101,118,101,108, -115, 0,109,105,110,105,109,117,109, 95, 99,111,114,114,101,108, 97,116,105,111,110, 0,100,101,102, 97,117,108,116, 95,116,114, - 97, 99,107,101,114, 0,100,101,102, 97,117,108,116, 95,112,121,114, 97,109,105,100, 95,108,101,118,101,108,115, 0,100,101,102, - 97,117,108,116, 95,109,105,110,105,109,117,109, 95, 99,111,114,114,101,108, 97,116,105,111,110, 0,100,101,102, 97,117,108,116, - 95,112, 97,116,116,101,114,110, 95,115,105,122,101, 0,100,101,102, 97,117,108,116, 95,115,101, 97,114, 99,104, 95,115,105,122, -101, 0,100,101,102, 97,117,108,116, 95,102,114, 97,109,101,115, 95,108,105,109,105,116, 0,100,101,102, 97,117,108,116, 95,109, - 97,114,103,105,110, 0,100,101,102, 97,117,108,116, 95,112, 97,116,116,101,114,110, 95,109, 97,116, 99,104, 0,100,101,102, 97, -117,108,116, 95,102,108, 97,103, 0,112,111,100, 0,107,101,121,102,114, 97,109,101, 49, 0,107,101,121,102,114, 97,109,101, 50, - 0,114,101,102,105,110,101, 95, 99, 97,109,101,114, 97, 95,105,110,116,114,105,110,115,105, 99,115, 0,112, 97,100, 50, 51, 0, - 99,108,101, 97,110, 95,102,114, 97,109,101,115, 0, 99,108,101, 97,110, 95, 97, 99,116,105,111,110, 0, 99,108,101, 97,110, 95, -101,114,114,111,114, 0,111, 98,106,101, 99,116, 95,100,105,115,116, 97,110, 99,101, 0,116,111,116, 95,116,114, 97, 99,107, 0, - 97, 99,116, 95,116,114, 97, 99,107, 0,109, 97,120,115, 99, 97,108,101, 0, 42,114,111,116, 95,116,114, 97, 99,107, 0,108,111, - 99,105,110,102, 0,115, 99, 97,108,101,105,110,102, 0,114,111,116,105,110,102, 0, 42,115, 99, 97,108,101,105, 98,117,102, 0, -108, 97,115,116, 95, 99, 97,109,101,114, 97, 0, 99, 97,109,110,114, 0, 42, 99, 97,109,101,114, 97,115, 0,116,114, 97, 99,107, -115, 0,114,101, 99,111,110,115,116,114,117, 99,116,105,111,110, 0,109,101,115,115, 97,103,101, 91, 50, 53, 54, 93, 0,115,101, -116,116,105,110,103,115, 0, 99, 97,109,101,114, 97, 0,115,116, 97, 98,105,108,105,122, 97,116,105,111,110, 0, 42, 97, 99,116, - 95,116,114, 97, 99,107, 0,111, 98,106,101, 99,116,115, 0,111, 98,106,101, 99,116,110,114, 0,116,111,116, 95,111, 98,106,101, - 99,116, 0, 42, 98,114,117,115,104, 95,103,114,111,117,112, 0, 99,117,114,114,101,110,116, 95,102,114, 97,109,101, 0,100,105, -115,112, 95,116,121,112,101, 0,105,109, 97,103,101, 95,102,105,108,101,102,111,114,109, 97,116, 0,101,102,102,101, 99,116, 95, -117,105, 0,112,114,101,118,105,101,119, 95,105,100, 0,105,110,105,116, 95, 99,111,108,111,114, 95,116,121,112,101, 0,112, 97, -100, 95,115, 0,105,109, 97,103,101, 95,114,101,115,111,108,117,116,105,111,110, 0,115,117, 98,115,116,101,112,115, 0,105,110, -105,116, 95, 99,111,108,111,114, 91, 52, 93, 0, 42,105,110,105,116, 95,116,101,120,116,117,114,101, 0,105,110,105,116, 95,108, - 97,121,101,114,110, 97,109,101, 91, 54, 52, 93, 0,100,114,121, 95,115,112,101,101,100, 0, 99,111,108,111,114, 95,100,114,121, - 95,116,104,114,101,115,104,111,108,100, 0,100,101,112,116,104, 95, 99,108, 97,109,112, 0,100,105,115,112, 95,102, 97, 99,116, -111,114, 0,115,112,114,101, 97,100, 95,115,112,101,101,100, 0, 99,111,108,111,114, 95,115,112,114,101, 97,100, 95,115,112,101, -101,100, 0,115,104,114,105,110,107, 95,115,112,101,101,100, 0,100,114,105,112, 95,118,101,108, 0,100,114,105,112, 95, 97, 99, - 99, 0,105,110,102,108,117,101,110, 99,101, 95,115, 99, 97,108,101, 0,114, 97,100,105,117,115, 95,115, 99, 97,108,101, 0,119, - 97,118,101, 95,100, 97,109,112,105,110,103, 0,119, 97,118,101, 95,115,112,101,101,100, 0,119, 97,118,101, 95,116,105,109,101, -115, 99, 97,108,101, 0,119, 97,118,101, 95,115,112,114,105,110,103, 0,105,109, 97,103,101, 95,111,117,116,112,117,116, 95,112, - 97,116,104, 91, 49, 48, 50, 52, 93, 0,111,117,116,112,117,116, 95,110, 97,109,101, 91, 54, 52, 93, 0,111,117,116,112,117,116, - 95,110, 97,109,101, 50, 91, 54, 52, 93, 0, 42,112,109,100, 0,115,117,114,102, 97, 99,101,115, 0, 97, 99,116,105,118,101, 95, -115,117,114, 0,101,114,114,111,114, 91, 54, 52, 93, 0, 99,111,108,108,105,115,105,111,110, 0,119,101,116,110,101,115,115, 0, -112, 97,114,116,105, 99,108,101, 95,114, 97,100,105,117,115, 0,112, 97,114,116,105, 99,108,101, 95,115,109,111,111,116,104, 0, -112, 97,105,110,116, 95,100,105,115,116, 97,110, 99,101, 0, 42,112, 97,105,110,116, 95,114, 97,109,112, 0, 42,118,101,108, 95, -114, 97,109,112, 0,112,114,111,120,105,109,105,116,121, 95,102, 97,108,108,111,102,102, 0,114, 97,121, 95,100,105,114, 0,119, - 97,118,101, 95,102, 97, 99,116,111,114, 0,119, 97,118,101, 95, 99,108, 97,109,112, 0,109, 97,120, 95,118,101,108,111, 99,105, -116,121, 0,115,109,117,100,103,101, 95,115,116,114,101,110,103,116,104, 0, 0, 84, 89, 80, 69, 16, 2, 0, 0, 99,104, 97,114, - 0,117, 99,104, 97,114, 0,115,104,111,114,116, 0,117,115,104,111,114,116, 0,105,110,116, 0,108,111,110,103, 0,117,108,111, -110,103, 0,102,108,111, 97,116, 0,100,111,117, 98,108,101, 0,105,110,116, 54, 52, 95,116, 0,117,105,110,116, 54, 52, 95,116, - 0,118,111,105,100, 0, 76,105,110,107, 0, 76,105,110,107, 68, 97,116, 97, 0, 76,105,115,116, 66, 97,115,101, 0,118,101, 99, - 50,115, 0,118,101, 99, 50,102, 0,118,101, 99, 51,102, 0,114, 99,116,105, 0,114, 99,116,102, 0, 73, 68, 80,114,111,112,101, -114,116,121, 68, 97,116, 97, 0, 73, 68, 80,114,111,112,101,114,116,121, 0, 73, 68, 0, 76,105, 98,114, 97,114,121, 0, 70,105, -108,101, 68, 97,116, 97, 0, 80,114,101,118,105,101,119, 73,109, 97,103,101, 0, 73,112,111, 68,114,105,118,101,114, 0, 79, 98, -106,101, 99,116, 0, 73,112,111, 67,117,114,118,101, 0, 66, 80,111,105,110,116, 0, 66,101,122, 84,114,105,112,108,101, 0, 73, -112,111, 0, 75,101,121, 66,108,111, 99,107, 0, 75,101,121, 0, 65,110,105,109, 68, 97,116, 97, 0, 84,101,120,116, 76,105,110, -101, 0, 84,101,120,116, 77, 97,114,107,101,114, 0, 84,101,120,116, 0, 80, 97, 99,107,101,100, 70,105,108,101, 0, 67, 97,109, -101,114, 97, 0, 73,109, 97,103,101, 85,115,101,114, 0, 83, 99,101,110,101, 0, 73,109, 97,103,101, 0, 71, 80, 85, 84,101,120, -116,117,114,101, 0, 97,110,105,109, 0, 82,101,110,100,101,114, 82,101,115,117,108,116, 0, 77, 84,101,120, 0, 84,101,120, 0, - 80,108,117,103,105,110, 84,101,120, 0, 67, 66, 68, 97,116, 97, 0, 67,111,108,111,114, 66, 97,110,100, 0, 69,110,118, 77, 97, -112, 0, 73,109, 66,117,102, 0, 80,111,105,110,116, 68,101,110,115,105,116,121, 0, 67,117,114,118,101, 77, 97,112,112,105,110, -103, 0, 86,111,120,101,108, 68, 97,116, 97, 0, 79, 99,101, 97,110, 84,101,120, 0, 98, 78,111,100,101, 84,114,101,101, 0, 84, -101,120, 77, 97,112,112,105,110,103, 0, 67,111,108,111,114, 77, 97,112,112,105,110,103, 0, 76, 97,109,112, 0, 86,111,108,117, -109,101, 83,101,116,116,105,110,103,115, 0, 71, 97,109,101, 83,101,116,116,105,110,103,115, 0, 77, 97,116,101,114,105, 97,108, - 0, 71,114,111,117,112, 0, 86, 70,111,110,116, 0, 86, 70,111,110,116, 68, 97,116, 97, 0, 77,101,116, 97, 69,108,101,109, 0, - 66,111,117,110,100, 66,111,120, 0, 77,101,116, 97, 66, 97,108,108, 0, 78,117,114, 98, 0, 67,104, 97,114, 73,110,102,111, 0, - 84,101,120,116, 66,111,120, 0, 69,100,105,116, 78,117,114, 98, 0, 71, 72, 97,115,104, 0, 67,117,114,118,101, 0, 80, 97,116, -104, 0, 83,101,108, 66,111,120, 0, 69,100,105,116, 70,111,110,116, 0, 77,101,115,104, 0, 77, 80,111,108,121, 0, 77, 84,101, -120, 80,111,108,121, 0, 77, 76,111,111,112, 0, 77, 76,111,111,112, 85, 86, 0, 77, 76,111,111,112, 67,111,108, 0, 77, 70, 97, - 99,101, 0, 77, 84, 70, 97, 99,101, 0, 84, 70, 97, 99,101, 0, 77, 86,101,114,116, 0, 77, 69,100,103,101, 0, 77, 68,101,102, -111,114,109, 86,101,114,116, 0, 77, 67,111,108, 0, 77, 83,116,105, 99,107,121, 0, 77, 83,101,108,101, 99,116, 0, 66, 77, 69, -100,105,116, 77,101,115,104, 0, 67,117,115,116,111,109, 68, 97,116, 97, 0, 77,117,108,116,105,114,101,115, 0, 77, 68,101,102, -111,114,109, 87,101,105,103,104,116, 0, 77, 70,108,111, 97,116, 80,114,111,112,101,114,116,121, 0, 77, 73,110,116, 80,114,111, -112,101,114,116,121, 0, 77, 83,116,114,105,110,103, 80,114,111,112,101,114,116,121, 0, 79,114,105,103, 83,112, 97, 99,101, 70, - 97, 99,101, 0, 79,114,105,103, 83,112, 97, 99,101, 76,111,111,112, 0, 77, 68,105,115,112,115, 0, 77,117,108,116,105,114,101, -115, 67,111,108, 0, 77,117,108,116,105,114,101,115, 67,111,108, 70, 97, 99,101, 0, 77,117,108,116,105,114,101,115, 70, 97, 99, -101, 0, 77,117,108,116,105,114,101,115, 69,100,103,101, 0, 77,117,108,116,105,114,101,115, 76,101,118,101,108, 0, 77, 82,101, - 99, 97,115,116, 0, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77, 97,112,112,105,110,103, 73,110,102,111, 77,111,100, -105,102,105,101,114, 68, 97,116, 97, 0, 83,117, 98,115,117,114,102, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 76, 97, -116,116,105, 99,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 67,117,114,118,101, 77,111,100,105,102,105,101,114, 68, - 97,116, 97, 0, 66,117,105,108,100, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77, 97,115,107, 77,111,100,105,102,105, -101,114, 68, 97,116, 97, 0, 65,114,114, 97,121, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77,105,114,114,111,114, 77, -111,100,105,102,105,101,114, 68, 97,116, 97, 0, 69,100,103,101, 83,112,108,105,116, 77,111,100,105,102,105,101,114, 68, 97,116, - 97, 0, 66,101,118,101,108, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 66, 77,101,115,104, 77,111,100,105,102,105,101, -114, 68, 97,116, 97, 0, 83,109,111,107,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,109,111,107,101, 68,111,109, - 97,105,110, 83,101,116,116,105,110,103,115, 0, 83,109,111,107,101, 70,108,111,119, 83,101,116,116,105,110,103,115, 0, 83,109, -111,107,101, 67,111,108,108, 83,101,116,116,105,110,103,115, 0, 68,105,115,112,108, 97, 99,101, 77,111,100,105,102,105,101,114, - 68, 97,116, 97, 0, 85, 86, 80,114,111,106,101, 99,116, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 68,101, 99,105,109, - 97,116,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,109,111,111,116,104, 77,111,100,105,102,105,101,114, 68, 97, -116, 97, 0, 67, 97,115,116, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 87, 97,118,101, 77,111,100,105,102,105,101,114, - 68, 97,116, 97, 0, 65,114,109, 97,116,117,114,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 72,111,111,107, 77,111, -100,105,102,105,101,114, 68, 97,116, 97, 0, 83,111,102,116, 98,111,100,121, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, - 67,108,111,116,104, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 67,108,111,116,104, 0, 67,108,111,116,104, 83,105,109, - 83,101,116,116,105,110,103,115, 0, 67,108,111,116,104, 67,111,108,108, 83,101,116,116,105,110,103,115, 0, 80,111,105,110,116, - 67, 97, 99,104,101, 0, 67,111,108,108,105,115,105,111,110, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 66, 86, 72, 84, -114,101,101, 0, 83,117,114,102, 97, 99,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 68,101,114,105,118,101,100, 77, -101,115,104, 0, 66, 86, 72, 84,114,101,101, 70,114,111,109, 77,101,115,104, 0, 66,111,111,108,101, 97,110, 77,111,100,105,102, -105,101,114, 68, 97,116, 97, 0, 77, 68,101,102, 73,110,102,108,117,101,110, 99,101, 0, 77, 68,101,102, 67,101,108,108, 0, 77, -101,115,104, 68,101,102,111,114,109, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 80, 97,114,116,105, 99,108,101, 83,121, -115,116,101,109, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 80, 97,114,116,105, 99,108,101, 83,121,115,116,101,109, 0, - 80, 97,114,116,105, 99,108,101, 73,110,115,116, 97,110, 99,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 69,120,112, -108,111,100,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77,117,108,116,105,114,101,115, 77,111,100,105,102,105,101, -114, 68, 97,116, 97, 0, 70,108,117,105,100,115,105,109, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 70,108,117,105,100, -115,105,109, 83,101,116,116,105,110,103,115, 0, 83,104,114,105,110,107,119,114, 97,112, 77,111,100,105,102,105,101,114, 68, 97, -116, 97, 0, 83,105,109,112,108,101, 68,101,102,111,114,109, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,104, 97,112, -101, 75,101,121, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,111,108,105,100,105,102,121, 77,111,100,105,102,105,101, -114, 68, 97,116, 97, 0, 83, 99,114,101,119, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 79, 99,101, 97,110, 77,111,100, -105,102,105,101,114, 68, 97,116, 97, 0, 79, 99,101, 97,110, 0, 79, 99,101, 97,110, 67, 97, 99,104,101, 0, 87, 97,114,112, 77, -111,100,105,102,105,101,114, 68, 97,116, 97, 0, 87,101,105,103,104,116, 86, 71, 69,100,105,116, 77,111,100,105,102,105,101,114, - 68, 97,116, 97, 0, 87,101,105,103,104,116, 86, 71, 77,105,120, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 87,101,105, -103,104,116, 86, 71, 80,114,111,120,105,109,105,116,121, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 68,121,110, 97,109, -105, 99, 80, 97,105,110,116, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 68,121,110, 97,109,105, 99, 80, 97,105,110,116, - 67, 97,110,118, 97,115, 83,101,116,116,105,110,103,115, 0, 68,121,110, 97,109,105, 99, 80, 97,105,110,116, 66,114,117,115,104, - 83,101,116,116,105,110,103,115, 0, 82,101,109,101,115,104, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 69,100,105,116, - 76, 97,116,116, 0, 76, 97,116,116,105, 99,101, 0, 98, 68,101,102,111,114,109, 71,114,111,117,112, 0, 83, 99,117,108,112,116, - 83,101,115,115,105,111,110, 0, 98, 65, 99,116,105,111,110, 0, 98, 80,111,115,101, 0, 98, 71, 80,100, 97,116, 97, 0, 98, 65, -110,105,109, 86,105,122, 83,101,116,116,105,110,103,115, 0, 98, 77,111,116,105,111,110, 80, 97,116,104, 0, 66,117,108,108,101, -116, 83,111,102,116, 66,111,100,121, 0, 80, 97,114,116, 68,101,102,108,101, 99,116, 0, 83,111,102,116, 66,111,100,121, 0, 79, - 98, 72,111,111,107, 0, 68,117,112,108,105, 79, 98,106,101, 99,116, 0, 82, 78, 71, 0, 69,102,102,101, 99,116,111,114, 87,101, -105,103,104,116,115, 0, 80, 84, 67, 97, 99,104,101, 69,120,116,114, 97, 0, 80, 84, 67, 97, 99,104,101, 77,101,109, 0, 80, 84, - 67, 97, 99,104,101, 69,100,105,116, 0, 83, 66, 86,101,114,116,101,120, 0, 66,111,100,121, 80,111,105,110,116, 0, 66,111,100, -121, 83,112,114,105,110,103, 0, 83, 66, 83, 99,114, 97,116, 99,104, 0, 70,108,117,105,100, 86,101,114,116,101,120, 86,101,108, -111, 99,105,116,121, 0, 87,111,114,108,100, 0, 66, 97,115,101, 0, 65,118,105, 67,111,100,101, 99, 68, 97,116, 97, 0, 81,117, -105, 99,107,116,105,109,101, 67,111,100,101, 99, 68, 97,116, 97, 0, 81,117,105, 99,107,116,105,109,101, 67,111,100,101, 99, 83, -101,116,116,105,110,103,115, 0, 70, 70, 77,112,101,103, 67,111,100,101, 99, 68, 97,116, 97, 0, 65,117,100,105,111, 68, 97,116, - 97, 0, 83, 99,101,110,101, 82,101,110,100,101,114, 76, 97,121,101,114, 0, 73,109, 97,103,101, 70,111,114,109, 97,116, 68, 97, -116, 97, 0, 82,101,110,100,101,114, 68, 97,116, 97, 0, 82,101,110,100,101,114, 80,114,111,102,105,108,101, 0, 71, 97,109,101, - 68,111,109,101, 0, 71, 97,109,101, 70,114, 97,109,105,110,103, 0, 82,101, 99, 97,115,116, 68, 97,116, 97, 0, 71, 97,109,101, - 68, 97,116, 97, 0, 84,105,109,101, 77, 97,114,107,101,114, 0, 80, 97,105,110,116, 0, 66,114,117,115,104, 0, 73,109, 97,103, -101, 80, 97,105,110,116, 83,101,116,116,105,110,103,115, 0, 80, 97,114,116,105, 99,108,101, 66,114,117,115,104, 68, 97,116, 97, - 0, 80, 97,114,116,105, 99,108,101, 69,100,105,116, 83,101,116,116,105,110,103,115, 0, 83, 99,117,108,112,116, 0, 85,118, 83, - 99,117,108,112,116, 0, 86, 80, 97,105,110,116, 0, 84,114, 97,110,115,102,111,114,109, 79,114,105,101,110,116, 97,116,105,111, -110, 0, 85,110,105,102,105,101,100, 80, 97,105,110,116, 83,101,116,116,105,110,103,115, 0, 84,111,111,108, 83,101,116,116,105, -110,103,115, 0, 98, 83,116, 97,116,115, 0, 85,110,105,116, 83,101,116,116,105,110,103,115, 0, 80,104,121,115,105, 99,115, 83, -101,116,116,105,110,103,115, 0, 69,100,105,116,105,110,103, 0, 83, 99,101,110,101, 83,116, 97,116,115, 0, 68, 97,103, 70,111, -114,101,115,116, 0, 77,111,118,105,101, 67,108,105,112, 0, 66, 71,112,105, 99, 0, 77,111,118,105,101, 67,108,105,112, 85,115, -101,114, 0, 82,101,103,105,111,110, 86,105,101,119, 51, 68, 0, 82,101,110,100,101,114, 73,110,102,111, 0, 82,101,110,100,101, -114, 69,110,103,105,110,101, 0, 86,105,101,119, 68,101,112,116,104,115, 0, 83,109,111,111,116,104, 86,105,101,119, 83,116,111, -114,101, 0,119,109, 84,105,109,101,114, 0, 86,105,101,119, 51, 68, 0, 83,112, 97, 99,101, 76,105,110,107, 0, 86,105,101,119, - 50, 68, 0, 83,112, 97, 99,101, 73,110,102,111, 0, 83,112, 97, 99,101, 73,112,111, 0, 98, 68,111,112,101, 83,104,101,101,116, - 0, 83,112, 97, 99,101, 66,117,116,115, 0, 83,112, 97, 99,101, 83,101,113, 0, 70,105,108,101, 83,101,108,101, 99,116, 80, 97, -114, 97,109,115, 0, 83,112, 97, 99,101, 70,105,108,101, 0, 70,105,108,101, 76,105,115,116, 0,119,109, 79,112,101,114, 97,116, -111,114, 0, 70,105,108,101, 76, 97,121,111,117,116, 0, 83,112, 97, 99,101, 79,111,112,115, 0, 84,114,101,101, 83,116,111,114, -101, 0, 84,114,101,101, 83,116,111,114,101, 69,108,101,109, 0, 83,112, 97, 99,101, 73,109, 97,103,101, 0, 83, 99,111,112,101, -115, 0, 72,105,115,116,111,103,114, 97,109, 0, 83,112, 97, 99,101, 78,108, 97, 0, 83,112, 97, 99,101, 84,101,120,116, 0, 83, - 99,114,105,112,116, 0, 83,112, 97, 99,101, 83, 99,114,105,112,116, 0, 83,112, 97, 99,101, 84,105,109,101, 67, 97, 99,104,101, - 0, 83,112, 97, 99,101, 84,105,109,101, 0, 83,112, 97, 99,101, 78,111,100,101, 0, 83,112, 97, 99,101, 76,111,103,105, 99, 0, - 67,111,110,115,111,108,101, 76,105,110,101, 0, 83,112, 97, 99,101, 67,111,110,115,111,108,101, 0, 83,112, 97, 99,101, 85,115, -101,114, 80,114,101,102, 0, 83,112, 97, 99,101, 67,108,105,112, 0, 77,111,118,105,101, 67,108,105,112, 83, 99,111,112,101,115, - 0,117,105, 70,111,110,116, 0,117,105, 70,111,110,116, 83,116,121,108,101, 0,117,105, 83,116,121,108,101, 0,117,105, 87,105, -100,103,101,116, 67,111,108,111,114,115, 0,117,105, 87,105,100,103,101,116, 83,116, 97,116,101, 67,111,108,111,114,115, 0,117, -105, 80, 97,110,101,108, 67,111,108,111,114,115, 0, 84,104,101,109,101, 85, 73, 0, 84,104,101,109,101, 83,112, 97, 99,101, 0, - 84,104,101,109,101, 87,105,114,101, 67,111,108,111,114, 0, 98, 84,104,101,109,101, 0, 98, 65,100,100,111,110, 0, 83,111,108, -105,100, 76,105,103,104,116, 0, 85,115,101,114, 68,101,102, 0, 98, 83, 99,114,101,101,110, 0, 83, 99,114, 86,101,114,116, 0, - 83, 99,114, 69,100,103,101, 0, 80, 97,110,101,108, 0, 80, 97,110,101,108, 84,121,112,101, 0,117,105, 76, 97,121,111,117,116, - 0, 83, 99,114, 65,114,101, 97, 0, 83,112, 97, 99,101, 84,121,112,101, 0, 65, 82,101,103,105,111,110, 0, 65, 82,101,103,105, -111,110, 84,121,112,101, 0, 70,105,108,101, 71,108,111, 98, 97,108, 0, 83,116,114,105,112, 69,108,101,109, 0, 83,116,114,105, -112, 67,114,111,112, 0, 83,116,114,105,112, 84,114, 97,110,115,102,111,114,109, 0, 83,116,114,105,112, 67,111,108,111,114, 66, - 97,108, 97,110, 99,101, 0, 83,116,114,105,112, 80,114,111,120,121, 0, 83,116,114,105,112, 0, 80,108,117,103,105,110, 83,101, -113, 0, 83,101,113,117,101,110, 99,101, 0, 98, 83,111,117,110,100, 0, 77,101,116, 97, 83,116, 97, 99,107, 0, 87,105,112,101, - 86, 97,114,115, 0, 71,108,111,119, 86, 97,114,115, 0, 84,114, 97,110,115,102,111,114,109, 86, 97,114,115, 0, 83,111,108,105, -100, 67,111,108,111,114, 86, 97,114,115, 0, 83,112,101,101,100, 67,111,110,116,114,111,108, 86, 97,114,115, 0, 69,102,102,101, - 99,116, 0, 66,117,105,108,100, 69,102,102, 0, 80, 97,114,116, 69,102,102, 0, 80, 97,114,116,105, 99,108,101, 0, 87, 97,118, -101, 69,102,102, 0, 98, 80,114,111,112,101,114,116,121, 0, 98, 78,101, 97,114, 83,101,110,115,111,114, 0, 98, 77,111,117,115, -101, 83,101,110,115,111,114, 0, 98, 84,111,117, 99,104, 83,101,110,115,111,114, 0, 98, 75,101,121, 98,111, 97,114,100, 83,101, -110,115,111,114, 0, 98, 80,114,111,112,101,114,116,121, 83,101,110,115,111,114, 0, 98, 65, 99,116,117, 97,116,111,114, 83,101, -110,115,111,114, 0, 98, 68,101,108, 97,121, 83,101,110,115,111,114, 0, 98, 67,111,108,108,105,115,105,111,110, 83,101,110,115, -111,114, 0, 98, 82, 97,100, 97,114, 83,101,110,115,111,114, 0, 98, 82, 97,110,100,111,109, 83,101,110,115,111,114, 0, 98, 82, - 97,121, 83,101,110,115,111,114, 0, 98, 65,114,109, 97,116,117,114,101, 83,101,110,115,111,114, 0, 98, 77,101,115,115, 97,103, -101, 83,101,110,115,111,114, 0, 98, 83,101,110,115,111,114, 0, 98, 67,111,110,116,114,111,108,108,101,114, 0, 98, 74,111,121, -115,116,105, 99,107, 83,101,110,115,111,114, 0, 98, 69,120,112,114,101,115,115,105,111,110, 67,111,110,116, 0, 98, 80,121,116, -104,111,110, 67,111,110,116, 0, 98, 65, 99,116,117, 97,116,111,114, 0, 98, 65,100,100, 79, 98,106,101, 99,116, 65, 99,116,117, - 97,116,111,114, 0, 98, 65, 99,116,105,111,110, 65, 99,116,117, 97,116,111,114, 0, 83,111,117,110,100, 51, 68, 0, 98, 83,111, -117,110,100, 65, 99,116,117, 97,116,111,114, 0, 98, 69,100,105,116, 79, 98,106,101, 99,116, 65, 99,116,117, 97,116,111,114, 0, - 98, 83, 99,101,110,101, 65, 99,116,117, 97,116,111,114, 0, 98, 80,114,111,112,101,114,116,121, 65, 99,116,117, 97,116,111,114, - 0, 98, 79, 98,106,101, 99,116, 65, 99,116,117, 97,116,111,114, 0, 98, 73,112,111, 65, 99,116,117, 97,116,111,114, 0, 98, 67, - 97,109,101,114, 97, 65, 99,116,117, 97,116,111,114, 0, 98, 67,111,110,115,116,114, 97,105,110,116, 65, 99,116,117, 97,116,111, -114, 0, 98, 71,114,111,117,112, 65, 99,116,117, 97,116,111,114, 0, 98, 82, 97,110,100,111,109, 65, 99,116,117, 97,116,111,114, - 0, 98, 77,101,115,115, 97,103,101, 65, 99,116,117, 97,116,111,114, 0, 98, 71, 97,109,101, 65, 99,116,117, 97,116,111,114, 0, - 98, 86,105,115,105, 98,105,108,105,116,121, 65, 99,116,117, 97,116,111,114, 0, 98, 84,119,111, 68, 70,105,108,116,101,114, 65, - 99,116,117, 97,116,111,114, 0, 98, 80, 97,114,101,110,116, 65, 99,116,117, 97,116,111,114, 0, 98, 83,116, 97,116,101, 65, 99, -116,117, 97,116,111,114, 0, 98, 65,114,109, 97,116,117,114,101, 65, 99,116,117, 97,116,111,114, 0, 98, 83,116,101,101,114,105, -110,103, 65, 99,116,117, 97,116,111,114, 0, 71,114,111,117,112, 79, 98,106,101, 99,116, 0, 66,111,110,101, 0, 98, 65,114,109, - 97,116,117,114,101, 0, 98, 77,111,116,105,111,110, 80, 97,116,104, 86,101,114,116, 0, 98, 80,111,115,101, 67,104, 97,110,110, -101,108, 0, 98, 73, 75, 80, 97,114, 97,109, 0, 98, 73,116, 97,115, 99, 0, 98, 65, 99,116,105,111,110, 71,114,111,117,112, 0, - 83,112, 97, 99,101, 65, 99,116,105,111,110, 0, 98, 65, 99,116,105,111,110, 67,104, 97,110,110,101,108, 0, 98, 67,111,110,115, -116,114, 97,105,110,116, 67,104, 97,110,110,101,108, 0, 98, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 67,111,110,115,116, -114, 97,105,110,116, 84, 97,114,103,101,116, 0, 98, 80,121,116,104,111,110, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 75, -105,110,101,109, 97,116,105, 99, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83,112,108,105,110,101, 73, 75, 67,111,110,115, -116,114, 97,105,110,116, 0, 98, 84,114, 97, 99,107, 84,111, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 82,111,116, 97,116, -101, 76,105,107,101, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 76,111, 99, 97,116,101, 76,105,107,101, 67,111,110,115,116, -114, 97,105,110,116, 0, 98, 83,105,122,101, 76,105,107,101, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83, 97,109,101, 86, -111,108,117,109,101, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 84,114, 97,110,115, 76,105,107,101, 67,111,110,115,116,114, - 97,105,110,116, 0, 98, 77,105,110, 77, 97,120, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 65, 99,116,105,111,110, 67,111, -110,115,116,114, 97,105,110,116, 0, 98, 76,111, 99,107, 84,114, 97, 99,107, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 68, - 97,109,112, 84,114, 97, 99,107, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 70,111,108,108,111,119, 80, 97,116,104, 67,111, -110,115,116,114, 97,105,110,116, 0, 98, 83,116,114,101,116, 99,104, 84,111, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 82, -105,103,105,100, 66,111,100,121, 74,111,105,110,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 67,108, 97,109,112, 84,111, - 67,111,110,115,116,114, 97,105,110,116, 0, 98, 67,104,105,108,100, 79,102, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 84, -114, 97,110,115,102,111,114,109, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 80,105,118,111,116, 67,111,110,115,116,114, 97, -105,110,116, 0, 98, 76,111, 99, 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 82,111,116, 76,105,109,105, -116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83,105,122,101, 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116, - 0, 98, 68,105,115,116, 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83,104,114,105,110,107,119,114, 97, -112, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 70,111,108,108,111,119, 84,114, 97, 99,107, 67,111,110,115,116,114, 97,105, -110,116, 0, 98, 67, 97,109,101,114, 97, 83,111,108,118,101,114, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 79, 98,106,101, - 99,116, 83,111,108,118,101,114, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 65, 99,116,105,111,110, 77,111,100,105,102,105, -101,114, 0, 98, 65, 99,116,105,111,110, 83,116,114,105,112, 0, 98, 78,111,100,101, 83,116, 97, 99,107, 0, 98, 78,111,100,101, - 83,111, 99,107,101,116, 0, 98, 78,111,100,101, 76,105,110,107, 0, 98, 78,111,100,101, 80,114,101,118,105,101,119, 0, 98, 78, -111,100,101, 0,117,105, 66,108,111, 99,107, 0, 98, 78,111,100,101, 84,121,112,101, 0, 98, 78,111,100,101, 84,114,101,101, 69, -120,101, 99, 0, 98, 78,111,100,101, 83,111, 99,107,101,116, 86, 97,108,117,101, 73,110,116, 0, 98, 78,111,100,101, 83,111, 99, -107,101,116, 86, 97,108,117,101, 70,108,111, 97,116, 0, 98, 78,111,100,101, 83,111, 99,107,101,116, 86, 97,108,117,101, 66,111, -111,108,101, 97,110, 0, 98, 78,111,100,101, 83,111, 99,107,101,116, 86, 97,108,117,101, 86,101, 99,116,111,114, 0, 98, 78,111, -100,101, 83,111, 99,107,101,116, 86, 97,108,117,101, 82, 71, 66, 65, 0, 78,111,100,101, 73,109, 97,103,101, 65,110,105,109, 0, - 78,111,100,101, 66,108,117,114, 68, 97,116, 97, 0, 78,111,100,101, 68, 66,108,117,114, 68, 97,116, 97, 0, 78,111,100,101, 66, -105,108, 97,116,101,114, 97,108, 66,108,117,114, 68, 97,116, 97, 0, 78,111,100,101, 72,117,101, 83, 97,116, 0, 78,111,100,101, - 73,109, 97,103,101, 70,105,108,101, 0, 78,111,100,101, 73,109, 97,103,101, 77,117,108,116,105, 70,105,108,101, 0, 78,111,100, -101, 73,109, 97,103,101, 77,117,108,116,105, 70,105,108,101, 83,111, 99,107,101,116, 0, 78,111,100,101, 67,104,114,111,109, 97, - 0, 78,111,100,101, 84,119,111, 88, 89,115, 0, 78,111,100,101, 84,119,111, 70,108,111, 97,116,115, 0, 78,111,100,101, 71,101, -111,109,101,116,114,121, 0, 78,111,100,101, 86,101,114,116,101,120, 67,111,108, 0, 78,111,100,101, 68,101,102,111, 99,117,115, - 0, 78,111,100,101, 83, 99,114,105,112,116, 68,105, 99,116, 0, 78,111,100,101, 71,108, 97,114,101, 0, 78,111,100,101, 84,111, -110,101,109, 97,112, 0, 78,111,100,101, 76,101,110,115, 68,105,115,116, 0, 78,111,100,101, 67,111,108,111,114, 66, 97,108, 97, -110, 99,101, 0, 78,111,100,101, 67,111,108,111,114,115,112,105,108,108, 0, 78,111,100,101, 84,101,120, 66, 97,115,101, 0, 78, -111,100,101, 84,101,120, 83,107,121, 0, 78,111,100,101, 84,101,120, 73,109, 97,103,101, 0, 78,111,100,101, 84,101,120, 67,104, -101, 99,107,101,114, 0, 78,111,100,101, 84,101,120, 69,110,118,105,114,111,110,109,101,110,116, 0, 78,111,100,101, 84,101,120, - 71,114, 97,100,105,101,110,116, 0, 78,111,100,101, 84,101,120, 78,111,105,115,101, 0, 78,111,100,101, 84,101,120, 86,111,114, -111,110,111,105, 0, 78,111,100,101, 84,101,120, 77,117,115,103,114, 97,118,101, 0, 78,111,100,101, 84,101,120, 87, 97,118,101, - 0, 78,111,100,101, 84,101,120, 77, 97,103,105, 99, 0, 78,111,100,101, 83,104, 97,100,101,114, 65,116,116,114,105, 98,117,116, -101, 0, 84,101,120, 78,111,100,101, 79,117,116,112,117,116, 0, 67,117,114,118,101, 77, 97,112, 80,111,105,110,116, 0, 67,117, -114,118,101, 77, 97,112, 0, 66,114,117,115,104, 67,108,111,110,101, 0, 67,117,115,116,111,109, 68, 97,116, 97, 76, 97,121,101, -114, 0, 67,117,115,116,111,109, 68, 97,116, 97, 69,120,116,101,114,110, 97,108, 0, 72, 97,105,114, 75,101,121, 0, 80, 97,114, -116,105, 99,108,101, 75,101,121, 0, 66,111,105,100, 80, 97,114,116,105, 99,108,101, 0, 66,111,105,100, 68, 97,116, 97, 0, 80, - 97,114,116,105, 99,108,101, 83,112,114,105,110,103, 0, 67,104,105,108,100, 80, 97,114,116,105, 99,108,101, 0, 80, 97,114,116, -105, 99,108,101, 84, 97,114,103,101,116, 0, 80, 97,114,116,105, 99,108,101, 68,117,112,108,105, 87,101,105,103,104,116, 0, 80, - 97,114,116,105, 99,108,101, 68, 97,116, 97, 0, 83, 80, 72, 70,108,117,105,100, 83,101,116,116,105,110,103,115, 0, 80, 97,114, -116,105, 99,108,101, 83,101,116,116,105,110,103,115, 0, 66,111,105,100, 83,101,116,116,105,110,103,115, 0, 80, 97,114,116,105, - 99,108,101, 67, 97, 99,104,101, 75,101,121, 0, 75, 68, 84,114,101,101, 0, 80, 97,114,116,105, 99,108,101, 68,114, 97,119, 68, - 97,116, 97, 0, 76,105,110,107, 78,111,100,101, 0, 98, 71, 80, 68,115,112,111,105,110,116, 0, 98, 71, 80, 68,115,116,114,111, -107,101, 0, 98, 71, 80, 68,102,114, 97,109,101, 0, 98, 71, 80, 68,108, 97,121,101,114, 0, 82,101,112,111,114,116, 76,105,115, -116, 0,119,109, 87,105,110,100,111,119, 77, 97,110, 97,103,101,114, 0,119,109, 87,105,110,100,111,119, 0,119,109, 75,101,121, - 67,111,110,102,105,103, 0,119,109, 69,118,101,110,116, 0,119,109, 83,117, 98, 87,105,110,100,111,119, 0,119,109, 71,101,115, -116,117,114,101, 0,119,109, 75,101,121, 77, 97,112, 73,116,101,109, 0, 80,111,105,110,116,101,114, 82, 78, 65, 0,119,109, 75, -101,121, 77, 97,112, 68,105,102,102, 73,116,101,109, 0,119,109, 75,101,121, 77, 97,112, 0,119,109, 79,112,101,114, 97,116,111, -114, 84,121,112,101, 0, 70, 77,111,100,105,102,105,101,114, 0, 70, 77,111,100, 95, 71,101,110,101,114, 97,116,111,114, 0, 70, - 77,111,100, 95, 70,117,110, 99,116,105,111,110, 71,101,110,101,114, 97,116,111,114, 0, 70, 67, 77, 95, 69,110,118,101,108,111, -112,101, 68, 97,116, 97, 0, 70, 77,111,100, 95, 69,110,118,101,108,111,112,101, 0, 70, 77,111,100, 95, 67,121, 99,108,101,115, - 0, 70, 77,111,100, 95, 80,121,116,104,111,110, 0, 70, 77,111,100, 95, 76,105,109,105,116,115, 0, 70, 77,111,100, 95, 78,111, -105,115,101, 0, 70, 77,111,100, 95, 83,116,101,112,112,101,100, 0, 68,114,105,118,101,114, 84, 97,114,103,101,116, 0, 68,114, -105,118,101,114, 86, 97,114, 0, 67,104, 97,110,110,101,108, 68,114,105,118,101,114, 0, 70, 80,111,105,110,116, 0, 70, 67,117, -114,118,101, 0, 65,110,105,109, 77, 97,112, 80, 97,105,114, 0, 65,110,105,109, 77, 97,112,112,101,114, 0, 78,108, 97, 83,116, -114,105,112, 0, 78,108, 97, 84,114, 97, 99,107, 0, 75, 83, 95, 80, 97,116,104, 0, 75,101,121,105,110,103, 83,101,116, 0, 65, -110,105,109, 79,118,101,114,114,105,100,101, 0, 73,100, 65,100,116, 84,101,109,112,108, 97,116,101, 0, 66,111,105,100, 82,117, -108,101, 0, 66,111,105,100, 82,117,108,101, 71,111, 97,108, 65,118,111,105,100, 0, 66,111,105,100, 82,117,108,101, 65,118,111, -105,100, 67,111,108,108,105,115,105,111,110, 0, 66,111,105,100, 82,117,108,101, 70,111,108,108,111,119, 76,101, 97,100,101,114, - 0, 66,111,105,100, 82,117,108,101, 65,118,101,114, 97,103,101, 83,112,101,101,100, 0, 66,111,105,100, 82,117,108,101, 70,105, -103,104,116, 0, 66,111,105,100, 83,116, 97,116,101, 0, 70, 76, 85, 73, 68, 95, 51, 68, 0, 87, 84, 85, 82, 66, 85, 76, 69, 78, - 67, 69, 0, 83,112,101, 97,107,101,114, 0, 77,111,118,105,101, 67,108,105,112, 80,114,111,120,121, 0, 77,111,118,105,101, 67, -108,105,112, 67, 97, 99,104,101, 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110,103, 0, 77,111,118,105,101, 84,114, 97, 99, -107,105,110,103, 84,114, 97, 99,107, 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110,103, 77, 97,114,107,101,114, 0, 77,111, -118,105,101, 82,101, 99,111,110,115,116,114,117, 99,116,101,100, 67, 97,109,101,114, 97, 0, 77,111,118,105,101, 84,114, 97, 99, -107,105,110,103, 67, 97,109,101,114, 97, 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110,103, 83,101,116,116,105,110,103,115, - 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110,103, 83,116, 97, 98,105,108,105,122, 97,116,105,111,110, 0, 77,111,118,105, -101, 84,114, 97, 99,107,105,110,103, 82,101, 99,111,110,115,116,114,117, 99,116,105,111,110, 0, 77,111,118,105,101, 84,114, 97, - 99,107,105,110,103, 79, 98,106,101, 99,116, 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110,103, 83,116, 97,116,115, 0, 68, -121,110, 97,109,105, 99, 80, 97,105,110,116, 83,117,114,102, 97, 99,101, 0, 80, 97,105,110,116, 83,117,114,102, 97, 99,101, 68, - 97,116, 97, 0, 84, 76, 69, 78, 1, 0, 1, 0, 2, 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 8, 0, 8, 0, 0, 0, - 16, 0, 24, 0, 16, 0, 4, 0, 8, 0, 12, 0, 16, 0, 16, 0, 32, 0,128, 0,120, 0,152, 8, 0, 0, 40, 0,144, 0,112, 5, -112, 0, 36, 0, 56, 0,160, 0,200, 0, 0, 1, 96, 0, 40, 0, 48, 0,224, 0, 16, 0,200, 0, 40, 0,216, 11, 48, 5, 0, 0, - 0, 0, 0, 0, 56, 1,168, 1,216, 4, 24, 0, 8, 3,200, 0, 0, 0,104, 0, 64, 1, 56, 4, 80, 0, 24, 1,144, 0, 56, 3, - 16, 2, 88, 0, 16, 0,128, 3,152, 0,136, 4, 0, 0,104, 0,104, 0, 0, 1, 80, 0, 8, 0, 16, 0, 32, 0, 0, 0, 8, 2, - 0, 0, 0, 0, 0, 0,232, 4, 12, 0, 16, 0, 8, 0, 12, 0, 4, 0, 20, 0, 48, 0, 64, 0, 20, 0, 12, 0, 16, 0, 4, 0, - 8, 0, 8, 0, 0, 0,176, 0,144, 1, 8, 0, 4, 0, 4, 0, 0, 1, 32, 0, 8, 0, 24, 0, 16, 0, 64, 0, 24, 0, 12, 0, - 64, 0, 4, 0,112, 0,200, 0,136, 0,192, 0,192, 0,128, 0,192, 0,192, 0,128, 0,120, 0,200, 0,120, 0,144, 0, 16, 1, - 56, 0,192, 0, 24, 1, 40, 1,120, 0,184, 0,200, 0, 64, 1,200, 0, 88, 1,112, 0,168, 0, 0, 0,152, 0, 48, 0, 40, 5, -192, 0, 0, 0,152, 0, 0, 0, 0, 0,128, 0, 8, 0, 8, 0,112, 1,144, 0,152, 2,136, 0,192, 0,120, 0,128, 0,224, 4, -208, 0,200, 0,112, 0,208, 0,144, 0, 16, 5, 0, 0, 0, 0, 48, 1,104, 1,160, 1,104, 1,136, 0,104, 0,112, 0,128, 0, - 16, 0, 96, 1, 88, 0, 0, 0,200, 0,216, 0,152, 0, 48, 0, 24, 0,120, 0,152, 0,216, 1, 0, 1,184, 0, 0, 0, 72, 0, - 32, 0,176, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 12, 0, 24, 2, 40, 0,184, 0,152, 0, 64, 0, 72, 0, 32, 0,120, 0, - 24, 0, 56, 9, 64, 0, 24, 0, 16, 0, 56, 0,168, 0, 96, 0, 24, 0, 88, 6, 48, 0, 16, 0,168, 0, 96, 0, 24, 0, 56, 0, -120, 0, 16, 0,232, 1, 32, 0, 8, 0, 24, 0, 80, 8, 0, 0, 0, 0,192, 8,104, 0, 8, 0,112, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 96, 1, 56, 0,144, 0, 64, 0,240, 0,112, 0,248, 0,240, 0,160, 7,104, 0, 0, 0,168, 0, 0, 0, 24, 1, - 16, 0, 16, 0, 40, 33,128, 16, 24, 16,216, 0,160, 2,168, 5, 64, 0, 24, 0,208, 0, 48, 1, 72, 0, 40, 0,136, 1,104, 0, - 40, 1, 56, 0, 24, 4, 32, 0,232, 0, 32, 0, 32, 0, 8, 0, 80, 3,224, 1, 16, 0,168, 36, 80, 0, 56, 0,112, 38, 8, 1, - 32, 0, 40, 0, 88, 1, 0, 0, 0, 0,160, 0, 0, 0, 40, 1, 0, 0, 48, 4, 8, 1, 16, 0, 8, 0, 44, 0, 16, 4, 72, 3, -200, 4, 72, 1,208, 4, 32, 0, 12, 0, 24, 0, 32, 0, 16, 0, 24, 0, 24, 0, 32, 0,136, 1, 0, 0, 64, 0, 96, 0, 80, 0, - 8, 0, 80, 0,136, 0,200, 0, 72, 0, 8, 0,136, 0, 76, 0, 72, 0,204, 0,136, 0,136, 0,128, 0,136, 0, 92, 0,128, 0, - 80, 0,112, 0, 16, 0,168, 0, 32, 0, 72, 0,120, 0, 24, 0,144, 0,112, 0,148, 0, 32, 0,128, 0, 88, 0, 88, 0,208, 0, -140, 0, 4, 0, 24, 0, 16, 0, 8, 0,160, 0, 48, 0, 40, 0, 72, 1, 0, 1, 16, 0, 32, 2, 4, 0, 40, 0,120, 0, 72, 1, -120, 0, 56, 0,120, 0,160, 0,112, 0,184, 0, 24, 0, 88, 0, 80, 0, 80, 0, 80, 0, 8, 0, 72, 0,104, 0,104, 0, 80, 0, - 80, 0, 24, 0, 88, 0,104, 0, 16, 0,144, 0,128, 0, 88, 0, 28, 0, 28, 0, 28, 0, 88, 0, 24, 0,160, 0, 16, 0,152, 0, - 72, 0,168, 0, 48, 0,208, 0, 56, 0, 16, 0, 88, 1, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 4, 0, 24, 0, 16, 0, 16, 0, - 40, 0, 28, 0, 12, 0, 12, 0, 32, 4, 40, 4, 32, 0, 44, 0, 24, 0, 8, 0,128, 0, 64, 0, 32, 0, 16, 0, 32, 0, 32, 0, - 8, 0, 96, 0, 20, 0,200, 3,216, 3,208, 3,200, 3,208, 3,208, 3,200, 3,208, 3,208, 3,208, 3,208, 3, 64, 0, 64, 0, - 12, 0, 56, 0, 24, 0,104, 0, 0, 4, 24, 0, 56, 0, 56, 0, 20, 0, 16, 0, 64, 0, 40, 0, 32, 0,192, 0, 60, 0, 16, 3, -104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 40, 0,192, 0, 40, 0, 88, 1, 0, 1,168, 0, 0, 0, 0, 0, 0, 0, -120, 0, 0, 0, 32, 0,136, 0, 0, 0,120, 0, 24, 0, 24, 0, 16, 0, 24, 0, 8, 0, 16, 0, 24, 0, 20, 0, 20, 0, 56, 0, - 24, 2, 40, 1, 16, 0,104, 0, 0, 1, 40, 0,208, 0,104, 0,112, 0,216, 1, 32, 0,128, 0, 56, 0, 80, 0, 64, 0,104, 0, - 72, 0, 64, 0,128, 0, 0, 0, 0, 0,184, 0, 8, 3, 0, 0,248, 0,192, 0, 16, 0, 72, 0, 48, 0, 64, 0, 56, 0, 24, 0, -128, 0, 0, 1, 16, 6, 0, 0, 83, 84, 82, 67,207, 1, 0, 0, 12, 0, 2, 0, 12, 0, 0, 0, 12, 0, 1, 0, 13, 0, 3, 0, - 13, 0, 0, 0, 13, 0, 1, 0, 11, 0, 2, 0, 14, 0, 2, 0, 11, 0, 3, 0, 11, 0, 4, 0, 15, 0, 2, 0, 2, 0, 5, 0, - 2, 0, 6, 0, 16, 0, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0, 17, 0, 3, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, - 18, 0, 4, 0, 4, 0, 8, 0, 4, 0, 9, 0, 4, 0, 10, 0, 4, 0, 11, 0, 19, 0, 4, 0, 7, 0, 8, 0, 7, 0, 9, 0, - 7, 0, 10, 0, 7, 0, 11, 0, 20, 0, 4, 0, 11, 0, 12, 0, 14, 0, 13, 0, 4, 0, 14, 0, 4, 0, 15, 0, 21, 0, 10, 0, - 21, 0, 0, 0, 21, 0, 1, 0, 0, 0, 16, 0, 0, 0, 17, 0, 2, 0, 18, 0, 0, 0, 19, 0, 4, 0, 20, 0, 20, 0, 21, 0, - 4, 0, 22, 0, 4, 0, 23, 0, 22, 0, 11, 0, 11, 0, 0, 0, 11, 0, 1, 0, 22, 0, 24, 0, 23, 0, 25, 0, 0, 0, 26, 0, - 2, 0, 27, 0, 2, 0, 28, 0, 2, 0, 18, 0, 4, 0, 29, 0, 4, 0, 30, 0, 21, 0, 31, 0, 23, 0, 8, 0, 22, 0, 32, 0, - 22, 0, 33, 0, 24, 0, 34, 0, 0, 0, 35, 0, 0, 0, 36, 0, 4, 0, 37, 0, 4, 0, 27, 0, 23, 0, 38, 0, 25, 0, 5, 0, - 4, 0, 39, 0, 4, 0, 40, 0, 2, 0, 41, 0, 2, 0, 42, 0, 4, 0, 43, 0, 26, 0, 6, 0, 27, 0, 44, 0, 2, 0, 45, 0, - 2, 0, 46, 0, 2, 0, 16, 0, 2, 0, 18, 0, 0, 0, 47, 0, 28, 0, 21, 0, 28, 0, 0, 0, 28, 0, 1, 0, 29, 0, 48, 0, - 30, 0, 49, 0, 19, 0, 50, 0, 19, 0, 51, 0, 2, 0, 45, 0, 2, 0, 46, 0, 2, 0, 52, 0, 2, 0, 53, 0, 2, 0, 54, 0, - 2, 0, 55, 0, 2, 0, 18, 0, 2, 0, 56, 0, 7, 0, 10, 0, 7, 0, 11, 0, 4, 0, 57, 0, 7, 0, 58, 0, 7, 0, 59, 0, - 7, 0, 60, 0, 26, 0, 61, 0, 31, 0, 7, 0, 22, 0, 32, 0, 14, 0, 62, 0, 19, 0, 63, 0, 2, 0, 45, 0, 2, 0, 64, 0, - 2, 0, 65, 0, 2, 0, 27, 0, 32, 0, 18, 0, 32, 0, 0, 0, 32, 0, 1, 0, 7, 0, 66, 0, 7, 0, 60, 0, 2, 0, 16, 0, - 2, 0, 46, 0, 2, 0, 67, 0, 2, 0, 18, 0, 4, 0, 68, 0, 4, 0, 30, 0, 11, 0, 2, 0, 7, 0, 69, 0, 0, 0, 19, 0, - 0, 0, 70, 0, 7, 0, 71, 0, 7, 0, 72, 0, 4, 0, 73, 0, 4, 0, 74, 0, 33, 0, 15, 0, 22, 0, 32, 0, 34, 0, 75, 0, - 32, 0, 76, 0, 0, 0, 77, 0, 4, 0, 78, 0, 7, 0, 60, 0, 14, 0, 79, 0, 31, 0, 80, 0, 22, 0, 81, 0, 2, 0, 16, 0, - 2, 0, 82, 0, 2, 0, 83, 0, 2, 0, 18, 0, 4, 0, 84, 0, 4, 0, 27, 0, 35, 0, 6, 0, 35, 0, 0, 0, 35, 0, 1, 0, - 0, 0, 85, 0, 0, 0, 86, 0, 4, 0, 22, 0, 4, 0, 87, 0, 36, 0, 10, 0, 36, 0, 0, 0, 36, 0, 1, 0, 4, 0, 88, 0, - 4, 0, 89, 0, 4, 0, 90, 0, 4, 0, 91, 0, 4, 0, 13, 0, 4, 0, 92, 0, 0, 0, 93, 0, 0, 0, 94, 0, 37, 0, 15, 0, - 22, 0, 32, 0, 0, 0, 95, 0, 4, 0, 92, 0, 4, 0, 96, 0, 14, 0, 97, 0, 35, 0, 98, 0, 35, 0, 99, 0, 4, 0,100, 0, - 4, 0,101, 0, 14, 0,102, 0, 0, 0,103, 0, 4, 0,104, 0, 4, 0,105, 0, 11, 0,106, 0, 8, 0,107, 0, 38, 0, 3, 0, - 4, 0,108, 0, 4, 0,109, 0, 11, 0, 2, 0, 39, 0, 20, 0, 22, 0, 32, 0, 34, 0, 75, 0, 0, 0, 16, 0, 0, 0,110, 0, - 2, 0, 18, 0, 7, 0,111, 0, 7, 0,112, 0, 7, 0,113, 0, 7, 0,114, 0, 7, 0,115, 0, 7, 0,116, 0, 7, 0,117, 0, - 7, 0,118, 0, 7, 0,119, 0, 7, 0,120, 0, 7, 0,121, 0, 31, 0, 80, 0, 27, 0,122, 0, 0, 0,123, 0, 0, 0,124, 0, - 40, 0, 14, 0, 41, 0,125, 0, 4, 0,126, 0, 4, 0,127, 0, 4, 0,128, 0, 4, 0,129, 0, 0, 0,130, 0, 0, 0,131, 0, - 0, 0,132, 0, 0, 0, 27, 0, 2, 0,133, 0, 2, 0,134, 0, 2, 0,135, 0, 2, 0, 18, 0, 4, 0, 30, 0, 42, 0, 33, 0, - 22, 0, 32, 0, 0, 0, 35, 0, 14, 0,136, 0, 43, 0,137, 0, 44, 0,138, 0, 45, 0,139, 0, 45, 0,140, 0, 2, 0,141, 0, - 2, 0,142, 0, 2, 0,132, 0, 2, 0, 18, 0, 2, 0,143, 0, 2, 0, 16, 0, 4, 0,144, 0, 2, 0,145, 0, 2, 0,146, 0, - 2, 0,147, 0, 2, 0,148, 0, 2, 0,149, 0, 2, 0,150, 0, 4, 0,151, 0, 4, 0,152, 0, 38, 0,153, 0, 25, 0,154, 0, - 7, 0,155, 0, 4, 0,156, 0, 2, 0,157, 0, 2, 0,158, 0, 2, 0,159, 0, 0, 0,160, 0, 0, 0,161, 0, 7, 0,162, 0, - 7, 0,163, 0, 46, 0, 65, 0, 2, 0,164, 0, 2, 0,165, 0, 2, 0,166, 0, 2, 0,167, 0, 27, 0,168, 0, 47, 0,169, 0, - 0, 0,170, 0, 0, 0,171, 0, 0, 0,172, 0, 0, 0,173, 0, 0, 0,174, 0, 7, 0,175, 0, 7, 0,176, 0, 7, 0,177, 0, - 2, 0,178, 0, 2, 0,179, 0, 2, 0,180, 0, 2, 0,181, 0, 2, 0,182, 0, 2, 0,183, 0, 0, 0,184, 0, 0, 0,124, 0, - 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, 7, 0,188, 0, 7, 0,189, 0, 7, 0, 56, 0, 7, 0,190, 0, 7, 0,191, 0, - 7, 0,192, 0, 7, 0,193, 0, 7, 0,194, 0, 7, 0,195, 0, 7, 0,196, 0, 7, 0,197, 0, 7, 0,198, 0, 7, 0,199, 0, - 7, 0,200, 0, 7, 0,201, 0, 7, 0,202, 0, 7, 0,203, 0, 7, 0,204, 0, 7, 0,205, 0, 7, 0,206, 0, 7, 0,207, 0, - 7, 0,208, 0, 7, 0,209, 0, 7, 0,210, 0, 7, 0,211, 0, 7, 0,212, 0, 7, 0,213, 0, 7, 0,214, 0, 7, 0,215, 0, - 7, 0,216, 0, 7, 0,217, 0, 7, 0,218, 0, 7, 0,219, 0, 7, 0,220, 0, 7, 0,221, 0, 7, 0,222, 0, 7, 0,223, 0, - 7, 0,224, 0, 7, 0,225, 0, 7, 0,226, 0, 48, 0, 15, 0, 0, 0, 35, 0, 11, 0,227, 0, 0, 0,228, 0, 0, 0,229, 0, - 4, 0,230, 0, 4, 0,231, 0, 11, 0,232, 0, 7, 0,233, 0, 7, 0,234, 0, 7, 0,235, 0, 4, 0,236, 0, 11, 0,237, 0, - 11, 0,238, 0, 4, 0,239, 0, 4, 0, 27, 0, 49, 0, 6, 0, 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, 7, 0,240, 0, - 7, 0, 66, 0, 4, 0, 63, 0, 50, 0, 5, 0, 2, 0, 18, 0, 2, 0, 37, 0, 2, 0, 63, 0, 2, 0,241, 0, 49, 0,235, 0, - 51, 0, 17, 0, 27, 0,168, 0, 42, 0,242, 0, 52, 0,243, 0, 7, 0,244, 0, 7, 0,245, 0, 2, 0, 16, 0, 2, 0,246, 0, - 7, 0,112, 0, 7, 0,113, 0, 7, 0,247, 0, 4, 0,248, 0, 2, 0,249, 0, 2, 0,250, 0, 4, 0,132, 0, 4, 0,144, 0, - 2, 0,251, 0, 2, 0,252, 0, 53, 0, 25, 0, 2, 0, 18, 0, 2, 0,253, 0, 7, 0,254, 0, 7, 0,255, 0, 2, 0,143, 0, - 2, 0, 0, 1, 4, 0, 1, 1, 4, 0, 2, 1, 27, 0,168, 0, 4, 0, 3, 1, 2, 0, 4, 1, 2, 0, 5, 1, 11, 0, 6, 1, - 7, 0, 7, 1, 7, 0, 8, 1, 2, 0, 9, 1, 2, 0, 10, 1, 2, 0, 11, 1, 2, 0, 12, 1, 7, 0, 13, 1, 7, 0, 14, 1, - 7, 0, 15, 1, 7, 0, 16, 1, 50, 0, 17, 1, 54, 0, 18, 1, 55, 0, 13, 0, 4, 0, 19, 1, 4, 0, 20, 1, 2, 0, 21, 1, - 2, 0, 18, 0, 2, 0, 22, 1, 2, 0, 23, 1, 27, 0,168, 0, 7, 0, 24, 1, 4, 0, 25, 1, 0, 0, 26, 1, 7, 0, 27, 1, - 4, 0, 28, 1, 4, 0,132, 0, 56, 0, 4, 0, 27, 0,168, 0, 0, 0, 29, 1, 4, 0, 30, 1, 4, 0, 27, 0, 47, 0, 64, 0, - 22, 0, 32, 0, 34, 0, 75, 0, 7, 0, 31, 1, 7, 0, 32, 1, 7, 0, 33, 1, 7, 0, 34, 1, 7, 0, 35, 1, 7, 0, 36, 1, - 7, 0, 37, 1, 7, 0, 38, 1, 7, 0, 39, 1, 7, 0, 30, 0, 7, 0, 40, 1, 7, 0, 41, 1, 7, 0, 42, 1, 7, 0, 43, 1, - 7, 0, 44, 1, 7, 0, 45, 1, 7, 0, 46, 1, 7, 0, 47, 1, 7, 0, 48, 1, 7, 0, 49, 1, 7, 0, 50, 1, 7, 0, 51, 1, - 2, 0, 52, 1, 2, 0, 53, 1, 2, 0, 54, 1, 2, 0, 55, 1, 2, 0, 56, 1, 2, 0, 57, 1, 2, 0, 58, 1, 2, 0, 18, 0, - 2, 0, 16, 0, 2, 0,246, 0, 7, 0, 59, 1, 7, 0, 60, 1, 7, 0, 61, 1, 7, 0, 62, 1, 4, 0, 63, 1, 4, 0, 64, 1, - 2, 0, 65, 1, 2, 0, 66, 1, 2, 0, 22, 1, 2, 0,130, 0, 4, 0, 22, 0, 4, 0,127, 0, 4, 0,128, 0, 4, 0,129, 0, - 7, 0, 67, 1, 7, 0, 68, 1, 7, 0, 91, 0, 40, 0, 69, 1, 57, 0, 70, 1, 31, 0, 80, 0, 42, 0,242, 0, 48, 0, 71, 1, - 50, 0, 17, 1, 51, 0, 72, 1, 25, 0,154, 0, 53, 0, 73, 1, 55, 0, 74, 1, 56, 0, 75, 1, 0, 0, 76, 1, 0, 0,124, 0, - 58, 0, 13, 0, 7, 0, 77, 1, 7, 0, 78, 1, 7, 0,176, 0, 4, 0, 18, 0, 0, 0,171, 0, 0, 0,172, 0, 0, 0,173, 0, - 0, 0,174, 0, 4, 0, 27, 0, 7, 0, 79, 1, 7, 0, 80, 1, 7, 0, 81, 1, 27, 0, 44, 0, 59, 0, 9, 0, 50, 0, 82, 1, - 7, 0, 33, 1, 7, 0, 34, 1, 7, 0, 35, 1, 4, 0, 18, 0, 7, 0, 83, 1, 7, 0, 84, 1, 4, 0, 85, 1, 4, 0, 86, 1, - 60, 0, 74, 0, 22, 0, 32, 0, 34, 0, 75, 0, 2, 0, 16, 0, 2, 0, 18, 0, 4, 0, 87, 1, 2, 0,179, 0, 2, 0, 88, 1, - 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, 7, 0,188, 0, 7, 0, 89, 1, 7, 0, 90, 1, 7, 0, 91, 1, 7, 0, 92, 1, - 7, 0, 93, 1, 7, 0, 94, 1, 7, 0, 95, 1, 7, 0, 96, 1, 7, 0, 97, 1, 7, 0, 98, 1, 7, 0, 99, 1, 54, 0,100, 1, - 2, 0,253, 0, 2, 0, 30, 0, 7, 0,112, 0, 7, 0,113, 0, 7, 0,101, 1, 7, 0,102, 1, 7, 0,103, 1, 7, 0,104, 1, - 7, 0,105, 1, 2, 0,106, 1, 2, 0,107, 1, 2, 0,108, 1, 2, 0,109, 1, 0, 0,110, 1, 0, 0,111, 1, 2, 0,112, 1, - 2, 0,113, 1, 2, 0,114, 1, 2, 0,115, 1, 2, 0,116, 1, 7, 0,117, 1, 7, 0,118, 1, 7, 0,119, 1, 7, 0,120, 1, - 2, 0,121, 1, 2, 0, 91, 0, 2, 0,122, 1, 2, 0,123, 1, 2, 0,124, 1, 2, 0,125, 1, 7, 0,126, 1, 7, 0,127, 1, - 7, 0,128, 1, 7, 0,129, 1, 7, 0,130, 1, 7, 0,131, 1, 7, 0,132, 1, 7, 0,133, 1, 7, 0,134, 1, 7, 0,135, 1, - 7, 0,136, 1, 7, 0,137, 1, 2, 0,138, 1, 0, 0,139, 1, 31, 0, 80, 0, 46, 0,140, 1, 2, 0,141, 1, 2, 0, 76, 1, - 0, 0,142, 1, 25, 0,154, 0, 57, 0, 70, 1, 61, 0, 18, 0, 7, 0,143, 1, 7, 0,144, 1, 7, 0,145, 1, 7, 0,146, 1, - 7, 0,147, 1, 7, 0,148, 1, 7, 0,149, 1, 7, 0,150, 1, 7, 0,151, 1, 7, 0,152, 1, 2, 0,153, 1, 2, 0,154, 1, - 2, 0,155, 1, 2, 0,156, 1, 7, 0,157, 1, 7, 0,158, 1, 7, 0,159, 1, 7, 0,160, 1, 62, 0, 4, 0, 4, 0, 18, 0, - 4, 0,161, 1, 4, 0,162, 1, 4, 0, 91, 0, 63, 0,126, 0, 22, 0, 32, 0, 34, 0, 75, 0, 2, 0,163, 1, 2, 0, 18, 0, - 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, 7, 0,164, 1, 7, 0,165, 1, 7, 0,166, 1, 7, 0,167, 1, 7, 0,168, 1, - 7, 0,169, 1, 7, 0,170, 1, 7, 0,171, 1, 7, 0,172, 1, 7, 0,173, 1, 7, 0,174, 1, 7, 0,175, 1, 7, 0,176, 1, - 7, 0,177, 1, 7, 0,178, 1, 7, 0,179, 1, 7, 0,180, 1, 7, 0,181, 1, 7, 0,182, 1, 7, 0,183, 1, 61, 0,184, 1, - 62, 0,185, 1, 7, 0,186, 1, 7, 0,187, 1, 7, 0,188, 1, 7, 0,189, 1, 7, 0,190, 1, 7, 0,191, 1, 7, 0,192, 1, - 2, 0,193, 1, 2, 0,194, 1, 2, 0,195, 1, 0, 0,196, 1, 0, 0,197, 1, 7, 0,198, 1, 7, 0,199, 1, 2, 0,200, 1, - 2, 0,201, 1, 7, 0,202, 1, 7, 0,203, 1, 7, 0,204, 1, 7, 0,205, 1, 2, 0,206, 1, 2, 0,207, 1, 4, 0, 87, 1, - 4, 0,208, 1, 2, 0,209, 1, 2, 0,210, 1, 2, 0,211, 1, 2, 0,212, 1, 7, 0,213, 1, 7, 0,214, 1, 7, 0,215, 1, - 7, 0,216, 1, 7, 0,217, 1, 7, 0,218, 1, 7, 0,219, 1, 7, 0,220, 1, 7, 0,221, 1, 7, 0,222, 1, 0, 0,223, 1, - 7, 0,224, 1, 7, 0,225, 1, 7, 0,226, 1, 4, 0,227, 1, 0, 0,228, 1, 0, 0,122, 1, 0, 0,229, 1, 0, 0, 76, 1, - 2, 0,230, 1, 2, 0,231, 1, 2, 0,141, 1, 2, 0,232, 1, 2, 0,233, 1, 2, 0,234, 1, 7, 0,235, 1, 7, 0,236, 1, - 7, 0,237, 1, 7, 0,238, 1, 7, 0,239, 1, 2, 0,164, 0, 2, 0,165, 0, 50, 0,240, 1, 50, 0,241, 1, 0, 0,242, 1, - 0, 0,243, 1, 0, 0,244, 1, 0, 0,245, 1, 2, 0,246, 1, 2, 0, 74, 0, 7, 0,247, 1, 7, 0,248, 1, 46, 0,140, 1, - 57, 0, 70, 1, 31, 0, 80, 0, 64, 0,249, 1, 25, 0,154, 0, 7, 0,250, 1, 7, 0,251, 1, 7, 0,252, 1, 7, 0,253, 1, - 7, 0,254, 1, 2, 0,255, 1, 2, 0, 30, 0, 7, 0, 0, 2, 7, 0, 1, 2, 7, 0, 2, 2, 7, 0, 3, 2, 7, 0, 4, 2, - 7, 0, 5, 2, 7, 0, 6, 2, 7, 0, 7, 2, 7, 0, 8, 2, 2, 0, 9, 2, 2, 0, 10, 2, 4, 0, 11, 2, 2, 0, 12, 2, - 2, 0, 13, 2, 14, 0, 14, 2, 65, 0, 4, 0, 22, 0, 32, 0, 0, 0, 35, 0, 66, 0, 2, 0, 38, 0,153, 0, 67, 0, 20, 0, - 67, 0, 0, 0, 67, 0, 1, 0, 68, 0, 15, 2, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 16, 2, 2, 0, 17, 2, 7, 0, 5, 0, - 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 18, 2, 7, 0, 19, 2, 7, 0, 20, 2, 7, 0, 21, 2, 7, 0, 22, 2, 7, 0, 23, 2, - 7, 0, 24, 2, 7, 0, 22, 0, 7, 0, 25, 2, 7, 0, 26, 2, 69, 0, 20, 0, 22, 0, 32, 0, 34, 0, 75, 0, 68, 0, 15, 2, - 14, 0, 27, 2, 14, 0, 28, 2, 14, 0, 29, 2, 31, 0, 80, 0, 63, 0, 30, 2, 0, 0, 18, 0, 0, 0, 31, 2, 2, 0, 32, 2, - 2, 0,178, 0, 2, 0, 27, 0, 7, 0, 77, 1, 7, 0,176, 0, 7, 0, 78, 1, 7, 0, 33, 2, 7, 0, 34, 2, 7, 0, 35, 2, - 67, 0, 36, 2, 30, 0, 11, 0, 7, 0, 37, 2, 7, 0, 38, 2, 7, 0, 39, 2, 7, 0,255, 0, 2, 0, 54, 0, 0, 0, 40, 2, - 0, 0, 41, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 44, 2, 0, 0, 45, 2, 29, 0, 7, 0, 7, 0, 46, 2, 7, 0, 38, 2, - 7, 0, 39, 2, 2, 0, 42, 2, 2, 0, 45, 2, 7, 0,255, 0, 7, 0, 27, 0, 70, 0, 21, 0, 70, 0, 0, 0, 70, 0, 1, 0, - 2, 0, 16, 0, 2, 0, 47, 2, 2, 0, 45, 2, 2, 0, 18, 0, 2, 0, 48, 2, 2, 0, 49, 2, 2, 0, 50, 2, 2, 0, 51, 2, - 2, 0, 52, 2, 2, 0, 53, 2, 2, 0, 54, 2, 2, 0, 55, 2, 7, 0, 56, 2, 7, 0, 57, 2, 29, 0, 48, 0, 30, 0, 49, 0, - 2, 0, 58, 2, 2, 0, 59, 2, 4, 0, 60, 2, 71, 0, 5, 0, 2, 0, 61, 2, 2, 0, 47, 2, 0, 0, 18, 0, 0, 0, 27, 0, - 2, 0, 30, 0, 72, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 62, 2, 7, 0, 63, 2, 73, 0, 4, 0, 14, 0, 64, 2, - 74, 0, 65, 2, 4, 0, 66, 2, 0, 0, 94, 0, 75, 0, 68, 0, 22, 0, 32, 0, 34, 0, 75, 0, 68, 0, 15, 2, 14, 0, 67, 2, - 14, 0, 28, 2, 73, 0, 68, 2, 27, 0, 69, 2, 27, 0, 70, 2, 27, 0, 71, 2, 31, 0, 80, 0, 76, 0, 72, 2, 33, 0, 73, 2, - 63, 0, 30, 2, 14, 0, 74, 2, 7, 0, 77, 1, 7, 0,176, 0, 7, 0, 78, 1, 2, 0, 16, 0, 2, 0,178, 0, 2, 0, 75, 2, - 2, 0, 76, 2, 7, 0, 77, 2, 7, 0, 78, 2, 4, 0, 79, 2, 2, 0, 27, 0, 2, 0, 32, 2, 2, 0, 18, 0, 2, 0, 80, 2, - 7, 0, 81, 2, 7, 0, 82, 2, 7, 0, 83, 2, 2, 0, 50, 2, 2, 0, 51, 2, 2, 0, 84, 2, 2, 0, 85, 2, 4, 0, 86, 2, - 11, 0, 87, 2, 2, 0, 22, 0, 2, 0, 97, 0, 2, 0, 66, 0, 2, 0, 88, 2, 7, 0, 89, 2, 7, 0, 90, 2, 7, 0, 91, 2, - 7, 0, 92, 2, 7, 0, 93, 2, 7, 0, 94, 2, 7, 0, 95, 2, 7, 0, 96, 2, 7, 0, 97, 2, 7, 0, 98, 2, 0, 0, 99, 2, - 77, 0,100, 2, 78, 0,101, 2, 0, 0,102, 2, 65, 0,103, 2, 65, 0,104, 2, 65, 0,105, 2, 65, 0,106, 2, 4, 0,107, 2, - 7, 0,108, 2, 4, 0,109, 2, 4, 0,110, 2, 72, 0,111, 2, 4, 0,112, 2, 4, 0,113, 2, 71, 0,114, 2, 71, 0,115, 2, - 79, 0, 47, 0, 22, 0, 32, 0, 34, 0, 75, 0, 68, 0, 15, 2, 31, 0, 80, 0, 33, 0, 73, 2, 63, 0, 30, 2, 80, 0,116, 2, - 81, 0,117, 2, 82, 0,118, 2, 83, 0,119, 2, 84, 0,120, 2, 85, 0,121, 2, 86, 0,122, 2, 87, 0,123, 2, 88, 0,124, 2, - 89, 0,125, 2, 90, 0,126, 2, 91, 0,127, 2, 92, 0,128, 2, 79, 0,129, 2, 93, 0,130, 2, 94, 0,131, 2, 95, 0,132, 2, - 95, 0,133, 2, 95, 0,134, 2, 95, 0,135, 2, 95, 0,136, 2, 4, 0, 53, 0, 4, 0,137, 2, 4, 0,138, 2, 4, 0,139, 2, - 4, 0,140, 2, 4, 0,141, 2, 4, 0,142, 2, 7, 0, 77, 1, 7, 0,176, 0, 7, 0, 78, 1, 2, 0,178, 0, 2, 0, 75, 2, - 2, 0,143, 2, 2, 0, 18, 0, 2, 0,144, 2, 2, 0,145, 2, 0, 0,146, 2, 0, 0,147, 2, 2, 0, 32, 2, 96, 0,148, 2, - 87, 0, 8, 0, 11, 0,149, 2, 7, 0,150, 2, 4, 0,151, 2, 0, 0, 18, 0, 0, 0,152, 2, 2, 0, 87, 1, 2, 0,153, 2, - 2, 0,154, 2, 85, 0, 7, 0, 4, 0,155, 2, 4, 0,156, 2, 4, 0,157, 2, 4, 0,158, 2, 2, 0, 47, 2, 0, 0,159, 2, - 0, 0, 18, 0, 89, 0, 5, 0, 4, 0,155, 2, 4, 0,156, 2, 0, 0,160, 2, 0, 0,161, 2, 2, 0, 18, 0, 97, 0, 2, 0, - 4, 0,162, 2, 7, 0, 39, 2, 90, 0, 3, 0, 97, 0,163, 2, 4, 0,164, 2, 4, 0, 18, 0, 88, 0, 4, 0, 7, 0,165, 2, - 2, 0,166, 2, 0, 0, 18, 0, 0, 0,161, 2, 91, 0, 4, 0, 0, 0,240, 0, 0, 0,185, 0, 0, 0,186, 0, 0, 0,187, 0, - 80, 0, 5, 0, 4, 0,167, 2, 4, 0,141, 2, 2, 0, 47, 2, 0, 0, 18, 0, 0, 0, 27, 0, 82, 0, 2, 0, 4, 0,168, 2, - 4, 0,169, 2, 81, 0, 6, 0, 42, 0,149, 2, 0, 0, 18, 0, 0, 0,152, 2, 2, 0, 87, 1, 2, 0,153, 2, 2, 0,154, 2, - 83, 0, 2, 0, 7, 0,170, 2, 4, 0, 18, 0, 84, 0, 4, 0, 0, 0,185, 0, 0, 0,186, 0, 0, 0,187, 0, 0, 0,240, 0, - 92, 0, 1, 0, 7, 0,171, 2, 93, 0, 2, 0, 4, 0, 13, 2, 4, 0, 16, 0, 86, 0, 7, 0, 7, 0,150, 2, 42, 0,149, 2, - 0, 0, 18, 0, 0, 0,152, 2, 2, 0, 87, 1, 2, 0,153, 2, 2, 0,154, 2, 98, 0, 1, 0, 7, 0,172, 2, 99, 0, 1, 0, - 4, 0,173, 2,100, 0, 1, 0, 0, 0,174, 2,101, 0, 1, 0, 7, 0,150, 2,102, 0, 1, 0, 7, 0,170, 2,103, 0, 4, 0, - 4, 0,175, 2, 4, 0,176, 2, 7, 0,177, 2, 4, 0,178, 2,104, 0, 4, 0, 7, 0,240, 0, 7, 0,185, 0, 7, 0,186, 0, - 7, 0,187, 0,105, 0, 1, 0,104, 0,151, 2,106, 0, 5, 0, 4, 0,179, 2, 4, 0,180, 2, 0, 0, 18, 0, 0, 0, 47, 2, - 0, 0,181, 2,107, 0, 2, 0, 4, 0,182, 2, 4, 0,180, 2,108, 0, 10, 0,108, 0, 0, 0,108, 0, 1, 0,106, 0,183, 2, -105, 0,184, 2,107, 0,185, 2, 4, 0, 53, 0, 4, 0,138, 2, 4, 0,137, 2, 4, 0, 27, 0, 88, 0,186, 2, 96, 0, 14, 0, - 14, 0,187, 2, 88, 0,186, 2, 0, 0,188, 2, 0, 0,189, 2, 0, 0,190, 2, 0, 0,191, 2, 0, 0,192, 2, 0, 0,193, 2, - 0, 0,194, 2, 0, 0, 18, 0, 95, 0,132, 2, 95, 0,134, 2, 2, 0,195, 2, 0, 0,196, 2,109, 0, 1, 0, 4, 0,173, 2, -110, 0, 9, 0,110, 0, 0, 0,110, 0, 1, 0, 4, 0, 16, 0, 4, 0, 87, 1, 4, 0,197, 2, 4, 0, 27, 0, 0, 0, 19, 0, - 41, 0,125, 0, 0, 0,198, 2,111, 0, 6, 0,110, 0,199, 2, 47, 0,200, 2, 27, 0,201, 2, 0, 0,202, 2, 4, 0,203, 2, - 4, 0,204, 2,112, 0, 7, 0,110, 0,199, 2, 2, 0,205, 2, 2, 0,187, 2, 2, 0,206, 2, 2, 0, 92, 0, 11, 0,207, 2, - 11, 0,208, 2,113, 0, 5, 0,110, 0,199, 2, 27, 0,168, 0, 0, 0, 19, 0, 7, 0,209, 2, 0, 0, 94, 0,114, 0, 5, 0, -110, 0,199, 2, 27, 0,168, 0, 0, 0, 19, 0, 2, 0,210, 2, 0, 0,211, 2,115, 0, 5, 0,110, 0,199, 2, 7, 0, 89, 0, - 7, 0,212, 2, 4, 0,213, 2, 4, 0,214, 2,116, 0, 5, 0,110, 0,199, 2, 27, 0,215, 2, 0, 0, 70, 0, 4, 0, 87, 1, - 4, 0, 18, 0,117, 0, 13, 0,110, 0,199, 2, 27, 0,216, 2, 27, 0,217, 2, 27, 0,218, 2, 27, 0,219, 2, 7, 0,220, 2, - 7, 0,221, 2, 7, 0,212, 2, 7, 0,222, 2, 4, 0,223, 2, 4, 0,224, 2, 4, 0, 92, 0, 4, 0,225, 2,118, 0, 5, 0, -110, 0,199, 2, 2, 0,226, 2, 2, 0, 18, 0, 7, 0,227, 2, 27, 0,228, 2,119, 0, 3, 0,110, 0,199, 2, 7, 0,229, 2, - 4, 0, 92, 0,120, 0, 10, 0,110, 0,199, 2, 7, 0,230, 2, 4, 0,231, 2, 4, 0, 27, 0, 2, 0, 92, 0, 2, 0,232, 2, - 2, 0,233, 2, 2, 0,234, 2, 7, 0,235, 2, 0, 0,236, 2,121, 0, 3, 0,110, 0,199, 2, 7, 0, 27, 0, 4, 0, 16, 0, -122, 0, 6, 0,110, 0,199, 2,123, 0,237, 2,124, 0,238, 2,125, 0,239, 2, 7, 0,240, 2, 4, 0, 16, 0,126, 0, 11, 0, -110, 0,199, 2, 47, 0,200, 2, 27, 0,201, 2, 0, 0,202, 2, 4, 0,203, 2, 4, 0,204, 2, 7, 0,209, 2, 4, 0,241, 2, - 0, 0,236, 2, 7, 0,242, 2, 4, 0, 27, 0,127, 0, 12, 0,110, 0,199, 2, 27, 0,243, 2, 42, 0,244, 2, 4, 0, 92, 0, - 4, 0,245, 2, 7, 0,246, 2, 7, 0,247, 2, 7, 0,248, 2, 7, 0,249, 2, 0, 0,202, 2, 4, 0,203, 2, 4, 0, 27, 0, -128, 0, 3, 0,110, 0,199, 2, 7, 0,250, 2, 4, 0,251, 2,129, 0, 5, 0,110, 0,199, 2, 7, 0,252, 2, 0, 0,236, 2, - 2, 0, 18, 0, 2, 0,253, 2,130, 0, 8, 0,110, 0,199, 2, 27, 0,168, 0, 7, 0,252, 2, 7, 0,255, 0, 7, 0,108, 0, - 0, 0,236, 2, 2, 0, 18, 0, 2, 0, 16, 0,131, 0, 21, 0,110, 0,199, 2, 47, 0,200, 2, 27, 0,201, 2, 0, 0,202, 2, - 4, 0,203, 2, 4, 0,204, 2, 27, 0,254, 2, 0, 0,236, 2, 2, 0, 18, 0, 2, 0, 27, 0, 7, 0,255, 2, 7, 0, 0, 3, - 7, 0, 1, 3, 7, 0, 81, 2, 7, 0, 2, 3, 7, 0, 3, 3, 7, 0, 4, 3, 7, 0, 5, 3, 7, 0, 6, 3, 7, 0, 7, 3, - 7, 0, 91, 0,132, 0, 7, 0,110, 0,199, 2, 2, 0, 8, 3, 2, 0, 9, 3, 4, 0, 30, 0, 27, 0,168, 0, 7, 0, 10, 3, - 0, 0,236, 2,133, 0, 10, 0,110, 0,199, 2, 27, 0,168, 0, 0, 0, 11, 3, 7, 0, 12, 3, 7, 0, 13, 3, 7, 0, 5, 3, - 4, 0, 14, 3, 4, 0, 15, 3, 7, 0, 16, 3, 0, 0, 19, 0,134, 0, 1, 0,110, 0,199, 2,135, 0, 7, 0,110, 0,199, 2, - 41, 0,125, 0,136, 0, 17, 3,137, 0, 18, 3,138, 0, 19, 3,139, 0, 20, 3, 14, 0, 21, 3,140, 0, 13, 0,110, 0,199, 2, - 88, 0, 22, 3, 88, 0, 23, 3, 88, 0, 24, 3, 88, 0, 25, 3, 88, 0, 26, 3, 88, 0, 27, 3, 85, 0, 28, 3, 4, 0, 29, 3, - 4, 0, 30, 3, 7, 0, 31, 3, 7, 0, 32, 3,141, 0, 33, 3,142, 0, 7, 0,110, 0,199, 2, 88, 0, 22, 3, 88, 0, 34, 3, -143, 0, 35, 3,144, 0, 33, 3, 4, 0, 36, 3, 4, 0, 29, 3,145, 0, 4, 0,110, 0,199, 2, 27, 0,168, 0, 4, 0, 37, 3, - 4, 0, 27, 0,146, 0, 2, 0, 4, 0, 38, 3, 7, 0, 39, 2,147, 0, 2, 0, 4, 0,128, 0, 4, 0, 39, 3,148, 0, 24, 0, -110, 0,199, 2, 27, 0,168, 0, 0, 0,236, 2, 2, 0, 40, 3, 2, 0, 18, 0, 2, 0, 87, 1, 2, 0, 27, 0,146, 0, 41, 3, - 4, 0, 42, 3, 7, 0, 43, 3, 4, 0, 53, 0, 4, 0, 44, 3,147, 0, 45, 3,146, 0, 46, 3, 4, 0, 47, 3, 4, 0, 48, 3, - 4, 0, 49, 3, 4, 0, 39, 3, 7, 0, 50, 3, 7, 0, 51, 3, 7, 0, 52, 3, 7, 0, 53, 3, 7, 0, 54, 3, 11, 0, 55, 3, -149, 0, 8, 0,110, 0,199, 2,150, 0, 56, 3,143, 0, 35, 3, 4, 0, 57, 3, 4, 0, 58, 3, 4, 0, 59, 3, 2, 0, 18, 0, - 2, 0, 56, 0,151, 0, 8, 0,110, 0,199, 2, 27, 0, 44, 0, 2, 0, 3, 1, 2, 0, 18, 0, 2, 0,226, 2, 2, 0, 56, 0, - 7, 0, 60, 3, 7, 0, 61, 3,152, 0, 6, 0,110, 0,199, 2, 4, 0, 62, 3, 2, 0, 18, 0, 2, 0, 63, 3, 7, 0, 64, 3, - 0, 0,170, 0,153, 0, 8, 0,110, 0,199, 2, 0, 0, 65, 3, 0, 0, 66, 3, 0, 0,193, 2, 0, 0, 67, 3, 0, 0, 68, 3, - 0, 0, 92, 0, 0, 0,181, 2,154, 0, 3, 0,110, 0,199, 2,155, 0, 69, 3,139, 0, 20, 3,156, 0, 10, 0,110, 0,199, 2, - 27, 0, 70, 3, 27, 0, 71, 3, 0, 0, 72, 3, 7, 0, 73, 3, 2, 0, 74, 3, 2, 0, 75, 3, 0, 0, 76, 3, 0, 0, 77, 3, - 0, 0,211, 2,157, 0, 9, 0,110, 0,199, 2, 27, 0, 78, 3, 0, 0, 72, 3, 7, 0, 79, 3, 7, 0, 80, 3, 0, 0, 87, 1, - 0, 0,226, 2, 0, 0, 81, 3, 0, 0, 27, 0,158, 0, 1, 0,110, 0,199, 2,159, 0, 11, 0,110, 0,199, 2, 0, 0,236, 2, - 7, 0,128, 0, 7, 0, 82, 3, 7, 0, 83, 3, 7, 0, 84, 3, 7, 0, 85, 3, 7, 0, 86, 3, 4, 0, 18, 0, 2, 0, 87, 3, - 2, 0, 88, 3,160, 0, 9, 0,110, 0,199, 2, 27, 0, 89, 3, 4, 0, 90, 3, 4, 0, 91, 3, 4, 0, 92, 3, 7, 0, 93, 3, - 7, 0, 94, 3, 2, 0,226, 2, 2, 0, 18, 0,161, 0, 29, 0,110, 0,199, 2,162, 0, 95, 3,163, 0, 96, 3, 4, 0, 97, 3, - 4, 0, 98, 3, 7, 0, 99, 3, 7, 0, 4, 3, 7, 0,100, 3, 7, 0,250, 0, 7, 0,101, 3, 7, 0,102, 3, 7, 0,103, 3, - 7, 0,104, 3, 7, 0,105, 3, 7, 0,240, 2, 4, 0,106, 3, 4, 0,107, 3, 0, 0,108, 3, 0, 0,109, 3, 0, 0,110, 3, - 0, 0,111, 3, 0, 0, 18, 0, 0, 0,112, 3, 2, 0,113, 3, 2, 0,114, 3, 4, 0,214, 2, 7, 0,108, 0, 7, 0,115, 3, - 4, 0, 27, 0,164, 0, 15, 0,110, 0,199, 2, 47, 0,200, 2, 27, 0,201, 2, 0, 0,202, 2, 4, 0,203, 2, 4, 0,204, 2, - 27, 0,116, 3, 27, 0,117, 3, 54, 0,100, 1, 0, 0,236, 2, 7, 0,209, 2, 7, 0,118, 3, 0, 0, 18, 0, 0, 0,253, 0, - 0, 0,211, 2,165, 0, 16, 0,110, 0,199, 2, 0, 0,236, 2, 2, 0,119, 3, 2, 0,253, 0, 7, 0,120, 3, 54, 0,121, 3, - 7, 0,122, 3, 7, 0,123, 3, 7, 0,124, 3, 0, 0,125, 3, 4, 0,126, 3, 47, 0,127, 3, 27, 0,128, 3, 4, 0,129, 3, - 0, 0,130, 3, 4, 0,131, 3,166, 0, 16, 0,110, 0,199, 2, 0, 0,132, 3, 0, 0,133, 3, 7, 0,134, 3, 7, 0,135, 3, - 0, 0,136, 3, 0, 0,137, 3, 0, 0,138, 3, 7, 0,124, 3, 0, 0,125, 3, 4, 0,126, 3, 47, 0,127, 3, 27, 0,128, 3, - 4, 0,129, 3, 0, 0,130, 3, 4, 0,131, 3,167, 0, 16, 0,110, 0,199, 2, 0, 0,236, 2, 4, 0,139, 3, 4, 0,140, 3, - 27, 0,141, 3, 7, 0,124, 3, 0, 0,125, 3, 4, 0,126, 3, 47, 0,127, 3, 27, 0,128, 3, 4, 0,129, 3, 0, 0,130, 3, - 7, 0,142, 3, 7, 0,143, 3, 2, 0,253, 0, 2, 0,144, 3,168, 0, 5, 0,110, 0,199, 2,169, 0,145, 3,170, 0,146, 3, - 4, 0, 16, 0, 4, 0, 27, 0,171, 0, 8, 0,110, 0,199, 2, 7, 0,147, 3, 7, 0,148, 3, 7, 0,149, 3, 0, 0,250, 0, - 0, 0, 18, 0, 0, 0, 87, 1, 0, 0, 27, 0,172, 0, 3, 0,173, 0,150, 3, 4, 0, 66, 2, 0, 0, 94, 0,173, 0, 29, 0, - 22, 0, 32, 0, 34, 0, 75, 0, 2, 0, 48, 2, 2, 0, 49, 2, 2, 0,151, 3, 2, 0, 18, 0, 2, 0,152, 3, 2, 0,153, 3, - 2, 0,154, 3, 2, 0, 30, 0, 0, 0,155, 3, 0, 0,156, 3, 0, 0,157, 3, 0, 0, 74, 0, 4, 0, 27, 0, 7, 0,158, 3, - 7, 0,159, 3, 7, 0,160, 3, 7, 0,161, 3, 7, 0,162, 3, 7, 0,163, 3, 29, 0,164, 3, 31, 0, 80, 0, 33, 0, 73, 2, - 90, 0,126, 2, 0, 0, 70, 0, 7, 0,165, 3, 7, 0,166, 3,172, 0,167, 3,174, 0, 5, 0,174, 0, 0, 0,174, 0, 1, 0, - 0, 0, 19, 0, 0, 0, 18, 0, 0, 0,124, 0, 68, 0, 3, 0, 7, 0,168, 3, 4, 0, 18, 0, 4, 0, 27, 0, 27, 0,128, 0, - 22, 0, 32, 0, 34, 0, 75, 0,175, 0,169, 3, 2, 0, 16, 0, 2, 0,170, 3, 4, 0,171, 3, 4, 0,172, 3, 4, 0,173, 3, - 0, 0,174, 3, 27, 0, 38, 0, 27, 0,175, 3, 27, 0,176, 3, 27, 0,177, 3, 27, 0,178, 3, 31, 0, 80, 0, 68, 0, 15, 2, -176, 0,179, 3,176, 0,180, 3,177, 0,181, 3, 11, 0, 2, 0,178, 0,182, 3,179, 0,183, 3,180, 0,184, 3, 14, 0,185, 3, - 14, 0,186, 3, 14, 0, 28, 2, 14, 0,187, 3, 14, 0,188, 3, 4, 0, 87, 1, 4, 0,189, 3, 63, 0, 30, 2, 0, 0,190, 3, - 4, 0, 32, 2, 4, 0,191, 3, 7, 0, 77, 1, 7, 0,192, 3, 7, 0,193, 3, 7, 0,176, 0, 7, 0,194, 3, 7, 0,195, 3, - 7, 0, 78, 1, 7, 0,196, 3, 7, 0, 18, 2, 7, 0,197, 3, 7, 0,198, 3, 7, 0,199, 3, 7, 0,200, 3, 7, 0,201, 3, - 7, 0,202, 3, 7, 0, 12, 3, 7, 0,203, 3, 7, 0,244, 0, 7, 0,204, 3, 4, 0,205, 3, 4, 0,206, 3, 2, 0, 18, 0, - 2, 0,207, 3, 2, 0,208, 3, 2, 0,209, 3, 2, 0,210, 3, 2, 0,211, 3, 2, 0,212, 3, 2, 0,213, 3, 2, 0,214, 3, - 0, 0,215, 3, 0, 0,216, 3, 4, 0,217, 3, 4, 0,218, 3, 4, 0,219, 3, 4, 0,220, 3, 7, 0,221, 3, 7, 0,108, 2, - 7, 0,222, 3, 7, 0,223, 3, 7, 0,224, 3, 7, 0,225, 3, 7, 0,226, 3, 7, 0,220, 0, 7, 0,227, 3, 7, 0,228, 3, - 7, 0,229, 3, 7, 0,230, 3, 7, 0,231, 3, 2, 0,232, 3, 0, 0,233, 3, 0, 0,234, 3, 0, 0,235, 3, 0, 0,236, 3, - 0, 0,110, 0, 0, 0,237, 3, 7, 0,238, 3, 7, 0,239, 3, 14, 0,240, 3, 14, 0,241, 3, 14, 0,242, 3, 14, 0,243, 3, - 7, 0,244, 3, 2, 0, 13, 2, 2, 0,245, 3, 7, 0,151, 2, 4, 0,246, 3, 4, 0,247, 3,181, 0,248, 3, 2, 0,249, 3, - 2, 0,251, 0, 7, 0,250, 3, 14, 0,251, 3, 14, 0,252, 3, 14, 0,253, 3, 14, 0,254, 3,182, 0, 73, 1,183, 0,255, 3, - 64, 0, 0, 4, 0, 0, 1, 4, 0, 0, 2, 4, 2, 0, 66, 2, 7, 0,143, 2,155, 0, 3, 4,143, 0, 4, 4,143, 0, 5, 4, - 10, 0, 6, 4, 10, 0, 7, 4, 4, 0, 8, 4, 4, 0, 9, 4, 14, 0, 10, 4, 14, 0, 11, 4, 14, 0, 12, 4, 7, 0, 13, 4, -184, 0, 14, 0,184, 0, 0, 0,184, 0, 1, 0, 27, 0, 38, 0, 7, 0, 12, 3, 7, 0, 79, 1, 7, 0, 13, 3, 7, 0, 5, 3, - 0, 0, 19, 0, 4, 0, 14, 3, 4, 0, 15, 3, 4, 0, 14, 4, 2, 0, 16, 0, 2, 0, 15, 4, 7, 0, 16, 3,185, 0, 12, 0, -185, 0, 0, 0,185, 0, 1, 0, 27, 0, 44, 0, 4, 0, 16, 4, 4, 0, 13, 2, 7, 0, 79, 1, 7, 0, 17, 4, 7, 0, 18, 4, - 7, 0,170, 2, 2, 0, 16, 0, 0, 0, 19, 4, 0, 0, 20, 4,182, 0, 40, 0, 4, 0, 18, 0, 2, 0, 21, 4, 2, 0, 22, 4, - 2, 0, 5, 3, 2, 0, 23, 4, 2, 0, 24, 4, 2, 0, 25, 4, 2, 0, 26, 4, 2, 0, 27, 4, 7, 0, 28, 4, 7, 0, 29, 4, - 7, 0, 30, 4, 7, 0, 31, 4, 7, 0, 32, 4, 7, 0, 33, 4, 7, 0, 34, 4, 7, 0, 35, 4, 7, 0, 36, 4, 7, 0, 37, 4, - 7, 0, 38, 4, 7, 0, 39, 4, 7, 0, 40, 4, 7, 0, 41, 4, 7, 0, 42, 4, 7, 0, 43, 4, 7, 0, 44, 4, 7, 0, 45, 4, - 7, 0, 46, 4, 7, 0, 47, 4, 7, 0, 48, 4, 7, 0, 49, 4, 7, 0, 50, 4, 7, 0, 51, 4, 7, 0, 52, 4, 7, 0, 53, 4, - 7, 0, 54, 4, 47, 0,169, 0,186, 0, 55, 4, 7, 0, 56, 4, 4, 0,214, 2,187, 0, 5, 0, 64, 0,249, 1, 7, 0, 57, 4, - 7, 0, 58, 4, 2, 0, 18, 0, 2, 0, 59, 4,188, 0, 5, 0,188, 0, 0, 0,188, 0, 1, 0, 4, 0, 16, 0, 4, 0, 60, 4, - 11, 0, 2, 0,189, 0, 9, 0,189, 0, 0, 0,189, 0, 1, 0, 4, 0, 61, 4, 4, 0, 62, 4, 4, 0, 63, 4, 4, 0, 18, 0, - 11, 0, 64, 4, 11, 0, 65, 4, 14, 0, 66, 4,139, 0, 23, 0,139, 0, 0, 0,139, 0, 1, 0, 4, 0, 18, 0, 4, 0, 67, 4, - 4, 0, 68, 4, 4, 0, 69, 4, 4, 0, 70, 4, 4, 0, 71, 4, 4, 0, 72, 4, 4, 0, 73, 4, 4, 0, 27, 0, 4, 0, 62, 4, - 4, 0, 13, 2, 2, 0, 74, 4, 2, 0, 56, 0, 0, 0, 19, 0, 0, 0, 75, 4, 0, 0, 76, 4, 0, 0, 77, 4, 0, 0, 78, 4, - 14, 0, 79, 4,190, 0, 80, 4, 11, 0, 81, 4,191, 0, 1, 0, 7, 0, 46, 2,181, 0, 30, 0, 4, 0, 18, 0, 7, 0, 82, 4, - 7, 0, 83, 4, 7, 0, 84, 4, 4, 0, 85, 4, 4, 0, 86, 4, 4, 0, 87, 4, 4, 0, 88, 4, 7, 0, 89, 4, 7, 0, 90, 4, - 7, 0, 91, 4, 7, 0, 92, 4, 7, 0, 93, 4, 7, 0, 94, 4, 7, 0, 95, 4, 7, 0, 96, 4, 7, 0, 97, 4, 7, 0, 98, 4, - 7, 0, 99, 4, 7, 0,100, 4, 7, 0,101, 4, 7, 0,102, 4, 7, 0,103, 4, 7, 0,104, 4, 7, 0,105, 4, 7, 0,106, 4, - 4, 0,107, 4, 4, 0,108, 4, 7, 0,109, 4, 7, 0,227, 3,183, 0, 54, 0, 4, 0, 62, 4, 4, 0,110, 4,192, 0,111, 4, -193, 0,112, 4, 0, 0, 27, 0, 0, 0,113, 4, 2, 0,114, 4, 7, 0,115, 4, 0, 0,116, 4, 7, 0,117, 4, 7, 0,118, 4, - 7, 0,119, 4, 7, 0,120, 4, 7, 0,121, 4, 7, 0,122, 4, 7, 0,123, 4, 7, 0,124, 4, 7, 0,125, 4, 2, 0,126, 4, - 0, 0,127, 4, 2, 0,128, 4, 7, 0,129, 4, 7, 0,130, 4, 0, 0,131, 4, 4, 0,129, 0, 4, 0,132, 4, 4, 0,133, 4, - 2, 0,134, 4, 2, 0,135, 4,191, 0,136, 4, 4, 0,137, 4, 4, 0, 82, 0, 7, 0,138, 4, 7, 0,139, 4, 7, 0,140, 4, - 7, 0,141, 4, 2, 0,142, 4, 2, 0,143, 4, 2, 0,144, 4, 2, 0,145, 4, 2, 0,146, 4, 2, 0,147, 4, 2, 0,148, 4, - 2, 0,149, 4,194, 0,150, 4, 7, 0,151, 4, 7, 0,152, 4,139, 0,153, 4, 14, 0, 21, 3,187, 0,154, 4, 7, 0,155, 4, - 7, 0,156, 4, 7, 0,157, 4, 4, 0,158, 4,195, 0, 1, 0, 7, 0,159, 4,155, 0, 52, 0,154, 0,160, 4, 2, 0, 16, 0, - 2, 0,161, 4, 2, 0,162, 4, 2, 0,163, 4, 7, 0,164, 4, 2, 0,165, 4, 2, 0,166, 4, 7, 0,167, 4, 2, 0,168, 4, - 2, 0,169, 4, 7, 0,170, 4, 7, 0,171, 4, 7, 0,172, 4, 4, 0,173, 4, 4, 0,174, 4, 4, 0,175, 4, 4, 0, 27, 0, - 7, 0,176, 4, 4, 0,177, 4, 7, 0,178, 4, 7, 0,179, 4, 7, 0,180, 4, 79, 0,181, 4, 79, 0,182, 4, 0, 0,183, 4, - 7, 0,184, 4, 7, 0,185, 4, 31, 0, 80, 0, 2, 0,186, 4, 0, 0,187, 4, 0, 0,188, 4, 7, 0,189, 4, 4, 0,190, 4, - 7, 0,191, 4, 7, 0,192, 4, 4, 0,193, 4, 4, 0, 18, 0, 7, 0,194, 4, 7, 0,195, 4, 7, 0,196, 4,195, 0,197, 4, - 4, 0, 53, 0, 7, 0,198, 4, 7, 0,199, 4, 7, 0,200, 4, 7, 0,201, 4, 7, 0,202, 4, 7, 0,203, 4, 7, 0,204, 4, - 4, 0,205, 4, 7, 0,206, 4,196, 0, 78, 0, 22, 0, 32, 0, 34, 0, 75, 0, 2, 0,179, 0, 2, 0, 88, 1, 2, 0,122, 1, - 2, 0,207, 4, 7, 0,208, 4, 7, 0,209, 4, 7, 0,210, 4, 7, 0,211, 4, 7, 0,212, 4, 7, 0,213, 4, 7, 0,170, 1, - 7, 0,172, 1, 7, 0,171, 1, 7, 0, 30, 0, 4, 0,214, 4, 7, 0,215, 4, 7, 0,216, 4, 7, 0,217, 4, 7, 0,218, 4, - 7, 0,219, 4, 7, 0,220, 4, 7, 0,221, 4, 2, 0,222, 4, 2, 0, 87, 1, 2, 0,223, 4, 2, 0,224, 4, 2, 0,225, 4, - 2, 0,226, 4, 2, 0,227, 4, 2, 0,228, 4, 7, 0,229, 4, 7, 0,230, 4, 7, 0,231, 4, 7, 0,232, 4, 7, 0,233, 4, - 7, 0,234, 4, 7, 0,235, 4, 7, 0,236, 4, 7, 0,237, 4, 7, 0,238, 4, 7, 0,239, 4, 7, 0,240, 4, 2, 0,241, 4, - 2, 0,242, 4, 2, 0,243, 4, 2, 0,244, 4, 7, 0,245, 4, 7, 0,246, 4, 7, 0,247, 4, 7, 0,248, 4, 2, 0,249, 4, - 2, 0,250, 4, 2, 0,251, 4, 2, 0,252, 4, 7, 0,253, 4, 7, 0,254, 4, 7, 0,255, 4, 7, 0, 0, 5, 7, 0, 1, 5, - 7, 0, 2, 5, 7, 0, 3, 5, 2, 0, 4, 5, 2, 0, 5, 5, 2, 0, 6, 5, 2, 0, 7, 5, 2, 0, 8, 5, 2, 0, 18, 0, - 7, 0, 9, 5, 7, 0, 10, 5, 31, 0, 80, 0, 46, 0,140, 1, 2, 0,141, 1, 2, 0, 76, 1, 2, 0,181, 2, 25, 0,154, 0, - 57, 0, 70, 1,197, 0, 8, 0,197, 0, 0, 0,197, 0, 1, 0, 4, 0,205, 3, 4, 0, 11, 5, 4, 0, 18, 0, 2, 0, 12, 5, - 2, 0, 13, 5, 27, 0,168, 0,198, 0, 13, 0, 11, 0, 14, 5, 11, 0, 15, 5, 4, 0, 16, 5, 4, 0, 17, 5, 4, 0, 18, 5, - 4, 0, 19, 5, 4, 0, 20, 5, 4, 0, 21, 5, 4, 0, 22, 5, 4, 0, 23, 5, 4, 0, 24, 5, 4, 0, 27, 0, 0, 0, 25, 5, -199, 0, 5, 0, 11, 0, 26, 5, 11, 0, 27, 5, 4, 0, 28, 5, 4, 0, 30, 0, 0, 0, 29, 5,200, 0, 17, 0, 4, 0, 30, 5, - 4, 0, 31, 5, 4, 0, 32, 5, 4, 0, 33, 5, 4, 0, 34, 5, 4, 0, 35, 5, 4, 0, 36, 5, 4, 0, 37, 5, 4, 0, 38, 5, - 4, 0, 39, 5, 4, 0, 40, 5, 4, 0, 41, 5, 2, 0, 42, 5, 2, 0, 43, 5, 4, 0, 44, 5, 4, 0, 45, 5, 4, 0, 91, 0, -201, 0, 17, 0, 4, 0, 16, 0, 4, 0, 32, 5, 4, 0, 46, 5, 4, 0, 47, 5, 4, 0, 48, 5, 4, 0, 49, 5, 4, 0, 50, 5, - 4, 0, 51, 5, 7, 0, 52, 5, 4, 0, 53, 5, 4, 0, 92, 0, 4, 0, 54, 5, 4, 0, 55, 5, 4, 0, 56, 5, 4, 0, 57, 5, - 4, 0, 58, 5, 21, 0, 31, 0,202, 0, 9, 0, 4, 0, 59, 5, 7, 0, 60, 5, 7, 0, 61, 5, 7, 0, 62, 5, 4, 0, 63, 5, - 2, 0, 18, 0, 2, 0, 27, 0, 7, 0, 84, 4, 7, 0, 30, 0,203, 0, 11, 0,203, 0, 0, 0,203, 0, 1, 0, 0, 0, 19, 0, - 63, 0, 64, 5, 64, 0, 65, 5, 4, 0,205, 3, 4, 0, 66, 5, 4, 0, 67, 5, 4, 0, 27, 0, 4, 0, 68, 5, 4, 0, 69, 5, -204, 0, 13, 0, 0, 0, 70, 5, 0, 0,250, 0, 0, 0, 71, 5, 0, 0, 18, 0, 0, 0, 72, 5, 0, 0, 73, 5, 0, 0, 74, 5, - 0, 0, 75, 5, 2, 0, 76, 5, 2, 0, 77, 5, 7, 0, 78, 5, 0, 0, 79, 5, 0, 0,124, 0,205, 0,106, 0,204, 0, 80, 5, -198, 0, 81, 5,199, 0, 82, 5,200, 0, 83, 5,201, 0, 84, 5, 4, 0, 36, 3, 4, 0,129, 0, 4, 0,132, 4, 7, 0, 85, 5, - 4, 0, 86, 5, 4, 0, 87, 5, 4, 0, 88, 5, 4, 0, 89, 5, 2, 0, 18, 0, 2, 0, 90, 5, 7, 0, 91, 5, 7, 0, 92, 5, - 7, 0, 93, 5, 7, 0, 94, 5, 7, 0, 95, 5, 2, 0, 96, 5, 2, 0, 97, 5, 2, 0, 98, 5, 2, 0, 99, 5, 2, 0,250, 0, - 2, 0,100, 5, 4, 0,101, 5, 2, 0,102, 5, 2, 0,103, 5, 2, 0,109, 1, 2, 0,108, 0, 2, 0,104, 5, 2, 0,105, 5, - 2, 0,106, 5, 2, 0,107, 5, 2, 0,108, 5, 2, 0, 71, 5, 2, 0, 70, 5, 2, 0,109, 5, 2, 0, 72, 5, 2, 0,110, 5, - 4, 0,111, 5, 4, 0, 87, 1, 4, 0,112, 5, 2, 0,113, 5, 2, 0, 91, 0, 2, 0,114, 5, 2, 0,115, 5, 2, 0,116, 5, - 2, 0,117, 5, 2, 0,118, 5, 2, 0,119, 5, 19, 0,120, 5, 19, 0,121, 5, 18, 0,122, 5, 14, 0,123, 5, 2, 0,124, 5, - 2, 0,125, 5, 7, 0,126, 5, 7, 0,127, 5, 7, 0,128, 5, 7, 0,129, 5, 4, 0,130, 5, 7, 0,131, 5, 7, 0,132, 5, - 7, 0,133, 5, 7, 0,134, 5, 2, 0,135, 5, 2, 0,136, 5, 2, 0,137, 5, 2, 0,138, 5, 2, 0,139, 5, 2, 0,140, 5, - 7, 0,141, 5, 7, 0,142, 5, 7, 0,143, 5, 0, 0,144, 5, 4, 0,145, 5, 2, 0,146, 5, 2, 0, 74, 0, 0, 0,147, 5, - 7, 0,148, 5, 7, 0,149, 5, 0, 0,150, 5, 0, 0,151, 5, 0, 0,152, 5, 0, 0,153, 5, 4, 0,154, 5, 2, 0,155, 5, - 2, 0,156, 5, 7, 0,157, 5, 7, 0,158, 5, 2, 0,159, 5, 2, 0,160, 5, 7, 0,161, 5, 2, 0,162, 5, 2, 0,163, 5, - 4, 0,164, 5, 2, 0,165, 5, 2, 0,166, 5, 2, 0,167, 5, 2, 0,168, 5, 7, 0,169, 5, 7, 0, 30, 0, 37, 0,170, 5, - 0, 0,171, 5,206, 0, 9, 0,206, 0, 0, 0,206, 0, 1, 0, 0, 0,172, 5, 2, 0,173, 5, 2, 0,174, 5, 2, 0,175, 5, - 2, 0, 91, 0, 7, 0,176, 5, 7, 0, 30, 0,207, 0, 7, 0, 2, 0,231, 2, 2, 0, 87, 1, 2, 0, 94, 3, 2, 0,177, 5, - 7, 0,178, 5, 7, 0, 30, 0, 37, 0,179, 5,208, 0, 5, 0, 7, 0,180, 5, 0, 0, 16, 0, 0, 0, 91, 0, 0, 0, 30, 0, - 0, 0, 74, 0,209, 0, 15, 0, 7, 0,181, 5, 7, 0,182, 5, 7, 0,183, 5, 7, 0,184, 5, 7, 0,185, 5, 7, 0,186, 5, - 7, 0,187, 5, 7, 0,188, 5, 7, 0,189, 5, 7, 0,190, 5, 4, 0,191, 5, 7, 0,192, 5, 7, 0,193, 5, 2, 0, 91, 0, - 2, 0, 30, 0,210, 0, 32, 0,208, 0,194, 5, 2, 0,195, 5, 2, 0, 97, 5, 2, 0, 98, 5, 2, 0, 99, 5, 2, 0,250, 0, - 2, 0,100, 5, 2, 0,196, 5, 2, 0,197, 5, 2, 0,198, 5, 2, 0,199, 5,207, 0,200, 5, 2, 0,201, 5, 2, 0,102, 5, - 7, 0,202, 5,209, 0,203, 5, 7, 0,220, 4, 7, 0,221, 4, 4, 0, 18, 0, 2, 0, 87, 1, 2, 0,204, 5, 2, 0,223, 4, - 2, 0,224, 4, 2, 0,205, 5, 2, 0, 27, 0, 2, 0,225, 4, 2, 0,226, 4, 2, 0,227, 4, 2, 0,228, 4, 2, 0,206, 5, - 2, 0, 91, 0, 7, 0,207, 5,211, 0, 6, 0,211, 0, 0, 0,211, 0, 1, 0, 4, 0, 61, 4, 0, 0, 19, 0, 4, 0, 18, 0, - 27, 0,208, 5,212, 0, 4, 0,213, 0,146, 3, 11, 0,209, 5, 0, 0,210, 5, 4, 0, 92, 0,214, 0, 8, 0,212, 0,211, 5, - 2, 0, 18, 0, 2, 0, 27, 0, 2, 0,212, 5, 2, 0,213, 5, 2, 0,214, 5, 4, 0, 91, 0, 11, 0,215, 5,215, 0, 6, 0, - 2, 0,108, 0, 2, 0, 67, 4, 2, 0,216, 5, 2, 0,225, 2, 4, 0, 18, 0, 7, 0,209, 2,216, 0, 14, 0, 2, 0, 18, 0, - 2, 0,217, 5, 2, 0,218, 5, 2, 0,219, 5,215, 0,220, 5, 11, 0,215, 5, 7, 0,221, 5, 7, 0, 56, 0, 4, 0,222, 5, - 4, 0,223, 5, 4, 0,224, 5, 4, 0,225, 5, 41, 0,125, 0, 27, 0,168, 0,217, 0, 14, 0,212, 0,211, 5, 4, 0, 92, 0, - 4, 0,226, 5, 7, 0,227, 5, 7, 0,228, 5, 7, 0,229, 5, 4, 0,230, 5, 4, 0,231, 5, 7, 0,232, 5, 7, 0,233, 5, - 4, 0,234, 5, 7, 0,235, 5, 7, 0,236, 5, 4, 0, 27, 0,218, 0, 1, 0,212, 0,211, 5,219, 0, 7, 0,212, 0,211, 5, - 2, 0, 18, 0, 2, 0, 27, 0, 4, 0, 37, 0, 4, 0,237, 5, 90, 0,238, 5, 11, 0,215, 5,220, 0, 5, 0,220, 0, 0, 0, -220, 0, 1, 0, 0, 0, 19, 0, 7, 0,239, 5, 4, 0, 27, 0,221, 0, 4, 0, 4, 0,108, 0, 7, 0,240, 5, 7, 0,178, 1, - 4, 0, 18, 0,222, 0, 85, 0,219, 0,241, 5,219, 0,242, 5,217, 0,169, 3,218, 0,243, 5, 7, 0,244, 5, 2, 0,245, 5, - 2, 0,246, 5, 7, 0,247, 5, 7, 0,248, 5, 2, 0, 67, 4, 2, 0,249, 5, 7, 0,250, 5, 7, 0,251, 5, 7, 0,252, 5, - 2, 0,253, 5, 2, 0,222, 5, 2, 0,254, 5, 2, 0,255, 5, 2, 0, 0, 6, 2, 0, 1, 6, 7, 0, 2, 6, 7, 0, 3, 6, - 7, 0, 4, 6, 2, 0, 5, 6, 2, 0, 6, 6, 2, 0, 7, 6, 2, 0, 8, 6, 2, 0, 9, 6, 2, 0, 10, 6, 2, 0, 11, 6, - 2, 0, 12, 6,214, 0, 13, 6,216, 0, 14, 6, 7, 0, 15, 6, 7, 0, 16, 6, 7, 0, 17, 6, 2, 0, 18, 6, 2, 0, 19, 6, - 0, 0, 20, 6, 0, 0, 21, 6, 2, 0, 22, 6, 7, 0, 23, 6, 7, 0, 24, 6, 7, 0, 25, 6, 7, 0, 26, 6, 7, 0, 27, 6, - 7, 0, 28, 6, 7, 0, 29, 6, 7, 0, 30, 6, 7, 0, 31, 6, 7, 0, 32, 6, 2, 0, 33, 6, 0, 0, 34, 6, 0, 0, 35, 6, - 0, 0, 36, 6, 0, 0, 37, 6, 27, 0, 38, 6, 0, 0, 39, 6, 0, 0, 40, 6, 0, 0, 41, 6, 0, 0, 42, 6, 0, 0, 43, 6, - 0, 0, 44, 6, 0, 0, 45, 6, 0, 0, 46, 6, 0, 0, 47, 6, 0, 0, 48, 6, 2, 0, 49, 6, 2, 0, 50, 6, 2, 0, 51, 6, - 2, 0, 52, 6, 0, 0, 53, 6, 0, 0, 54, 6, 0, 0, 55, 6, 0, 0, 56, 6, 4, 0, 57, 6, 4, 0, 58, 6, 4, 0, 59, 6, - 4, 0, 60, 6, 2, 0, 61, 6, 2, 0, 91, 0, 4, 0, 62, 6, 7, 0, 63, 6, 7, 0, 64, 6,221, 0, 65, 6,223, 0, 8, 0, - 4, 0, 66, 6, 4, 0, 67, 6, 4, 0, 68, 6, 4, 0, 69, 6, 4, 0, 70, 6, 4, 0, 71, 6, 4, 0, 53, 0, 4, 0,138, 2, -224, 0, 4, 0, 7, 0, 72, 6, 0, 0, 73, 6, 0, 0, 74, 6, 2, 0, 18, 0,225, 0, 4, 0, 7, 0, 75, 6, 4, 0, 18, 0, - 4, 0, 76, 6, 4, 0, 56, 0, 41, 0, 46, 0, 22, 0, 32, 0, 34, 0, 75, 0, 27, 0,208, 5,196, 0, 77, 6, 41, 0, 78, 6, - 14, 0, 79, 6,197, 0, 80, 6, 27, 0, 81, 6, 7, 0, 82, 6, 7, 0, 83, 6, 7, 0, 84, 6, 7, 0, 85, 6, 4, 0,205, 3, - 4, 0, 86, 6, 4, 0, 87, 6, 2, 0, 18, 0, 2, 0, 76, 1, 57, 0, 70, 1,226, 0, 88, 6,222, 0, 89, 6,227, 0, 90, 6, -205, 0,185, 0,202, 0, 91, 6, 14, 0,102, 0, 14, 0, 92, 6, 11, 0, 93, 6, 11, 0, 94, 6, 11, 0, 95, 6, 11, 0, 96, 6, - 11, 0, 97, 6,228, 0, 98, 6, 2, 0, 99, 6, 2, 0,100, 6, 2, 0,251, 0, 2, 0,206, 3, 4, 0,216, 3, 4, 0,101, 6, - 14, 0,102, 6,208, 0,194, 5,210, 0,103, 6,224, 0,104, 6,178, 0,182, 3,225, 0,105, 6,229, 0,106, 6, 10, 0, 7, 4, - 10, 0,107, 6,230, 0, 14, 0,230, 0, 0, 0,230, 0, 1, 0, 42, 0,242, 0, 40, 0, 69, 1,229, 0,106, 6,231, 0,108, 6, - 7, 0, 96, 2, 7, 0, 97, 2, 7, 0,108, 0, 7, 0,109, 6, 2, 0,110, 6, 2, 0, 18, 0, 2, 0,143, 0, 2, 0, 27, 0, -232, 0, 39, 0, 7, 0,111, 6, 7, 0,112, 6, 7, 0,113, 6, 7, 0,114, 6, 7, 0,115, 6, 7, 0,116, 6, 7, 0,117, 6, - 7, 0,118, 6, 7, 0,119, 6, 68, 0,120, 6,178, 0,182, 3,232, 0,121, 6,233, 0,122, 6,234, 0,123, 6,235, 0,124, 6, -236, 0,125, 6,237, 0,126, 6, 7, 0,127, 6, 7, 0,128, 6, 7, 0, 94, 1, 7, 0,129, 6, 7, 0,130, 6, 7, 0,131, 6, - 7, 0,132, 6, 7, 0,175, 0, 7, 0,133, 6, 0, 0,134, 6, 0, 0,135, 6, 0, 0,110, 6, 0, 0,136, 6, 2, 0,137, 6, - 2, 0,138, 6, 7, 0,139, 6, 2, 0,140, 6, 2, 0,141, 6, 7, 0,142, 6, 7, 0,143, 6, 7, 0,144, 6, 7, 0,145, 6, -238, 0, 51, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, 7, 0,128, 6, - 7, 0, 94, 1, 7, 0,150, 6, 2, 0,151, 6, 0, 0,211, 2, 4, 0,152, 6, 2, 0,135, 6, 2, 0,110, 6, 27, 0,208, 5, - 27, 0,153, 6, 14, 0,154, 6,230, 0,155, 6,238, 0,121, 6, 0, 0,156, 6, 4, 0,205, 3, 4, 0, 86, 6, 2, 0,157, 6, - 2, 0,158, 6, 2, 0,159, 6, 2, 0,160, 6, 2, 0, 18, 0, 2, 0, 31, 2, 7, 0,114, 0, 7, 0,161, 6, 7, 0,162, 6, - 7, 0,163, 6, 7, 0,175, 0, 7, 0, 82, 6, 2, 0,164, 6, 2, 0,165, 6, 2, 0,166, 6, 0, 0,167, 6, 0, 0,168, 6, - 0, 0,169, 6, 0, 0,170, 6, 0, 0,171, 6, 14, 0,172, 6, 14, 0,173, 6, 14, 0,174, 6, 2, 0,175, 6, 2, 0,152, 2, - 2, 0,176, 6, 0, 0,177, 6, 11, 0,178, 6,178, 0,182, 3,240, 0, 24, 0, 19, 0, 37, 0, 19, 0, 63, 0, 18, 0,179, 6, - 18, 0,180, 6, 18, 0,181, 6, 7, 0,182, 6, 7, 0,183, 6, 7, 0,184, 6, 7, 0,185, 6, 2, 0,186, 6, 2, 0,187, 6, - 2, 0,188, 6, 2, 0,189, 6, 2, 0,190, 6, 2, 0, 18, 0, 2, 0,191, 6, 2, 0,192, 6, 2, 0,193, 6, 2, 0,194, 6, - 2, 0,195, 6, 2, 0,160, 6, 7, 0,196, 6, 4, 0,197, 6, 4, 0,198, 6,239, 0, 6, 0,239, 0, 0, 0,239, 0, 1, 0, - 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6,241, 0, 8, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, - 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, 0, 0,199, 6, 0, 0,124, 0,242, 0, 14, 0,239, 0, 0, 0,239, 0, 1, 0, - 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6,240, 0,200, 6,243, 0,201, 6, 14, 0,202, 6, 2, 0, 87, 1, - 2, 0,203, 6, 4, 0, 18, 0, 7, 0,204, 6, 4, 0,160, 6,244, 0, 21, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, - 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6,240, 0,200, 6, 2, 0,205, 6, 2, 0,206, 6, 2, 0,207, 6, 2, 0,208, 6, - 2, 0,191, 6, 2, 0,209, 6, 2, 0,210, 6, 0, 0, 18, 0, 0, 0, 27, 0, 11, 0, 72, 2, 4, 0,211, 6, 4, 0,212, 6, - 22, 0,213, 6, 11, 0,214, 6,245, 0, 18, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, - 2, 0,149, 6,240, 0,200, 6, 7, 0, 96, 2, 7, 0, 97, 2, 2, 0,205, 6, 2, 0,215, 6, 2, 0,216, 6, 2, 0,217, 6, - 4, 0, 18, 0, 7, 0,218, 6, 4, 0,110, 6, 4, 0, 27, 0,178, 0,182, 3,246, 0, 16, 0, 0, 0,219, 6, 0, 0,220, 6, - 0, 0,221, 6, 0, 0,222, 6, 0, 0,223, 6, 0, 0,224, 6, 4, 0,225, 6, 4, 0,226, 6, 4, 0,227, 6, 2, 0, 16, 0, - 2, 0, 18, 0, 2, 0,228, 6, 2, 0,229, 6, 2, 0,190, 1, 2, 0,230, 6, 0, 0,231, 6,247, 0, 16, 0,239, 0, 0, 0, -239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 4, 0,232, 6,246, 0,233, 6,248, 0,234, 6, 14, 0,235, 6, 14, 0,236, 6, -249, 0,237, 6,237, 0,238, 6,250, 0,239, 6, 2, 0,240, 6, 2, 0,241, 6, 2, 0,242, 6, 2, 0, 30, 0,251, 0, 15, 0, -239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6,240, 0,200, 6, 14, 0,243, 6, -252, 0,244, 6, 0, 0,245, 6,253, 0,246, 6, 2, 0, 18, 0, 2, 0,247, 6, 2, 0,248, 6, 2, 0,249, 6,254, 0, 25, 0, -239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 4, 0, 18, 0, 42, 0,244, 2, 40, 0, 69, 1, 54, 0,250, 6, -255, 0,251, 6, 0, 1,252, 6,178, 0,182, 3, 7, 0,253, 6, 7, 0, 96, 2, 7, 0, 97, 2, 7, 0,218, 6, 7, 0,254, 6, - 7, 0,255, 6, 2, 0, 0, 7, 2, 0, 27, 0, 2, 0, 1, 7, 2, 0, 2, 7, 0, 0, 3, 7, 0, 0, 4, 7, 0, 0, 5, 7, - 0, 0,160, 6, 1, 1, 11, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, - 2, 0,203, 6, 2, 0, 18, 0, 4, 0, 27, 0,243, 0,201, 6,240, 0,200, 6, 2, 1, 31, 0,239, 0, 0, 0,239, 0, 1, 0, - 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, 37, 0, 6, 7, 4, 0, 7, 7, 4, 0, 8, 7, 2, 0, 92, 0, - 2, 0, 9, 7, 2, 0, 10, 7, 0, 0, 11, 7, 0, 0, 12, 7, 4, 0, 13, 7, 4, 0, 14, 7, 4, 0, 15, 7, 2, 0, 16, 7, - 2, 0, 17, 7, 2, 0, 18, 7, 2, 0, 19, 7, 7, 0, 20, 7, 18, 0, 21, 7, 18, 0, 22, 7, 4, 0, 23, 7, 4, 0, 24, 7, - 0, 0, 25, 7, 0, 0, 26, 7, 2, 0, 27, 7, 0, 0,211, 2, 11, 0, 28, 7, 3, 1, 10, 0, 22, 0, 32, 0, 11, 0, 29, 7, - 11, 0, 30, 7, 11, 0, 31, 7, 11, 0, 32, 7, 11, 0, 33, 7, 4, 0, 92, 0, 4, 0, 34, 7, 0, 0, 35, 7, 0, 0, 36, 7, - 4, 1, 10, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 3, 1, 37, 7, 2, 0, 92, 0, - 2, 0, 9, 7, 4, 0, 91, 0, 11, 0, 38, 7, 5, 1, 3, 0, 5, 1, 0, 0, 5, 1, 1, 0, 7, 0, 39, 7, 6, 1, 9, 0, -239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6,240, 0,200, 6, 14, 0, 40, 7, 4, 0, 41, 7, - 4, 0, 18, 0, 7, 1, 27, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, -240, 0,200, 6, 22, 0, 42, 7, 22, 0, 81, 0, 2, 0, 18, 0, 2, 0, 91, 0, 7, 0, 43, 7, 7, 0, 96, 2, 7, 0, 97, 2, - 7, 0,218, 6, 7, 0, 44, 7, 7, 0, 45, 7, 7, 0, 46, 7, 57, 0, 70, 1, 57, 0, 47, 7, 4, 0, 48, 7, 2, 0, 49, 7, - 2, 0, 50, 7, 2, 0,251, 0, 2, 0, 86, 1, 14, 0, 51, 7,178, 0,182, 3, 8, 1, 10, 0,239, 0, 0, 0,239, 0, 1, 0, - 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, 2, 0, 18, 0, 2, 0,214, 3, 4, 0, 27, 0,178, 0,182, 3, - 9, 1, 7, 0, 9, 1, 0, 0, 9, 1, 1, 0, 4, 0, 52, 7, 4, 0, 22, 0, 0, 0, 85, 0, 4, 0, 53, 7, 4, 0, 16, 0, - 10, 1, 14, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, 4, 0, 10, 7, - 4, 0, 27, 0, 14, 0, 54, 7, 14, 0, 55, 7, 0, 0, 56, 7, 0, 0, 57, 7, 4, 0, 58, 7, 4, 0, 59, 7, 11, 1, 6, 0, -239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 4, 0, 27, 0, 0, 0, 60, 7, 12, 1, 24, 0,239, 0, 0, 0, -239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0, 96, 2, 7, 0, 97, 2, 7, 0, 61, 7, 7, 0, 62, 7, 7, 0,218, 6, -231, 0, 63, 7,229, 0,106, 6, 13, 1,251, 6, 4, 0, 18, 0, 2, 0, 87, 1, 2, 0,110, 6, 4, 0, 64, 7, 7, 0, 65, 7, - 7, 0,148, 3, 7, 0, 94, 3, 4, 0, 27, 0, 7, 0, 66, 7, 7, 0, 67, 7, 4, 0, 68, 7, 4, 0, 69, 7, 14, 1, 7, 0, - 14, 1, 0, 0, 14, 1, 1, 0, 0, 0, 70, 7, 2, 0, 71, 7, 2, 0, 72, 7, 2, 0, 73, 7, 2, 0, 27, 0, 15, 1, 12, 0, - 2, 0, 72, 7, 2, 0, 74, 7, 2, 0, 75, 7, 0, 0,211, 2, 2, 0, 76, 7, 2, 0, 77, 7, 2, 0, 78, 7, 2, 0, 79, 7, - 2, 0, 80, 7, 2, 0,191, 6, 7, 0, 81, 7, 7, 0, 82, 7, 16, 1, 18, 0, 16, 1, 0, 0, 16, 1, 1, 0, 0, 0, 19, 0, - 15, 1, 83, 7, 15, 1, 84, 7, 15, 1, 85, 7, 15, 1, 86, 7, 7, 0, 87, 7, 2, 0, 88, 7, 2, 0, 89, 7, 2, 0, 90, 7, - 2, 0, 91, 7, 2, 0, 92, 7, 2, 0, 93, 7, 2, 0, 94, 7, 2, 0, 95, 7, 2, 0, 96, 7, 2, 0, 27, 0, 17, 1, 10, 0, - 0, 0, 97, 7, 0, 0, 98, 7, 0, 0, 99, 7, 0, 0,100, 7, 0, 0,101, 7, 0, 0,102, 7, 2, 0,103, 7, 2, 0,104, 7, - 2, 0,105, 7, 2, 0,106, 7, 18, 1, 8, 0, 0, 0,107, 7, 0, 0,108, 7, 0, 0,109, 7, 0, 0,110, 7, 0, 0,111, 7, - 0, 0,112, 7, 7, 0,109, 6, 7, 0, 27, 0, 19, 1, 3, 0, 0, 0,113, 7, 2, 0,114, 7, 2, 0, 27, 0, 20, 1, 22, 0, - 17, 1,115, 7, 17, 1,116, 7, 17, 1,117, 7, 17, 1,118, 7, 17, 1,119, 7, 17, 1,120, 7, 17, 1,121, 7, 17, 1,122, 7, - 17, 1,123, 7, 17, 1,124, 7, 17, 1,125, 7, 17, 1,126, 7, 17, 1,127, 7, 17, 1,128, 7, 17, 1,129, 7, 17, 1,130, 7, - 17, 1,131, 7, 18, 1,132, 7, 19, 1,133, 7, 0, 0,134, 7, 7, 0,135, 7, 7, 0, 27, 0, 21, 1,122, 0, 0, 0,136, 7, - 0, 0,137, 7, 0, 0,101, 7, 0, 0,138, 7, 0, 0,113, 7, 0, 0,139, 7, 0, 0,140, 7, 0, 0,141, 7, 0, 0,142, 7, - 0, 0,143, 7, 0, 0,144, 7, 0, 0,145, 7, 0, 0,146, 7, 0, 0,147, 7, 0, 0,148, 7, 0, 0,149, 7, 0, 0,150, 7, - 0, 0,151, 7, 0, 0,152, 7, 0, 0,153, 7, 0, 0,154, 7, 0, 0,155, 7, 0, 0,156, 7, 0, 0,157, 7, 0, 0,158, 7, - 0, 0,159, 7, 0, 0,160, 7, 0, 0,161, 7, 0, 0,162, 7, 0, 0,163, 7, 0, 0,164, 7, 0, 0,165, 7, 0, 0,166, 7, - 0, 0,167, 7, 0, 0,168, 7, 0, 0,169, 7, 0, 0,170, 7, 0, 0,171, 7, 0, 0,172, 7, 0, 0,173, 7, 0, 0,174, 7, - 0, 0,175, 7, 0, 0,176, 7, 0, 0,177, 7, 0, 0,178, 7, 0, 0,179, 7, 0, 0,180, 7, 0, 0,181, 7, 0, 0,182, 7, - 0, 0,183, 7, 0, 0,184, 7, 0, 0,185, 7, 0, 0,186, 7, 0, 0,187, 7, 0, 0,188, 7, 0, 0,189, 7, 0, 0,190, 7, - 0, 0,191, 7, 0, 0,192, 7, 0, 0,193, 7, 0, 0,194, 7, 0, 0,195, 7, 0, 0,196, 7, 0, 0,197, 7, 0, 0,198, 7, - 0, 0,199, 7, 0, 0,200, 7, 0, 0,201, 7, 0, 0,202, 7, 0, 0,203, 7, 0, 0,204, 7, 0, 0,205, 7, 0, 0,206, 7, - 0, 0,207, 7, 0, 0,208, 7, 0, 0,209, 7, 0, 0,210, 7, 0, 0,211, 7, 0, 0,212, 7, 0, 0,213, 7, 0, 0,214, 7, - 0, 0,215, 7, 0, 0,216, 7, 0, 0,217, 7, 0, 0,218, 7, 0, 0,219, 7, 0, 0,220, 7, 0, 0,221, 7, 0, 0,222, 7, - 0, 0,223, 7, 0, 0,224, 7, 0, 0,225, 7, 0, 0,226, 7, 0, 0,227, 7, 0, 0,228, 7, 0, 0,229, 7, 0, 0,230, 7, - 0, 0,231, 7, 0, 0,232, 7, 0, 0,233, 7, 0, 0,234, 7, 0, 0,235, 7, 0, 0,236, 7, 0, 0,237, 7, 0, 0,238, 7, - 0, 0,239, 7, 0, 0,240, 7, 0, 0,241, 7, 0, 0,242, 7, 0, 0,243, 7, 0, 0,244, 7, 0, 0,245, 7, 0, 0,246, 7, - 0, 0,247, 7, 0, 0,248, 7, 0, 0,249, 7, 0, 0,250, 7, 0, 0,251, 7, 0, 0,252, 7, 0, 0,253, 7, 0, 0,254, 7, - 0, 0,255, 7, 22, 1, 5, 0, 0, 0, 0, 8, 0, 0,159, 7, 0, 0,165, 7, 2, 0, 18, 0, 2, 0, 27, 0, 23, 1, 24, 0, - 23, 1, 0, 0, 23, 1, 1, 0, 0, 0,172, 5, 20, 1, 1, 8, 21, 1, 2, 8, 21, 1, 3, 8, 21, 1, 4, 8, 21, 1, 5, 8, - 21, 1, 6, 8, 21, 1, 7, 8, 21, 1, 8, 8, 21, 1, 9, 8, 21, 1, 10, 8, 21, 1, 11, 8, 21, 1, 12, 8, 21, 1, 13, 8, - 21, 1, 14, 8, 21, 1, 15, 8, 21, 1, 16, 8, 21, 1, 17, 8, 21, 1, 18, 8, 22, 1, 19, 8, 4, 0, 20, 8, 4, 0, 27, 0, - 24, 1, 3, 0, 24, 1, 0, 0, 24, 1, 1, 0, 0, 0, 21, 8, 25, 1, 5, 0, 4, 0, 18, 0, 4, 0, 27, 0, 7, 0,151, 2, - 7, 0, 22, 8, 7, 0, 46, 2, 26, 1, 95, 0, 4, 0, 18, 0, 4, 0, 23, 8, 4, 0, 24, 8, 0, 0, 25, 8, 0, 0, 26, 8, - 0, 0, 27, 8, 0, 0, 28, 8, 0, 0, 29, 8, 0, 0, 30, 8, 0, 0, 31, 8, 0, 0, 32, 8, 0, 0, 33, 8, 0, 0, 34, 8, - 4, 0, 35, 8, 2, 0, 36, 8, 2, 0, 37, 8, 2, 0, 38, 8, 2, 0, 39, 8, 4, 0, 40, 8, 4, 0, 41, 8, 4, 0, 42, 8, - 4, 0, 43, 8, 2, 0, 44, 8, 2, 0, 45, 8, 4, 0, 46, 8, 4, 0, 47, 8, 4, 0, 48, 8, 4, 0, 49, 8, 4, 0, 50, 8, - 4, 0, 54, 7, 4, 0, 51, 8, 2, 0, 52, 8, 2, 0, 53, 8, 2, 0, 54, 8, 2, 0, 55, 8, 14, 0, 56, 8, 14, 0, 57, 8, - 14, 0, 58, 8, 14, 0, 59, 8, 14, 0, 60, 8, 14, 0, 61, 8, 0, 0, 62, 8, 2, 0, 63, 8, 2, 0, 64, 8, 2, 0, 65, 8, - 2, 0, 66, 8, 2, 0, 67, 8, 2, 0, 68, 8, 2, 0, 69, 8, 2, 0, 70, 8, 25, 1, 71, 8, 2, 0, 72, 8, 2, 0, 73, 8, - 2, 0, 74, 8, 2, 0, 75, 8, 2, 0, 76, 8, 2, 0, 77, 8, 2, 0, 78, 8, 2, 0, 79, 8, 4, 0, 80, 8, 4, 0, 81, 8, - 2, 0, 82, 8, 2, 0, 83, 8, 2, 0, 84, 8, 2, 0, 85, 8, 2, 0, 86, 8, 2, 0, 87, 8, 2, 0, 88, 8, 2, 0, 89, 8, - 2, 0, 90, 8, 2, 0, 91, 8, 2, 0, 92, 8, 2, 0, 93, 8, 2, 0, 94, 8, 2, 0, 95, 8, 2, 0, 96, 8, 2, 0, 97, 8, - 2, 0, 98, 8, 2, 0, 99, 8, 7, 0,100, 8, 4, 0,101, 8, 7, 0,102, 8, 2, 0, 18, 6, 2, 0, 19, 6, 2, 0,103, 8, - 2, 0,104, 8, 50, 0,105, 8, 7, 0,106, 8, 2, 0,107, 8, 2, 0, 74, 0, 0, 0,108, 8, 4, 0,109, 8, 4, 0,110, 8, - 7, 0,111, 8, 7, 0, 27, 0, 27, 1, 24, 0, 22, 0, 32, 0, 14, 0,112, 8, 14, 0,113, 8, 14, 0,114, 8, 14, 0,146, 6, - 41, 0,125, 0, 41, 0,115, 8, 4, 0,116, 8, 4, 0, 91, 0, 2, 0,117, 8, 2, 0,118, 8, 2, 0,119, 8, 2, 0,120, 8, - 2, 0,121, 8, 2, 0,122, 8, 2, 0,123, 8, 2, 0,124, 8, 2, 0,125, 8, 2, 0,126, 8, 2, 0,127, 8, 2, 0, 27, 0, -237, 0,128, 8, 11, 0,129, 8, 2, 0,130, 8, 28, 1, 5, 0, 28, 1, 0, 0, 28, 1, 1, 0, 28, 1,131, 8, 15, 0,132, 8, - 4, 0, 18, 0, 29, 1, 7, 0, 29, 1, 0, 0, 29, 1, 1, 0, 28, 1,133, 8, 28, 1,134, 8, 2, 0,121, 5, 2, 0, 18, 0, - 4, 0, 27, 0, 30, 1, 25, 0, 30, 1, 0, 0, 30, 1, 1, 0, 31, 1,135, 8, 32, 1,239, 6, 0, 0,136, 8, 0, 0,137, 8, - 0, 0,138, 8, 2, 0,139, 8, 2, 0,140, 8, 2, 0,141, 8, 2, 0,142, 8, 2, 0,143, 8, 2, 0, 27, 0, 2, 0, 18, 0, - 2, 0, 69, 7, 2, 0,144, 8, 2, 0,145, 8, 4, 0,146, 8, 30, 1,147, 8, 11, 0,148, 8, 4, 0,149, 8, 4, 0,150, 8, - 4, 0,151, 8, 4, 0,152, 8, 0, 0,153, 8, 33, 1, 22, 0, 33, 1, 0, 0, 33, 1, 1, 0, 28, 1,133, 8, 28, 1,134, 8, - 28, 1,154, 8, 28, 1,155, 8, 27, 1,156, 8, 18, 0, 51, 0, 0, 0,147, 6, 0, 0,157, 8, 2, 0,192, 6, 2, 0,193, 6, - 2, 0,158, 8, 2, 0, 27, 0, 2, 0,121, 8, 2, 0, 53, 7, 2, 0, 18, 0, 34, 1,135, 8, 14, 0,159, 8, 14, 0,146, 6, - 14, 0,160, 8, 14, 0,161, 8, 35, 1, 24, 0, 35, 1, 0, 0, 35, 1, 1, 0,240, 0,200, 6, 18, 0,162, 8, 18, 0,163, 8, - 2, 0,192, 6, 2, 0,193, 6, 2, 0,164, 8, 2, 0,165, 8, 2, 0,166, 8, 2, 0, 18, 0, 7, 0, 92, 2, 2, 0,141, 8, - 2, 0,142, 8, 2, 0,120, 8, 2, 0,167, 8, 2, 0,125, 8, 2, 0, 86, 1, 36, 1,135, 8, 14, 0,168, 8, 14, 0,169, 8, - 14, 0,160, 8, 0, 0,170, 8, 11, 0,171, 8, 37, 1, 14, 0, 0, 0,172, 8, 2, 0,173, 8, 2, 0,174, 8, 2, 0,175, 8, - 2, 0,176, 8, 2, 0,110, 5, 2, 0,177, 8, 27, 1,178, 8, 41, 0,179, 8, 4, 0,180, 8, 4, 0,181, 8, 4, 0,182, 8, - 4, 0, 27, 0, 0, 0, 70, 7, 38, 1, 3, 0, 0, 0,183, 8, 4, 0,184, 8, 4, 0,185, 8, 39, 1, 4, 0, 4, 0, 7, 7, - 4, 0,186, 8, 4, 0, 13, 7, 4, 0,187, 8, 40, 1, 2, 0, 4, 0,188, 8, 4, 0,189, 8, 41, 1, 5, 0, 7, 0,190, 8, - 7, 0,191, 8, 7, 0,192, 8, 4, 0, 18, 0, 4, 0, 27, 0, 42, 1, 7, 0, 0, 0,193, 8, 0, 0,221, 6, 44, 0,138, 0, - 2, 0,194, 8, 2, 0, 72, 5, 2, 0,195, 8, 2, 0,196, 8, 43, 1, 12, 0, 43, 1, 0, 0, 43, 1, 1, 0, 4, 0, 28, 0, - 4, 0,197, 8, 4, 0,198, 8, 4, 0,199, 8, 38, 1,200, 8, 0, 0,193, 8, 42, 1,176, 3, 39, 1,201, 8, 40, 1,202, 8, - 41, 1,203, 8, 44, 1, 12, 0, 0, 0, 35, 0, 11, 0,227, 0, 0, 0,228, 0, 4, 0,231, 0, 4, 0,239, 0, 11, 0,232, 0, - 7, 0,234, 0, 7, 0,235, 0, 11, 0,204, 8, 11, 0,205, 8, 11, 0,236, 0, 11, 0,238, 0, 45, 1, 48, 0, 45, 1, 0, 0, - 45, 1, 1, 0, 11, 0,206, 8, 11, 0, 25, 0, 0, 0, 19, 0, 4, 0, 18, 0, 4, 0, 16, 0, 4, 0, 22, 0, 4, 0, 89, 0, - 4, 0,207, 8, 4, 0,208, 8, 4, 0,198, 8, 4, 0,199, 8, 4, 0,209, 8, 4, 0,250, 0, 4, 0,210, 8, 4, 0,211, 8, - 7, 0,212, 8, 7, 0,213, 8, 7, 0,214, 8, 2, 0,215, 8, 2, 0,216, 8, 4, 0,217, 8, 4, 0,218, 8, 43, 1,219, 8, - 31, 0, 80, 0, 41, 0,125, 0, 27, 0,220, 8, 44, 0,138, 0,229, 0,106, 6, 7, 0,221, 8, 7, 0,222, 8, 44, 1, 71, 1, - 45, 1,223, 8, 45, 1,224, 8, 45, 1,225, 8, 14, 0,226, 8, 46, 1,227, 8, 11, 0,228, 8, 7, 0, 84, 4, 7, 0,229, 8, - 7, 0,230, 8, 7, 0,231, 8, 11, 0,232, 8, 4, 0,233, 8, 4, 0,234, 8, 4, 0,235, 8, 7, 0,236, 8, 47, 1, 4, 0, - 47, 1, 0, 0, 47, 1, 1, 0, 14, 0,237, 8, 45, 1,238, 8,226, 0, 11, 0, 14, 0,239, 8, 14, 0,226, 8, 14, 0,240, 8, - 45, 1,241, 8, 0, 0,242, 8, 0, 0,243, 8, 4, 0,244, 8, 4, 0,245, 8, 4, 0,246, 8, 4, 0, 27, 0, 19, 0,247, 8, - 48, 1, 4, 0, 7, 0,248, 8, 7, 0, 94, 3, 2, 0,249, 8, 2, 0,250, 8, 49, 1, 6, 0, 7, 0,251, 8, 7, 0,252, 8, - 7, 0,253, 8, 7, 0,254, 8, 4, 0,255, 8, 4, 0, 0, 9, 50, 1, 8, 0, 7, 0, 1, 9, 7, 0, 2, 9, 7, 0, 3, 9, - 7, 0, 4, 9, 7, 0, 5, 9, 4, 0,250, 2, 4, 0, 6, 9, 4, 0, 7, 9, 51, 1, 2, 0, 7, 0,180, 5, 7, 0, 27, 0, - 52, 1, 5, 0, 7, 0, 8, 9, 7, 0, 9, 9, 4, 0, 92, 0, 4, 0,212, 2, 4, 0, 10, 9, 53, 1, 6, 0, 53, 1, 0, 0, - 53, 1, 1, 0, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 11, 9, 2, 0, 56, 0, 54, 1, 8, 0, 54, 1, 0, 0, 54, 1, 1, 0, - 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 11, 9, 2, 0, 56, 0, 7, 0, 22, 0, 7, 0,129, 0, 55, 1, 45, 0, 55, 1, 0, 0, - 55, 1, 1, 0, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 11, 9, 2, 0,246, 0, 2, 0,126, 4, 2, 0, 12, 9, 7, 0, 13, 9, - 7, 0, 90, 0, 7, 0, 7, 3, 4, 0, 14, 9, 4, 0, 82, 0, 4, 0,214, 2, 7, 0, 15, 9, 7, 0, 16, 9, 7, 0, 17, 9, - 7, 0, 18, 9, 7, 0, 19, 9, 7, 0, 20, 9, 7, 0, 4, 3, 7, 0, 68, 1, 7, 0, 21, 9, 7, 0, 22, 9, 7, 0, 27, 0, - 7, 0, 23, 9, 7, 0, 24, 9, 7, 0, 25, 9, 2, 0, 26, 9, 2, 0, 27, 9, 2, 0, 28, 9, 2, 0, 29, 9, 2, 0, 30, 9, - 2, 0, 31, 9, 2, 0, 32, 9, 2, 0, 33, 9, 2, 0, 31, 2, 2, 0, 34, 9, 2, 0, 28, 2, 2, 0, 35, 9, 0, 0, 36, 9, - 0, 0, 37, 9, 7, 0,244, 0, 56, 1, 38, 9, 64, 0,249, 1, 57, 1, 16, 0, 57, 1, 0, 0, 57, 1, 1, 0, 2, 0, 16, 0, - 2, 0, 18, 0, 2, 0, 11, 9, 2, 0,246, 0, 7, 0,255, 2, 7, 0, 0, 3, 7, 0, 1, 3, 7, 0, 81, 2, 7, 0, 2, 3, - 7, 0, 3, 3, 7, 0, 39, 9, 7, 0, 4, 3, 7, 0, 6, 3, 7, 0, 7, 3,253, 0, 5, 0, 2, 0, 16, 0, 2, 0, 40, 9, - 2, 0, 18, 0, 2, 0, 41, 9, 22, 0, 42, 7,252, 0, 3, 0, 4, 0, 68, 0, 4, 0, 42, 9,253, 0, 2, 0, 58, 1, 7, 0, - 58, 1, 0, 0, 58, 1, 1, 0, 0, 0, 19, 0, 2, 0, 16, 0, 2, 0, 18, 0, 4, 0, 21, 0, 11, 0, 43, 9, 59, 1, 5, 0, - 0, 0, 19, 0, 7, 0, 94, 1, 7, 0, 44, 9, 4, 0, 45, 9, 4, 0, 27, 0, 60, 1, 4, 0, 2, 0, 16, 0, 2, 0, 18, 0, - 2, 0, 91, 0, 2, 0, 30, 0, 61, 1, 4, 0, 0, 0, 19, 0, 63, 0, 46, 9, 7, 0, 94, 1, 7, 0, 27, 0, 62, 1, 6, 0, - 2, 0, 47, 9, 2, 0, 48, 9, 2, 0, 16, 0, 2, 0, 49, 9, 0, 0, 50, 9, 0, 0, 51, 9, 63, 1, 5, 0, 4, 0, 16, 0, - 4, 0, 27, 0, 0, 0, 19, 0, 0, 0, 52, 9, 0, 0, 53, 9, 64, 1, 3, 0, 4, 0, 16, 0, 4, 0, 27, 0, 0, 0, 19, 0, - 65, 1, 4, 0, 2, 0, 54, 9, 2, 0, 55, 9, 2, 0, 18, 0, 2, 0, 27, 0, 66, 1, 6, 0, 0, 0, 19, 0, 0, 0, 56, 9, - 2, 0, 57, 9, 2, 0, 4, 3, 2, 0, 87, 1, 2, 0, 30, 0, 67, 1, 5, 0, 0, 0, 19, 0, 7, 0, 94, 3, 7, 0,217, 4, - 2, 0, 18, 0, 2, 0,226, 2, 68, 1, 3, 0, 0, 0, 19, 0, 4, 0,214, 2, 4, 0, 54, 9, 69, 1, 7, 0, 0, 0, 19, 0, - 7, 0,217, 4, 0, 0, 58, 9, 0, 0, 59, 9, 2, 0, 87, 1, 2, 0, 91, 0, 4, 0, 60, 9, 70, 1, 4, 0, 0, 0, 61, 9, - 0, 0, 62, 9, 4, 0, 16, 0, 7, 0,230, 2, 71, 1, 3, 0, 27, 0, 63, 9, 0, 0, 64, 9, 0, 0, 65, 9, 72, 1, 18, 0, - 72, 1, 0, 0, 72, 1, 1, 0, 2, 0, 16, 0, 2, 0, 66, 9, 2, 0, 18, 0, 2, 0, 67, 9, 2, 0, 68, 9, 2, 0, 69, 9, - 2, 0, 91, 0, 2, 0, 30, 0, 0, 0, 19, 0, 11, 0, 2, 0, 73, 1, 70, 9, 27, 0, 44, 0, 2, 0,216, 5, 2, 0,176, 2, - 2, 0, 71, 9, 2, 0, 27, 0, 74, 1, 11, 0, 0, 0, 19, 0, 0, 0, 16, 0, 0, 0, 72, 9, 2, 0, 18, 0, 2, 0,226, 2, - 2, 0, 73, 9, 4, 0, 74, 9, 4, 0, 75, 9, 4, 0, 76, 9, 4, 0, 77, 9, 4, 0, 78, 9, 75, 1, 1, 0, 0, 0, 79, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,114,114,114,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,130,130,130,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 57, 57,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,170, 64,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, + 32,255,255,255, 75, 75, 75,255,204, 0,153,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 32, 0, 0,255, 0, 32, 0,255, + 0, 0,128,255, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255,255,255,255,255, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,200,200,200,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76,255, + 0, 0, 0, 0,250,250,250,255, 15, 15, 15,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100,255,140, 25,255,250,250,250,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130,130,130,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250,250,250,255, 0, 0, 0, 0, +250,250,250,255,250,250,250,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,255,255,255,150, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,150,150,150,100,112,112,112,100, 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 79,101, 73,255,135,177,125,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255,153, 64, 48,255, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, +240,175,144,255, 82, 96,110,255,124,137,150,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0,255,255,133, 0,255, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,255,255,255,150, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,150,150,150,100,112,112,112,100, 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 79,101, 73,255,135,177,125,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 82, 96,110,255,124,137,150,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0,255,255,133, 0,255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,107,107,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,255,255,255,150, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,150,150,150,100,112,112,112,100, 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 79,101, 73,255,135,177,125,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 82, 96,110,255,124,137,150,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0,255,255,133, 0,255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,116,116,116,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81,105,135,255, 32, 32,143,255, +109, 88,129,255, 78,152, 62,255, 46,143,143,255,169, 84,124,255,126,126, 80,255,162, 95,111,255,109,145,131,255,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 53, 53,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0,255,255,255, 10,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 18, 66,176, 38, +255,133, 0,178,255,133, 0,127, 0,255, 0,255,255, 0, 0,255,225,210,195, 35, 0, 0, 0, 0, 0, 0, 0, 0,153,153,153,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255,198,119,119,255,255, 0, 0,255, 64, 64, 64,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0,100, 0, 0,255, 0, 0,200,255,128, 0, 80,255, 95, 95, 0,255, 0,100, 50,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51,127, 51, 76,130,135,140, 76,114,114,114,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,173,173,173,255,127,112,112,100, 0, 0, 0, 0, 91, 91, 91,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 57, 57,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,255,255,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 5,155,155,155,160,100,104,111,255,111,106,100,255,104,106,117,255,105,117,110,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,100,100,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,140, 25,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, +255, 32, 32,255, 75, 75, 75,255, 0, 0, 0, 0, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255, 0, 0, 0, 0, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,128,255,255,255,255,255,255, 0,170, 0,255,220, 96, 96,255,220, 96, 96,255, + 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 57, 57,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,102,102,102,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 94, 94, 94,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,170, 64,255, + 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, 0, 0, 0,255,255,160, 0,255,219, 37, 18,255, + 32,255,255,255, 75, 75, 75,255,204, 0,153,255, 0, 0, 0, 18,255,133, 0, 60,255,133, 0,255, 32, 0, 0,255, 0, 32, 0,255, + 0, 0,128,255, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, + 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,240,144,160,255,255,255,255,255, 0, 0, 0,255, +144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0, 0, 0, 0, 0,255,240,255, 64,255, 64,192, 48,255,240,144,160,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,128, + 0, 0, 0,255,255,255, 0,255, 4, 0, 0, 0,255,127,127, 0,255,255,255,255,255,255,255, 0,255,127, 0, 0,255,127,127,127, +255,200,200,200,255,255, 0, 0,255, 0, 0,255,255, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154, 0, 0,255, +189, 17, 17,255,247, 10, 10,255, 0, 0, 0, 0,247, 64, 24,255,246,105, 19,255,250,153, 0,255, 0, 0, 0, 0, 30,145, 9,255, + 89,183, 11,255,131,239, 29,255, 0, 0, 0, 0, 10, 54,148,255, 54,103,223,255, 94,193,239,255, 0, 0, 0, 0,169, 41, 78,255, +193, 65,106,255,240, 93,145,255, 0, 0, 0, 0, 67, 12,120,255, 84, 58,163,255,135,100,213,255, 0, 0, 0, 0, 36,120, 90,255, + 60,149,121,255,111,182,171,255, 0, 0, 0, 0, 75,112,124,255,106,134,145,255,155,194,205,255, 0, 0, 0, 0,244,201, 12,255, +238,194, 54,255,243,255, 0,255, 0, 0, 0, 0, 30, 32, 36,255, 72, 76, 86,255,255,255,255,255, 0, 0, 0, 0,111, 47,106,255, +152, 69,190,255,211, 48,214,255, 0, 0, 0, 0,108,142, 34,255,127,176, 34,255,187,239, 91,255, 0, 0, 0, 0,141,141,141,255, +176,176,176,255,222,222,222,255, 0, 0, 0, 0,131, 67, 38,255,139, 88, 17,255,189,106, 17,255, 0, 0, 0, 0, 8, 49, 14,255, + 28, 67, 11,255, 52, 98, 43,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0,136,154,198, 6, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0, 40,155,198, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,111, 95,115, 99,101,110,101, 95, 51,100,115, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0, 40,155,198, 6, 0, 0, 0, 0,207, 0, 0, 0, + 1, 0, 0, 0,104,238,199, 6, 0, 0, 0, 0,136,154,198, 6, 0, 0, 0, 0,105,111, 95,115, 99,101,110,101, 95,102, 98,120, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0,104,238,199, 6, + 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0, 8,239,199, 6, 0, 0, 0, 0, 40,155,198, 6, 0, 0, 0, 0,105,111, 95, 97, +110,105,109, 95, 98,118,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 80, 0, 0, 0, 8,239,199, 6, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0,168,239,199, 6, 0, 0, 0, 0,104,238,199, 6, + 0, 0, 0, 0,105,111, 95,109,101,115,104, 95,112,108,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0,168,239,199, 6, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0, 72,240,199, 6, + 0, 0, 0, 0, 8,239,199, 6, 0, 0, 0, 0,105,111, 95,115, 99,101,110,101, 95,111, 98,106, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0, 72,240,199, 6, 0, 0, 0, 0,207, 0, 0, 0, + 1, 0, 0, 0,232,240,199, 6, 0, 0, 0, 0,168,239,199, 6, 0, 0, 0, 0,105,111, 95,115, 99,101,110,101, 95,120, 51,100, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0,232,240,199, 6, + 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0,136,241,199, 6, 0, 0, 0, 0, 72,240,199, 6, 0, 0, 0, 0,105,111, 95,109, +101,115,104, 95,115,116,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 80, 0, 0, 0,136,241,199, 6, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0, 40,242,199, 6, 0, 0, 0, 0,232,240,199, 6, + 0, 0, 0, 0,105,111, 95,109,101,115,104, 95,117,118, 95,108, 97,121,111,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0, 40,242,199, 6, 0, 0, 0, 0,207, 0, 0, 0, 1, 0, 0, 0,200,242,199, 6, + 0, 0, 0, 0,136,241,199, 6, 0, 0, 0, 0,105,111, 95, 99,117,114,118,101, 95,115,118,103, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0,200,242,199, 6, 0, 0, 0, 0,207, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,242,199, 6, 0, 0, 0, 0, 99,121, 99,108,101,115, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,232, 0, 0, 0,104,243,199, 6, + 0, 0, 0, 0,199, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,101,102, 97, +117,108,116, 32, 83,116,121,108,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,255,255, 0, 0,154,153, 25, 62, 0, 0,128, 63, 0, 0, 12, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,255,255, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 0, 0, 11, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,255,255, 0, 0,154,153, 25, 62, 0, 0,128, 63, 0, 0, 11, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 8, 0, 5, 0, 5, 0, 8, 0, 2, 0, 8, 0, 4, 0, 0, 0, 68, 78, 65, 49,156, 4, 1, 0, 24, 9,236, 0, + 73,127, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 83, 68, 78, 65, 78, 65, 77, 69, 58, 13, 0, 0, 42,110,101,120,116, 0, 42,112, +114,101,118, 0, 42,100, 97,116, 97, 0, 42,102,105,114,115,116, 0, 42,108, 97,115,116, 0,120, 0,121, 0,122, 0,120,109,105, +110, 0,120,109, 97,120, 0,121,109,105,110, 0,121,109, 97,120, 0, 42,112,111,105,110,116,101,114, 0,103,114,111,117,112, 0, +118, 97,108, 0,118, 97,108, 50, 0,116,121,112,101, 0,115,117, 98,116,121,112,101, 0,102,108, 97,103, 0,110, 97,109,101, 91, + 54, 52, 93, 0,115, 97,118,101,100, 0,100, 97,116, 97, 0,108,101,110, 0,116,111,116, 97,108,108,101,110, 0, 42,110,101,119, +105,100, 0, 42,108,105, 98, 0,110, 97,109,101, 91, 54, 54, 93, 0,112, 97,100, 0,117,115, 0,105, 99,111,110, 95,105,100, 0, +112, 97,100, 50, 0, 42,112,114,111,112,101,114,116,105,101,115, 0,105,100, 0, 42,105,100, 98,108,111, 99,107, 0, 42,102,105, +108,101,100, 97,116, 97, 0,110, 97,109,101, 91, 49, 48, 50, 52, 93, 0,102,105,108,101,112, 97,116,104, 91, 49, 48, 50, 52, 93, + 0,116,111,116, 0, 42,112, 97,114,101,110,116, 0,119, 91, 50, 93, 0,104, 91, 50, 93, 0, 99,104, 97,110,103,101,100, 91, 50, + 93, 0, 99,104, 97,110,103,101,100, 95,116,105,109,101,115,116, 97,109,112, 91, 50, 93, 0, 42,114,101, 99,116, 91, 50, 93, 0, + 42,111, 98, 0, 98,108,111, 99,107,116,121,112,101, 0, 97,100,114, 99,111,100,101, 0,110, 97,109,101, 91, 49, 50, 56, 93, 0, + 42, 98,112, 0, 42, 98,101,122,116, 0,109, 97,120,114, 99,116, 0,116,111,116,114, 99,116, 0,118, 97,114,116,121,112,101, 0, +116,111,116,118,101,114,116, 0,105,112,111, 0,101,120,116,114, 97,112, 0,114,116, 0, 98,105,116,109, 97,115,107, 0,115,108, +105,100,101, 95,109,105,110, 0,115,108,105,100,101, 95,109, 97,120, 0, 99,117,114,118, 97,108, 0, 42,100,114,105,118,101,114, + 0, 99,117,114,118,101, 0, 99,117,114, 0,115,104,111,119,107,101,121, 0,109,117,116,101,105,112,111, 0,112,111,115, 0,112, + 97,100, 49, 0,114,101,108, 97,116,105,118,101, 0,116,111,116,101,108,101,109, 0,117,105,100, 0, 42,119,101,105,103,104,116, +115, 0,118,103,114,111,117,112, 91, 54, 52, 93, 0,115,108,105,100,101,114,109,105,110, 0,115,108,105,100,101,114,109, 97,120, + 0, 42, 97,100,116, 0, 42,114,101,102,107,101,121, 0,101,108,101,109,115,116,114, 91, 51, 50, 93, 0,101,108,101,109,115,105, +122,101, 0, 98,108,111, 99,107, 0, 42,105,112,111, 0, 42,102,114,111,109, 0,116,111,116,107,101,121, 0,115,108,117,114,112, +104, 0, 99,116,105,109,101, 0,117,105,100,103,101,110, 0, 42,108,105,110,101, 0, 42,102,111,114,109, 97,116, 0, 98,108,101, +110, 0,108,105,110,101,110,111, 0,115,116, 97,114,116, 0,101,110,100, 0,102,108, 97,103,115, 0, 99,111,108,111,114, 91, 52, + 93, 0,112, 97,100, 91, 52, 93, 0, 42,110, 97,109,101, 0,110,108,105,110,101,115, 0,108,105,110,101,115, 0, 42, 99,117,114, +108, 0, 42,115,101,108,108, 0, 99,117,114, 99, 0,115,101,108, 99, 0,109, 97,114,107,101,114,115, 0, 42,117,110,100,111, 95, + 98,117,102, 0,117,110,100,111, 95,112,111,115, 0,117,110,100,111, 95,108,101,110, 0, 42, 99,111,109,112,105,108,101,100, 0, +109,116,105,109,101, 0,115,105,122,101, 0,115,101,101,107, 0,100,116,120, 0,112, 97,115,115,101,112, 97,114,116, 97,108,112, +104, 97, 0, 99,108,105,112,115,116, 97, 0, 99,108,105,112,101,110,100, 0,108,101,110,115, 0,111,114,116,104,111, 95,115, 99, + 97,108,101, 0,100,114, 97,119,115,105,122,101, 0,115,101,110,115,111,114, 95,120, 0,115,101,110,115,111,114, 95,121, 0,115, +104,105,102,116,120, 0,115,104,105,102,116,121, 0, 89, 70, 95,100,111,102,100,105,115,116, 0, 42,100,111,102, 95,111, 98, 0, +115,101,110,115,111,114, 95,102,105,116, 0,112, 97,100, 91, 55, 93, 0, 42,115, 99,101,110,101, 0,102,114, 97,109,101,110,114, + 0,102,114, 97,109,101,115, 0,111,102,102,115,101,116, 0,115,102,114, 97, 0,102,105,101, 95,105,109, 97, 0, 99,121, 99,108, + 0,111,107, 0,109,117,108,116,105, 95,105,110,100,101,120, 0,108, 97,121,101,114, 0,112, 97,115,115, 0,105, 98,117,102,115, + 0, 42,103,112,117,116,101,120,116,117,114,101, 0, 42, 97,110,105,109, 0, 42,114,114, 0, 42,114,101,110,100,101,114,115, 91, + 56, 93, 0,114,101,110,100,101,114, 95,115,108,111,116, 0,108, 97,115,116, 95,114,101,110,100,101,114, 95,115,108,111,116, 0, +115,111,117,114, 99,101, 0,108, 97,115,116,102,114, 97,109,101, 0,116,112, 97,103,101,102,108, 97,103, 0,116,111,116, 98,105, +110,100, 0,120,114,101,112, 0,121,114,101,112, 0,116,119,115,116, 97, 0,116,119,101,110,100, 0, 98,105,110,100, 99,111,100, +101, 0, 42,114,101,112, 98,105,110,100, 0, 42,112, 97, 99,107,101,100,102,105,108,101, 0, 42,112,114,101,118,105,101,119, 0, +108, 97,115,116,117,112,100, 97,116,101, 0,108, 97,115,116,117,115,101,100, 0, 97,110,105,109,115,112,101,101,100, 0,103,101, +110, 95,120, 0,103,101,110, 95,121, 0,103,101,110, 95,116,121,112,101, 0,103,101,110, 95,102,108, 97,103, 0, 97,115,112,120, + 0, 97,115,112,121, 0,116,101,120, 99,111, 0,109, 97,112,116,111, 0,109, 97,112,116,111,110,101,103, 0, 98,108,101,110,100, +116,121,112,101, 0, 42,111, 98,106,101, 99,116, 0, 42,116,101,120, 0,117,118,110, 97,109,101, 91, 54, 52, 93, 0,112,114,111, +106,120, 0,112,114,111,106,121, 0,112,114,111,106,122, 0,109, 97,112,112,105,110,103, 0,111,102,115, 91, 51, 93, 0,115,105, +122,101, 91, 51, 93, 0,114,111,116, 0,116,101,120,102,108, 97,103, 0, 99,111,108,111,114,109,111,100,101,108, 0,112,109, 97, +112,116,111, 0,112,109, 97,112,116,111,110,101,103, 0,110,111,114,109, 97,112,115,112, 97, 99,101, 0,119,104,105, 99,104, 95, +111,117,116,112,117,116, 0, 98,114,117,115,104, 95,109, 97,112, 95,109,111,100,101, 0,114, 0,103, 0, 98, 0,107, 0,100,101, +102, 95,118, 97,114, 0, 99,111,108,102, 97, 99, 0,118, 97,114,102, 97, 99, 0,110,111,114,102, 97, 99, 0,100,105,115,112,102, + 97, 99, 0,119, 97,114,112,102, 97, 99, 0, 99,111,108,115,112,101, 99,102, 97, 99, 0,109,105,114,114,102, 97, 99, 0, 97,108, +112,104, 97,102, 97, 99, 0,100,105,102,102,102, 97, 99, 0,115,112,101, 99,102, 97, 99, 0,101,109,105,116,102, 97, 99, 0,104, + 97,114,100,102, 97, 99, 0,114, 97,121,109,105,114,114,102, 97, 99, 0,116,114, 97,110,115,108,102, 97, 99, 0, 97,109, 98,102, + 97, 99, 0, 99,111,108,101,109,105,116,102, 97, 99, 0, 99,111,108,114,101,102,108,102, 97, 99, 0, 99,111,108,116,114, 97,110, +115,102, 97, 99, 0,100,101,110,115,102, 97, 99, 0,115, 99, 97,116,116,101,114,102, 97, 99, 0,114,101,102,108,102, 97, 99, 0, +116,105,109,101,102, 97, 99, 0,108,101,110,103,116,104,102, 97, 99, 0, 99,108,117,109,112,102, 97, 99, 0,100, 97,109,112,102, + 97, 99, 0,107,105,110,107,102, 97, 99, 0,114,111,117,103,104,102, 97, 99, 0,112, 97,100,101,110,115,102, 97, 99, 0,103,114, + 97,118,105,116,121,102, 97, 99, 0,108,105,102,101,102, 97, 99, 0,115,105,122,101,102, 97, 99, 0,105,118,101,108,102, 97, 99, + 0,102,105,101,108,100,102, 97, 99, 0,115,104, 97,100,111,119,102, 97, 99, 0,122,101,110,117,112,102, 97, 99, 0,122,101,110, +100,111,119,110,102, 97, 99, 0, 98,108,101,110,100,102, 97, 99, 0, 42,104, 97,110,100,108,101, 0, 42,112,110, 97,109,101, 0, + 42,115,116,110, 97,109,101,115, 0,115,116,121,112,101,115, 0,118, 97,114,115, 0, 42,118, 97,114,115,116,114, 0, 42,114,101, +115,117,108,116, 0, 42, 99,102,114, 97, 0,100, 97,116, 97, 91, 51, 50, 93, 0, 40, 42,100,111,105,116, 41, 40, 41, 0, 40, 42, +105,110,115,116, 97,110, 99,101, 95,105,110,105,116, 41, 40, 41, 0, 40, 42, 99, 97,108,108, 98, 97, 99,107, 41, 40, 41, 0,118, +101,114,115,105,111,110, 0, 97, 0,105,112,111,116,121,112,101, 0, 42,105,109, 97, 0, 42, 99,117, 98,101, 91, 54, 93, 0,105, +109, 97,116, 91, 52, 93, 91, 52, 93, 0,111, 98,105,109, 97,116, 91, 51, 93, 91, 51, 93, 0,115,116,121,112,101, 0,118,105,101, +119,115, 99, 97,108,101, 0,110,111,116,108, 97,121, 0, 99,117, 98,101,114,101,115, 0,100,101,112,116,104, 0,114,101, 99, 97, +108, 99, 0,108, 97,115,116,115,105,122,101, 0,102, 97,108,108,111,102,102, 95,116,121,112,101, 0,102, 97,108,108,111,102,102, + 95,115,111,102,116,110,101,115,115, 0,114, 97,100,105,117,115, 0, 99,111,108,111,114, 95,115,111,117,114, 99,101, 0,116,111, +116,112,111,105,110,116,115, 0,112,100,112, 97,100, 0,112,115,121,115, 0,112,115,121,115, 95, 99, 97, 99,104,101, 95,115,112, + 97, 99,101, 0,111, 98, 95, 99, 97, 99,104,101, 95,115,112, 97, 99,101, 0, 42,112,111,105,110,116, 95,116,114,101,101, 0, 42, +112,111,105,110,116, 95,100, 97,116, 97, 0,110,111,105,115,101, 95,115,105,122,101, 0,110,111,105,115,101, 95,100,101,112,116, +104, 0,110,111,105,115,101, 95,105,110,102,108,117,101,110, 99,101, 0,110,111,105,115,101, 95, 98, 97,115,105,115, 0,112,100, +112, 97,100, 51, 91, 51, 93, 0,110,111,105,115,101, 95,102, 97, 99, 0,115,112,101,101,100, 95,115, 99, 97,108,101, 0,102, 97, +108,108,111,102,102, 95,115,112,101,101,100, 95,115, 99, 97,108,101, 0,112,100,112, 97,100, 50, 0, 42, 99,111, 98, 97, 0, 42, +102, 97,108,108,111,102,102, 95, 99,117,114,118,101, 0,114,101,115,111,108, 91, 51, 93, 0,105,110,116,101,114,112, 95,116,121, +112,101, 0,102,105,108,101, 95,102,111,114,109, 97,116, 0,101,120,116,101,110,100, 0,115,109,111,107,101,100, 95,116,121,112, +101, 0,105,110,116, 95,109,117,108,116,105,112,108,105,101,114, 0,115,116,105,108,108, 95,102,114, 97,109,101, 0,115,111,117, +114, 99,101, 95,112, 97,116,104, 91, 49, 48, 50, 52, 93, 0, 42,100, 97,116, 97,115,101,116, 0, 99, 97, 99,104,101,100,102,114, + 97,109,101, 0,111, 99,101, 97,110,109,111,100, 91, 54, 52, 93, 0,111,117,116,112,117,116, 0,110,111,105,115,101,115,105,122, +101, 0,116,117,114, 98,117,108, 0, 98,114,105,103,104,116, 0, 99,111,110,116,114, 97,115,116, 0,115, 97,116,117,114, 97,116, +105,111,110, 0,114,102, 97, 99, 0,103,102, 97, 99, 0, 98,102, 97, 99, 0,102,105,108,116,101,114,115,105,122,101, 0,109,103, + 95, 72, 0,109,103, 95,108, 97, 99,117,110, 97,114,105,116,121, 0,109,103, 95,111, 99,116, 97,118,101,115, 0,109,103, 95,111, +102,102,115,101,116, 0,109,103, 95,103, 97,105,110, 0,100,105,115,116, 95, 97,109,111,117,110,116, 0,110,115, 95,111,117,116, +115, 99, 97,108,101, 0,118,110, 95,119, 49, 0,118,110, 95,119, 50, 0,118,110, 95,119, 51, 0,118,110, 95,119, 52, 0,118,110, + 95,109,101,120,112, 0,118,110, 95,100,105,115,116,109, 0,118,110, 95, 99,111,108,116,121,112,101, 0,110,111,105,115,101,100, +101,112,116,104, 0,110,111,105,115,101,116,121,112,101, 0,110,111,105,115,101, 98, 97,115,105,115, 0,110,111,105,115,101, 98, + 97,115,105,115, 50, 0,105,109, 97,102,108, 97,103, 0, 99,114,111,112,120,109,105,110, 0, 99,114,111,112,121,109,105,110, 0, + 99,114,111,112,120,109, 97,120, 0, 99,114,111,112,121,109, 97,120, 0,116,101,120,102,105,108,116,101,114, 0, 97,102,109, 97, +120, 0,120,114,101,112,101, 97,116, 0,121,114,101,112,101, 97,116, 0, 99,104,101, 99,107,101,114,100,105,115,116, 0,110, 97, + 98,108, 97, 0,105,117,115,101,114, 0, 42,110,111,100,101,116,114,101,101, 0, 42,112,108,117,103,105,110, 0, 42,101,110,118, + 0, 42,112,100, 0, 42,118,100, 0, 42,111,116, 0,117,115,101, 95,110,111,100,101,115, 0,108,111, 99, 91, 51, 93, 0,114,111, +116, 91, 51, 93, 0,109, 97,116, 91, 52, 93, 91, 52, 93, 0,109,105,110, 91, 51, 93, 0,109, 97,120, 91, 51, 93, 0, 99,111, 98, + 97, 0, 98,108,101,110,100, 95, 99,111,108,111,114, 91, 51, 93, 0, 98,108,101,110,100, 95,102, 97, 99,116,111,114, 0, 98,108, +101,110,100, 95,116,121,112,101, 0,112, 97,100, 91, 51, 93, 0,109,111,100,101, 0,116,111,116,101,120, 0,115,104,100,119,114, + 0,115,104,100,119,103, 0,115,104,100,119, 98, 0,115,104,100,119,112, 97,100, 0,101,110,101,114,103,121, 0,100,105,115,116, + 0,115,112,111,116,115,105,122,101, 0,115,112,111,116, 98,108,101,110,100, 0,104, 97,105,110,116, 0, 97,116,116, 49, 0, 97, +116,116, 50, 0, 42, 99,117,114,102, 97,108,108,111,102,102, 0,115,104, 97,100,115,112,111,116,115,105,122,101, 0, 98,105, 97, +115, 0,115,111,102,116, 0, 99,111,109,112,114,101,115,115,116,104,114,101,115,104, 0,112, 97,100, 53, 91, 51, 93, 0, 98,117, +102,115,105,122,101, 0,115, 97,109,112, 0, 98,117,102,102,101,114,115, 0,102,105,108,116,101,114,116,121,112,101, 0, 98,117, +102,102,108, 97,103, 0, 98,117,102,116,121,112,101, 0,114, 97,121, 95,115, 97,109,112, 0,114, 97,121, 95,115, 97,109,112,121, + 0,114, 97,121, 95,115, 97,109,112,122, 0,114, 97,121, 95,115, 97,109,112, 95,116,121,112,101, 0, 97,114,101, 97, 95,115,104, + 97,112,101, 0, 97,114,101, 97, 95,115,105,122,101, 0, 97,114,101, 97, 95,115,105,122,101,121, 0, 97,114,101, 97, 95,115,105, +122,101,122, 0, 97,100, 97,112,116, 95,116,104,114,101,115,104, 0,114, 97,121, 95,115, 97,109,112, 95,109,101,116,104,111,100, + 0,116,101,120, 97, 99,116, 0,115,104, 97,100,104, 97,108,111,115,116,101,112, 0,115,117,110, 95,101,102,102,101, 99,116, 95, +116,121,112,101, 0,115,107,121, 98,108,101,110,100,116,121,112,101, 0,104,111,114,105,122,111,110, 95, 98,114,105,103,104,116, +110,101,115,115, 0,115,112,114,101, 97,100, 0,115,117,110, 95, 98,114,105,103,104,116,110,101,115,115, 0,115,117,110, 95,115, +105,122,101, 0, 98, 97, 99,107,115, 99, 97,116,116,101,114,101,100, 95,108,105,103,104,116, 0,115,117,110, 95,105,110,116,101, +110,115,105,116,121, 0, 97,116,109, 95,116,117,114, 98,105,100,105,116,121, 0, 97,116,109, 95,105,110,115, 99, 97,116,116,101, +114,105,110,103, 95,102, 97, 99,116,111,114, 0, 97,116,109, 95,101,120,116,105,110, 99,116,105,111,110, 95,102, 97, 99,116,111, +114, 0, 97,116,109, 95,100,105,115,116, 97,110, 99,101, 95,102, 97, 99,116,111,114, 0,115,107,121, 98,108,101,110,100,102, 97, + 99, 0,115,107,121, 95,101,120,112,111,115,117,114,101, 0,115,107,121, 95, 99,111,108,111,114,115,112, 97, 99,101, 0,112, 97, +100, 52, 91, 54, 93, 0, 42,109,116,101,120, 91, 49, 56, 93, 0,112,114, 95,116,101,120,116,117,114,101, 0,112, 97,100, 54, 91, + 52, 93, 0,100,101,110,115,105,116,121, 0,101,109,105,115,115,105,111,110, 0,115, 99, 97,116,116,101,114,105,110,103, 0,114, +101,102,108,101, 99,116,105,111,110, 0,101,109,105,115,115,105,111,110, 95, 99,111,108, 91, 51, 93, 0,116,114, 97,110,115,109, +105,115,115,105,111,110, 95, 99,111,108, 91, 51, 93, 0,114,101,102,108,101, 99,116,105,111,110, 95, 99,111,108, 91, 51, 93, 0, +100,101,110,115,105,116,121, 95,115, 99, 97,108,101, 0,100,101,112,116,104, 95, 99,117,116,111,102,102, 0, 97,115,121,109,109, +101,116,114,121, 0,115,116,101,112,115,105,122,101, 95,116,121,112,101, 0,115,104, 97,100,101,102,108, 97,103, 0,115,104, 97, +100,101, 95,116,121,112,101, 0,112,114,101, 99, 97, 99,104,101, 95,114,101,115,111,108,117,116,105,111,110, 0,115,116,101,112, +115,105,122,101, 0,109,115, 95,100,105,102,102, 0,109,115, 95,105,110,116,101,110,115,105,116,121, 0,109,115, 95,115,112,114, +101, 97,100, 0, 97,108,112,104, 97, 95, 98,108,101,110,100, 0,102, 97, 99,101, 95,111,114,105,101,110,116, 97,116,105,111,110, + 0,109, 97,116,101,114,105, 97,108, 95,116,121,112,101, 0,115,112,101, 99,114, 0,115,112,101, 99,103, 0,115,112,101, 99, 98, + 0,109,105,114,114, 0,109,105,114,103, 0,109,105,114, 98, 0, 97,109, 98,114, 0, 97,109, 98, 98, 0, 97,109, 98,103, 0, 97, +109, 98, 0,101,109,105,116, 0, 97,110,103, 0,115,112,101, 99,116,114, 97, 0,114, 97,121, 95,109,105,114,114,111,114, 0, 97, +108,112,104, 97, 0,114,101,102, 0,115,112,101, 99, 0,122,111,102,102,115, 0, 97,100,100, 0,116,114, 97,110,115,108,117, 99, +101,110, 99,121, 0,118,111,108, 0,103, 97,109,101, 0,102,114,101,115,110,101,108, 95,109,105,114, 0,102,114,101,115,110,101, +108, 95,109,105,114, 95,105, 0,102,114,101,115,110,101,108, 95,116,114, 97, 0,102,114,101,115,110,101,108, 95,116,114, 97, 95, +105, 0,102,105,108,116,101,114, 0,116,120, 95,108,105,109,105,116, 0,116,120, 95,102, 97,108,108,111,102,102, 0,114, 97,121, + 95,100,101,112,116,104, 0,114, 97,121, 95,100,101,112,116,104, 95,116,114, 97, 0,104, 97,114, 0,115,101,101,100, 49, 0,115, +101,101,100, 50, 0,103,108,111,115,115, 95,109,105,114, 0,103,108,111,115,115, 95,116,114, 97, 0,115, 97,109,112, 95,103,108, +111,115,115, 95,109,105,114, 0,115, 97,109,112, 95,103,108,111,115,115, 95,116,114, 97, 0, 97,100, 97,112,116, 95,116,104,114, +101,115,104, 95,109,105,114, 0, 97,100, 97,112,116, 95,116,104,114,101,115,104, 95,116,114, 97, 0, 97,110,105,115,111, 95,103, +108,111,115,115, 95,109,105,114, 0,100,105,115,116, 95,109,105,114, 0,102, 97,100,101,116,111, 95,109,105,114, 0,115,104, 97, +100,101, 95,102,108, 97,103, 0,109,111,100,101, 95,108, 0,102,108, 97,114,101, 99, 0,115,116, 97,114, 99, 0,108,105,110,101, + 99, 0,114,105,110,103, 99, 0,104, 97,115,105,122,101, 0,102,108, 97,114,101,115,105,122,101, 0,115,117, 98,115,105,122,101, + 0,102,108, 97,114,101, 98,111,111,115,116, 0,115,116,114, 97,110,100, 95,115,116, 97, 0,115,116,114, 97,110,100, 95,101,110, +100, 0,115,116,114, 97,110,100, 95,101, 97,115,101, 0,115,116,114, 97,110,100, 95,115,117,114,102,110,111,114, 0,115,116,114, + 97,110,100, 95,109,105,110, 0,115,116,114, 97,110,100, 95,119,105,100,116,104,102, 97,100,101, 0,115,116,114, 97,110,100, 95, +117,118,110, 97,109,101, 91, 54, 52, 93, 0,115, 98,105, 97,115, 0,108, 98,105, 97,115, 0,115,104, 97,100, 95, 97,108,112,104, + 97, 0,115,101,112,116,101,120, 0,114,103, 98,115,101,108, 0,112,114, 95,116,121,112,101, 0,112,114, 95, 98, 97, 99,107, 0, +112,114, 95,108, 97,109,112, 0,109,108, 95,102,108, 97,103, 0,100,105,102,102, 95,115,104, 97,100,101,114, 0,115,112,101, 99, + 95,115,104, 97,100,101,114, 0,114,111,117,103,104,110,101,115,115, 0,114,101,102,114, 97, 99, 0,112, 97,114, 97,109, 91, 52, + 93, 0,114,109,115, 0,100, 97,114,107,110,101,115,115, 0, 42,114, 97,109,112, 95, 99,111,108, 0, 42,114, 97,109,112, 95,115, +112,101, 99, 0,114, 97,109,112,105,110, 95, 99,111,108, 0,114, 97,109,112,105,110, 95,115,112,101, 99, 0,114, 97,109,112, 98, +108,101,110,100, 95, 99,111,108, 0,114, 97,109,112, 98,108,101,110,100, 95,115,112,101, 99, 0,114, 97,109,112, 95,115,104,111, +119, 0,112, 97,100, 51, 0,114, 97,109,112,102, 97, 99, 95, 99,111,108, 0,114, 97,109,112,102, 97, 99, 95,115,112,101, 99, 0, + 42,103,114,111,117,112, 0,102,114,105, 99,116,105,111,110, 0,102,104, 0,114,101,102,108,101, 99,116, 0,102,104,100,105,115, +116, 0,120,121,102,114,105, 99,116, 0,100,121,110, 97,109,111,100,101, 0,115,115,115, 95,114, 97,100,105,117,115, 91, 51, 93, + 0,115,115,115, 95, 99,111,108, 91, 51, 93, 0,115,115,115, 95,101,114,114,111,114, 0,115,115,115, 95,115, 99, 97,108,101, 0, +115,115,115, 95,105,111,114, 0,115,115,115, 95, 99,111,108,102, 97, 99, 0,115,115,115, 95,116,101,120,102, 97, 99, 0,115,115, +115, 95,102,114,111,110,116, 0,115,115,115, 95, 98, 97, 99,107, 0,115,115,115, 95,102,108, 97,103, 0,115,115,115, 95,112,114, +101,115,101,116, 0,109, 97,112,116,111, 95,116,101,120,116,117,114,101,100, 0,115,104, 97,100,111,119,111,110,108,121, 95,102, +108, 97,103, 0,105,110,100,101,120, 0,103,112,117,109, 97,116,101,114,105, 97,108, 0, 42, 98, 98, 0,115,101,108, 99,111,108, + 49, 0,115,101,108, 99,111,108, 50, 0,113,117, 97,116, 91, 52, 93, 0,101,120,112,120, 0,101,120,112,121, 0,101,120,112,122, + 0,114, 97,100, 0,114, 97,100, 50, 0,115, 0, 42,109, 97,116, 0, 42,105,109, 97,116, 0,101,108,101,109,115, 0,100,105,115, +112, 0, 42,101,100,105,116,101,108,101,109,115, 0, 42, 42,109, 97,116, 0,102,108, 97,103, 50, 0,116,111,116, 99,111,108, 0, +119,105,114,101,115,105,122,101, 0,114,101,110,100,101,114,115,105,122,101, 0,116,104,114,101,115,104, 0, 42,108, 97,115,116, +101,108,101,109, 0,118,101, 99, 91, 51, 93, 91, 51, 93, 0, 97,108,102, 97, 0,119,101,105,103,104,116, 0,104, 49, 0,104, 50, + 0,102, 49, 0,102, 50, 0,102, 51, 0,104,105,100,101, 0,118,101, 99, 91, 52, 93, 0,109, 97,116, 95,110,114, 0,112,110,116, +115,117, 0,112,110,116,115,118, 0,114,101,115,111,108,117, 0,114,101,115,111,108,118, 0,111,114,100,101,114,117, 0,111,114, +100,101,114,118, 0,102,108, 97,103,117, 0,102,108, 97,103,118, 0, 42,107,110,111,116,115,117, 0, 42,107,110,111,116,115,118, + 0,116,105,108,116, 95,105,110,116,101,114,112, 0,114, 97,100,105,117,115, 95,105,110,116,101,114,112, 0, 99,104, 97,114,105, +100,120, 0,107,101,114,110, 0,119, 0,104, 0,110,117,114, 98,115, 0, 42,107,101,121,105,110,100,101,120, 0,115,104, 97,112, +101,110,114, 0,110,117,114, 98, 0, 42,101,100,105,116,110,117,114, 98, 0, 42, 98,101,118,111, 98,106, 0, 42,116, 97,112,101, +114,111, 98,106, 0, 42,116,101,120,116,111,110, 99,117,114,118,101, 0, 42,112, 97,116,104, 0, 42,107,101,121, 0, 98,101,118, + 0,100,114, 97,119,102,108, 97,103, 0,116,119,105,115,116, 95,109,111,100,101, 0,116,119,105,115,116, 95,115,109,111,111,116, +104, 0,115,109, 97,108,108, 99, 97,112,115, 95,115, 99, 97,108,101, 0,112, 97,116,104,108,101,110, 0, 98,101,118,114,101,115, +111,108, 0,119,105,100,116,104, 0,101,120,116, 49, 0,101,120,116, 50, 0,114,101,115,111,108,117, 95,114,101,110, 0,114,101, +115,111,108,118, 95,114,101,110, 0, 97, 99,116,110,117, 0, 42,108, 97,115,116,115,101,108, 0,115,112, 97, 99,101,109,111,100, +101, 0,115,112, 97, 99,105,110,103, 0,108,105,110,101,100,105,115,116, 0,115,104,101, 97,114, 0,102,115,105,122,101, 0,119, +111,114,100,115,112, 97, 99,101, 0,117,108,112,111,115, 0,117,108,104,101,105,103,104,116, 0,120,111,102, 0,121,111,102, 0, +108,105,110,101,119,105,100,116,104, 0, 42,115,116,114, 0, 42,115,101,108, 98,111,120,101,115, 0, 42,101,100,105,116,102,111, +110,116, 0,102, 97,109,105,108,121, 91, 50, 52, 93, 0, 42,118,102,111,110,116, 0, 42,118,102,111,110,116, 98, 0, 42,118,102, +111,110,116,105, 0, 42,118,102,111,110,116, 98,105, 0,115,101,112, 99,104, 97,114, 0,116,111,116, 98,111,120, 0, 97, 99,116, + 98,111,120, 0, 42,116, 98, 0,115,101,108,115,116, 97,114,116, 0,115,101,108,101,110,100, 0, 42,115,116,114,105,110,102,111, + 0, 99,117,114,105,110,102,111, 0, 42,109,115,101,108,101, 99,116, 0, 42,109,112,111,108,121, 0, 42,109,116,112,111,108,121, + 0, 42,109,108,111,111,112, 0, 42,109,108,111,111,112,117,118, 0, 42,109,108,111,111,112, 99,111,108, 0, 42,109,102, 97, 99, +101, 0, 42,109,116,102, 97, 99,101, 0, 42,116,102, 97, 99,101, 0, 42,109,118,101,114,116, 0, 42,109,101,100,103,101, 0, 42, +100,118,101,114,116, 0, 42,109, 99,111,108, 0, 42,109,115,116,105, 99,107,121, 0, 42,116,101,120, 99,111,109,101,115,104, 0, + 42,101,100,105,116, 95, 98,116,109,101,115,104, 0,118,100, 97,116, 97, 0,101,100, 97,116, 97, 0,102,100, 97,116, 97, 0,112, +100, 97,116, 97, 0,108,100, 97,116, 97, 0,116,111,116,101,100,103,101, 0,116,111,116,102, 97, 99,101, 0,116,111,116,115,101, +108,101, 99,116, 0,116,111,116,112,111,108,121, 0,116,111,116,108,111,111,112, 0, 97, 99,116, 95,102, 97, 99,101, 0,115,109, +111,111,116,104,114,101,115,104, 0,115,117, 98,100,105,118, 0,115,117, 98,100,105,118,114, 0,115,117, 98,115,117,114,102,116, +121,112,101, 0,101,100,105,116,102,108, 97,103, 0, 42,109,114, 0, 42,116,112, 97,103,101, 0,117,118, 91, 52, 93, 91, 50, 93, + 0, 99,111,108, 91, 52, 93, 0,116,114, 97,110,115,112, 0,116,105,108,101, 0,117,110,119,114, 97,112, 0,118, 49, 0,118, 50, + 0,118, 51, 0,118, 52, 0,101,100, 99,111,100,101, 0, 99,114,101, 97,115,101, 0, 98,119,101,105,103,104,116, 0,100,101,102, + 95,110,114, 0, 42,100,119, 0,116,111,116,119,101,105,103,104,116, 0, 99,111, 91, 51, 93, 0,110,111, 91, 51, 93, 0,108,111, +111,112,115,116, 97,114,116, 0,118, 0,101, 0,117,118, 91, 50, 93, 0, 99,111, 91, 50, 93, 0,102, 0,105, 0,115, 91, 50, 53, + 54, 93, 0,116,111,116,100,105,115,112, 0,108,101,118,101,108, 0, 40, 42,100,105,115,112,115, 41, 40, 41, 0, 42,104,105,100, +100,101,110, 0,118, 91, 52, 93, 0,109,105,100, 0,112, 97,100, 91, 50, 93, 0,118, 91, 50, 93, 0, 42,102, 97, 99,101,115, 0, + 42, 99,111,108,102, 97, 99,101,115, 0, 42,101,100,103,101,115, 0, 42,118,101,114,116,115, 0,108,101,118,101,108,115, 0,108, +101,118,101,108, 95, 99,111,117,110,116, 0, 99,117,114,114,101,110,116, 0,110,101,119,108,118,108, 0,101,100,103,101,108,118, +108, 0,112,105,110,108,118,108, 0,114,101,110,100,101,114,108,118,108, 0,117,115,101, 95, 99,111,108, 0, 42,101,100,103,101, + 95,102,108, 97,103,115, 0, 42,101,100,103,101, 95, 99,114,101, 97,115,101,115, 0,115,116, 97, 99,107,105,110,100,101,120, 0, + 42,101,114,114,111,114, 0,109,111,100,105,102,105,101,114, 0, 42,116,101,120,116,117,114,101, 0, 42,109, 97,112, 95,111, 98, +106,101, 99,116, 0,117,118,108, 97,121,101,114, 95,110, 97,109,101, 91, 54, 52, 93, 0,117,118,108, 97,121,101,114, 95,116,109, +112, 0,116,101,120,109, 97,112,112,105,110,103, 0,115,117, 98,100,105,118, 84,121,112,101, 0,114,101,110,100,101,114, 76,101, +118,101,108,115, 0, 42,101,109, 67, 97, 99,104,101, 0, 42,109, 67, 97, 99,104,101, 0,115,116,114,101,110,103,116,104, 0,100, +101,102, 97,120,105,115, 0,112, 97,100, 91, 54, 93, 0,108,101,110,103,116,104, 0,114, 97,110,100,111,109,105,122,101, 0,115, +101,101,100, 0, 42,111, 98, 95, 97,114,109, 0, 42,115,116, 97,114,116, 95, 99, 97,112, 0, 42,101,110,100, 95, 99, 97,112, 0, + 42, 99,117,114,118,101, 95,111, 98, 0, 42,111,102,102,115,101,116, 95,111, 98, 0,111,102,102,115,101,116, 91, 51, 93, 0,115, + 99, 97,108,101, 91, 51, 93, 0,109,101,114,103,101, 95,100,105,115,116, 0,102,105,116, 95,116,121,112,101, 0,111,102,102,115, +101,116, 95,116,121,112,101, 0, 99,111,117,110,116, 0, 97,120,105,115, 0,116,111,108,101,114, 97,110, 99,101, 0, 42,109,105, +114,114,111,114, 95,111, 98, 0,115,112,108,105,116, 95, 97,110,103,108,101, 0,118, 97,108,117,101, 0,114,101,115, 0,118, 97, +108, 95,102,108, 97,103,115, 0,108,105,109, 95,102,108, 97,103,115, 0,101, 95,102,108, 97,103,115, 0, 98,101,118,101,108, 95, + 97,110,103,108,101, 0,100,101,102,103,114,112, 95,110, 97,109,101, 91, 54, 52, 93, 0, 42,100,111,109, 97,105,110, 0, 42,102, +108,111,119, 0, 42, 99,111,108,108, 0,116,105,109,101, 0,100,105,114,101, 99,116,105,111,110, 0,109,105,100,108,101,118,101, +108, 0, 42,112,114,111,106,101, 99,116,111,114,115, 91, 49, 48, 93, 0, 42,105,109, 97,103,101, 0,110,117,109, 95,112,114,111, +106,101, 99,116,111,114,115, 0, 97,115,112,101, 99,116,120, 0, 97,115,112,101, 99,116,121, 0,115, 99, 97,108,101,120, 0,115, + 99, 97,108,101,121, 0,112,101,114, 99,101,110,116, 0,102, 97, 99,101, 67,111,117,110,116, 0,102, 97, 99, 0,114,101,112,101, + 97,116, 0, 42,111, 98,106,101, 99,116, 99,101,110,116,101,114, 0,115,116, 97,114,116,120, 0,115,116, 97,114,116,121, 0,104, +101,105,103,104,116, 0,110, 97,114,114,111,119, 0,115,112,101,101,100, 0,100, 97,109,112, 0,102, 97,108,108,111,102,102, 0, +116,105,109,101,111,102,102,115, 0,108,105,102,101,116,105,109,101, 0,100,101,102,111,114,109,102,108, 97,103, 0,109,117,108, +116,105, 0, 42,112,114,101,118, 67,111,115, 0,115,117, 98,116, 97,114,103,101,116, 91, 54, 52, 93, 0,112, 97,114,101,110,116, +105,110,118, 91, 52, 93, 91, 52, 93, 0, 99,101,110,116, 91, 51, 93, 0, 42,105,110,100,101,120, 97,114, 0,116,111,116,105,110, +100,101,120, 0,102,111,114, 99,101, 0, 42, 99,108,111,116,104, 79, 98,106,101, 99,116, 0, 42,115,105,109, 95,112, 97,114,109, +115, 0, 42, 99,111,108,108, 95,112, 97,114,109,115, 0, 42,112,111,105,110,116, 95, 99, 97, 99,104,101, 0,112,116, 99, 97, 99, +104,101,115, 0, 42,120, 0, 42,120,110,101,119, 0, 42,120,111,108,100, 0, 42, 99,117,114,114,101,110,116, 95,120,110,101,119, + 0, 42, 99,117,114,114,101,110,116, 95,120, 0, 42, 99,117,114,114,101,110,116, 95,118, 0, 42,109,102, 97, 99,101,115, 0,110, +117,109,118,101,114,116,115, 0,110,117,109,102, 97, 99,101,115, 0,116,105,109,101, 95,120, 0,116,105,109,101, 95,120,110,101, +119, 0, 42, 98,118,104,116,114,101,101, 0, 42,118, 0, 42,100,109, 0, 99,102,114, 97, 0,111,112,101,114, 97,116,105,111,110, + 0,118,101,114,116,101,120, 0,116,111,116,105,110,102,108,117,101,110, 99,101, 0,103,114,105,100,115,105,122,101, 0, 42, 98, +105,110,100,105,110,102,108,117,101,110, 99,101,115, 0, 42, 98,105,110,100,111,102,102,115,101,116,115, 0, 42, 98,105,110,100, + 99, 97,103,101, 99,111,115, 0,116,111,116, 99, 97,103,101,118,101,114,116, 0, 42,100,121,110,103,114,105,100, 0, 42,100,121, +110,105,110,102,108,117,101,110, 99,101,115, 0, 42,100,121,110,118,101,114,116,115, 0, 42,112, 97,100, 50, 0,100,121,110,103, +114,105,100,115,105,122,101, 0,100,121,110, 99,101,108,108,109,105,110, 91, 51, 93, 0,100,121,110, 99,101,108,108,119,105,100, +116,104, 0, 98,105,110,100,109, 97,116, 91, 52, 93, 91, 52, 93, 0, 42, 98,105,110,100,119,101,105,103,104,116,115, 0, 42, 98, +105,110,100, 99,111,115, 0, 40, 42, 98,105,110,100,102,117,110, 99, 41, 40, 41, 0, 42,112,115,121,115, 0,116,111,116,100,109, +118,101,114,116, 0,116,111,116,100,109,101,100,103,101, 0,116,111,116,100,109,102, 97, 99,101, 0,112,111,115,105,116,105,111, +110, 0,114, 97,110,100,111,109, 95,112,111,115,105,116,105,111,110, 0, 42,102, 97, 99,101,112, 97, 0,118,103,114,111,117,112, + 0,112,114,111,116,101, 99,116, 0,108,118,108, 0,115, 99,117,108,112,116,108,118,108, 0,116,111,116,108,118,108, 0,115,105, +109,112,108,101, 0, 42,102,115,115, 0, 42,116, 97,114,103,101,116, 0, 42, 97,117,120, 84, 97,114,103,101,116, 0,118,103,114, +111,117,112, 95,110, 97,109,101, 91, 54, 52, 93, 0,107,101,101,112, 68,105,115,116, 0,115,104,114,105,110,107, 84,121,112,101, + 0,115,104,114,105,110,107, 79,112,116,115, 0,112,114,111,106, 65,120,105,115, 0,115,117, 98,115,117,114,102, 76,101,118,101, +108,115, 0, 42,111,114,105,103,105,110, 0,102, 97, 99,116,111,114, 0,108,105,109,105,116, 91, 50, 93, 0,111,114,105,103,105, +110, 79,112,116,115, 0,111,102,102,115,101,116, 95,102, 97, 99, 0,111,102,102,115,101,116, 95,102, 97, 99, 95,118,103, 0, 99, +114,101, 97,115,101, 95,105,110,110,101,114, 0, 99,114,101, 97,115,101, 95,111,117,116,101,114, 0, 99,114,101, 97,115,101, 95, +114,105,109, 0,109, 97,116, 95,111,102,115, 0,109, 97,116, 95,111,102,115, 95,114,105,109, 0, 42,111, 98, 95, 97,120,105,115, + 0,115,116,101,112,115, 0,114,101,110,100,101,114, 95,115,116,101,112,115, 0,105,116,101,114, 0,115, 99,114,101,119, 95,111, +102,115, 0, 97,110,103,108,101, 0, 42,111, 99,101, 97,110, 0, 42,111, 99,101, 97,110, 99, 97, 99,104,101, 0,114,101,115,111, +108,117,116,105,111,110, 0,115,112, 97,116,105, 97,108, 95,115,105,122,101, 0,119,105,110,100, 95,118,101,108,111, 99,105,116, +121, 0,115,109, 97,108,108,101,115,116, 95,119, 97,118,101, 0,119, 97,118,101, 95, 97,108,105,103,110,109,101,110,116, 0,119, + 97,118,101, 95,100,105,114,101, 99,116,105,111,110, 0,119, 97,118,101, 95,115, 99, 97,108,101, 0, 99,104,111,112, 95, 97,109, +111,117,110,116, 0,102,111, 97,109, 95, 99,111,118,101,114, 97,103,101, 0, 98, 97,107,101,115,116, 97,114,116, 0, 98, 97,107, +101,101,110,100, 0, 99, 97, 99,104,101,112, 97,116,104, 91, 49, 48, 50, 52, 93, 0,102,111, 97,109,108, 97,121,101,114,110, 97, +109,101, 91, 54, 52, 93, 0, 99, 97, 99,104,101,100, 0,103,101,111,109,101,116,114,121, 95,109,111,100,101, 0,114,101,102,114, +101,115,104, 0,114,101,112,101, 97,116, 95,120, 0,114,101,112,101, 97,116, 95,121, 0,102,111, 97,109, 95,102, 97,100,101, 0, + 42,111, 98,106,101, 99,116, 95,102,114,111,109, 0, 42,111, 98,106,101, 99,116, 95,116,111, 0,102, 97,108,108,111,102,102, 95, +114, 97,100,105,117,115, 0,101,100,105,116, 95,102,108, 97,103,115, 0,100,101,102, 97,117,108,116, 95,119,101,105,103,104,116, + 0, 42, 99,109, 97,112, 95, 99,117,114,118,101, 0, 97,100,100, 95,116,104,114,101,115,104,111,108,100, 0,114,101,109, 95,116, +104,114,101,115,104,111,108,100, 0,109, 97,115,107, 95, 99,111,110,115,116, 97,110,116, 0,109, 97,115,107, 95,100,101,102,103, +114,112, 95,110, 97,109,101, 91, 54, 52, 93, 0,109, 97,115,107, 95,116,101,120, 95,117,115,101, 95, 99,104, 97,110,110,101,108, + 0, 42,109, 97,115,107, 95,116,101,120,116,117,114,101, 0, 42,109, 97,115,107, 95,116,101,120, 95,109, 97,112, 95,111, 98,106, + 0,109, 97,115,107, 95,116,101,120, 95,109, 97,112,112,105,110,103, 0,109, 97,115,107, 95,116,101,120, 95,117,118,108, 97,121, +101,114, 95,110, 97,109,101, 91, 54, 52, 93, 0,112, 97,100, 95,105, 49, 0,100,101,102,103,114,112, 95,110, 97,109,101, 95, 97, + 91, 54, 52, 93, 0,100,101,102,103,114,112, 95,110, 97,109,101, 95, 98, 91, 54, 52, 93, 0,100,101,102, 97,117,108,116, 95,119, +101,105,103,104,116, 95, 97, 0,100,101,102, 97,117,108,116, 95,119,101,105,103,104,116, 95, 98, 0,109,105,120, 95,109,111,100, +101, 0,109,105,120, 95,115,101,116, 0,112, 97,100, 95, 99, 49, 91, 54, 93, 0,112,114,111,120,105,109,105,116,121, 95,109,111, +100,101, 0,112,114,111,120,105,109,105,116,121, 95,102,108, 97,103,115, 0, 42,112,114,111,120,105,109,105,116,121, 95,111, 98, + 95,116, 97,114,103,101,116, 0,109,105,110, 95,100,105,115,116, 0,109, 97,120, 95,100,105,115,116, 0,112, 97,100, 95,115, 49, + 0, 42, 99, 97,110,118, 97,115, 0, 42, 98,114,117,115,104, 0,116,104,114,101,115,104,111,108,100, 0,115, 99, 97,108,101, 0, +104,101,114,109,105,116,101, 95,110,117,109, 0, 42,108, 97,116,116, 0,112,110,116,115,119, 0,111,112,110,116,115,117, 0,111, +112,110,116,115,118, 0,111,112,110,116,115,119, 0,116,121,112,101,117, 0,116,121,112,101,118, 0,116,121,112,101,119, 0,102, +117, 0,102,118, 0,102,119, 0,100,117, 0,100,118, 0,100,119, 0, 42,100,101,102, 0, 42,108, 97,116,116,105, 99,101,100, 97, +116, 97, 0,108, 97,116,109, 97,116, 91, 52, 93, 91, 52, 93, 0, 42,101,100,105,116,108, 97,116,116, 0,118,101, 99, 91, 56, 93, + 91, 51, 93, 0, 42,115, 99,117,108,112,116, 0,112, 97,114,116,121,112,101, 0,112, 97,114, 49, 0,112, 97,114, 50, 0,112, 97, +114, 51, 0,112, 97,114,115,117, 98,115,116,114, 91, 54, 52, 93, 0, 42,116,114, 97, 99,107, 0, 42,112,114,111,120,121, 0, 42, +112,114,111,120,121, 95,103,114,111,117,112, 0, 42,112,114,111,120,121, 95,102,114,111,109, 0, 42, 97, 99,116,105,111,110, 0, + 42,112,111,115,101,108,105, 98, 0, 42,112,111,115,101, 0, 42,103,112,100, 0, 97,118,115, 0, 42,109,112, 97,116,104, 0, 99, +111,110,115,116,114, 97,105,110,116, 67,104, 97,110,110,101,108,115, 0,101,102,102,101, 99,116, 0,100,101,102, 98, 97,115,101, + 0,109,111,100,105,102,105,101,114,115, 0,114,101,115,116,111,114,101, 95,109,111,100,101, 0, 42,109, 97,116, 98,105,116,115, + 0, 97, 99,116, 99,111,108, 0,100,108,111, 99, 91, 51, 93, 0,111,114,105,103, 91, 51, 93, 0,100,115,105,122,101, 91, 51, 93, + 0,100,115, 99, 97,108,101, 91, 51, 93, 0,100,114,111,116, 91, 51, 93, 0,100,113,117, 97,116, 91, 52, 93, 0,114,111,116, 65, +120,105,115, 91, 51, 93, 0,100,114,111,116, 65,120,105,115, 91, 51, 93, 0,114,111,116, 65,110,103,108,101, 0,100,114,111,116, + 65,110,103,108,101, 0,111, 98,109, 97,116, 91, 52, 93, 91, 52, 93, 0, 99,111,110,115,116,105,110,118, 91, 52, 93, 91, 52, 93, + 0,105,109, 97,116, 95,114,101,110, 91, 52, 93, 91, 52, 93, 0,108, 97,121, 0,112, 97,100, 54, 0, 99,111,108, 98,105,116,115, + 0,116,114, 97,110,115,102,108, 97,103, 0,112,114,111,116,101, 99,116,102,108, 97,103, 0,116,114, 97, 99,107,102,108, 97,103, + 0,117,112,102,108, 97,103, 0,110,108, 97,102,108, 97,103, 0,105,112,111,102,108, 97,103, 0,115, 99, 97,102,108, 97,103, 0, +115, 99, 97,118,105,115,102,108, 97,103, 0,112, 97,100, 53, 0,100,117,112,111,110, 0,100,117,112,111,102,102, 0,100,117,112, +115,116, 97, 0,100,117,112,101,110,100, 0,115,102, 0,109, 97,115,115, 0,100, 97,109,112,105,110,103, 0,105,110,101,114,116, +105, 97, 0,102,111,114,109,102, 97, 99,116,111,114, 0,114,100, 97,109,112,105,110,103, 0,109, 97,114,103,105,110, 0,109, 97, +120, 95,118,101,108, 0,109,105,110, 95,118,101,108, 0,109, 95, 99,111,110,116, 97, 99,116, 80,114,111, 99,101,115,115,105,110, +103, 84,104,114,101,115,104,111,108,100, 0,111, 98,115,116, 97, 99,108,101, 82, 97,100, 0,114,111,116,109,111,100,101, 0, 98, +111,117,110,100,116,121,112,101, 0, 99,111,108,108,105,115,105,111,110, 95, 98,111,117,110,100,116,121,112,101, 0,114,101,115, +116,114,105, 99,116,102,108, 97,103, 0,100,116, 0,101,109,112,116,121, 95,100,114, 97,119,116,121,112,101, 0,101,109,112,116, +121, 95,100,114, 97,119,115,105,122,101, 0,100,117,112,102, 97, 99,101,115, 99, 97, 0,112,114,111,112, 0,115,101,110,115,111, +114,115, 0, 99,111,110,116,114,111,108,108,101,114,115, 0, 97, 99,116,117, 97,116,111,114,115, 0, 98, 98,115,105,122,101, 91, + 51, 93, 0, 97, 99,116,100,101,102, 0,103, 97,109,101,102,108, 97,103, 0,103, 97,109,101,102,108, 97,103, 50, 0, 42, 98,115, +111,102,116, 0,115,111,102,116,102,108, 97,103, 0, 97,110,105,115,111,116,114,111,112,105, 99, 70,114,105, 99,116,105,111,110, + 91, 51, 93, 0, 99,111,110,115,116,114, 97,105,110,116,115, 0,110,108, 97,115,116,114,105,112,115, 0,104,111,111,107,115, 0, +112, 97,114,116,105, 99,108,101,115,121,115,116,101,109, 0, 42,115,111,102,116, 0, 42,100,117,112, 95,103,114,111,117,112, 0, + 98,111,100,121, 95,116,121,112,101, 0,115,104, 97,112,101,102,108, 97,103, 0, 42,102,108,117,105,100,115,105,109, 83,101,116, +116,105,110,103,115, 0, 42,100,101,114,105,118,101,100, 68,101,102,111,114,109, 0, 42,100,101,114,105,118,101,100, 70,105,110, + 97,108, 0,108, 97,115,116, 68, 97,116, 97, 77, 97,115,107, 0, 99,117,115,116,111,109,100, 97,116, 97, 95,109, 97,115,107, 0, +115,116, 97,116,101, 0,105,110,105,116, 95,115,116, 97,116,101, 0,103,112,117,108, 97,109,112, 0,112, 99, 95,105,100,115, 0, + 42,100,117,112,108,105,108,105,115,116, 0,105,109, 97, 95,111,102,115, 91, 50, 93, 0, 99,117,114,105,110,100,101,120, 0, 97, + 99,116,105,118,101, 0,111,114,105,103,108, 97,121, 0,111,109, 97,116, 91, 52, 93, 91, 52, 93, 0,111,114, 99,111, 91, 51, 93, + 0,110,111, 95,100,114, 97,119, 0, 97,110,105,109, 97,116,101,100, 0,100,101,102,108,101, 99,116, 0,102,111,114, 99,101,102, +105,101,108,100, 0,115,104, 97,112,101, 0,116,101,120, 95,109,111,100,101, 0,107,105,110,107, 0,107,105,110,107, 95, 97,120, +105,115, 0,122,100,105,114, 0,102, 95,115,116,114,101,110,103,116,104, 0,102, 95,100, 97,109,112, 0,102, 95,102,108,111,119, + 0,102, 95,115,105,122,101, 0,102, 95,112,111,119,101,114, 0,109, 97,120,100,105,115,116, 0,109,105,110,100,105,115,116, 0, +102, 95,112,111,119,101,114, 95,114, 0,109, 97,120,114, 97,100, 0,109,105,110,114, 97,100, 0,112,100,101,102, 95,100, 97,109, +112, 0,112,100,101,102, 95,114,100, 97,109,112, 0,112,100,101,102, 95,112,101,114,109, 0,112,100,101,102, 95,102,114,105, 99, +116, 0,112,100,101,102, 95,114,102,114,105, 99,116, 0,112,100,101,102, 95,115,116,105, 99,107,110,101,115,115, 0, 97, 98,115, +111,114,112,116,105,111,110, 0,112,100,101,102, 95,115, 98,100, 97,109,112, 0,112,100,101,102, 95,115, 98,105,102,116, 0,112, +100,101,102, 95,115, 98,111,102,116, 0, 99,108,117,109,112, 95,102, 97, 99, 0, 99,108,117,109,112, 95,112,111,119, 0,107,105, +110,107, 95,102,114,101,113, 0,107,105,110,107, 95,115,104, 97,112,101, 0,107,105,110,107, 95, 97,109,112, 0,102,114,101,101, + 95,101,110,100, 0,116,101,120, 95,110, 97, 98,108, 97, 0, 42,114,110,103, 0,102, 95,110,111,105,115,101, 0,119,101,105,103, +104,116, 91, 49, 51, 93, 0,103,108,111, 98, 97,108, 95,103,114, 97,118,105,116,121, 0,114,116, 91, 51, 93, 0,116,111,116,100, + 97,116, 97, 0,102,114, 97,109,101, 0,116,111,116,112,111,105,110,116, 0,100, 97,116, 97, 95,116,121,112,101,115, 0, 42,100, + 97,116, 97, 91, 56, 93, 0, 42, 99,117,114, 91, 56, 93, 0,101,120,116,114, 97,100, 97,116, 97, 0,115,116,101,112, 0,115,105, +109,102,114, 97,109,101, 0,115,116, 97,114,116,102,114, 97,109,101, 0,101,110,100,102,114, 97,109,101, 0,101,100,105,116,102, +114, 97,109,101, 0,108, 97,115,116, 95,101,120, 97, 99,116, 0,108, 97,115,116, 95,118, 97,108,105,100, 0, 99,111,109,112,114, +101,115,115,105,111,110, 0,112,114,101,118, 95,110, 97,109,101, 91, 54, 52, 93, 0,105,110,102,111, 91, 54, 52, 93, 0,112, 97, +116,104, 91, 49, 48, 50, 52, 93, 0, 42, 99, 97, 99,104,101,100, 95,102,114, 97,109,101,115, 0,109,101,109, 95, 99, 97, 99,104, +101, 0, 42,101,100,105,116, 0, 40, 42,102,114,101,101, 95,101,100,105,116, 41, 40, 41, 0,108,105,110, 83,116,105,102,102, 0, + 97,110,103, 83,116,105,102,102, 0,118,111,108,117,109,101, 0,118,105,116,101,114, 97,116,105,111,110,115, 0,112,105,116,101, +114, 97,116,105,111,110,115, 0,100,105,116,101,114, 97,116,105,111,110,115, 0, 99,105,116,101,114, 97,116,105,111,110,115, 0, +107, 83, 82, 72, 82, 95, 67, 76, 0,107, 83, 75, 72, 82, 95, 67, 76, 0,107, 83, 83, 72, 82, 95, 67, 76, 0,107, 83, 82, 95, 83, + 80, 76, 84, 95, 67, 76, 0,107, 83, 75, 95, 83, 80, 76, 84, 95, 67, 76, 0,107, 83, 83, 95, 83, 80, 76, 84, 95, 67, 76, 0,107, + 86, 67, 70, 0,107, 68, 80, 0,107, 68, 71, 0,107, 76, 70, 0,107, 80, 82, 0,107, 86, 67, 0,107, 68, 70, 0,107, 77, 84, 0, +107, 67, 72, 82, 0,107, 75, 72, 82, 0,107, 83, 72, 82, 0,107, 65, 72, 82, 0, 99,111,108,108,105,115,105,111,110,102,108, 97, +103,115, 0,110,117,109, 99,108,117,115,116,101,114,105,116,101,114, 97,116,105,111,110,115, 0,119,101,108,100,105,110,103, 0, +116,111,116,115,112,114,105,110,103, 0, 42, 98,112,111,105,110,116, 0, 42, 98,115,112,114,105,110,103, 0,109,115,103, 95,108, +111, 99,107, 0,109,115,103, 95,118, 97,108,117,101, 0,110,111,100,101,109, 97,115,115, 0,110, 97,109,101,100, 86, 71, 95, 77, + 97,115,115, 91, 54, 52, 93, 0,103,114, 97,118, 0,109,101,100,105, 97,102,114,105, 99,116, 0,114,107,108,105,109,105,116, 0, +112,104,121,115,105, 99,115, 95,115,112,101,101,100, 0,103,111, 97,108,115,112,114,105,110,103, 0,103,111, 97,108,102,114,105, + 99,116, 0,109,105,110,103,111, 97,108, 0,109, 97,120,103,111, 97,108, 0,100,101,102,103,111, 97,108, 0,118,101,114,116,103, +114,111,117,112, 0,110, 97,109,101,100, 86, 71, 95, 83,111,102,116,103,111, 97,108, 91, 54, 52, 93, 0,102,117,122,122,121,110, +101,115,115, 0,105,110,115,112,114,105,110,103, 0,105,110,102,114,105, 99,116, 0,110, 97,109,101,100, 86, 71, 95, 83,112,114, +105,110,103, 95, 75, 91, 54, 52, 93, 0,101,102,114, 97, 0,105,110,116,101,114,118, 97,108, 0,108,111, 99, 97,108, 0,115,111, +108,118,101,114,102,108, 97,103,115, 0, 42, 42,107,101,121,115, 0,116,111,116,112,111,105,110,116,107,101,121, 0,115,101, 99, +111,110,100,115,112,114,105,110,103, 0, 99,111,108, 98, 97,108,108, 0, 98, 97,108,108,100, 97,109,112, 0, 98, 97,108,108,115, +116,105,102,102, 0,115, 98, 99, 95,109,111,100,101, 0, 97,101,114,111,101,100,103,101, 0,109,105,110,108,111,111,112,115, 0, +109, 97,120,108,111,111,112,115, 0, 99,104,111,107,101, 0,115,111,108,118,101,114, 95, 73, 68, 0,112,108, 97,115,116,105, 99, + 0,115,112,114,105,110,103,112,114,101,108,111, 97,100, 0, 42,115, 99,114, 97,116, 99,104, 0,115,104,101, 97,114,115,116,105, +102,102, 0,105,110,112,117,115,104, 0, 42,112,111,105,110,116, 99, 97, 99,104,101, 0, 42,101,102,102,101, 99,116,111,114, 95, +119,101,105,103,104,116,115, 0,108, 99,111,109, 91, 51, 93, 0,108,114,111,116, 91, 51, 93, 91, 51, 93, 0,108,115, 99, 97,108, +101, 91, 51, 93, 91, 51, 93, 0,108, 97,115,116, 95,102,114, 97,109,101, 0,118,101,108, 91, 51, 93, 0, 42,102,109,100, 0,115, +104,111,119, 95, 97,100,118, 97,110, 99,101,100,111,112,116,105,111,110,115, 0,114,101,115,111,108,117,116,105,111,110,120,121, +122, 0,112,114,101,118,105,101,119,114,101,115,120,121,122, 0,114,101, 97,108,115,105,122,101, 0,103,117,105, 68,105,115,112, +108, 97,121, 77,111,100,101, 0,114,101,110,100,101,114, 68,105,115,112,108, 97,121, 77,111,100,101, 0,118,105,115, 99,111,115, +105,116,121, 86, 97,108,117,101, 0,118,105,115, 99,111,115,105,116,121, 77,111,100,101, 0,118,105,115, 99,111,115,105,116,121, + 69,120,112,111,110,101,110,116, 0,103,114, 97,118, 91, 51, 93, 0, 97,110,105,109, 83,116, 97,114,116, 0, 97,110,105,109, 69, +110,100, 0, 98, 97,107,101, 83,116, 97,114,116, 0, 98, 97,107,101, 69,110,100, 0,102,114, 97,109,101, 79,102,102,115,101,116, + 0,103,115,116, 97,114, 0,109, 97,120, 82,101,102,105,110,101, 0,105,110,105, 86,101,108,120, 0,105,110,105, 86,101,108,121, + 0,105,110,105, 86,101,108,122, 0, 42,111,114,103, 77,101,115,104, 0, 42,109,101,115,104, 66, 66, 0,115,117,114,102,100, 97, +116, 97, 80, 97,116,104, 91, 49, 48, 50, 52, 93, 0, 98, 98, 83,116, 97,114,116, 91, 51, 93, 0, 98, 98, 83,105,122,101, 91, 51, + 93, 0,116,121,112,101, 70,108, 97,103,115, 0,100,111,109, 97,105,110, 78,111,118,101, 99,103,101,110, 0,118,111,108,117,109, +101, 73,110,105,116, 84,121,112,101, 0,112, 97,114,116, 83,108,105,112, 86, 97,108,117,101, 0,103,101,110,101,114, 97,116,101, + 84,114, 97, 99,101,114,115, 0,103,101,110,101,114, 97,116,101, 80, 97,114,116,105, 99,108,101,115, 0,115,117,114,102, 97, 99, +101, 83,109,111,111,116,104,105,110,103, 0,115,117,114,102, 97, 99,101, 83,117, 98,100,105,118,115, 0,112, 97,114,116,105, 99, +108,101, 73,110,102, 83,105,122,101, 0,112, 97,114,116,105, 99,108,101, 73,110,102, 65,108,112,104, 97, 0,102, 97,114, 70,105, +101,108,100, 83,105,122,101, 0, 42,109,101,115,104, 86,101,108,111, 99,105,116,105,101,115, 0, 99,112,115, 84,105,109,101, 83, +116, 97,114,116, 0, 99,112,115, 84,105,109,101, 69,110,100, 0, 99,112,115, 81,117, 97,108,105,116,121, 0, 97,116,116,114, 97, + 99,116,102,111,114, 99,101, 83,116,114,101,110,103,116,104, 0, 97,116,116,114, 97, 99,116,102,111,114, 99,101, 82, 97,100,105, +117,115, 0,118,101,108,111, 99,105,116,121,102,111,114, 99,101, 83,116,114,101,110,103,116,104, 0,118,101,108,111, 99,105,116, +121,102,111,114, 99,101, 82, 97,100,105,117,115, 0,108, 97,115,116,103,111,111,100,102,114, 97,109,101, 0, 97,110,105,109, 82, + 97,116,101, 0,109,105,115,116,121,112,101, 0,104,111,114,114, 0,104,111,114,103, 0,104,111,114, 98, 0,122,101,110,114, 0, +122,101,110,103, 0,122,101,110, 98, 0,102, 97,115,116, 99,111,108, 0,101,120,112,111,115,117,114,101, 0,101,120,112, 0,114, + 97,110,103,101, 0,108,105,110,102, 97, 99, 0,108,111,103,102, 97, 99, 0,103,114, 97,118,105,116,121, 0, 97, 99,116,105,118, +105,116,121, 66,111,120, 82, 97,100,105,117,115, 0,115,107,121,116,121,112,101, 0,111, 99, 99,108,117,115,105,111,110, 82,101, +115, 0,112,104,121,115,105, 99,115, 69,110,103,105,110,101, 0,116,105, 99,114, 97,116,101, 0,109, 97,120,108,111,103,105, 99, +115,116,101,112, 0,112,104,121,115,117, 98,115,116,101,112, 0,109, 97,120,112,104,121,115,116,101,112, 0,109,105,115,105, 0, +109,105,115,116,115,116, 97, 0,109,105,115,116,100,105,115,116, 0,109,105,115,116,104,105, 0,115,116, 97,114,114, 0,115,116, + 97,114,103, 0,115,116, 97,114, 98, 0,115,116, 97,114,107, 0,115,116, 97,114,115,105,122,101, 0,115,116, 97,114,109,105,110, +100,105,115,116, 0,115,116, 97,114,100,105,115,116, 0,115,116, 97,114, 99,111,108,110,111,105,115,101, 0,100,111,102,115,116, + 97, 0,100,111,102,101,110,100, 0,100,111,102,109,105,110, 0,100,111,102,109, 97,120, 0, 97,111,100,105,115,116, 0, 97,111, +100,105,115,116,102, 97, 99, 0, 97,111,101,110,101,114,103,121, 0, 97,111, 98,105, 97,115, 0, 97,111,109,111,100,101, 0, 97, +111,115, 97,109,112, 0, 97,111,109,105,120, 0, 97,111, 99,111,108,111,114, 0, 97,111, 95, 97,100, 97,112,116, 95,116,104,114, +101,115,104, 0, 97,111, 95, 97,100, 97,112,116, 95,115,112,101,101,100, 95,102, 97, 99, 0, 97,111, 95, 97,112,112,114,111,120, + 95,101,114,114,111,114, 0, 97,111, 95, 97,112,112,114,111,120, 95, 99,111,114,114,101, 99,116,105,111,110, 0, 97,111, 95,105, +110,100,105,114,101, 99,116, 95,101,110,101,114,103,121, 0, 97,111, 95,101,110,118, 95,101,110,101,114,103,121, 0, 97,111, 95, +112, 97,100, 50, 0, 97,111, 95,105,110,100,105,114,101, 99,116, 95, 98,111,117,110, 99,101,115, 0, 97,111, 95,112, 97,100, 0, + 97,111, 95,115, 97,109,112, 95,109,101,116,104,111,100, 0, 97,111, 95,103, 97,116,104,101,114, 95,109,101,116,104,111,100, 0, + 97,111, 95, 97,112,112,114,111,120, 95,112, 97,115,115,101,115, 0, 42, 97,111,115,112,104,101,114,101, 0, 42, 97,111,116, 97, + 98,108,101,115, 0,115,101,108, 99,111,108, 0,115,120, 0,115,121, 0, 42,108,112, 70,111,114,109, 97,116, 0, 42,108,112, 80, + 97,114,109,115, 0, 99, 98, 70,111,114,109, 97,116, 0, 99, 98, 80, 97,114,109,115, 0,102, 99, 99, 84,121,112,101, 0,102, 99, + 99, 72, 97,110,100,108,101,114, 0,100,119, 75,101,121, 70,114, 97,109,101, 69,118,101,114,121, 0,100,119, 81,117, 97,108,105, +116,121, 0,100,119, 66,121,116,101,115, 80,101,114, 83,101, 99,111,110,100, 0,100,119, 70,108, 97,103,115, 0,100,119, 73,110, +116,101,114,108,101, 97,118,101, 69,118,101,114,121, 0, 97,118,105, 99,111,100,101, 99,110, 97,109,101, 91, 49, 50, 56, 93, 0, + 42, 99,100, 80, 97,114,109,115, 0, 42,112, 97,100, 0, 99,100, 83,105,122,101, 0,113,116, 99,111,100,101, 99,110, 97,109,101, + 91, 49, 50, 56, 93, 0, 99,111,100,101, 99, 84,121,112,101, 0, 99,111,100,101, 99, 83,112, 97,116,105, 97,108, 81,117, 97,108, +105,116,121, 0, 99,111,100,101, 99, 0, 99,111,100,101, 99, 70,108, 97,103,115, 0, 99,111,108,111,114, 68,101,112,116,104, 0, + 99,111,100,101, 99, 84,101,109,112,111,114, 97,108, 81,117, 97,108,105,116,121, 0,109,105,110, 83,112, 97,116,105, 97,108, 81, +117, 97,108,105,116,121, 0,109,105,110, 84,101,109,112,111,114, 97,108, 81,117, 97,108,105,116,121, 0,107,101,121, 70,114, 97, +109,101, 82, 97,116,101, 0, 98,105,116, 82, 97,116,101, 0, 97,117,100,105,111, 99,111,100,101, 99, 84,121,112,101, 0, 97,117, +100,105,111, 83, 97,109,112,108,101, 82, 97,116,101, 0, 97,117,100,105,111, 66,105,116, 68,101,112,116,104, 0, 97,117,100,105, +111, 67,104, 97,110,110,101,108,115, 0, 97,117,100,105,111, 67,111,100,101, 99, 70,108, 97,103,115, 0, 97,117,100,105,111, 66, +105,116, 82, 97,116,101, 0, 97,117,100,105,111, 95, 99,111,100,101, 99, 0,118,105,100,101,111, 95, 98,105,116,114, 97,116,101, + 0, 97,117,100,105,111, 95, 98,105,116,114, 97,116,101, 0, 97,117,100,105,111, 95,109,105,120,114, 97,116,101, 0, 97,117,100, +105,111, 95, 99,104, 97,110,110,101,108,115, 0, 97,117,100,105,111, 95,112, 97,100, 0, 97,117,100,105,111, 95,118,111,108,117, +109,101, 0,103,111,112, 95,115,105,122,101, 0,114, 99, 95,109,105,110, 95,114, 97,116,101, 0,114, 99, 95,109, 97,120, 95,114, + 97,116,101, 0,114, 99, 95, 98,117,102,102,101,114, 95,115,105,122,101, 0,109,117,120, 95,112, 97, 99,107,101,116, 95,115,105, +122,101, 0,109,117,120, 95,114, 97,116,101, 0,109,105,120,114, 97,116,101, 0,109, 97,105,110, 0,115,112,101,101,100, 95,111, +102, 95,115,111,117,110,100, 0,100,111,112,112,108,101,114, 95,102, 97, 99,116,111,114, 0,100,105,115,116, 97,110, 99,101, 95, +109,111,100,101,108, 0, 42,109, 97,116, 95,111,118,101,114,114,105,100,101, 0, 42,108,105,103,104,116, 95,111,118,101,114,114, +105,100,101, 0,108, 97,121, 95,122,109, 97,115,107, 0,108, 97,121,102,108, 97,103, 0,112, 97,115,115,102,108, 97,103, 0,112, + 97,115,115, 95,120,111,114, 0,105,109,116,121,112,101, 0,112,108, 97,110,101,115, 0,113,117, 97,108,105,116,121, 0, 99,111, +109,112,114,101,115,115, 0,101,120,114, 95, 99,111,100,101, 99, 0, 99,105,110,101,111,110, 95,102,108, 97,103, 0, 99,105,110, +101,111,110, 95,119,104,105,116,101, 0, 99,105,110,101,111,110, 95, 98,108, 97, 99,107, 0, 99,105,110,101,111,110, 95,103, 97, +109,109, 97, 0,106,112, 50, 95,102,108, 97,103, 0,105,109, 95,102,111,114,109, 97,116, 0, 42, 97,118,105, 99,111,100,101, 99, +100, 97,116, 97, 0, 42,113,116, 99,111,100,101, 99,100, 97,116, 97, 0,113,116, 99,111,100,101, 99,115,101,116,116,105,110,103, +115, 0,102,102, 99,111,100,101, 99,100, 97,116, 97, 0,115,117, 98,102,114, 97,109,101, 0,112,115,102,114, 97, 0,112,101,102, +114, 97, 0,105,109, 97,103,101,115, 0,102,114, 97,109, 97,112,116,111, 0,116,104,114,101, 97,100,115, 0,102,114, 97,109,101, +108,101,110, 0, 98,108,117,114,102, 97, 99, 0,101,100,103,101, 82, 0,101,100,103,101, 71, 0,101,100,103,101, 66, 0,102,117, +108,108,115, 99,114,101,101,110, 0,120,112,108, 97,121, 0,121,112,108, 97,121, 0,102,114,101,113,112,108, 97,121, 0, 97,116, +116,114,105, 98, 0,102,114, 97,109,101, 95,115,116,101,112, 0,115,116,101,114,101,111,109,111,100,101, 0,100,105,109,101,110, +115,105,111,110,115,112,114,101,115,101,116, 0,109, 97,120,105,109,115,105,122,101, 0,120,115, 99,104, 0,121,115, 99,104, 0, +120,112, 97,114,116,115, 0,121,112, 97,114,116,115, 0,115,117, 98,105,109,116,121,112,101, 0,100,105,115,112,108, 97,121,109, +111,100,101, 0,115, 99,101,109,111,100,101, 0,114, 97,121,116,114, 97, 99,101, 95,111,112,116,105,111,110,115, 0,114, 97,121, +116,114, 97, 99,101, 95,115,116,114,117, 99,116,117,114,101, 0,111, 99,114,101,115, 0,112, 97,100, 52, 0, 97,108,112,104, 97, +109,111,100,101, 0,111,115, 97, 0,102,114,115, 95,115,101, 99, 0,101,100,103,101,105,110,116, 0,115, 97,102,101,116,121, 0, + 98,111,114,100,101,114, 0,100,105,115,112,114,101, 99,116, 0,108, 97,121,101,114,115, 0, 97, 99,116,108, 97,121, 0,109, 98, +108,117,114, 95,115, 97,109,112,108,101,115, 0,120, 97,115,112, 0,121, 97,115,112, 0,102,114,115, 95,115,101, 99, 95, 98, 97, +115,101, 0,103, 97,117,115,115, 0, 99,111,108,111,114, 95,109,103,116, 95,102,108, 97,103, 0,112,111,115,116,103, 97,109,109, + 97, 0,112,111,115,116,104,117,101, 0,112,111,115,116,115, 97,116, 0,100,105,116,104,101,114, 95,105,110,116,101,110,115,105, +116,121, 0, 98, 97,107,101, 95,111,115, 97, 0, 98, 97,107,101, 95,102,105,108,116,101,114, 0, 98, 97,107,101, 95,109,111,100, +101, 0, 98, 97,107,101, 95,102,108, 97,103, 0, 98, 97,107,101, 95,110,111,114,109, 97,108, 95,115,112, 97, 99,101, 0, 98, 97, +107,101, 95,113,117, 97,100, 95,115,112,108,105,116, 0, 98, 97,107,101, 95,109, 97,120,100,105,115,116, 0, 98, 97,107,101, 95, + 98,105, 97,115,100,105,115,116, 0, 98, 97,107,101, 95,112, 97,100, 0,112,105, 99, 91, 49, 48, 50, 52, 93, 0,115,116, 97,109, +112, 0,115,116, 97,109,112, 95,102,111,110,116, 95,105,100, 0,115,116, 97,109,112, 95,117,100, 97,116, 97, 91, 55, 54, 56, 93, + 0,102,103, 95,115,116, 97,109,112, 91, 52, 93, 0, 98,103, 95,115,116, 97,109,112, 91, 52, 93, 0,115,101,113, 95,112,114,101, +118, 95,116,121,112,101, 0,115,101,113, 95,114,101,110,100, 95,116,121,112,101, 0,115,101,113, 95,102,108, 97,103, 0,112, 97, +100, 53, 91, 53, 93, 0,115,105,109,112,108,105,102,121, 95,102,108, 97,103, 0,115,105,109,112,108,105,102,121, 95,115,117, 98, +115,117,114,102, 0,115,105,109,112,108,105,102,121, 95,115,104, 97,100,111,119,115, 97,109,112,108,101,115, 0,115,105,109,112, +108,105,102,121, 95,112, 97,114,116,105, 99,108,101,115, 0,115,105,109,112,108,105,102,121, 95, 97,111,115,115,115, 0, 99,105, +110,101,111,110,119,104,105,116,101, 0, 99,105,110,101,111,110, 98,108, 97, 99,107, 0, 99,105,110,101,111,110,103, 97,109,109, + 97, 0,106,112, 50, 95,112,114,101,115,101,116, 0,106,112, 50, 95,100,101,112,116,104, 0,114,112, 97,100, 51, 0,100,111,109, +101,114,101,115, 0,100,111,109,101,109,111,100,101, 0,100,111,109,101, 97,110,103,108,101, 0,100,111,109,101,116,105,108,116, + 0,100,111,109,101,114,101,115, 98,117,102, 0, 42,100,111,109,101,116,101,120,116, 0,101,110,103,105,110,101, 91, 51, 50, 93, + 0,110, 97,109,101, 91, 51, 50, 93, 0,112, 97,114,116,105, 99,108,101, 95,112,101,114, 99, 0,115,117, 98,115,117,114,102, 95, +109, 97,120, 0,115,104, 97,100, 98,117,102,115, 97,109,112,108,101, 95,109, 97,120, 0, 97,111, 95,101,114,114,111,114, 0,116, +105,108,116, 0,114,101,115, 98,117,102, 0, 42,119, 97,114,112,116,101,120,116, 0, 99,111,108, 91, 51, 93, 0, 99,101,108,108, +115,105,122,101, 0, 99,101,108,108,104,101,105,103,104,116, 0, 97,103,101,110,116,109, 97,120,115,108,111,112,101, 0, 97,103, +101,110,116,109, 97,120, 99,108,105,109, 98, 0, 97,103,101,110,116,104,101,105,103,104,116, 0, 97,103,101,110,116,114, 97,100, +105,117,115, 0,101,100,103,101,109, 97,120,108,101,110, 0,101,100,103,101,109, 97,120,101,114,114,111,114, 0,114,101,103,105, +111,110,109,105,110,115,105,122,101, 0,114,101,103,105,111,110,109,101,114,103,101,115,105,122,101, 0,118,101,114,116,115,112, +101,114,112,111,108,121, 0,100,101,116, 97,105,108,115, 97,109,112,108,101,100,105,115,116, 0,100,101,116, 97,105,108,115, 97, +109,112,108,101,109, 97,120,101,114,114,111,114, 0,102,114, 97,109,105,110,103, 0,112,108, 97,121,101,114,102,108, 97,103, 0, +114,116, 49, 0,114,116, 50, 0, 97, 97,115, 97,109,112,108,101,115, 0,112, 97,100, 52, 91, 51, 93, 0,100,111,109,101, 0,115, +116,101,114,101,111,102,108, 97,103, 0,101,121,101,115,101,112, 97,114, 97,116,105,111,110, 0,114,101, 99, 97,115,116, 68, 97, +116, 97, 0,109, 97,116,109,111,100,101, 0,101,120,105,116,107,101,121, 0,111, 98,115,116, 97, 99,108,101, 83,105,109,117,108, + 97,116,105,111,110, 0,108,101,118,101,108, 72,101,105,103,104,116, 0, 42, 99, 97,109,101,114, 97, 0, 42,112, 97,105,110,116, + 95, 99,117,114,115,111,114, 0,112, 97,105,110,116, 95, 99,117,114,115,111,114, 95, 99,111,108, 91, 52, 93, 0,112, 97,105,110, +116, 0,115,101, 97,109, 95, 98,108,101,101,100, 0,110,111,114,109, 97,108, 95, 97,110,103,108,101, 0,115, 99,114,101,101,110, + 95,103,114, 97, 98, 95,115,105,122,101, 91, 50, 93, 0, 42,112, 97,105,110,116, 99,117,114,115,111,114, 0,105,110,118,101,114, +116, 0,116,111,116,114,101,107,101,121, 0,116,111,116, 97,100,100,107,101,121, 0, 98,114,117,115,104,116,121,112,101, 0, 98, +114,117,115,104, 91, 55, 93, 0,101,109,105,116,116,101,114,100,105,115,116, 0,115,101,108,101, 99,116,109,111,100,101, 0,101, +100,105,116,116,121,112,101, 0,100,114, 97,119, 95,115,116,101,112, 0,102, 97,100,101, 95,102,114, 97,109,101,115, 0,114, 97, +100,105, 97,108, 95,115,121,109,109, 91, 51, 93, 0,108, 97,115,116, 95,120, 0,108, 97,115,116, 95,121, 0,108, 97,115,116, 95, + 97,110,103,108,101, 0,100,114, 97,119, 95, 97,110, 99,104,111,114,101,100, 0, 97,110, 99,104,111,114,101,100, 95,115,105,122, +101, 0, 97,110, 99,104,111,114,101,100, 95,108,111, 99, 97,116,105,111,110, 91, 51, 93, 0, 97,110, 99,104,111,114,101,100, 95, +105,110,105,116,105, 97,108, 95,109,111,117,115,101, 91, 50, 93, 0,100,114, 97,119, 95,112,114,101,115,115,117,114,101, 0,112, +114,101,115,115,117,114,101, 95,118, 97,108,117,101, 0,115,112,101, 99,105, 97,108, 95,114,111,116, 97,116,105,111,110, 0, 42, +118,112, 97,105,110,116, 95,112,114,101,118, 0, 42,119,112, 97,105,110,116, 95,112,114,101,118, 0,109, 97,116, 91, 51, 93, 91, + 51, 93, 0,117,110,112,114,111,106,101, 99,116,101,100, 95,114, 97,100,105,117,115, 0, 42,118,112, 97,105,110,116, 0, 42,119, +112, 97,105,110,116, 0, 42,117,118,115, 99,117,108,112,116, 0,118,103,114,111,117,112, 95,119,101,105,103,104,116, 0, 99,111, +114,110,101,114,116,121,112,101, 0,101,100,105,116, 98,117,116,102,108, 97,103, 0,106,111,105,110,116,114,105,108,105,109,105, +116, 0,100,101,103,114, 0,116,117,114,110, 0,101,120,116,114, 95,111,102,102,115, 0,100,111,117, 98,108,105,109,105,116, 0, +110,111,114,109, 97,108,115,105,122,101, 0, 97,117,116,111,109,101,114,103,101, 0,115,101,103,109,101,110,116,115, 0,114,105, +110,103,115, 0,118,101,114,116,105, 99,101,115, 0,117,110,119,114, 97,112,112,101,114, 0,117,118, 99, 97,108, 99, 95,114, 97, +100,105,117,115, 0,117,118, 99, 97,108, 99, 95, 99,117, 98,101,115,105,122,101, 0,117,118, 99, 97,108, 99, 95,109, 97,114,103, +105,110, 0,117,118, 99, 97,108, 99, 95,109, 97,112,100,105,114, 0,117,118, 99, 97,108, 99, 95,109, 97,112, 97,108,105,103,110, + 0,117,118, 99, 97,108, 99, 95,102,108, 97,103, 0,117,118, 95,102,108, 97,103, 0,117,118, 95,115,101,108,101, 99,116,109,111, +100,101, 0,117,118, 95,115,117, 98,115,117,114,102, 95,108,101,118,101,108, 0,103,112,101,110, 99,105,108, 95,102,108, 97,103, +115, 0, 97,117,116,111,105,107, 95, 99,104, 97,105,110,108,101,110, 0,105,109, 97,112, 97,105,110,116, 0,112, 97,114,116,105, + 99,108,101, 0,112,114,111,112,111,114,116,105,111,110, 97,108, 95,115,105,122,101, 0,115,101,108,101, 99,116, 95,116,104,114, +101,115,104, 0, 99,108,101, 97,110, 95,116,104,114,101,115,104, 0, 97,117,116,111,107,101,121, 95,109,111,100,101, 0, 97,117, +116,111,107,101,121, 95,102,108, 97,103, 0,109,117,108,116,105,114,101,115, 95,115,117, 98,100,105,118, 95,116,121,112,101, 0, +112, 97,100, 50, 91, 53, 93, 0,115,107,103,101,110, 95,114,101,115,111,108,117,116,105,111,110, 0,115,107,103,101,110, 95,116, +104,114,101,115,104,111,108,100, 95,105,110,116,101,114,110, 97,108, 0,115,107,103,101,110, 95,116,104,114,101,115,104,111,108, +100, 95,101,120,116,101,114,110, 97,108, 0,115,107,103,101,110, 95,108,101,110,103,116,104, 95,114, 97,116,105,111, 0,115,107, +103,101,110, 95,108,101,110,103,116,104, 95,108,105,109,105,116, 0,115,107,103,101,110, 95, 97,110,103,108,101, 95,108,105,109, +105,116, 0,115,107,103,101,110, 95, 99,111,114,114,101,108, 97,116,105,111,110, 95,108,105,109,105,116, 0,115,107,103,101,110, + 95,115,121,109,109,101,116,114,121, 95,108,105,109,105,116, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,101,116, 95, 97, +110,103,108,101, 95,119,101,105,103,104,116, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,101,116, 95,108,101,110,103,116, +104, 95,119,101,105,103,104,116, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,101,116, 95,100,105,115,116, 97,110, 99,101, + 95,119,101,105,103,104,116, 0,115,107,103,101,110, 95,111,112,116,105,111,110,115, 0,115,107,103,101,110, 95,112,111,115,116, +112,114,111, 0,115,107,103,101,110, 95,112,111,115,116,112,114,111, 95,112, 97,115,115,101,115, 0,115,107,103,101,110, 95,115, +117, 98,100,105,118,105,115,105,111,110,115, 91, 51, 93, 0,115,107,103,101,110, 95,109,117,108,116,105, 95,108,101,118,101,108, + 0, 42,115,107,103,101,110, 95,116,101,109,112,108, 97,116,101, 0, 98,111,110,101, 95,115,107,101,116, 99,104,105,110,103, 0, + 98,111,110,101, 95,115,107,101,116, 99,104,105,110,103, 95, 99,111,110,118,101,114,116, 0,115,107,103,101,110, 95,115,117, 98, +100,105,118,105,115,105,111,110, 95,110,117,109, 98,101,114, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,101,116, 95,111, +112,116,105,111,110,115, 0,115,107,103,101,110, 95,114,101,116, 97,114,103,101,116, 95,114,111,108,108, 0,115,107,103,101,110, + 95,115,105,100,101, 95,115,116,114,105,110,103, 91, 56, 93, 0,115,107,103,101,110, 95,110,117,109, 95,115,116,114,105,110,103, + 91, 56, 93, 0,101,100,103,101, 95,109,111,100,101, 0,101,100,103,101, 95,109,111,100,101, 95,108,105,118,101, 95,117,110,119, +114, 97,112, 0,115,110, 97,112, 95,109,111,100,101, 0,115,110, 97,112, 95,102,108, 97,103, 0,115,110, 97,112, 95,116, 97,114, +103,101,116, 0,112,114,111,112,111,114,116,105,111,110, 97,108, 0,112,114,111,112, 95,109,111,100,101, 0,112,114,111,112,111, +114,116,105,111,110, 97,108, 95,111, 98,106,101, 99,116,115, 0,112, 97,100, 91, 53, 93, 0, 97,117,116,111, 95,110,111,114,109, + 97,108,105,122,101, 0,109,117,108,116,105,112, 97,105,110,116, 0,117,115,101, 95,117,118, 95,115, 99,117,108,112,116, 0,117, +118, 95,115, 99,117,108,112,116, 95,115,101,116,116,105,110,103,115, 0,117,118, 95,115, 99,117,108,112,116, 95,116,111,111,108, + 0,117,118, 95,114,101,108, 97,120, 95,109,101,116,104,111,100, 0,115, 99,117,108,112,116, 95,112, 97,105,110,116, 95,115,101, +116,116,105,110,103,115, 0,115, 99,117,108,112,116, 95,112, 97,105,110,116, 95,117,110,105,102,105,101,100, 95,115,105,122,101, + 0,115, 99,117,108,112,116, 95,112, 97,105,110,116, 95,117,110,105,102,105,101,100, 95,117,110,112,114,111,106,101, 99,116,101, +100, 95,114, 97,100,105,117,115, 0,115, 99,117,108,112,116, 95,112, 97,105,110,116, 95,117,110,105,102,105,101,100, 95, 97,108, +112,104, 97, 0,117,110,105,102,105,101,100, 95,112, 97,105,110,116, 95,115,101,116,116,105,110,103,115, 0,116,111,116,111, 98, +106, 0,116,111,116,108, 97,109,112, 0,116,111,116,111, 98,106,115,101,108, 0,116,111,116, 99,117,114,118,101, 0,116,111,116, +109,101,115,104, 0,116,111,116, 97,114,109, 97,116,117,114,101, 0,115, 99, 97,108,101, 95,108,101,110,103,116,104, 0,115,121, +115,116,101,109, 0,115,121,115,116,101,109, 95,114,111,116, 97,116,105,111,110, 0,103,114, 97,118,105,116,121, 91, 51, 93, 0, +113,117,105, 99,107, 95, 99, 97, 99,104,101, 95,115,116,101,112, 0, 42,119,111,114,108,100, 0, 42,115,101,116, 0, 98, 97,115, +101, 0, 42, 98, 97,115, 97, 99,116, 0, 42,111, 98,101,100,105,116, 0, 99,117,114,115,111,114, 91, 51, 93, 0,116,119, 99,101, +110,116, 91, 51, 93, 0,116,119,109,105,110, 91, 51, 93, 0,116,119,109, 97,120, 91, 51, 93, 0,108, 97,121, 97, 99,116, 0,108, + 97,121, 95,117,112,100, 97,116,101,100, 0, 42,101,100, 0, 42,116,111,111,108,115,101,116,116,105,110,103,115, 0, 42,115,116, + 97,116,115, 0, 97,117,100,105,111, 0,116,114, 97,110,115,102,111,114,109, 95,115,112, 97, 99,101,115, 0, 42,115,111,117,110, +100, 95,115, 99,101,110,101, 0, 42,115,111,117,110,100, 95,115, 99,101,110,101, 95,104, 97,110,100,108,101, 0, 42,115,111,117, +110,100, 95,115, 99,114,117, 98, 95,104, 97,110,100,108,101, 0, 42,115,112,101, 97,107,101,114, 95,104, 97,110,100,108,101,115, + 0, 42,102,112,115, 95,105,110,102,111, 0, 42,116,104,101, 68, 97,103, 0,100, 97,103,105,115,118, 97,108,105,100, 0,100, 97, +103,102,108, 97,103,115, 0, 97, 99,116,105,118,101, 95,107,101,121,105,110,103,115,101,116, 0,107,101,121,105,110,103,115,101, +116,115, 0,103,109, 0,117,110,105,116, 0,112,104,121,115,105, 99,115, 95,115,101,116,116,105,110,103,115, 0, 42, 99,108,105, +112, 0, 99,117,115,116,111,109,100, 97,116, 97, 95,109, 97,115,107, 95,109,111,100, 97,108, 0, 99,117,115,101,114, 0, 98,108, +101,110,100, 0,118,105,101,119, 0,119,105,110,109, 97,116, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,109, 97,116, 91, 52, 93, + 91, 52, 93, 0,118,105,101,119,105,110,118, 91, 52, 93, 91, 52, 93, 0,112,101,114,115,109, 97,116, 91, 52, 93, 91, 52, 93, 0, +112,101,114,115,105,110,118, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,109, 97,116,111, 98, 91, 52, 93, 91, 52, 93, 0,112,101, +114,115,109, 97,116,111, 98, 91, 52, 93, 91, 52, 93, 0, 99,108,105,112, 91, 54, 93, 91, 52, 93, 0, 99,108,105,112, 95,108,111, + 99, 97,108, 91, 54, 93, 91, 52, 93, 0, 42, 99,108,105,112, 98, 98, 0, 42,108,111, 99, 97,108,118,100, 0, 42,114,105, 0, 42, +114,101,110,100,101,114, 95,101,110,103,105,110,101, 0, 42,100,101,112,116,104,115, 0, 42,115,109,115, 0, 42,115,109,111,111, +116,104, 95,116,105,109,101,114, 0,116,119,109, 97,116, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,113,117, 97,116, 91, 52, 93, + 0,122,102, 97, 99, 0, 99, 97,109,100,120, 0, 99, 97,109,100,121, 0,112,105,120,115,105,122,101, 0, 99, 97,109,122,111,111, +109, 0,105,115, 95,112,101,114,115,112, 0,112,101,114,115,112, 0,118,105,101,119,108,111, 99,107, 0,116,119,100,114, 97,119, +102,108, 97,103, 0,114,102,108, 97,103, 0,108,118,105,101,119,113,117, 97,116, 91, 52, 93, 0,108,112,101,114,115,112, 0,108, +118,105,101,119, 0,103,114,105,100,118,105,101,119, 0,116,119, 97,110,103,108,101, 91, 51, 93, 0,114,111,116, 95, 97,110,103, +108,101, 0,114,111,116, 95, 97,120,105,115, 91, 51, 93, 0,114,101,103,105,111,110, 98, 97,115,101, 0,115,112, 97, 99,101,116, +121,112,101, 0, 98,108,111, 99,107,115, 99, 97,108,101, 0, 98,108,111, 99,107,104, 97,110,100,108,101,114, 91, 56, 93, 0, 98, +117,110,100,108,101, 95,115,105,122,101, 0, 98,117,110,100,108,101, 95,100,114, 97,119,116,121,112,101, 0,108, 97,121, 95,117, +115,101,100, 0, 42,111, 98, 95, 99,101,110,116,114,101, 0, 98,103,112,105, 99, 98, 97,115,101, 0, 42, 98,103,112,105, 99, 0, +111, 98, 95, 99,101,110,116,114,101, 95, 98,111,110,101, 91, 54, 52, 93, 0,100,114, 97,119,116,121,112,101, 0,111, 98, 95, 99, +101,110,116,114,101, 95, 99,117,114,115,111,114, 0,115, 99,101,110,101,108,111, 99,107, 0, 97,114,111,117,110,100, 0,103,114, +105,100, 0,110,101, 97,114, 0,102, 97,114, 0,109,111,100,101,115,101,108,101, 99,116, 0,103,114,105,100,108,105,110,101,115, + 0,103,114,105,100,115,117, 98,100,105,118, 0,103,114,105,100,102,108, 97,103, 0,116,119,116,121,112,101, 0,116,119,109,111, +100,101, 0,116,119,102,108, 97,103, 0,112, 97,100, 50, 91, 50, 93, 0, 97,102,116,101,114,100,114, 97,119, 95,116,114, 97,110, +115,112, 0, 97,102,116,101,114,100,114, 97,119, 95,120,114, 97,121, 0, 97,102,116,101,114,100,114, 97,119, 95,120,114, 97,121, +116,114, 97,110,115,112, 0,122, 98,117,102, 0,120,114, 97,121, 0,112, 97,100, 51, 91, 50, 93, 0, 42,112,114,111,112,101,114, +116,105,101,115, 95,115,116,111,114, 97,103,101, 0,118,101,114,116, 0,104,111,114, 0,109, 97,115,107, 0,109,105,110, 91, 50, + 93, 0,109, 97,120, 91, 50, 93, 0,109,105,110,122,111,111,109, 0,109, 97,120,122,111,111,109, 0,115, 99,114,111,108,108, 0, +115, 99,114,111,108,108, 95,117,105, 0,107,101,101,112,116,111,116, 0,107,101,101,112,122,111,111,109, 0,107,101,101,112,111, +102,115, 0, 97,108,105,103,110, 0,119,105,110,120, 0,119,105,110,121, 0,111,108,100,119,105,110,120, 0,111,108,100,119,105, +110,121, 0, 42,116, 97, 98, 95,111,102,102,115,101,116, 0,116, 97, 98, 95,110,117,109, 0,116, 97, 98, 95, 99,117,114, 0,114, +112,116, 95,109, 97,115,107, 0,118, 50,100, 0, 42, 97,100,115, 0,103,104,111,115,116, 67,117,114,118,101,115, 0, 97,117,116, +111,115,110, 97,112, 0, 99,117,114,115,111,114, 86, 97,108, 0,109, 97,105,110, 98, 0,109, 97,105,110, 98,111, 0,109, 97,105, +110, 98,117,115,101,114, 0,114,101, 95, 97,108,105,103,110, 0,112,114,101,118,105,101,119, 0,116,101,120,116,117,114,101, 95, + 99,111,110,116,101,120,116, 0,112, 97,116,104,102,108, 97,103, 0,100, 97,116, 97,105, 99,111,110, 0, 42,112,105,110,105,100, + 0, 42,116,101,120,117,115,101,114, 0,114,101,110,100,101,114, 95,115,105,122,101, 0, 99,104, 97,110,115,104,111,119,110, 0, +122,101, 98,114, 97, 0,122,111,111,109, 0,116,105,116,108,101, 91, 51, 50, 93, 0,100,105,114, 91, 49, 48, 53, 54, 93, 0,102, +105,108,101, 91, 50, 53, 54, 93, 0,114,101,110, 97,109,101,102,105,108,101, 91, 50, 53, 54, 93, 0,114,101,110, 97,109,101,101, +100,105,116, 91, 50, 53, 54, 93, 0,102,105,108,116,101,114, 95,103,108,111, 98, 91, 54, 52, 93, 0, 97, 99,116,105,118,101, 95, +102,105,108,101, 0,115,101,108, 95,102,105,114,115,116, 0,115,101,108, 95,108, 97,115,116, 0,115,111,114,116, 0,100,105,115, +112,108, 97,121, 0,102, 95,102,112, 0,102,112, 95,115,116,114, 91, 56, 93, 0,115, 99,114,111,108,108, 95,111,102,102,115,101, +116, 0, 42,112, 97,114, 97,109,115, 0, 42,102,105,108,101,115, 0, 42,102,111,108,100,101,114,115, 95,112,114,101,118, 0, 42, +102,111,108,100,101,114,115, 95,110,101,120,116, 0, 42,111,112, 0, 42,115,109,111,111,116,104,115, 99,114,111,108,108, 95,116, +105,109,101,114, 0, 42,108, 97,121,111,117,116, 0,114,101, 99,101,110,116,110,114, 0, 98,111,111,107,109, 97,114,107,110,114, + 0,115,121,115,116,101,109,110,114, 0,116,114,101,101, 0, 42,116,114,101,101,115,116,111,114,101, 0,115,101, 97,114, 99,104, + 95,115,116,114,105,110,103, 91, 51, 50, 93, 0,115,101, 97,114, 99,104, 95,116,115,101, 0,111,117,116,108,105,110,101,118,105, +115, 0,115,116,111,114,101,102,108, 97,103, 0,115,101, 97,114, 99,104, 95,102,108, 97,103,115, 0, 42, 99,117,109, 97,112, 0, +115, 99,111,112,101,115, 0,115, 97,109,112,108,101, 95,108,105,110,101, 95,104,105,115,116, 0, 99,117,114,115,111,114, 91, 50, + 93, 0, 99,101,110,116,120, 0, 99,101,110,116,121, 0, 99,117,114,116,105,108,101, 0,108,111, 99,107, 0,112,105,110, 0,100, +116, 95,117,118, 0,115,116,105, 99,107,121, 0,100,116, 95,117,118,115,116,114,101,116, 99,104, 0, 42,116,101,120,116, 0,116, +111,112, 0,118,105,101,119,108,105,110,101,115, 0,109,101,110,117,110,114, 0,108,104,101,105,103,104,116, 0, 99,119,105,100, +116,104, 0,108,105,110,101,110,114,115, 95,116,111,116, 0,108,101,102,116, 0,115,104,111,119,108,105,110,101,110,114,115, 0, +116, 97, 98,110,117,109, 98,101,114, 0,115,104,111,119,115,121,110,116, 97,120, 0,108,105,110,101, 95,104,108,105,103,104,116, + 0,111,118,101,114,119,114,105,116,101, 0,108,105,118,101, 95,101,100,105,116, 0,112,105,120, 95,112,101,114, 95,108,105,110, +101, 0,116,120,116,115, 99,114,111,108,108, 0,116,120,116, 98, 97,114, 0,119,111,114,100,119,114, 97,112, 0,100,111,112,108, +117,103,105,110,115, 0,102,105,110,100,115,116,114, 91, 50, 53, 54, 93, 0,114,101,112,108, 97, 99,101,115,116,114, 91, 50, 53, + 54, 93, 0,109, 97,114,103,105,110, 95, 99,111,108,117,109,110, 0, 42,100,114, 97,119, 99, 97, 99,104,101, 0, 42,112,121, 95, +100,114, 97,119, 0, 42,112,121, 95,101,118,101,110,116, 0, 42,112,121, 95, 98,117,116,116,111,110, 0, 42,112,121, 95, 98,114, +111,119,115,101,114, 99, 97,108,108, 98, 97, 99,107, 0, 42,112,121, 95,103,108,111, 98, 97,108,100,105, 99,116, 0,108, 97,115, +116,115,112, 97, 99,101, 0,115, 99,114,105,112,116,110, 97,109,101, 91, 49, 48, 50, 52, 93, 0,115, 99,114,105,112,116, 97,114, +103, 91, 50, 53, 54, 93, 0, 42,115, 99,114,105,112,116, 0, 42, 98,117,116, 95,114,101,102,115, 0, 42, 97,114,114, 97,121, 0, + 99, 97, 99,104,101,115, 0, 99, 97, 99,104,101, 95,100,105,115,112,108, 97,121, 0, 42,105,100, 0, 97,115,112,101, 99,116, 0, +112, 97,100,102, 0,109,120, 0,109,121, 0, 42,101,100,105,116,116,114,101,101, 0,116,114,101,101,116,121,112,101, 0,116,101, +120,102,114,111,109, 0,115,104, 97,100,101,114,102,114,111,109, 0,108,105,110,107,100,114, 97,103, 0,108,101,110, 95, 97,108, +108,111, 99, 0, 99,117,114,115,111,114, 0,115, 99,114,111,108,108, 98, 97, 99,107, 0,104,105,115,116,111,114,121, 0,112,114, +111,109,112,116, 91, 50, 53, 54, 93, 0,108, 97,110,103,117, 97,103,101, 91, 51, 50, 93, 0,115,101,108, 95,115,116, 97,114,116, + 0,115,101,108, 95,101,110,100, 0,102,105,108,116,101,114, 91, 54, 52, 93, 0,120,108,111, 99,107,111,102, 0,121,108,111, 99, +107,111,102, 0,117,115,101,114, 0,112, 97,116,104, 95,108,101,110,103,116,104, 0,108,111, 99, 91, 50, 93, 0,115,116, 97, 98, +109, 97,116, 91, 52, 93, 91, 52, 93, 0,117,110,105,115,116, 97, 98,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,111,115,116,112, +114,111, 99, 95,102,108, 97,103, 0, 42,100,114, 97,119, 95, 99,111,110,116,101,120,116, 0,102,105,108,101,110, 97,109,101, 91, + 49, 48, 50, 52, 93, 0, 98,108,102, 95,105,100, 0,117,105,102,111,110,116, 95,105,100, 0,114, 95,116,111, 95,108, 0,112,111, +105,110,116,115, 0,107,101,114,110,105,110,103, 0,105,116, 97,108,105, 99, 0, 98,111,108,100, 0,115,104, 97,100,111,119, 0, +115,104, 97,100,120, 0,115,104, 97,100,121, 0,115,104, 97,100,111,119, 97,108,112,104, 97, 0,115,104, 97,100,111,119, 99,111, +108,111,114, 0,112, 97,110,101,108,116,105,116,108,101, 0,103,114,111,117,112,108, 97, 98,101,108, 0,119,105,100,103,101,116, +108, 97, 98,101,108, 0,119,105,100,103,101,116, 0,112, 97,110,101,108,122,111,111,109, 0,109,105,110,108, 97, 98,101,108, 99, +104, 97,114,115, 0,109,105,110,119,105,100,103,101,116, 99,104, 97,114,115, 0, 99,111,108,117,109,110,115,112, 97, 99,101, 0, +116,101,109,112,108, 97,116,101,115,112, 97, 99,101, 0, 98,111,120,115,112, 97, 99,101, 0, 98,117,116,116,111,110,115,112, 97, + 99,101,120, 0, 98,117,116,116,111,110,115,112, 97, 99,101,121, 0,112, 97,110,101,108,115,112, 97, 99,101, 0,112, 97,110,101, +108,111,117,116,101,114, 0,111,117,116,108,105,110,101, 91, 52, 93, 0,105,110,110,101,114, 91, 52, 93, 0,105,110,110,101,114, + 95,115,101,108, 91, 52, 93, 0,105,116,101,109, 91, 52, 93, 0,116,101,120,116, 91, 52, 93, 0,116,101,120,116, 95,115,101,108, + 91, 52, 93, 0,115,104, 97,100,101,100, 0,115,104, 97,100,101,116,111,112, 0,115,104, 97,100,101,100,111,119,110, 0, 97,108, +112,104, 97, 95, 99,104,101, 99,107, 0,105,110,110,101,114, 95, 97,110,105,109, 91, 52, 93, 0,105,110,110,101,114, 95, 97,110, +105,109, 95,115,101,108, 91, 52, 93, 0,105,110,110,101,114, 95,107,101,121, 91, 52, 93, 0,105,110,110,101,114, 95,107,101,121, + 95,115,101,108, 91, 52, 93, 0,105,110,110,101,114, 95,100,114,105,118,101,110, 91, 52, 93, 0,105,110,110,101,114, 95,100,114, +105,118,101,110, 95,115,101,108, 91, 52, 93, 0,104,101, 97,100,101,114, 91, 52, 93, 0,115,104,111,119, 95,104,101, 97,100,101, +114, 0,119, 99,111,108, 95,114,101,103,117,108, 97,114, 0,119, 99,111,108, 95,116,111,111,108, 0,119, 99,111,108, 95,116,101, +120,116, 0,119, 99,111,108, 95,114, 97,100,105,111, 0,119, 99,111,108, 95,111,112,116,105,111,110, 0,119, 99,111,108, 95,116, +111,103,103,108,101, 0,119, 99,111,108, 95,110,117,109, 0,119, 99,111,108, 95,110,117,109,115,108,105,100,101,114, 0,119, 99, +111,108, 95,109,101,110,117, 0,119, 99,111,108, 95,112,117,108,108,100,111,119,110, 0,119, 99,111,108, 95,109,101,110,117, 95, + 98, 97, 99,107, 0,119, 99,111,108, 95,109,101,110,117, 95,105,116,101,109, 0,119, 99,111,108, 95,116,111,111,108,116,105,112, + 0,119, 99,111,108, 95, 98,111,120, 0,119, 99,111,108, 95,115, 99,114,111,108,108, 0,119, 99,111,108, 95,112,114,111,103,114, +101,115,115, 0,119, 99,111,108, 95,108,105,115,116, 95,105,116,101,109, 0,119, 99,111,108, 95,115,116, 97,116,101, 0,112, 97, +110,101,108, 0,105, 99,111,110,102,105,108,101, 91, 50, 53, 54, 93, 0,105, 99,111,110, 95, 97,108,112,104, 97, 0, 98, 97, 99, +107, 91, 52, 93, 0,116,105,116,108,101, 91, 52, 93, 0,116,101,120,116, 95,104,105, 91, 52, 93, 0,104,101, 97,100,101,114, 95, +116,105,116,108,101, 91, 52, 93, 0,104,101, 97,100,101,114, 95,116,101,120,116, 91, 52, 93, 0,104,101, 97,100,101,114, 95,116, +101,120,116, 95,104,105, 91, 52, 93, 0, 98,117,116,116,111,110, 91, 52, 93, 0, 98,117,116,116,111,110, 95,116,105,116,108,101, + 91, 52, 93, 0, 98,117,116,116,111,110, 95,116,101,120,116, 91, 52, 93, 0, 98,117,116,116,111,110, 95,116,101,120,116, 95,104, +105, 91, 52, 93, 0,108,105,115,116, 91, 52, 93, 0,108,105,115,116, 95,116,105,116,108,101, 91, 52, 93, 0,108,105,115,116, 95, +116,101,120,116, 91, 52, 93, 0,108,105,115,116, 95,116,101,120,116, 95,104,105, 91, 52, 93, 0,112, 97,110,101,108, 91, 52, 93, + 0,112, 97,110,101,108, 95,116,105,116,108,101, 91, 52, 93, 0,112, 97,110,101,108, 95,116,101,120,116, 91, 52, 93, 0,112, 97, +110,101,108, 95,116,101,120,116, 95,104,105, 91, 52, 93, 0,115,104, 97,100,101, 49, 91, 52, 93, 0,115,104, 97,100,101, 50, 91, + 52, 93, 0,104,105,108,105,116,101, 91, 52, 93, 0,103,114,105,100, 91, 52, 93, 0,119,105,114,101, 91, 52, 93, 0,115,101,108, +101, 99,116, 91, 52, 93, 0,108, 97,109,112, 91, 52, 93, 0,115,112,101, 97,107,101,114, 91, 52, 93, 0,101,109,112,116,121, 91, + 52, 93, 0, 99, 97,109,101,114, 97, 91, 52, 93, 0,112, 97,100, 91, 56, 93, 0, 97, 99,116,105,118,101, 91, 52, 93, 0,103,114, +111,117,112, 91, 52, 93, 0,103,114,111,117,112, 95, 97, 99,116,105,118,101, 91, 52, 93, 0,116,114, 97,110,115,102,111,114,109, + 91, 52, 93, 0,118,101,114,116,101,120, 91, 52, 93, 0,118,101,114,116,101,120, 95,115,101,108,101, 99,116, 91, 52, 93, 0,101, +100,103,101, 91, 52, 93, 0,101,100,103,101, 95,115,101,108,101, 99,116, 91, 52, 93, 0,101,100,103,101, 95,115,101, 97,109, 91, + 52, 93, 0,101,100,103,101, 95,115,104, 97,114,112, 91, 52, 93, 0,101,100,103,101, 95,102, 97, 99,101,115,101,108, 91, 52, 93, + 0,101,100,103,101, 95, 99,114,101, 97,115,101, 91, 52, 93, 0,102, 97, 99,101, 91, 52, 93, 0,102, 97, 99,101, 95,115,101,108, +101, 99,116, 91, 52, 93, 0,102, 97, 99,101, 95,100,111,116, 91, 52, 93, 0,101,120,116,114, 97, 95,101,100,103,101, 95,108,101, +110, 91, 52, 93, 0,101,120,116,114, 97, 95,102, 97, 99,101, 95, 97,110,103,108,101, 91, 52, 93, 0,101,120,116,114, 97, 95,102, + 97, 99,101, 95, 97,114,101, 97, 91, 52, 93, 0,112, 97,100, 51, 91, 52, 93, 0,110,111,114,109, 97,108, 91, 52, 93, 0,118,101, +114,116,101,120, 95,110,111,114,109, 97,108, 91, 52, 93, 0, 98,111,110,101, 95,115,111,108,105,100, 91, 52, 93, 0, 98,111,110, +101, 95,112,111,115,101, 91, 52, 93, 0,115,116,114,105,112, 91, 52, 93, 0,115,116,114,105,112, 95,115,101,108,101, 99,116, 91, + 52, 93, 0, 99,102,114, 97,109,101, 91, 52, 93, 0,110,117,114, 98, 95,117,108,105,110,101, 91, 52, 93, 0,110,117,114, 98, 95, +118,108,105,110,101, 91, 52, 93, 0, 97, 99,116, 95,115,112,108,105,110,101, 91, 52, 93, 0,110,117,114, 98, 95,115,101,108, 95, +117,108,105,110,101, 91, 52, 93, 0,110,117,114, 98, 95,115,101,108, 95,118,108,105,110,101, 91, 52, 93, 0,108, 97,115,116,115, +101,108, 95,112,111,105,110,116, 91, 52, 93, 0,104, 97,110,100,108,101, 95,102,114,101,101, 91, 52, 93, 0,104, 97,110,100,108, +101, 95, 97,117,116,111, 91, 52, 93, 0,104, 97,110,100,108,101, 95,118,101, 99,116, 91, 52, 93, 0,104, 97,110,100,108,101, 95, + 97,108,105,103,110, 91, 52, 93, 0,104, 97,110,100,108,101, 95, 97,117,116,111, 95, 99,108, 97,109,112,101,100, 91, 52, 93, 0, +104, 97,110,100,108,101, 95,115,101,108, 95,102,114,101,101, 91, 52, 93, 0,104, 97,110,100,108,101, 95,115,101,108, 95, 97,117, +116,111, 91, 52, 93, 0,104, 97,110,100,108,101, 95,115,101,108, 95,118,101, 99,116, 91, 52, 93, 0,104, 97,110,100,108,101, 95, +115,101,108, 95, 97,108,105,103,110, 91, 52, 93, 0,104, 97,110,100,108,101, 95,115,101,108, 95, 97,117,116,111, 95, 99,108, 97, +109,112,101,100, 91, 52, 93, 0,100,115, 95, 99,104, 97,110,110,101,108, 91, 52, 93, 0,100,115, 95,115,117, 98, 99,104, 97,110, +110,101,108, 91, 52, 93, 0, 99,111,110,115,111,108,101, 95,111,117,116,112,117,116, 91, 52, 93, 0, 99,111,110,115,111,108,101, + 95,105,110,112,117,116, 91, 52, 93, 0, 99,111,110,115,111,108,101, 95,105,110,102,111, 91, 52, 93, 0, 99,111,110,115,111,108, +101, 95,101,114,114,111,114, 91, 52, 93, 0, 99,111,110,115,111,108,101, 95, 99,117,114,115,111,114, 91, 52, 93, 0,118,101,114, +116,101,120, 95,115,105,122,101, 0,111,117,116,108,105,110,101, 95,119,105,100,116,104, 0,102, 97, 99,101,100,111,116, 95,115, +105,122,101, 0,110,111,111,100,108,101, 95, 99,117,114,118,105,110,103, 0,115,121,110,116, 97,120,108, 91, 52, 93, 0,115,121, +110,116, 97,120,110, 91, 52, 93, 0,115,121,110,116, 97,120, 98, 91, 52, 93, 0,115,121,110,116, 97,120,118, 91, 52, 93, 0,115, +121,110,116, 97,120, 99, 91, 52, 93, 0,109,111,118,105,101, 91, 52, 93, 0,109,111,118,105,101, 99,108,105,112, 91, 52, 93, 0, +105,109, 97,103,101, 91, 52, 93, 0,115, 99,101,110,101, 91, 52, 93, 0, 97,117,100,105,111, 91, 52, 93, 0,101,102,102,101, 99, +116, 91, 52, 93, 0,112,108,117,103,105,110, 91, 52, 93, 0,116,114, 97,110,115,105,116,105,111,110, 91, 52, 93, 0,109,101,116, + 97, 91, 52, 93, 0,101,100,105,116,109,101,115,104, 95, 97, 99,116,105,118,101, 91, 52, 93, 0,104, 97,110,100,108,101, 95,118, +101,114,116,101,120, 91, 52, 93, 0,104, 97,110,100,108,101, 95,118,101,114,116,101,120, 95,115,101,108,101, 99,116, 91, 52, 93, + 0,104, 97,110,100,108,101, 95,118,101,114,116,101,120, 95,115,105,122,101, 0,109, 97,114,107,101,114, 95,111,117,116,108,105, +110,101, 91, 52, 93, 0,109, 97,114,107,101,114, 91, 52, 93, 0, 97, 99,116, 95,109, 97,114,107,101,114, 91, 52, 93, 0,115,101, +108, 95,109, 97,114,107,101,114, 91, 52, 93, 0,100,105,115, 95,109, 97,114,107,101,114, 91, 52, 93, 0,108,111, 99,107, 95,109, + 97,114,107,101,114, 91, 52, 93, 0, 98,117,110,100,108,101, 95,115,111,108,105,100, 91, 52, 93, 0,112, 97,116,104, 95, 98,101, +102,111,114,101, 91, 52, 93, 0,112, 97,116,104, 95, 97,102,116,101,114, 91, 52, 93, 0, 99, 97,109,101,114, 97, 95,112, 97,116, +104, 91, 52, 93, 0,104,112, 97,100, 91, 55, 93, 0,112,114,101,118,105,101,119, 95, 98, 97, 99,107, 91, 52, 93, 0,112,114,101, +118,105,101,119, 95,115,116,105,116, 99,104, 95,102, 97, 99,101, 91, 52, 93, 0,112,114,101,118,105,101,119, 95,115,116,105,116, + 99,104, 95,101,100,103,101, 91, 52, 93, 0,112,114,101,118,105,101,119, 95,115,116,105,116, 99,104, 95,118,101,114,116, 91, 52, + 93, 0,112,114,101,118,105,101,119, 95,115,116,105,116, 99,104, 95,115,116,105,116, 99,104, 97, 98,108,101, 91, 52, 93, 0,112, +114,101,118,105,101,119, 95,115,116,105,116, 99,104, 95,117,110,115,116,105,116, 99,104, 97, 98,108,101, 91, 52, 93, 0,112,114, +101,118,105,101,119, 95,115,116,105,116, 99,104, 95, 97, 99,116,105,118,101, 91, 52, 93, 0,109, 97,116, 99,104, 91, 52, 93, 0, +115,101,108,101, 99,116,101,100, 95,104,105,103,104,108,105,103,104,116, 91, 52, 93, 0,115,111,108,105,100, 91, 52, 93, 0,116, +117,105, 0,116, 98,117,116,115, 0,116,118, 51,100, 0,116,102,105,108,101, 0,116,105,112,111, 0,116,105,110,102,111, 0,116, + 97, 99,116, 0,116,110,108, 97, 0,116,115,101,113, 0,116,105,109, 97, 0,116,101,120,116, 0,116,111,111,112,115, 0,116,116, +105,109,101, 0,116,110,111,100,101, 0,116,108,111,103,105, 99, 0,116,117,115,101,114,112,114,101,102, 0,116, 99,111,110,115, +111,108,101, 0,116, 99,108,105,112, 0,116, 97,114,109, 91, 50, 48, 93, 0, 97, 99,116,105,118,101, 95,116,104,101,109,101, 95, + 97,114,101, 97, 0,109,111,100,117,108,101, 91, 54, 52, 93, 0,115,112,101, 99, 91, 52, 93, 0,100,117,112,102,108, 97,103, 0, +115, 97,118,101,116,105,109,101, 0,116,101,109,112,100,105,114, 91, 55, 54, 56, 93, 0,102,111,110,116,100,105,114, 91, 55, 54, + 56, 93, 0,114,101,110,100,101,114,100,105,114, 91, 49, 48, 50, 52, 93, 0,116,101,120,116,117,100,105,114, 91, 55, 54, 56, 93, + 0,112,108,117,103,116,101,120,100,105,114, 91, 55, 54, 56, 93, 0,112,108,117,103,115,101,113,100,105,114, 91, 55, 54, 56, 93, + 0,112,121,116,104,111,110,100,105,114, 91, 55, 54, 56, 93, 0,115,111,117,110,100,100,105,114, 91, 55, 54, 56, 93, 0,105,109, + 97,103,101, 95,101,100,105,116,111,114, 91, 49, 48, 50, 52, 93, 0, 97,110,105,109, 95,112,108, 97,121,101,114, 91, 49, 48, 50, + 52, 93, 0, 97,110,105,109, 95,112,108, 97,121,101,114, 95,112,114,101,115,101,116, 0,118, 50,100, 95,109,105,110, 95,103,114, +105,100,115,105,122,101, 0,116,105,109,101, 99,111,100,101, 95,115,116,121,108,101, 0,118,101,114,115,105,111,110,115, 0,100, + 98,108, 95, 99,108,105, 99,107, 95,116,105,109,101, 0,103, 97,109,101,102,108, 97,103,115, 0,119,104,101,101,108,108,105,110, +101,115, 99,114,111,108,108, 0,117,105,102,108, 97,103, 0,108, 97,110,103,117, 97,103,101, 0,117,115,101,114,112,114,101,102, + 0,118,105,101,119,122,111,111,109, 0,109,105,120, 98,117,102,115,105,122,101, 0, 97,117,100,105,111,100,101,118,105, 99,101, + 0, 97,117,100,105,111,114, 97,116,101, 0, 97,117,100,105,111,102,111,114,109, 97,116, 0, 97,117,100,105,111, 99,104, 97,110, +110,101,108,115, 0,100,112,105, 0,101,110, 99,111,100,105,110,103, 0,116,114, 97,110,115,111,112,116,115, 0,109,101,110,117, +116,104,114,101,115,104,111,108,100, 49, 0,109,101,110,117,116,104,114,101,115,104,111,108,100, 50, 0,116,104,101,109,101,115, + 0,117,105,102,111,110,116,115, 0,117,105,115,116,121,108,101,115, 0,107,101,121,109, 97,112,115, 0,117,115,101,114, 95,107, +101,121,109, 97,112,115, 0, 97,100,100,111,110,115, 0,107,101,121, 99,111,110,102,105,103,115,116,114, 91, 54, 52, 93, 0,117, +110,100,111,115,116,101,112,115, 0,117,110,100,111,109,101,109,111,114,121, 0,103,112, 95,109, 97,110,104, 97,116,116,101,110, +100,105,115,116, 0,103,112, 95,101,117, 99,108,105,100,101, 97,110,100,105,115,116, 0,103,112, 95,101,114, 97,115,101,114, 0, +103,112, 95,115,101,116,116,105,110,103,115, 0,116, 98, 95,108,101,102,116,109,111,117,115,101, 0,116, 98, 95,114,105,103,104, +116,109,111,117,115,101, 0,108,105,103,104,116, 91, 51, 93, 0,116,119, 95,104,111,116,115,112,111,116, 0,116,119, 95,102,108, + 97,103, 0,116,119, 95,104, 97,110,100,108,101,115,105,122,101, 0,116,119, 95,115,105,122,101, 0,116,101,120,116,105,109,101, +111,117,116, 0,116,101,120, 99,111,108,108,101, 99,116,114, 97,116,101, 0,119,109,100,114, 97,119,109,101,116,104,111,100, 0, +100,114, 97,103,116,104,114,101,115,104,111,108,100, 0,109,101,109, 99, 97, 99,104,101,108,105,109,105,116, 0,112,114,101,102, +101,116, 99,104,102,114, 97,109,101,115, 0,102,114, 97,109,101,115,101,114,118,101,114,112,111,114,116, 0,112, 97,100, 95,114, +111,116, 95, 97,110,103,108,101, 0,111, 98, 99,101,110,116,101,114, 95,100,105, 97, 0,114,118,105,115,105,122,101, 0,114,118, +105, 98,114,105,103,104,116, 0,114,101, 99,101,110,116, 95,102,105,108,101,115, 0,115,109,111,111,116,104, 95,118,105,101,119, +116,120, 0,103,108,114,101,115,108,105,109,105,116, 0, 99,117,114,115,115,105,122,101, 0, 99,111,108,111,114, 95,112,105, 99, +107,101,114, 95,116,121,112,101, 0,105,112,111, 95,110,101,119, 0,107,101,121,104, 97,110,100,108,101,115, 95,110,101,119, 0, +115, 99,114, 99, 97,115,116,102,112,115, 0,115, 99,114, 99, 97,115,116,119, 97,105,116, 0,119,105,100,103,101,116, 95,117,110, +105,116, 0, 97,110,105,115,111,116,114,111,112,105, 99, 95,102,105,108,116,101,114, 0,117,115,101, 95, 49, 54, 98,105,116, 95, +116,101,120,116,117,114,101,115, 0,112, 97,100, 56, 0,110,100,111,102, 95,115,101,110,115,105,116,105,118,105,116,121, 0,110, +100,111,102, 95,102,108, 97,103, 0,103,108, 97,108,112,104, 97, 99,108,105,112, 0,116,101,120,116, 95,114,101,110,100,101,114, + 0,112, 97,100, 57, 0, 99,111, 98, 97, 95,119,101,105,103,104,116, 0,115, 99,117,108,112,116, 95,112, 97,105,110,116, 95,111, +118,101,114,108, 97,121, 95, 99,111,108, 91, 51, 93, 0,116,119,101, 97,107, 95,116,104,114,101,115,104,111,108,100, 0, 97,117, +116,104,111,114, 91, 56, 48, 93, 0, 99,111,109,112,117,116,101, 95,100,101,118,105, 99,101, 95,116,121,112,101, 0, 99,111,109, +112,117,116,101, 95,100,101,118,105, 99,101, 95,105,100, 0,102, 99,117, 95,105,110, 97, 99,116,105,118,101, 95, 97,108,112,104, + 97, 0,118,101,114,116, 98, 97,115,101, 0,101,100,103,101, 98, 97,115,101, 0, 97,114,101, 97, 98, 97,115,101, 0, 42,110,101, +119,115, 99,101,110,101, 0,114,101,100,114, 97,119,115, 95,102,108, 97,103, 0,102,117,108,108, 0,116,101,109,112, 0,119,105, +110,105,100, 0,100,111, 95,100,114, 97,119, 0,100,111, 95,114,101,102,114,101,115,104, 0,100,111, 95,100,114, 97,119, 95,103, +101,115,116,117,114,101, 0,100,111, 95,100,114, 97,119, 95,112, 97,105,110,116, 99,117,114,115,111,114, 0,100,111, 95,100,114, + 97,119, 95,100,114, 97,103, 0,115,119, 97,112, 0,109, 97,105,110,119,105,110, 0,115,117, 98,119,105,110, 97, 99,116,105,118, +101, 0, 42, 97,110,105,109,116,105,109,101,114, 0, 42, 99,111,110,116,101,120,116, 0,104, 97,110,100,108,101,114, 91, 56, 93, + 0, 42,110,101,119,118, 0,118,101, 99, 0, 42,118, 49, 0, 42,118, 50, 0, 42,116,121,112,101, 0,112, 97,110,101,108,110, 97, +109,101, 91, 54, 52, 93, 0,116, 97, 98,110, 97,109,101, 91, 54, 52, 93, 0,100,114, 97,119,110, 97,109,101, 91, 54, 52, 93, 0, +111,102,115,120, 0,111,102,115,121, 0,115,105,122,101,120, 0,115,105,122,101,121, 0,108, 97, 98,101,108,111,102,115, 0,114, +117,110,116,105,109,101, 95,102,108, 97,103, 0, 99,111,110,116,114,111,108, 0,115,110, 97,112, 0,115,111,114,116,111,114,100, +101,114, 0, 42,112, 97,110,101,108,116, 97, 98, 0, 42, 97, 99,116,105,118,101,100, 97,116, 97, 0,108,105,115,116, 95,115, 99, +114,111,108,108, 0,108,105,115,116, 95,115,105,122,101, 0,108,105,115,116, 95,108, 97,115,116, 95,108,101,110, 0,108,105,115, +116, 95,103,114,105,112, 95,115,105,122,101, 0,108,105,115,116, 95,115,101, 97,114, 99,104, 91, 54, 52, 93, 0, 42,118, 51, 0, + 42,118, 52, 0, 42,102,117,108,108, 0, 98,117,116,115,112, 97, 99,101,116,121,112,101, 0,104,101, 97,100,101,114,116,121,112, +101, 0,115,112, 97, 99,101,100, 97,116, 97, 0,104, 97,110,100,108,101,114,115, 0, 97, 99,116,105,111,110,122,111,110,101,115, + 0,119,105,110,114, 99,116, 0,100,114, 97,119,114, 99,116, 0,115,119,105,110,105,100, 0,114,101,103,105,111,110,116,121,112, +101, 0, 97,108,105,103,110,109,101,110,116, 0,100,111, 95,100,114, 97,119, 95,111,118,101,114,108, 97,121, 0,117,105, 98,108, +111, 99,107,115, 0,112, 97,110,101,108,115, 0, 42,104,101, 97,100,101,114,115,116,114, 0, 42,114,101,103,105,111,110,100, 97, +116, 97, 0,115,117, 98,118,115,116,114, 91, 52, 93, 0,115,117, 98,118,101,114,115,105,111,110, 0,112, 97,100,115, 0,109,105, +110,118,101,114,115,105,111,110, 0,109,105,110,115,117, 98,118,101,114,115,105,111,110, 0,119,105,110,112,111,115, 0, 42, 99, +117,114,115, 99,114,101,101,110, 0, 42, 99,117,114,115, 99,101,110,101, 0,102,105,108,101,102,108, 97,103,115, 0,103,108,111, + 98, 97,108,102, 0,114,101,118,105,115,105,111,110, 0,110, 97,109,101, 91, 50, 53, 54, 93, 0,111,114,105,103, 95,119,105,100, +116,104, 0,111,114,105,103, 95,104,101,105,103,104,116, 0, 98,111,116,116,111,109, 0,114,105,103,104,116, 0,120,111,102,115, + 0,121,111,102,115, 0,108,105,102,116, 91, 51, 93, 0,103, 97,109,109, 97, 91, 51, 93, 0,103, 97,105,110, 91, 51, 93, 0,100, +105,114, 91, 55, 54, 56, 93, 0,116, 99, 0, 98,117,105,108,100, 95,115,105,122,101, 95,102,108, 97,103,115, 0, 98,117,105,108, +100, 95,116, 99, 95,102,108, 97,103,115, 0,100,111,110,101, 0,115,116, 97,114,116,115,116,105,108,108, 0,101,110,100,115,116, +105,108,108, 0, 42,115,116,114,105,112,100, 97,116, 97, 0, 42, 99,114,111,112, 0, 42,116,114, 97,110,115,102,111,114,109, 0, + 42, 99,111,108,111,114, 95, 98, 97,108, 97,110, 99,101, 0, 42,105,110,115,116, 97,110, 99,101, 95,112,114,105,118, 97,116,101, + 95,100, 97,116, 97, 0, 42, 42, 99,117,114,114,101,110,116, 95,112,114,105,118, 97,116,101, 95,100, 97,116, 97, 0, 42,116,109, +112, 0,115,116, 97,114,116,111,102,115, 0,101,110,100,111,102,115, 0,109, 97, 99,104,105,110,101, 0,115,116, 97,114,116,100, +105,115,112, 0,101,110,100,100,105,115,112, 0,115, 97,116, 0,109,117,108, 0,104, 97,110,100,115,105,122,101, 0, 97,110,105, +109, 95,112,114,101,115,101,101,107, 0,115,116,114,101, 97,109,105,110,100,101,120, 0,109,117,108,116,105, 99, 97,109, 95,115, +111,117,114, 99,101, 0, 99,108,105,112, 95,102,108, 97,103, 0, 42,115,116,114,105,112, 0, 42,115, 99,101,110,101, 95, 99, 97, +109,101,114, 97, 0,101,102,102,101, 99,116, 95,102, 97,100,101,114, 0,115,112,101,101,100, 95,102, 97,100,101,114, 0, 42,115, +101,113, 49, 0, 42,115,101,113, 50, 0, 42,115,101,113, 51, 0,115,101,113, 98, 97,115,101, 0, 42,115,111,117,110,100, 0, 42, +115, 99,101,110,101, 95,115,111,117,110,100, 0,112,105,116, 99,104, 0,112, 97,110, 0,115,116,114,111, 98,101, 0, 42,101,102, +102,101, 99,116,100, 97,116, 97, 0, 97,110,105,109, 95,115,116, 97,114,116,111,102,115, 0, 97,110,105,109, 95,101,110,100,111, +102,115, 0, 98,108,101,110,100, 95,109,111,100,101, 0, 98,108,101,110,100, 95,111,112, 97, 99,105,116,121, 0, 42,111,108,100, + 98, 97,115,101,112, 0, 42,112, 97,114,115,101,113, 0, 42,115,101,113, 98, 97,115,101,112, 0,109,101,116, 97,115,116, 97, 99, +107, 0, 42, 97, 99,116, 95,115,101,113, 0, 97, 99,116, 95,105,109, 97,103,101,100,105,114, 91, 49, 48, 50, 52, 93, 0, 97, 99, +116, 95,115,111,117,110,100,100,105,114, 91, 49, 48, 50, 52, 93, 0,111,118,101,114, 95,111,102,115, 0,111,118,101,114, 95, 99, +102,114, 97, 0,111,118,101,114, 95,102,108, 97,103, 0,111,118,101,114, 95, 98,111,114,100,101,114, 0,101,100,103,101, 87,105, +100,116,104, 0,102,111,114,119, 97,114,100, 0,119,105,112,101,116,121,112,101, 0,102, 77,105,110,105, 0,102, 67,108, 97,109, +112, 0,102, 66,111,111,115,116, 0,100, 68,105,115,116, 0,100, 81,117, 97,108,105,116,121, 0, 98, 78,111, 67,111,109,112, 0, + 83, 99, 97,108,101,120, 73,110,105, 0, 83, 99, 97,108,101,121, 73,110,105, 0,120, 73,110,105, 0,121, 73,110,105, 0,114,111, +116, 73,110,105, 0,105,110,116,101,114,112,111,108, 97,116,105,111,110, 0,117,110,105,102,111,114,109, 95,115, 99, 97,108,101, + 0, 42,102,114, 97,109,101, 77, 97,112, 0,103,108,111, 98, 97,108, 83,112,101,101,100, 0,108, 97,115,116, 86, 97,108,105,100, + 70,114, 97,109,101, 0, 98,117,116,116,121,112,101, 0,117,115,101,114,106,105,116, 0,115,116, 97, 0,116,111,116,112, 97,114, +116, 0,110,111,114,109,102, 97, 99, 0,111, 98,102, 97, 99, 0,114, 97,110,100,102, 97, 99, 0,116,101,120,102, 97, 99, 0,114, + 97,110,100,108,105,102,101, 0,102,111,114, 99,101, 91, 51, 93, 0,118,101, 99,116,115,105,122,101, 0,109, 97,120,108,101,110, + 0,100,101,102,118,101, 99, 91, 51, 93, 0,109,117,108,116, 91, 52, 93, 0,108,105,102,101, 91, 52, 93, 0, 99,104,105,108,100, + 91, 52, 93, 0,109, 97,116, 91, 52, 93, 0,116,101,120,109, 97,112, 0, 99,117,114,109,117,108,116, 0,115,116, 97,116,105, 99, +115,116,101,112, 0,111,109, 97,116, 0,116,105,109,101,116,101,120, 0,115,112,101,101,100,116,101,120, 0,102,108, 97,103, 50, +110,101,103, 0,118,101,114,116,103,114,111,117,112, 95,118, 0,118,103,114,111,117,112,110, 97,109,101, 91, 54, 52, 93, 0,118, +103,114,111,117,112,110, 97,109,101, 95,118, 91, 54, 52, 93, 0, 42,107,101,121,115, 0,109,105,110,102, 97, 99, 0,110,114, 0, +117,115,101,100, 0,117,115,101,100,101,108,101,109, 0, 42,112,111,105,110, 0,114,101,115,101,116,100,105,115,116, 0,108, 97, +115,116,118, 97,108, 0, 42,109, 97, 0,107,101,121, 0,113,117, 97,108, 0,113,117, 97,108, 50, 0,116, 97,114,103,101,116, 78, + 97,109,101, 91, 54, 52, 93, 0,116,111,103,103,108,101, 78, 97,109,101, 91, 54, 52, 93, 0,118, 97,108,117,101, 91, 54, 52, 93, + 0,109, 97,120,118, 97,108,117,101, 91, 54, 52, 93, 0,100,101,108, 97,121, 0,100,117,114, 97,116,105,111,110, 0,109, 97,116, +101,114,105, 97,108, 78, 97,109,101, 91, 54, 52, 93, 0,100, 97,109,112,116,105,109,101,114, 0,112,114,111,112,110, 97,109,101, + 91, 54, 52, 93, 0,109, 97,116,110, 97,109,101, 91, 54, 52, 93, 0, 97,120,105,115,102,108, 97,103, 0,112,111,115,101, 99,104, + 97,110,110,101,108, 91, 54, 52, 93, 0, 99,111,110,115,116,114, 97,105,110,116, 91, 54, 52, 93, 0, 42,102,114,111,109, 79, 98, +106,101, 99,116, 0,115,117, 98,106,101, 99,116, 91, 54, 52, 93, 0, 98,111,100,121, 91, 54, 52, 93, 0,111,116,121,112,101, 0, +112,117,108,115,101, 0,102,114,101,113, 0,116,111,116,108,105,110,107,115, 0, 42, 42,108,105,110,107,115, 0,116, 97,112, 0, +106,111,121,105,110,100,101,120, 0, 97,120,105,115, 95,115,105,110,103,108,101, 0, 97,120,105,115,102, 0, 98,117,116,116,111, +110, 0,104, 97,116, 0,104, 97,116,102, 0,112,114,101, 99,105,115,105,111,110, 0,115,116,114, 91, 49, 50, 56, 93, 0, 42,109, +121,110,101,119, 0,105,110,112,117,116,115, 0,116,111,116,115,108,105,110,107,115, 0, 42, 42,115,108,105,110,107,115, 0,118, + 97,108,111, 0,115,116, 97,116,101, 95,109, 97,115,107, 0, 42, 97, 99,116, 0,102,114, 97,109,101, 80,114,111,112, 91, 54, 52, + 93, 0, 98,108,101,110,100,105,110, 0,112,114,105,111,114,105,116,121, 0,101,110,100, 95,114,101,115,101,116, 0,115,116,114, +105,100,101, 97,120,105,115, 0,115,116,114,105,100,101,108,101,110,103,116,104, 0,108, 97,121,101,114, 95,119,101,105,103,104, +116, 0,109,105,110, 95,103, 97,105,110, 0,109, 97,120, 95,103, 97,105,110, 0,114,101,102,101,114,101,110, 99,101, 95,100,105, +115,116, 97,110, 99,101, 0,109, 97,120, 95,100,105,115,116, 97,110, 99,101, 0,114,111,108,108,111,102,102, 95,102, 97, 99,116, +111,114, 0, 99,111,110,101, 95,105,110,110,101,114, 95, 97,110,103,108,101, 0, 99,111,110,101, 95,111,117,116,101,114, 95, 97, +110,103,108,101, 0, 99,111,110,101, 95,111,117,116,101,114, 95,103, 97,105,110, 0,115,110,100,110,114, 0,115,111,117,110,100, + 51, 68, 0,112, 97,100, 54, 91, 49, 93, 0, 42,109,101, 0,108,105,110, 86,101,108,111, 99,105,116,121, 91, 51, 93, 0, 97,110, +103, 86,101,108,111, 99,105,116,121, 91, 51, 93, 0,108,111, 99, 97,108,102,108, 97,103, 0,100,121,110, 95,111,112,101,114, 97, +116,105,111,110, 0,102,111,114, 99,101,108,111, 99, 91, 51, 93, 0,102,111,114, 99,101,114,111,116, 91, 51, 93, 0,112, 97,100, + 49, 91, 51, 93, 0,108,105,110,101, 97,114,118,101,108,111, 99,105,116,121, 91, 51, 93, 0, 97,110,103,117,108, 97,114,118,101, +108,111, 99,105,116,121, 91, 51, 93, 0, 42,114,101,102,101,114,101,110, 99,101, 0,109,105,110, 0,109, 97,120, 0,114,111,116, +100, 97,109,112, 0,109,105,110,108,111, 99, 91, 51, 93, 0,109, 97,120,108,111, 99, 91, 51, 93, 0,109,105,110,114,111,116, 91, + 51, 93, 0,109, 97,120,114,111,116, 91, 51, 93, 0,109, 97,116,112,114,111,112, 91, 54, 52, 93, 0, 98,117,116,115,116, 97, 0, + 98,117,116,101,110,100, 0,100,105,115,116,114,105, 98,117,116,105,111,110, 0,105,110,116, 95, 97,114,103, 95, 49, 0,105,110, +116, 95, 97,114,103, 95, 50, 0,102,108,111, 97,116, 95, 97,114,103, 95, 49, 0,102,108,111, 97,116, 95, 97,114,103, 95, 50, 0, +116,111, 80,114,111,112, 78, 97,109,101, 91, 54, 52, 93, 0, 42,116,111, 79, 98,106,101, 99,116, 0, 98,111,100,121, 84,121,112, +101, 0,102,105,108,101,110, 97,109,101, 91, 54, 52, 93, 0,108,111, 97,100, 97,110,105,110, 97,109,101, 91, 54, 52, 93, 0,105, +110,116, 95, 97,114,103, 0,102,108,111, 97,116, 95, 97,114,103, 0,105,110,102,108,117,101,110, 99,101, 0, 42,115,117, 98,116, + 97,114,103,101,116, 0,102, 97, 99,105,110,103, 97,120,105,115, 0,118,101,108,111, 99,105,116,121, 0, 97, 99, 99,101,108,101, +114, 97,116,105,111,110, 0,116,117,114,110,115,112,101,101,100, 0,117,112,100, 97,116,101, 84,105,109,101, 0, 42,110, 97,118, +109,101,115,104, 0,103,111, 0, 42,110,101,119,112, 97, 99,107,101,100,102,105,108,101, 0, 97,116,116,101,110,117, 97,116,105, +111,110, 0,100,105,115,116, 97,110, 99,101, 0, 42, 99, 97, 99,104,101, 0, 42,119, 97,118,101,102,111,114,109, 0, 42,112,108, + 97,121, 98, 97, 99,107, 95,104, 97,110,100,108,101, 0, 42,108, 97,109,112,114,101,110, 0,103,111, 98,106,101, 99,116, 0,100, +117,112,108,105, 95,111,102,115, 91, 51, 93, 0, 42,112,114,111,112, 0, 99,104,105,108,100, 98, 97,115,101, 0,114,111,108,108, + 0,104,101, 97,100, 91, 51, 93, 0,116, 97,105,108, 91, 51, 93, 0, 98,111,110,101, 95,109, 97,116, 91, 51, 93, 91, 51, 93, 0, + 97,114,109, 95,104,101, 97,100, 91, 51, 93, 0, 97,114,109, 95,116, 97,105,108, 91, 51, 93, 0, 97,114,109, 95,109, 97,116, 91, + 52, 93, 91, 52, 93, 0, 97,114,109, 95,114,111,108,108, 0,120,119,105,100,116,104, 0,122,119,105,100,116,104, 0,101, 97,115, +101, 49, 0,101, 97,115,101, 50, 0,114, 97,100, 95,104,101, 97,100, 0,114, 97,100, 95,116, 97,105,108, 0,112, 97,100, 91, 49, + 93, 0, 98,111,110,101, 98, 97,115,101, 0, 99,104, 97,105,110, 98, 97,115,101, 0, 42,101,100, 98,111, 0, 42, 97, 99,116, 95, + 98,111,110,101, 0, 42, 97, 99,116, 95,101,100, 98,111,110,101, 0, 42,115,107,101,116, 99,104, 0,103,101,118,101,114,116,100, +101,102,111,114,109,101,114, 0,108, 97,121,101,114, 95,117,115,101,100, 0,108, 97,121,101,114, 95,112,114,111,116,101, 99,116, +101,100, 0,103,104,111,115,116,101,112, 0,103,104,111,115,116,115,105,122,101, 0,103,104,111,115,116,116,121,112,101, 0,112, + 97,116,104,115,105,122,101, 0,103,104,111,115,116,115,102, 0,103,104,111,115,116,101,102, 0,112, 97,116,104,115,102, 0,112, + 97,116,104,101,102, 0,112, 97,116,104, 98, 99, 0,112, 97,116,104, 97, 99, 0, 42,112,111,105,110,116,115, 0,115,116, 97,114, +116, 95,102,114, 97,109,101, 0,101,110,100, 95,102,114, 97,109,101, 0,103,104,111,115,116, 95,115,102, 0,103,104,111,115,116, + 95,101,102, 0,103,104,111,115,116, 95, 98, 99, 0,103,104,111,115,116, 95, 97, 99, 0,103,104,111,115,116, 95,116,121,112,101, + 0,103,104,111,115,116, 95,115,116,101,112, 0,103,104,111,115,116, 95,102,108, 97,103, 0,112, 97,116,104, 95,116,121,112,101, + 0,112, 97,116,104, 95,115,116,101,112, 0,112, 97,116,104, 95,118,105,101,119,102,108, 97,103, 0,112, 97,116,104, 95, 98, 97, +107,101,102,108, 97,103, 0,112, 97,116,104, 95,115,102, 0,112, 97,116,104, 95,101,102, 0,112, 97,116,104, 95, 98, 99, 0,112, + 97,116,104, 95, 97, 99, 0,105,107,102,108, 97,103, 0, 97,103,114,112, 95,105,110,100,101,120, 0, 99,111,110,115,116,102,108, + 97,103, 0,115,101,108,101, 99,116,102,108, 97,103, 0,112, 97,100, 48, 91, 54, 93, 0, 42, 98,111,110,101, 0, 42, 99,104,105, +108,100, 0,105,107,116,114,101,101, 0,115,105,107,116,114,101,101, 0, 42, 99,117,115,116,111,109, 0, 42, 99,117,115,116,111, +109, 95,116,120, 0,101,117,108, 91, 51, 93, 0, 99,104, 97,110, 95,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,111,115,101, 95, +109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,111,115,101, 95,104,101, 97,100, 91, 51, 93, 0,112,111,115,101, 95,116, 97,105,108, + 91, 51, 93, 0,108,105,109,105,116,109,105,110, 91, 51, 93, 0,108,105,109,105,116,109, 97,120, 91, 51, 93, 0,115,116,105,102, +102,110,101,115,115, 91, 51, 93, 0,105,107,115,116,114,101,116, 99,104, 0,105,107,114,111,116,119,101,105,103,104,116, 0,105, +107,108,105,110,119,101,105,103,104,116, 0, 42,116,101,109,112, 0, 99,104, 97,110, 98, 97,115,101, 0, 42, 99,104, 97,110,104, + 97,115,104, 0,112,114,111,120,121, 95,108, 97,121,101,114, 0,115,116,114,105,100,101, 95,111,102,102,115,101,116, 91, 51, 93, + 0, 99,121, 99,108,105, 99, 95,111,102,102,115,101,116, 91, 51, 93, 0, 97,103,114,111,117,112,115, 0, 97, 99,116,105,118,101, + 95,103,114,111,117,112, 0,105,107,115,111,108,118,101,114, 0, 42,105,107,100, 97,116, 97, 0, 42,105,107,112, 97,114, 97,109, + 0,112,114,111,120,121, 95, 97, 99,116, 95, 98,111,110,101, 91, 54, 52, 93, 0,110,117,109,105,116,101,114, 0,110,117,109,115, +116,101,112, 0,109,105,110,115,116,101,112, 0,109, 97,120,115,116,101,112, 0,115,111,108,118,101,114, 0,102,101,101,100, 98, + 97, 99,107, 0,109, 97,120,118,101,108, 0,100, 97,109,112,109, 97,120, 0,100, 97,109,112,101,112,115, 0, 99,104, 97,110,110, +101,108,115, 0, 99,117,115,116,111,109, 67,111,108, 0, 99,115, 0, 99,117,114,118,101,115, 0,103,114,111,117,112,115, 0, 97, + 99,116,105,118,101, 95,109, 97,114,107,101,114, 0,105,100,114,111,111,116, 0, 42,115,111,117,114, 99,101, 0, 42,102,105,108, +116,101,114, 95,103,114,112, 0,115,101, 97,114, 99,104,115,116,114, 91, 54, 52, 93, 0,102,105,108,116,101,114,102,108, 97,103, + 0,114,101,110, 97,109,101, 73,110,100,101,120, 0, 97,100,115, 0,116,105,109,101,115,108,105,100,101, 0, 42,103,114,112, 0, +110, 97,109,101, 91, 51, 48, 93, 0,111,119,110,115,112, 97, 99,101, 0,116, 97,114,115,112, 97, 99,101, 0,101,110,102,111,114, + 99,101, 0,104,101, 97,100,116, 97,105,108, 0,108,105,110, 95,101,114,114,111,114, 0,114,111,116, 95,101,114,114,111,114, 0, + 42,116, 97,114, 0,109, 97,116,114,105,120, 91, 52, 93, 91, 52, 93, 0,115,112, 97, 99,101, 0,114,111,116, 79,114,100,101,114, + 0,116, 97,114,110,117,109, 0,116, 97,114,103,101,116,115, 0,105,116,101,114, 97,116,105,111,110,115, 0,114,111,111,116, 98, +111,110,101, 0,109, 97,120, 95,114,111,111,116, 98,111,110,101, 0, 42,112,111,108,101,116, 97,114, 0,112,111,108,101,115,117, + 98,116, 97,114,103,101,116, 91, 54, 52, 93, 0,112,111,108,101, 97,110,103,108,101, 0,111,114,105,101,110,116,119,101,105,103, +104,116, 0,103,114, 97, 98,116, 97,114,103,101,116, 91, 51, 93, 0,110,117,109,112,111,105,110,116,115, 0, 99,104, 97,105,110, +108,101,110, 0,120,122, 83, 99, 97,108,101, 77,111,100,101, 0,114,101,115,101,114,118,101,100, 49, 0,114,101,115,101,114,118, +101,100, 50, 0,109,105,110,109, 97,120,102,108, 97,103, 0,115,116,117, 99,107, 0, 99, 97, 99,104,101, 91, 51, 93, 0,108,111, + 99,107,102,108, 97,103, 0,102,111,108,108,111,119,102,108, 97,103, 0,118,111,108,109,111,100,101, 0,112,108, 97,110,101, 0, +111,114,103,108,101,110,103,116,104, 0, 98,117,108,103,101, 0,112,105,118, 88, 0,112,105,118, 89, 0,112,105,118, 90, 0, 97, +120, 88, 0, 97,120, 89, 0, 97,120, 90, 0,109,105,110, 76,105,109,105,116, 91, 54, 93, 0,109, 97,120, 76,105,109,105,116, 91, + 54, 93, 0,101,120,116,114, 97, 70,122, 0,105,110,118,109, 97,116, 91, 52, 93, 91, 52, 93, 0,102,114,111,109, 0,116,111, 0, +109, 97,112, 91, 51, 93, 0,101,120,112,111, 0,102,114,111,109, 95,109,105,110, 91, 51, 93, 0,102,114,111,109, 95,109, 97,120, + 91, 51, 93, 0,116,111, 95,109,105,110, 91, 51, 93, 0,116,111, 95,109, 97,120, 91, 51, 93, 0,114,111,116, 65,120,105,115, 0, +122,109,105,110, 0,122,109, 97,120, 0,112, 97,100, 91, 57, 93, 0,116,114, 97, 99,107, 91, 54, 52, 93, 0,111, 98,106,101, 99, +116, 91, 54, 52, 93, 0, 42,100,101,112,116,104, 95,111, 98, 0, 99,104, 97,110,110,101,108, 91, 51, 50, 93, 0,110,111, 95,114, +111,116, 95, 97,120,105,115, 0,115,116,114,105,100,101, 95, 97,120,105,115, 0, 99,117,114,109,111,100, 0, 97, 99,116,115,116, + 97,114,116, 0, 97, 99,116,101,110,100, 0, 97, 99,116,111,102,102,115, 0,115,116,114,105,100,101,108,101,110, 0, 98,108,101, +110,100,111,117,116, 0,115,116,114,105,100,101, 99,104, 97,110,110,101,108, 91, 51, 50, 93, 0,111,102,102,115, 95, 98,111,110, +101, 91, 51, 50, 93, 0,104, 97,115,105,110,112,117,116, 0,104, 97,115,111,117,116,112,117,116, 0,100, 97,116, 97,116,121,112, +101, 0,115,111, 99,107,101,116,116,121,112,101, 0,105,115, 95, 99,111,112,121, 0,101,120,116,101,114,110, 97,108, 0, 42,110, +101,119, 95,115,111, 99,107, 0, 42,115,116,111,114, 97,103,101, 0,108,105,109,105,116, 0,115,116,114,117, 99,116, 95,116,121, +112,101, 0,108,111, 99,120, 0,108,111, 99,121, 0, 42,100,101,102, 97,117,108,116, 95,118, 97,108,117,101, 0,115,116, 97, 99, +107, 95,105,110,100,101,120, 0,115,116, 97, 99,107, 95,116,121,112,101, 0,111,119,110, 95,105,110,100,101,120, 0,116,111, 95, +105,110,100,101,120, 0, 42,103,114,111,117,112,115,111, 99,107, 0, 42,108,105,110,107, 0,110,115, 0, 42,114,101, 99,116, 0, +120,115,105,122,101, 0,121,115,105,122,101, 0, 42,110,101,119, 95,110,111,100,101, 0,108, 97,115,116,121, 0,111,117,116,112, +117,116,115, 0,109,105,110,105,119,105,100,116,104, 0,117,112,100, 97,116,101, 0,108, 97, 98,101,108, 91, 54, 52, 93, 0, 99, +117,115,116,111,109, 49, 0, 99,117,115,116,111,109, 50, 0, 99,117,115,116,111,109, 51, 0, 99,117,115,116,111,109, 52, 0,110, +101,101,100, 95,101,120,101, 99, 0,101,120,101, 99, 0, 42,116,104,114,101, 97,100,100, 97,116, 97, 0,116,111,116,114, 0, 98, +117,116,114, 0,112,114,118,114, 0, 42, 98,108,111, 99,107, 0, 42,116,121,112,101,105,110,102,111, 0, 42,102,114,111,109,110, +111,100,101, 0, 42,116,111,110,111,100,101, 0, 42,102,114,111,109,115,111, 99,107, 0, 42,116,111,115,111, 99,107, 0,110,111, +100,101,115, 0,108,105,110,107,115, 0,105,110,105,116, 0, 99,117,114, 95,105,110,100,101,120, 0,110,111,100,101,116,121,112, +101, 0, 42,101,120,101, 99,100, 97,116, 97, 0, 40, 42,112,114,111,103,114,101,115,115, 41, 40, 41, 0, 40, 42,115,116, 97,116, +115, 95,100,114, 97,119, 41, 40, 41, 0, 40, 42,116,101,115,116, 95, 98,114,101, 97,107, 41, 40, 41, 0, 42,116, 98,104, 0, 42, +112,114,104, 0, 42,115,100,104, 0,118, 97,108,117,101, 91, 51, 93, 0,118, 97,108,117,101, 91, 52, 93, 0, 99,121, 99,108,105, + 99, 0,109,111,118,105,101, 0,115, 97,109,112,108,101,115, 0,109, 97,120,115,112,101,101,100, 0,109,105,110,115,112,101,101, +100, 0, 99,117,114,118,101,100, 0,112,101,114, 99,101,110,116,120, 0,112,101,114, 99,101,110,116,121, 0, 98,111,107,101,104, + 0,103, 97,109,109, 97, 0,105,109, 97,103,101, 95,105,110, 95,119,105,100,116,104, 0,105,109, 97,103,101, 95,105,110, 95,104, +101,105,103,104,116, 0, 99,101,110,116,101,114, 95,120, 0, 99,101,110,116,101,114, 95,121, 0,115,112,105,110, 0,119,114, 97, +112, 0,115,105,103,109, 97, 95, 99,111,108,111,114, 0,115,105,103,109, 97, 95,115,112, 97, 99,101, 0,104,117,101, 0, 98, 97, +115,101, 95,112, 97,116,104, 91, 49, 48, 50, 52, 93, 0,102,111,114,109, 97,116, 0, 97, 99,116,105,118,101, 95,105,110,112,117, +116, 0,117,115,101, 95,114,101,110,100,101,114, 95,102,111,114,109, 97,116, 0,117,115,101, 95,110,111,100,101, 95,102,111,114, +109, 97,116, 0,116, 49, 0,116, 50, 0,116, 51, 0,102,115,116,114,101,110,103,116,104, 0,102, 97,108,112,104, 97, 0,107,101, +121, 91, 52, 93, 0, 97,108,103,111,114,105,116,104,109, 0, 99,104, 97,110,110,101,108, 0,120, 49, 0,120, 50, 0,121, 49, 0, +121, 50, 0,102, 97, 99, 95,120, 49, 0,102, 97, 99, 95,120, 50, 0,102, 97, 99, 95,121, 49, 0,102, 97, 99, 95,121, 50, 0, 99, +111,108,110, 97,109,101, 91, 54, 52, 93, 0, 98,107,116,121,112,101, 0,112, 97,100, 95, 99, 49, 0,103, 97,109, 99,111, 0,110, +111, 95,122, 98,117,102, 0,102,115,116,111,112, 0,109, 97,120, 98,108,117,114, 0, 98,116,104,114,101,115,104, 0,114,111,116, + 97,116,105,111,110, 0,112, 97,100, 95,102, 49, 0, 42,100,105, 99,116, 0, 42,110,111,100,101, 0, 99,111,108,109,111,100, 0, +109,105,120, 0,102, 97,100,101, 0, 97,110,103,108,101, 95,111,102,115, 0,109, 0, 99, 0,106,105,116, 0,112,114,111,106, 0, +102,105,116, 0,115,108,111,112,101, 91, 51, 93, 0,112,111,119,101,114, 91, 51, 93, 0,108,105,102,116, 95,108,103,103, 91, 51, + 93, 0,103, 97,109,109, 97, 95,105,110,118, 91, 51, 93, 0,108,105,109, 99,104, 97,110, 0,117,110,115,112,105,108,108, 0,108, +105,109,115, 99, 97,108,101, 0,117,115,112,105,108,108,114, 0,117,115,112,105,108,108,103, 0,117,115,112,105,108,108, 98, 0, +116,101,120, 95,109, 97,112,112,105,110,103, 0, 99,111,108,111,114, 95,109, 97,112,112,105,110,103, 0,115,117,110, 95,100,105, +114,101, 99,116,105,111,110, 91, 51, 93, 0,116,117,114, 98,105,100,105,116,121, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, + 0,112,114,111,106,101, 99,116,105,111,110, 0,103,114, 97,100,105,101,110,116, 95,116,121,112,101, 0, 99,111,108,111,114,105, +110,103, 0,109,117,115,103,114, 97,118,101, 95,116,121,112,101, 0,119, 97,118,101, 95,116,121,112,101, 0,115,104,111,114,116, +121, 0,109,105,110,116, 97, 98,108,101, 0,109, 97,120,116, 97, 98,108,101, 0,101,120,116, 95,105,110, 91, 50, 93, 0,101,120, +116, 95,111,117,116, 91, 50, 93, 0, 42, 99,117,114,118,101, 0, 42,116, 97, 98,108,101, 0, 42,112,114,101,109,117,108,116, 97, + 98,108,101, 0,112,114,101,115,101,116, 0, 99,104, 97,110,103,101,100, 95,116,105,109,101,115,116, 97,109,112, 0, 99,117,114, +114, 0, 99,108,105,112,114, 0, 99,109, 91, 52, 93, 0, 98,108, 97, 99,107, 91, 51, 93, 0,119,104,105,116,101, 91, 51, 93, 0, + 98,119,109,117,108, 91, 51, 93, 0,115, 97,109,112,108,101, 91, 51, 93, 0,120, 95,114,101,115,111,108,117,116,105,111,110, 0, +100, 97,116, 97, 95,114, 91, 50, 53, 54, 93, 0,100, 97,116, 97, 95,103, 91, 50, 53, 54, 93, 0,100, 97,116, 97, 95, 98, 91, 50, + 53, 54, 93, 0,100, 97,116, 97, 95,108,117,109, 97, 91, 50, 53, 54, 93, 0,115, 97,109,112,108,101, 95,102,117,108,108, 0,115, + 97,109,112,108,101, 95,108,105,110,101,115, 0, 97, 99, 99,117,114, 97, 99,121, 0,119, 97,118,101,102,114,109, 95,109,111,100, +101, 0,119, 97,118,101,102,114,109, 95, 97,108,112,104, 97, 0,119, 97,118,101,102,114,109, 95,121,102, 97, 99, 0,119, 97,118, +101,102,114,109, 95,104,101,105,103,104,116, 0,118,101, 99,115, 99,111,112,101, 95, 97,108,112,104, 97, 0,118,101, 99,115, 99, +111,112,101, 95,104,101,105,103,104,116, 0,109,105,110,109, 97,120, 91, 51, 93, 91, 50, 93, 0,104,105,115,116, 0, 42,119, 97, +118,101,102,111,114,109, 95, 49, 0, 42,119, 97,118,101,102,111,114,109, 95, 50, 0, 42,119, 97,118,101,102,111,114,109, 95, 51, + 0, 42,118,101, 99,115, 99,111,112,101, 0,119, 97,118,101,102,111,114,109, 95,116,111,116, 0,111,102,102,115,101,116, 91, 50, + 93, 0, 99,108,111,110,101, 0,109,116,101,120, 0, 42,105, 99,111,110, 95,105,109, 98,117,102, 0,105, 99,111,110, 95,102,105, +108,101,112, 97,116,104, 91, 49, 48, 50, 52, 93, 0,110,111,114,109, 97,108, 95,119,101,105,103,104,116, 0,111, 98, 95,109,111, +100,101, 0,106,105,116,116,101,114, 0,115,109,111,111,116,104, 95,115,116,114,111,107,101, 95,114, 97,100,105,117,115, 0,115, +109,111,111,116,104, 95,115,116,114,111,107,101, 95,102, 97, 99,116,111,114, 0,114, 97,116,101, 0,114,103, 98, 91, 51, 93, 0, +115, 99,117,108,112,116, 95,112,108, 97,110,101, 0,112,108, 97,110,101, 95,111,102,102,115,101,116, 0,115, 99,117,108,112,116, + 95,116,111,111,108, 0,118,101,114,116,101,120,112, 97,105,110,116, 95,116,111,111,108, 0,105,109, 97,103,101,112, 97,105,110, +116, 95,116,111,111,108, 0,112, 97,100, 51, 91, 53, 93, 0, 97,117,116,111,115,109,111,111,116,104, 95,102, 97, 99,116,111,114, + 0, 99,114,101, 97,115,101, 95,112,105,110, 99,104, 95,102, 97, 99,116,111,114, 0,112,108, 97,110,101, 95,116,114,105,109, 0, +116,101,120,116,117,114,101, 95,115, 97,109,112,108,101, 95, 98,105, 97,115, 0,116,101,120,116,117,114,101, 95,111,118,101,114, +108, 97,121, 95, 97,108,112,104, 97, 0, 97,100,100, 95, 99,111,108, 91, 51, 93, 0,115,117, 98, 95, 99,111,108, 91, 51, 93, 0, + 97, 99,116,105,118,101, 95,114,110,100, 0, 97, 99,116,105,118,101, 95, 99,108,111,110,101, 0, 97, 99,116,105,118,101, 95,109, + 97,115,107, 0, 42,108, 97,121,101,114,115, 0,116,121,112,101,109, 97,112, 91, 51, 52, 93, 0,116,111,116,108, 97,121,101,114, + 0,109, 97,120,108, 97,121,101,114, 0,116,111,116,115,105,122,101, 0, 42,112,111,111,108, 0, 42,101,120,116,101,114,110, 97, +108, 0,114,111,116, 91, 52, 93, 0, 97,118,101, 91, 51, 93, 0, 42,103,114,111,117,110,100, 0,119, 97,110,100,101,114, 91, 51, + 93, 0,114,101,115,116, 95,108,101,110,103,116,104, 0,112, 97,114,116,105, 99,108,101, 95,105,110,100,101,120, 91, 50, 93, 0, +100,101,108,101,116,101, 95,102,108, 97,103, 0,110,117,109, 0,112, 97,114,101,110,116, 0,112, 97, 91, 52, 93, 0,119, 91, 52, + 93, 0,102,117,118, 91, 52, 93, 0,102,111,102,102,115,101,116, 0,112,114,101,118, 95,115,116, 97,116,101, 0, 42,104, 97,105, +114, 0, 42, 98,111,105,100, 0,100,105,101,116,105,109,101, 0,110,117,109, 95,100,109, 99, 97, 99,104,101, 0,104, 97,105,114, + 95,105,110,100,101,120, 0, 97,108,105,118,101, 0,115,112,114,105,110,103, 95,107, 0,112,108, 97,115,116,105, 99,105,116,121, + 95, 99,111,110,115,116, 97,110,116, 0,121,105,101,108,100, 95,114, 97,116,105,111, 0,112,108, 97,115,116,105, 99,105,116,121, + 95, 98, 97,108, 97,110, 99,101, 0,121,105,101,108,100, 95, 98, 97,108, 97,110, 99,101, 0,118,105,115, 99,111,115,105,116,121, + 95,111,109,101,103, 97, 0,118,105,115, 99,111,115,105,116,121, 95, 98,101,116, 97, 0,115,116,105,102,102,110,101,115,115, 95, +107, 0,115,116,105,102,102,110,101,115,115, 95,107,110,101, 97,114, 0,114,101,115,116, 95,100,101,110,115,105,116,121, 0, 98, +117,111,121, 97,110, 99,121, 0,115,112,114,105,110,103, 95,102,114, 97,109,101,115, 0, 42, 98,111,105,100,115, 0, 42,102,108, +117,105,100, 0,100,105,115,116,114, 0,112,104,121,115,116,121,112,101, 0, 97,118,101,109,111,100,101, 0,114,101, 97, 99,116, +101,118,101,110,116, 0,100,114, 97,119, 0,100,114, 97,119, 95, 97,115, 0,100,114, 97,119, 95,115,105,122,101, 0, 99,104,105, +108,100,116,121,112,101, 0,114,101,110, 95, 97,115, 0,115,117, 98,102,114, 97,109,101,115, 0,100,114, 97,119, 95, 99,111,108, + 0,114,101,110, 95,115,116,101,112, 0,104, 97,105,114, 95,115,116,101,112, 0,107,101,121,115, 95,115,116,101,112, 0, 97,100, + 97,112,116, 95, 97,110,103,108,101, 0, 97,100, 97,112,116, 95,112,105,120, 0,114,111,116,102,114,111,109, 0,105,110,116,101, +103,114, 97,116,111,114, 0, 98, 98, 95, 97,108,105,103,110, 0, 98, 98, 95,117,118, 95,115,112,108,105,116, 0, 98, 98, 95, 97, +110,105,109, 0, 98, 98, 95,115,112,108,105,116, 95,111,102,102,115,101,116, 0, 98, 98, 95,116,105,108,116, 0, 98, 98, 95,114, + 97,110,100, 95,116,105,108,116, 0, 98, 98, 95,111,102,102,115,101,116, 91, 50, 93, 0, 98, 98, 95,115,105,122,101, 91, 50, 93, + 0, 98, 98, 95,118,101,108, 95,104,101, 97,100, 0, 98, 98, 95,118,101,108, 95,116, 97,105,108, 0, 99,111,108,111,114, 95,118, +101, 99, 95,109, 97,120, 0,115,105,109,112,108,105,102,121, 95,114,101,102,115,105,122,101, 0,115,105,109,112,108,105,102,121, + 95,114, 97,116,101, 0,115,105,109,112,108,105,102,121, 95,116,114, 97,110,115,105,116,105,111,110, 0,115,105,109,112,108,105, +102,121, 95,118,105,101,119,112,111,114,116, 0,116,105,109,101,116,119,101, 97,107, 0, 99,111,117,114, 97,110,116, 95,116, 97, +114,103,101,116, 0,106,105,116,102, 97, 99, 0,101,102,102, 95,104, 97,105,114, 0,103,114,105,100, 95,114, 97,110,100, 0,112, +115, 95,111,102,102,115,101,116, 91, 49, 93, 0,103,114,105,100, 95,114,101,115, 0,101,102,102,101, 99,116,111,114, 95, 97,109, +111,117,110,116, 0,116,105,109,101, 95,102,108, 97,103, 0,116,105,109,101, 95,112, 97,100, 91, 51, 93, 0,112, 97,114,116,102, + 97, 99, 0,116, 97,110,102, 97, 99, 0,116, 97,110,112,104, 97,115,101, 0,114,101, 97, 99,116,102, 97, 99, 0,111, 98, 95,118, +101,108, 91, 51, 93, 0, 97,118,101,102, 97, 99, 0,112,104, 97,115,101,102, 97, 99, 0,114, 97,110,100,114,111,116,102, 97, 99, + 0,114, 97,110,100,112,104, 97,115,101,102, 97, 99, 0,114, 97,110,100,115,105,122,101, 0, 97, 99, 99, 91, 51, 93, 0,100,114, + 97,103,102, 97, 99, 0, 98,114,111,119,110,102, 97, 99, 0,114, 97,110,100,108,101,110,103,116,104, 0, 99,104,105,108,100, 95, +110, 98,114, 0,114,101,110, 95, 99,104,105,108,100, 95,110, 98,114, 0,112, 97,114,101,110,116,115, 0, 99,104,105,108,100,115, +105,122,101, 0, 99,104,105,108,100,114, 97,110,100,115,105,122,101, 0, 99,104,105,108,100,114, 97,100, 0, 99,104,105,108,100, +102,108, 97,116, 0, 99,108,117,109,112,112,111,119, 0,107,105,110,107, 95,102,108, 97,116, 0,107,105,110,107, 95, 97,109,112, + 95, 99,108,117,109,112, 0,114,111,117,103,104, 49, 0,114,111,117,103,104, 49, 95,115,105,122,101, 0,114,111,117,103,104, 50, + 0,114,111,117,103,104, 50, 95,115,105,122,101, 0,114,111,117,103,104, 50, 95,116,104,114,101,115, 0,114,111,117,103,104, 95, +101,110,100, 0,114,111,117,103,104, 95,101,110,100, 95,115,104, 97,112,101, 0, 99,108,101,110,103,116,104, 0, 99,108,101,110, +103,116,104, 95,116,104,114,101,115, 0,112, 97,114,116,105,110,103, 95,102, 97, 99, 0,112, 97,114,116,105,110,103, 95,109,105, +110, 0,112, 97,114,116,105,110,103, 95,109, 97,120, 0, 98,114, 97,110, 99,104, 95,116,104,114,101,115, 0,100,114, 97,119, 95, +108,105,110,101, 91, 50, 93, 0,112, 97,116,104, 95,115,116, 97,114,116, 0,112, 97,116,104, 95,101,110,100, 0,116,114, 97,105, +108, 95, 99,111,117,110,116, 0,107,101,121,101,100, 95,108,111,111,112,115, 0,100,117,112,108,105,119,101,105,103,104,116,115, + 0, 42,101,102,102, 95,103,114,111,117,112, 0, 42,100,117,112, 95,111, 98, 0, 42, 98, 98, 95,111, 98, 0, 42,112,100, 50, 0, + 42,112, 97,114,116, 0, 42,112, 97,114,116,105, 99,108,101,115, 0, 42, 42,112, 97,116,104, 99, 97, 99,104,101, 0, 42, 42, 99, +104,105,108,100, 99, 97, 99,104,101, 0,112, 97,116,104, 99, 97, 99,104,101, 98,117,102,115, 0, 99,104,105,108,100, 99, 97, 99, +104,101, 98,117,102,115, 0, 42, 99,108,109,100, 0, 42,104, 97,105,114, 95,105,110, 95,100,109, 0, 42,104, 97,105,114, 95,111, +117,116, 95,100,109, 0, 42,116, 97,114,103,101,116, 95,111, 98, 0, 42,108, 97,116,116,105, 99,101, 0,116,114,101,101, 95,102, +114, 97,109,101, 0, 98,118,104,116,114,101,101, 95,102,114, 97,109,101, 0, 99,104,105,108,100, 95,115,101,101,100, 0,116,111, +116,117,110,101,120,105,115,116, 0,116,111,116, 99,104,105,108,100, 0,116,111,116, 99, 97, 99,104,101,100, 0,116,111,116, 99, +104,105,108,100, 99, 97, 99,104,101, 0,116, 97,114,103,101,116, 95,112,115,121,115, 0,116,111,116,107,101,121,101,100, 0, 98, + 97,107,101,115,112, 97, 99,101, 0, 98, 98, 95,117,118,110, 97,109,101, 91, 51, 93, 91, 54, 52, 93, 0,118,103,114,111,117,112, + 91, 49, 50, 93, 0,118,103, 95,110,101,103, 0,114,116, 51, 0, 42,114,101,110,100,101,114,100, 97,116, 97, 0, 42,101,102,102, +101, 99,116,111,114,115, 0, 42,102,108,117,105,100, 95,115,112,114,105,110,103,115, 0,116,111,116, 95,102,108,117,105,100,115, +112,114,105,110,103,115, 0, 97,108,108,111, 99, 95,102,108,117,105,100,115,112,114,105,110,103,115, 0, 42,116,114,101,101, 0, + 42,112,100,100, 0, 42,102,114, 97,110,100, 0,100,116, 95,102,114, 97, 99, 0, 95,112, 97,100, 0, 67,100,105,115, 0, 67,118, +105, 0,115,116,114,117, 99,116,117,114, 97,108, 0, 98,101,110,100,105,110,103, 0,109, 97,120, 95, 98,101,110,100, 0,109, 97, +120, 95,115,116,114,117, 99,116, 0,109, 97,120, 95,115,104,101, 97,114, 0, 97,118,103, 95,115,112,114,105,110,103, 95,108,101, +110, 0,116,105,109,101,115, 99, 97,108,101, 0,101,102,102, 95,102,111,114, 99,101, 95,115, 99, 97,108,101, 0,101,102,102, 95, +119,105,110,100, 95,115, 99, 97,108,101, 0,115,105,109, 95,116,105,109,101, 95,111,108,100, 0,118,101,108,111, 99,105,116,121, + 95,115,109,111,111,116,104, 0, 99,111,108,108,105,100,101,114, 95,102,114,105, 99,116,105,111,110, 0,118,101,108, 95,100, 97, +109,112,105,110,103, 0,115,116,101,112,115, 80,101,114, 70,114, 97,109,101, 0,112,114,101,114,111,108,108, 0,109, 97,120,115, +112,114,105,110,103,108,101,110, 0,115,111,108,118,101,114, 95,116,121,112,101, 0,118,103,114,111,117,112, 95, 98,101,110,100, + 0,118,103,114,111,117,112, 95,109, 97,115,115, 0,118,103,114,111,117,112, 95,115,116,114,117, 99,116, 0,115,104, 97,112,101, +107,101,121, 95,114,101,115,116, 0,112,114,101,115,101,116,115, 0,114,101,115,101,116, 0, 42, 99,111,108,108,105,115,105,111, +110, 95,108,105,115,116, 0,101,112,115,105,108,111,110, 0,115,101,108,102, 95,102,114,105, 99,116,105,111,110, 0,115,101,108, +102,101,112,115,105,108,111,110, 0,114,101,112,101,108, 95,102,111,114, 99,101, 0,100,105,115,116, 97,110, 99,101, 95,114,101, +112,101,108, 0,115,101,108,102, 95,108,111,111,112, 95, 99,111,117,110,116, 0,108,111,111,112, 95, 99,111,117,110,116, 0,112, +114,101,115,115,117,114,101, 0,116,104,105, 99,107,110,101,115,115, 0,115,116,114,111,107,101,115, 0,102,114, 97,109,101,110, +117,109, 0, 42, 97, 99,116,102,114, 97,109,101, 0,103,115,116,101,112, 0,105,110,102,111, 91, 49, 50, 56, 93, 0,115, 98,117, +102,102,101,114, 95,115,105,122,101, 0,115, 98,117,102,102,101,114, 95,115,102,108, 97,103, 0, 42,115, 98,117,102,102,101,114, + 0,108,105,115,116, 0,112,114,105,110,116,108,101,118,101,108, 0,115,116,111,114,101,108,101,118,101,108, 0, 42,114,101,112, +111,114,116,116,105,109,101,114, 0, 42,119,105,110,100,114, 97,119, 97, 98,108,101, 0, 42,119,105,110, 97, 99,116,105,118,101, + 0,119,105,110,100,111,119,115, 0,105,110,105,116,105, 97,108,105,122,101,100, 0,102,105,108,101, 95,115, 97,118,101,100, 0, +111,112, 95,117,110,100,111, 95,100,101,112,116,104, 0,111,112,101,114, 97,116,111,114,115, 0,113,117,101,117,101, 0,114,101, +112,111,114,116,115, 0,106,111, 98,115, 0,112, 97,105,110,116, 99,117,114,115,111,114,115, 0,100,114, 97,103,115, 0,107,101, +121, 99,111,110,102,105,103,115, 0, 42,100,101,102, 97,117,108,116, 99,111,110,102, 0, 42, 97,100,100,111,110, 99,111,110,102, + 0, 42,117,115,101,114, 99,111,110,102, 0,116,105,109,101,114,115, 0, 42, 97,117,116,111,115, 97,118,101,116,105,109,101,114, + 0, 42,103,104,111,115,116,119,105,110, 0,103,114, 97, 98, 99,117,114,115,111,114, 0, 42,115, 99,114,101,101,110, 0, 42,110, +101,119,115, 99,114,101,101,110, 0,115, 99,114,101,101,110,110, 97,109,101, 91, 54, 52, 93, 0,112,111,115,120, 0,112,111,115, +121, 0,119,105,110,100,111,119,115,116, 97,116,101, 0,109,111,110,105,116,111,114, 0,108, 97,115,116, 99,117,114,115,111,114, + 0,109,111,100, 97,108, 99,117,114,115,111,114, 0, 97,100,100,109,111,117,115,101,109,111,118,101, 0, 42,101,118,101,110,116, +115,116, 97,116,101, 0, 42, 99,117,114,115,119,105,110, 0, 42,116,119,101, 97,107, 0,100,114, 97,119,109,101,116,104,111,100, + 0,100,114, 97,119,102, 97,105,108, 0, 42,100,114, 97,119,100, 97,116, 97, 0,109,111,100, 97,108,104, 97,110,100,108,101,114, +115, 0,115,117, 98,119,105,110,100,111,119,115, 0,103,101,115,116,117,114,101, 0,105,100,110, 97,109,101, 91, 54, 52, 93, 0, +112,114,111,112,118, 97,108,117,101, 0,115,104,105,102,116, 0, 99,116,114,108, 0, 97,108,116, 0,111,115,107,101,121, 0,107, +101,121,109,111,100,105,102,105,101,114, 0,109, 97,112,116,121,112,101, 0, 42,112,116,114, 0, 42,114,101,109,111,118,101, 95, +105,116,101,109, 0, 42, 97,100,100, 95,105,116,101,109, 0,105,116,101,109,115, 0,100,105,102,102, 95,105,116,101,109,115, 0, +115,112, 97, 99,101,105,100, 0,114,101,103,105,111,110,105,100, 0,107,109,105, 95,105,100, 0, 40, 42,112,111,108,108, 41, 40, + 41, 0, 42,109,111,100, 97,108, 95,105,116,101,109,115, 0, 98, 97,115,101,110, 97,109,101, 91, 54, 52, 93, 0, 97, 99,116,107, +101,121,109, 97,112, 0, 42, 99,117,115,116,111,109,100, 97,116, 97, 0, 42,112,121, 95,105,110,115,116, 97,110, 99,101, 0, 42, +114,101,112,111,114,116,115, 0,109, 97, 99,114,111, 0, 42,111,112,109, 0, 42,101,100, 97,116, 97, 0, 42, 99,111,101,102,102, +105, 99,105,101,110,116,115, 0, 97,114,114, 97,121,115,105,122,101, 0,112,111,108,121, 95,111,114,100,101,114, 0, 97,109,112, +108,105,116,117,100,101, 0,112,104, 97,115,101, 95,109,117,108,116,105,112,108,105,101,114, 0,112,104, 97,115,101, 95,111,102, +102,115,101,116, 0,118, 97,108,117,101, 95,111,102,102,115,101,116, 0,109,105,100,118, 97,108, 0, 98,101,102,111,114,101, 95, +109,111,100,101, 0, 97,102,116,101,114, 95,109,111,100,101, 0, 98,101,102,111,114,101, 95, 99,121, 99,108,101,115, 0, 97,102, +116,101,114, 95, 99,121, 99,108,101,115, 0,114,101, 99,116, 0,112,104, 97,115,101, 0,109,111,100,105,102,105, 99, 97,116,105, +111,110, 0,115,116,101,112, 95,115,105,122,101, 0, 42,114,110, 97, 95,112, 97,116,104, 0,112, 99,104, 97,110, 95,110, 97,109, +101, 91, 51, 50, 93, 0,116,114, 97,110,115, 67,104, 97,110, 0,105,100,116,121,112,101, 0,116, 97,114,103,101,116,115, 91, 56, + 93, 0,110,117,109, 95,116, 97,114,103,101,116,115, 0,118, 97,114,105, 97, 98,108,101,115, 0,101,120,112,114,101,115,115,105, +111,110, 91, 50, 53, 54, 93, 0, 42,101,120,112,114, 95, 99,111,109,112, 0,118,101, 99, 91, 50, 93, 0, 42,102,112,116, 0, 97, +114,114, 97,121, 95,105,110,100,101,120, 0, 99,111,108,111,114, 95,109,111,100,101, 0, 99,111,108,111,114, 91, 51, 93, 0,102, +114,111,109, 91, 49, 50, 56, 93, 0,116,111, 91, 49, 50, 56, 93, 0,109, 97,112,112,105,110,103,115, 0,115,116,114,105,112,115, + 0, 42,114,101,109, 97,112, 0,102, 99,117,114,118,101,115, 0,115,116,114,105,112, 95,116,105,109,101, 0, 98,108,101,110,100, +109,111,100,101, 0,101,120,116,101,110,100,109,111,100,101, 0, 42,115,112,101, 97,107,101,114, 95,104, 97,110,100,108,101, 0, +103,114,111,117,112, 91, 54, 52, 93, 0,103,114,111,117,112,109,111,100,101, 0,107,101,121,105,110,103,102,108, 97,103, 0,112, + 97,116,104,115, 0,100,101,115, 99,114,105,112,116,105,111,110, 91, 50, 52, 48, 93, 0,116,121,112,101,105,110,102,111, 91, 54, + 52, 93, 0, 97, 99,116,105,118,101, 95,112, 97,116,104, 0, 42,116,109,112, 97, 99,116, 0,110,108, 97, 95,116,114, 97, 99,107, +115, 0, 42, 97, 99,116,115,116,114,105,112, 0,100,114,105,118,101,114,115, 0,111,118,101,114,114,105,100,101,115, 0, 97, 99, +116, 95, 98,108,101,110,100,109,111,100,101, 0, 97, 99,116, 95,101,120,116,101,110,100,109,111,100,101, 0, 97, 99,116, 95,105, +110,102,108,117,101,110, 99,101, 0,114,117,108,101, 0,111,112,116,105,111,110,115, 0,102,101, 97,114, 95,102, 97, 99,116,111, +114, 0,115,105,103,110, 97,108, 95,105,100, 0,108,111,111,107, 95, 97,104,101, 97,100, 0,111,108,111, 99, 91, 51, 93, 0,113, +117,101,117,101, 95,115,105,122,101, 0,119, 97,110,100,101,114, 0,102,108,101,101, 95,100,105,115,116, 97,110, 99,101, 0,104, +101, 97,108,116,104, 0,115,116, 97,116,101, 95,105,100, 0,114,117,108,101,115, 0, 99,111,110,100,105,116,105,111,110,115, 0, + 97, 99,116,105,111,110,115, 0,114,117,108,101,115,101,116, 95,116,121,112,101, 0,114,117,108,101, 95,102,117,122,122,105,110, +101,115,115, 0,108, 97,115,116, 95,115,116, 97,116,101, 95,105,100, 0,108, 97,110,100,105,110,103, 95,115,109,111,111,116,104, +110,101,115,115, 0, 98, 97,110,107,105,110,103, 0, 97,103,103,114,101,115,115,105,111,110, 0, 97,105,114, 95,109,105,110, 95, +115,112,101,101,100, 0, 97,105,114, 95,109, 97,120, 95,115,112,101,101,100, 0, 97,105,114, 95,109, 97,120, 95, 97, 99, 99, 0, + 97,105,114, 95,109, 97,120, 95, 97,118,101, 0, 97,105,114, 95,112,101,114,115,111,110, 97,108, 95,115,112, 97, 99,101, 0,108, + 97,110,100, 95,106,117,109,112, 95,115,112,101,101,100, 0,108, 97,110,100, 95,109, 97,120, 95,115,112,101,101,100, 0,108, 97, +110,100, 95,109, 97,120, 95, 97, 99, 99, 0,108, 97,110,100, 95,109, 97,120, 95, 97,118,101, 0,108, 97,110,100, 95,112,101,114, +115,111,110, 97,108, 95,115,112, 97, 99,101, 0,108, 97,110,100, 95,115,116,105, 99,107, 95,102,111,114, 99,101, 0,115,116, 97, +116,101,115, 0, 42,115,109,100, 0, 42,102,108,117,105,100, 95,103,114,111,117,112, 0, 42, 99,111,108,108, 95,103,114,111,117, +112, 0, 42,119,116, 0, 42,116,101,120, 95,119,116, 0, 42,116,101,120, 95,115,104, 97,100,111,119, 0, 42,115,104, 97,100,111, +119, 0,112, 48, 91, 51, 93, 0,112, 49, 91, 51, 93, 0,100,120, 0,111,109,101,103, 97, 0,116,101,109,112, 65,109, 98, 0, 98, +101,116, 97, 0,114,101,115, 91, 51, 93, 0, 97,109,112,108,105,102,121, 0,109, 97,120,114,101,115, 0,118,105,101,119,115,101, +116,116,105,110,103,115, 0,110,111,105,115,101, 0,100,105,115,115, 95,112,101,114, 99,101,110,116, 0,100,105,115,115, 95,115, +112,101,101,100, 0,114,101,115, 95,119,116, 91, 51, 93, 0,100,120, 95,119,116, 0,118, 51,100,110,117,109, 0, 99, 97, 99,104, +101, 95, 99,111,109,112, 0, 99, 97, 99,104,101, 95,104,105,103,104, 95, 99,111,109,112, 0, 42,112,111,105,110,116, 95, 99, 97, + 99,104,101, 91, 50, 93, 0,112,116, 99, 97, 99,104,101,115, 91, 50, 93, 0, 98,111,114,100,101,114, 95, 99,111,108,108,105,115, +105,111,110,115, 0,116,105,109,101, 95,115, 99, 97,108,101, 0,118,111,114,116,105, 99,105,116,121, 0,118,101,108,111, 99,105, +116,121, 91, 50, 93, 0,118,101,108, 95,109,117,108,116,105, 0,118,103,114,112, 95,104,101, 97,116, 95,115, 99, 97,108,101, 91, + 50, 93, 0,118,103,114,111,117,112, 95,102,108,111,119, 0,118,103,114,111,117,112, 95,100,101,110,115,105,116,121, 0,118,103, +114,111,117,112, 95,104,101, 97,116, 0, 42,112,111,105,110,116,115, 95,111,108,100, 0, 42,118,101,108, 0,109, 97,116, 95,111, +108,100, 91, 52, 93, 91, 52, 93, 0,118,111,108,117,109,101, 95,109, 97,120, 0,118,111,108,117,109,101, 95,109,105,110, 0,100, +105,115,116, 97,110, 99,101, 95,109, 97,120, 0,100,105,115,116, 97,110, 99,101, 95,114,101,102,101,114,101,110, 99,101, 0, 99, +111,110,101, 95, 97,110,103,108,101, 95,111,117,116,101,114, 0, 99,111,110,101, 95, 97,110,103,108,101, 95,105,110,110,101,114, + 0, 99,111,110,101, 95,118,111,108,117,109,101, 95,111,117,116,101,114, 0,114,101,110,100,101,114, 95,102,108, 97,103, 0, 98, +117,105,108,100, 95,115,105,122,101, 95,102,108, 97,103, 0, 98,117,105,108,100, 95,116, 99, 95,102,108, 97,103, 0,108, 97,115, +116,115,105,122,101, 91, 50, 93, 0,116,114, 97, 99,107,105,110,103, 0, 42,116,114, 97, 99,107,105,110,103, 95, 99,111,110,116, +101,120,116, 0,112,114,111,120,121, 0,116,114, 97, 99,107, 95,112,114,101,118,105,101,119, 95,104,101,105,103,104,116, 0, 42, +116,114, 97, 99,107, 95,112,114,101,118,105,101,119, 0,116,114, 97, 99,107, 95,112,111,115, 91, 50, 93, 0,116,114, 97, 99,107, + 95,100,105,115, 97, 98,108,101,100, 0, 42,109, 97,114,107,101,114, 0,115,108,105,100,101, 95,115, 99, 97,108,101, 91, 50, 93, + 0,101,114,114,111,114, 0, 42,105,110,116,114,105,110,115,105, 99,115, 0,115,101,110,115,111,114, 95,119,105,100,116,104, 0, +112,105,120,101,108, 95, 97,115,112,101, 99,116, 0,102,111, 99, 97,108, 0,117,110,105,116,115, 0,112,114,105,110, 99,105,112, + 97,108, 91, 50, 93, 0,107, 49, 0,107, 50, 0,107, 51, 0,112,111,115, 91, 50, 93, 0,112, 97,116, 95,109,105,110, 91, 50, 93, + 0,112, 97,116, 95,109, 97,120, 91, 50, 93, 0,115,101, 97,114, 99,104, 95,109,105,110, 91, 50, 93, 0,115,101, 97,114, 99,104, + 95,109, 97,120, 91, 50, 93, 0,109, 97,114,107,101,114,115,110,114, 0,108, 97,115,116, 95,109, 97,114,107,101,114, 0, 42,109, + 97,114,107,101,114,115, 0, 98,117,110,100,108,101, 95,112,111,115, 91, 51, 93, 0,112, 97,116, 95,102,108, 97,103, 0,115,101, + 97,114, 99,104, 95,102,108, 97,103, 0,102,114, 97,109,101,115, 95,108,105,109,105,116, 0,112, 97,116,116,101,114,110, 95,109, + 97,116, 99,104, 0,116,114, 97, 99,107,101,114, 0,112,121,114, 97,109,105,100, 95,108,101,118,101,108,115, 0,109,105,110,105, +109,117,109, 95, 99,111,114,114,101,108, 97,116,105,111,110, 0,100,101,102, 97,117,108,116, 95,116,114, 97, 99,107,101,114, 0, +100,101,102, 97,117,108,116, 95,112,121,114, 97,109,105,100, 95,108,101,118,101,108,115, 0,100,101,102, 97,117,108,116, 95,109, +105,110,105,109,117,109, 95, 99,111,114,114,101,108, 97,116,105,111,110, 0,100,101,102, 97,117,108,116, 95,112, 97,116,116,101, +114,110, 95,115,105,122,101, 0,100,101,102, 97,117,108,116, 95,115,101, 97,114, 99,104, 95,115,105,122,101, 0,100,101,102, 97, +117,108,116, 95,102,114, 97,109,101,115, 95,108,105,109,105,116, 0,100,101,102, 97,117,108,116, 95,109, 97,114,103,105,110, 0, +100,101,102, 97,117,108,116, 95,112, 97,116,116,101,114,110, 95,109, 97,116, 99,104, 0,100,101,102, 97,117,108,116, 95,102,108, + 97,103, 0,109,111,116,105,111,110, 95,102,108, 97,103, 0,107,101,121,102,114, 97,109,101, 49, 0,107,101,121,102,114, 97,109, +101, 50, 0,114,101,102,105,110,101, 95, 99, 97,109,101,114, 97, 95,105,110,116,114,105,110,115,105, 99,115, 0, 99,108,101, 97, +110, 95,102,114, 97,109,101,115, 0, 99,108,101, 97,110, 95, 97, 99,116,105,111,110, 0, 99,108,101, 97,110, 95,101,114,114,111, +114, 0,111, 98,106,101, 99,116, 95,100,105,115,116, 97,110, 99,101, 0,116,111,116, 95,116,114, 97, 99,107, 0, 97, 99,116, 95, +116,114, 97, 99,107, 0,109, 97,120,115, 99, 97,108,101, 0, 42,114,111,116, 95,116,114, 97, 99,107, 0,108,111, 99,105,110,102, + 0,115, 99, 97,108,101,105,110,102, 0,114,111,116,105,110,102, 0, 42,115, 99, 97,108,101,105, 98,117,102, 0,108, 97,115,116, + 95, 99, 97,109,101,114, 97, 0, 99, 97,109,110,114, 0, 42, 99, 97,109,101,114, 97,115, 0,116,114, 97, 99,107,115, 0,114,101, + 99,111,110,115,116,114,117, 99,116,105,111,110, 0,109,101,115,115, 97,103,101, 91, 50, 53, 54, 93, 0,115,101,116,116,105,110, +103,115, 0, 99, 97,109,101,114, 97, 0,115,116, 97, 98,105,108,105,122, 97,116,105,111,110, 0, 42, 97, 99,116, 95,116,114, 97, + 99,107, 0,111, 98,106,101, 99,116,115, 0,111, 98,106,101, 99,116,110,114, 0,116,111,116, 95,111, 98,106,101, 99,116, 0, 42, + 98,114,117,115,104, 95,103,114,111,117,112, 0, 99,117,114,114,101,110,116, 95,102,114, 97,109,101, 0,100,105,115,112, 95,116, +121,112,101, 0,105,109, 97,103,101, 95,102,105,108,101,102,111,114,109, 97,116, 0,101,102,102,101, 99,116, 95,117,105, 0,112, +114,101,118,105,101,119, 95,105,100, 0,105,110,105,116, 95, 99,111,108,111,114, 95,116,121,112,101, 0,112, 97,100, 95,115, 0, +105,109, 97,103,101, 95,114,101,115,111,108,117,116,105,111,110, 0,115,117, 98,115,116,101,112,115, 0,105,110,105,116, 95, 99, +111,108,111,114, 91, 52, 93, 0, 42,105,110,105,116, 95,116,101,120,116,117,114,101, 0,105,110,105,116, 95,108, 97,121,101,114, +110, 97,109,101, 91, 54, 52, 93, 0,100,114,121, 95,115,112,101,101,100, 0, 99,111,108,111,114, 95,100,114,121, 95,116,104,114, +101,115,104,111,108,100, 0,100,101,112,116,104, 95, 99,108, 97,109,112, 0,100,105,115,112, 95,102, 97, 99,116,111,114, 0,115, +112,114,101, 97,100, 95,115,112,101,101,100, 0, 99,111,108,111,114, 95,115,112,114,101, 97,100, 95,115,112,101,101,100, 0,115, +104,114,105,110,107, 95,115,112,101,101,100, 0,100,114,105,112, 95,118,101,108, 0,100,114,105,112, 95, 97, 99, 99, 0,105,110, +102,108,117,101,110, 99,101, 95,115, 99, 97,108,101, 0,114, 97,100,105,117,115, 95,115, 99, 97,108,101, 0,119, 97,118,101, 95, +100, 97,109,112,105,110,103, 0,119, 97,118,101, 95,115,112,101,101,100, 0,119, 97,118,101, 95,116,105,109,101,115, 99, 97,108, +101, 0,119, 97,118,101, 95,115,112,114,105,110,103, 0,105,109, 97,103,101, 95,111,117,116,112,117,116, 95,112, 97,116,104, 91, + 49, 48, 50, 52, 93, 0,111,117,116,112,117,116, 95,110, 97,109,101, 91, 54, 52, 93, 0,111,117,116,112,117,116, 95,110, 97,109, +101, 50, 91, 54, 52, 93, 0, 42,112,109,100, 0,115,117,114,102, 97, 99,101,115, 0, 97, 99,116,105,118,101, 95,115,117,114, 0, +101,114,114,111,114, 91, 54, 52, 93, 0, 99,111,108,108,105,115,105,111,110, 0,119,101,116,110,101,115,115, 0,112, 97,114,116, +105, 99,108,101, 95,114, 97,100,105,117,115, 0,112, 97,114,116,105, 99,108,101, 95,115,109,111,111,116,104, 0,112, 97,105,110, +116, 95,100,105,115,116, 97,110, 99,101, 0, 42,112, 97,105,110,116, 95,114, 97,109,112, 0, 42,118,101,108, 95,114, 97,109,112, + 0,112,114,111,120,105,109,105,116,121, 95,102, 97,108,108,111,102,102, 0,114, 97,121, 95,100,105,114, 0,119, 97,118,101, 95, +102, 97, 99,116,111,114, 0,119, 97,118,101, 95, 99,108, 97,109,112, 0,109, 97,120, 95,118,101,108,111, 99,105,116,121, 0,115, +109,117,100,103,101, 95,115,116,114,101,110,103,116,104, 0, 0, 84, 89, 80, 69, 16, 2, 0, 0, 99,104, 97,114, 0,117, 99,104, + 97,114, 0,115,104,111,114,116, 0,117,115,104,111,114,116, 0,105,110,116, 0,108,111,110,103, 0,117,108,111,110,103, 0,102, +108,111, 97,116, 0,100,111,117, 98,108,101, 0,105,110,116, 54, 52, 95,116, 0,117,105,110,116, 54, 52, 95,116, 0,118,111,105, +100, 0, 76,105,110,107, 0, 76,105,110,107, 68, 97,116, 97, 0, 76,105,115,116, 66, 97,115,101, 0,118,101, 99, 50,115, 0,118, +101, 99, 50,102, 0,118,101, 99, 51,102, 0,114, 99,116,105, 0,114, 99,116,102, 0, 73, 68, 80,114,111,112,101,114,116,121, 68, + 97,116, 97, 0, 73, 68, 80,114,111,112,101,114,116,121, 0, 73, 68, 0, 76,105, 98,114, 97,114,121, 0, 70,105,108,101, 68, 97, +116, 97, 0, 80,114,101,118,105,101,119, 73,109, 97,103,101, 0, 73,112,111, 68,114,105,118,101,114, 0, 79, 98,106,101, 99,116, + 0, 73,112,111, 67,117,114,118,101, 0, 66, 80,111,105,110,116, 0, 66,101,122, 84,114,105,112,108,101, 0, 73,112,111, 0, 75, +101,121, 66,108,111, 99,107, 0, 75,101,121, 0, 65,110,105,109, 68, 97,116, 97, 0, 84,101,120,116, 76,105,110,101, 0, 84,101, +120,116, 77, 97,114,107,101,114, 0, 84,101,120,116, 0, 80, 97, 99,107,101,100, 70,105,108,101, 0, 67, 97,109,101,114, 97, 0, + 73,109, 97,103,101, 85,115,101,114, 0, 83, 99,101,110,101, 0, 73,109, 97,103,101, 0, 71, 80, 85, 84,101,120,116,117,114,101, + 0, 97,110,105,109, 0, 82,101,110,100,101,114, 82,101,115,117,108,116, 0, 77, 84,101,120, 0, 84,101,120, 0, 80,108,117,103, +105,110, 84,101,120, 0, 67, 66, 68, 97,116, 97, 0, 67,111,108,111,114, 66, 97,110,100, 0, 69,110,118, 77, 97,112, 0, 73,109, + 66,117,102, 0, 80,111,105,110,116, 68,101,110,115,105,116,121, 0, 67,117,114,118,101, 77, 97,112,112,105,110,103, 0, 86,111, +120,101,108, 68, 97,116, 97, 0, 79, 99,101, 97,110, 84,101,120, 0, 98, 78,111,100,101, 84,114,101,101, 0, 84,101,120, 77, 97, +112,112,105,110,103, 0, 67,111,108,111,114, 77, 97,112,112,105,110,103, 0, 76, 97,109,112, 0, 86,111,108,117,109,101, 83,101, +116,116,105,110,103,115, 0, 71, 97,109,101, 83,101,116,116,105,110,103,115, 0, 77, 97,116,101,114,105, 97,108, 0, 71,114,111, +117,112, 0, 86, 70,111,110,116, 0, 86, 70,111,110,116, 68, 97,116, 97, 0, 77,101,116, 97, 69,108,101,109, 0, 66,111,117,110, +100, 66,111,120, 0, 77,101,116, 97, 66, 97,108,108, 0, 78,117,114, 98, 0, 67,104, 97,114, 73,110,102,111, 0, 84,101,120,116, + 66,111,120, 0, 69,100,105,116, 78,117,114, 98, 0, 71, 72, 97,115,104, 0, 67,117,114,118,101, 0, 80, 97,116,104, 0, 83,101, +108, 66,111,120, 0, 69,100,105,116, 70,111,110,116, 0, 77,101,115,104, 0, 77, 83,101,108,101, 99,116, 0, 77, 80,111,108,121, + 0, 77, 84,101,120, 80,111,108,121, 0, 77, 76,111,111,112, 0, 77, 76,111,111,112, 85, 86, 0, 77, 76,111,111,112, 67,111,108, + 0, 77, 70, 97, 99,101, 0, 77, 84, 70, 97, 99,101, 0, 84, 70, 97, 99,101, 0, 77, 86,101,114,116, 0, 77, 69,100,103,101, 0, + 77, 68,101,102,111,114,109, 86,101,114,116, 0, 77, 67,111,108, 0, 77, 83,116,105, 99,107,121, 0, 66, 77, 69,100,105,116, 77, +101,115,104, 0, 67,117,115,116,111,109, 68, 97,116, 97, 0, 77,117,108,116,105,114,101,115, 0, 77, 68,101,102,111,114,109, 87, +101,105,103,104,116, 0, 77, 70,108,111, 97,116, 80,114,111,112,101,114,116,121, 0, 77, 73,110,116, 80,114,111,112,101,114,116, +121, 0, 77, 83,116,114,105,110,103, 80,114,111,112,101,114,116,121, 0, 79,114,105,103, 83,112, 97, 99,101, 70, 97, 99,101, 0, + 79,114,105,103, 83,112, 97, 99,101, 76,111,111,112, 0, 77, 68,105,115,112,115, 0, 77,117,108,116,105,114,101,115, 67,111,108, + 0, 77,117,108,116,105,114,101,115, 67,111,108, 70, 97, 99,101, 0, 77,117,108,116,105,114,101,115, 70, 97, 99,101, 0, 77,117, +108,116,105,114,101,115, 69,100,103,101, 0, 77,117,108,116,105,114,101,115, 76,101,118,101,108, 0, 77, 82,101, 99, 97,115,116, + 0, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77, 97,112,112,105,110,103, 73,110,102,111, 77,111,100,105,102,105,101, +114, 68, 97,116, 97, 0, 83,117, 98,115,117,114,102, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 76, 97,116,116,105, 99, +101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 67,117,114,118,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, + 66,117,105,108,100, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77, 97,115,107, 77,111,100,105,102,105,101,114, 68, 97, +116, 97, 0, 65,114,114, 97,121, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77,105,114,114,111,114, 77,111,100,105,102, +105,101,114, 68, 97,116, 97, 0, 69,100,103,101, 83,112,108,105,116, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 66,101, +118,101,108, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 66, 77,101,115,104, 77,111,100,105,102,105,101,114, 68, 97,116, + 97, 0, 83,109,111,107,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,109,111,107,101, 68,111,109, 97,105,110, 83, +101,116,116,105,110,103,115, 0, 83,109,111,107,101, 70,108,111,119, 83,101,116,116,105,110,103,115, 0, 83,109,111,107,101, 67, +111,108,108, 83,101,116,116,105,110,103,115, 0, 68,105,115,112,108, 97, 99,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, + 0, 85, 86, 80,114,111,106,101, 99,116, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 68,101, 99,105,109, 97,116,101, 77, +111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,109,111,111,116,104, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 67, + 97,115,116, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 87, 97,118,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, + 0, 65,114,109, 97,116,117,114,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 72,111,111,107, 77,111,100,105,102,105, +101,114, 68, 97,116, 97, 0, 83,111,102,116, 98,111,100,121, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 67,108,111,116, +104, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 67,108,111,116,104, 0, 67,108,111,116,104, 83,105,109, 83,101,116,116, +105,110,103,115, 0, 67,108,111,116,104, 67,111,108,108, 83,101,116,116,105,110,103,115, 0, 80,111,105,110,116, 67, 97, 99,104, +101, 0, 67,111,108,108,105,115,105,111,110, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 66, 86, 72, 84,114,101,101, 0, + 83,117,114,102, 97, 99,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 68,101,114,105,118,101,100, 77,101,115,104, 0, + 66, 86, 72, 84,114,101,101, 70,114,111,109, 77,101,115,104, 0, 66,111,111,108,101, 97,110, 77,111,100,105,102,105,101,114, 68, + 97,116, 97, 0, 77, 68,101,102, 73,110,102,108,117,101,110, 99,101, 0, 77, 68,101,102, 67,101,108,108, 0, 77,101,115,104, 68, +101,102,111,114,109, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 80, 97,114,116,105, 99,108,101, 83,121,115,116,101,109, + 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 80, 97,114,116,105, 99,108,101, 83,121,115,116,101,109, 0, 80, 97,114,116, +105, 99,108,101, 73,110,115,116, 97,110, 99,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 69,120,112,108,111,100,101, + 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 77,117,108,116,105,114,101,115, 77,111,100,105,102,105,101,114, 68, 97,116, + 97, 0, 70,108,117,105,100,115,105,109, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 70,108,117,105,100,115,105,109, 83, +101,116,116,105,110,103,115, 0, 83,104,114,105,110,107,119,114, 97,112, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83, +105,109,112,108,101, 68,101,102,111,114,109, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,104, 97,112,101, 75,101,121, + 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,111,108,105,100,105,102,121, 77,111,100,105,102,105,101,114, 68, 97,116, + 97, 0, 83, 99,114,101,119, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 79, 99,101, 97,110, 77,111,100,105,102,105,101, +114, 68, 97,116, 97, 0, 79, 99,101, 97,110, 0, 79, 99,101, 97,110, 67, 97, 99,104,101, 0, 87, 97,114,112, 77,111,100,105,102, +105,101,114, 68, 97,116, 97, 0, 87,101,105,103,104,116, 86, 71, 69,100,105,116, 77,111,100,105,102,105,101,114, 68, 97,116, 97, + 0, 87,101,105,103,104,116, 86, 71, 77,105,120, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 87,101,105,103,104,116, 86, + 71, 80,114,111,120,105,109,105,116,121, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 68,121,110, 97,109,105, 99, 80, 97, +105,110,116, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 68,121,110, 97,109,105, 99, 80, 97,105,110,116, 67, 97,110,118, + 97,115, 83,101,116,116,105,110,103,115, 0, 68,121,110, 97,109,105, 99, 80, 97,105,110,116, 66,114,117,115,104, 83,101,116,116, +105,110,103,115, 0, 82,101,109,101,115,104, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 69,100,105,116, 76, 97,116,116, + 0, 76, 97,116,116,105, 99,101, 0, 98, 68,101,102,111,114,109, 71,114,111,117,112, 0, 83, 99,117,108,112,116, 83,101,115,115, +105,111,110, 0, 98, 65, 99,116,105,111,110, 0, 98, 80,111,115,101, 0, 98, 71, 80,100, 97,116, 97, 0, 98, 65,110,105,109, 86, +105,122, 83,101,116,116,105,110,103,115, 0, 98, 77,111,116,105,111,110, 80, 97,116,104, 0, 66,117,108,108,101,116, 83,111,102, +116, 66,111,100,121, 0, 80, 97,114,116, 68,101,102,108,101, 99,116, 0, 83,111,102,116, 66,111,100,121, 0, 79, 98, 72,111,111, +107, 0, 68,117,112,108,105, 79, 98,106,101, 99,116, 0, 82, 78, 71, 0, 69,102,102,101, 99,116,111,114, 87,101,105,103,104,116, +115, 0, 80, 84, 67, 97, 99,104,101, 69,120,116,114, 97, 0, 80, 84, 67, 97, 99,104,101, 77,101,109, 0, 80, 84, 67, 97, 99,104, +101, 69,100,105,116, 0, 83, 66, 86,101,114,116,101,120, 0, 66,111,100,121, 80,111,105,110,116, 0, 66,111,100,121, 83,112,114, +105,110,103, 0, 83, 66, 83, 99,114, 97,116, 99,104, 0, 70,108,117,105,100, 86,101,114,116,101,120, 86,101,108,111, 99,105,116, +121, 0, 87,111,114,108,100, 0, 66, 97,115,101, 0, 65,118,105, 67,111,100,101, 99, 68, 97,116, 97, 0, 81,117,105, 99,107,116, +105,109,101, 67,111,100,101, 99, 68, 97,116, 97, 0, 81,117,105, 99,107,116,105,109,101, 67,111,100,101, 99, 83,101,116,116,105, +110,103,115, 0, 70, 70, 77,112,101,103, 67,111,100,101, 99, 68, 97,116, 97, 0, 65,117,100,105,111, 68, 97,116, 97, 0, 83, 99, +101,110,101, 82,101,110,100,101,114, 76, 97,121,101,114, 0, 73,109, 97,103,101, 70,111,114,109, 97,116, 68, 97,116, 97, 0, 82, +101,110,100,101,114, 68, 97,116, 97, 0, 82,101,110,100,101,114, 80,114,111,102,105,108,101, 0, 71, 97,109,101, 68,111,109,101, + 0, 71, 97,109,101, 70,114, 97,109,105,110,103, 0, 82,101, 99, 97,115,116, 68, 97,116, 97, 0, 71, 97,109,101, 68, 97,116, 97, + 0, 84,105,109,101, 77, 97,114,107,101,114, 0, 80, 97,105,110,116, 0, 66,114,117,115,104, 0, 73,109, 97,103,101, 80, 97,105, +110,116, 83,101,116,116,105,110,103,115, 0, 80, 97,114,116,105, 99,108,101, 66,114,117,115,104, 68, 97,116, 97, 0, 80, 97,114, +116,105, 99,108,101, 69,100,105,116, 83,101,116,116,105,110,103,115, 0, 83, 99,117,108,112,116, 0, 85,118, 83, 99,117,108,112, +116, 0, 86, 80, 97,105,110,116, 0, 84,114, 97,110,115,102,111,114,109, 79,114,105,101,110,116, 97,116,105,111,110, 0, 85,110, +105,102,105,101,100, 80, 97,105,110,116, 83,101,116,116,105,110,103,115, 0, 84,111,111,108, 83,101,116,116,105,110,103,115, 0, + 98, 83,116, 97,116,115, 0, 85,110,105,116, 83,101,116,116,105,110,103,115, 0, 80,104,121,115,105, 99,115, 83,101,116,116,105, +110,103,115, 0, 69,100,105,116,105,110,103, 0, 83, 99,101,110,101, 83,116, 97,116,115, 0, 68, 97,103, 70,111,114,101,115,116, + 0, 77,111,118,105,101, 67,108,105,112, 0, 66, 71,112,105, 99, 0, 77,111,118,105,101, 67,108,105,112, 85,115,101,114, 0, 82, +101,103,105,111,110, 86,105,101,119, 51, 68, 0, 82,101,110,100,101,114, 73,110,102,111, 0, 82,101,110,100,101,114, 69,110,103, +105,110,101, 0, 86,105,101,119, 68,101,112,116,104,115, 0, 83,109,111,111,116,104, 86,105,101,119, 83,116,111,114,101, 0,119, +109, 84,105,109,101,114, 0, 86,105,101,119, 51, 68, 0, 83,112, 97, 99,101, 76,105,110,107, 0, 86,105,101,119, 50, 68, 0, 83, +112, 97, 99,101, 73,110,102,111, 0, 83,112, 97, 99,101, 73,112,111, 0, 98, 68,111,112,101, 83,104,101,101,116, 0, 83,112, 97, + 99,101, 66,117,116,115, 0, 83,112, 97, 99,101, 83,101,113, 0, 70,105,108,101, 83,101,108,101, 99,116, 80, 97,114, 97,109,115, + 0, 83,112, 97, 99,101, 70,105,108,101, 0, 70,105,108,101, 76,105,115,116, 0,119,109, 79,112,101,114, 97,116,111,114, 0, 70, +105,108,101, 76, 97,121,111,117,116, 0, 83,112, 97, 99,101, 79,111,112,115, 0, 84,114,101,101, 83,116,111,114,101, 0, 84,114, +101,101, 83,116,111,114,101, 69,108,101,109, 0, 83,112, 97, 99,101, 73,109, 97,103,101, 0, 83, 99,111,112,101,115, 0, 72,105, +115,116,111,103,114, 97,109, 0, 83,112, 97, 99,101, 78,108, 97, 0, 83,112, 97, 99,101, 84,101,120,116, 0, 83, 99,114,105,112, +116, 0, 83,112, 97, 99,101, 83, 99,114,105,112,116, 0, 83,112, 97, 99,101, 84,105,109,101, 67, 97, 99,104,101, 0, 83,112, 97, + 99,101, 84,105,109,101, 0, 83,112, 97, 99,101, 78,111,100,101, 0, 83,112, 97, 99,101, 76,111,103,105, 99, 0, 67,111,110,115, +111,108,101, 76,105,110,101, 0, 83,112, 97, 99,101, 67,111,110,115,111,108,101, 0, 83,112, 97, 99,101, 85,115,101,114, 80,114, +101,102, 0, 83,112, 97, 99,101, 67,108,105,112, 0, 77,111,118,105,101, 67,108,105,112, 83, 99,111,112,101,115, 0,117,105, 70, +111,110,116, 0,117,105, 70,111,110,116, 83,116,121,108,101, 0,117,105, 83,116,121,108,101, 0,117,105, 87,105,100,103,101,116, + 67,111,108,111,114,115, 0,117,105, 87,105,100,103,101,116, 83,116, 97,116,101, 67,111,108,111,114,115, 0,117,105, 80, 97,110, +101,108, 67,111,108,111,114,115, 0, 84,104,101,109,101, 85, 73, 0, 84,104,101,109,101, 83,112, 97, 99,101, 0, 84,104,101,109, +101, 87,105,114,101, 67,111,108,111,114, 0, 98, 84,104,101,109,101, 0, 98, 65,100,100,111,110, 0, 83,111,108,105,100, 76,105, +103,104,116, 0, 85,115,101,114, 68,101,102, 0, 98, 83, 99,114,101,101,110, 0, 83, 99,114, 86,101,114,116, 0, 83, 99,114, 69, +100,103,101, 0, 80, 97,110,101,108, 0, 80, 97,110,101,108, 84,121,112,101, 0,117,105, 76, 97,121,111,117,116, 0, 83, 99,114, + 65,114,101, 97, 0, 83,112, 97, 99,101, 84,121,112,101, 0, 65, 82,101,103,105,111,110, 0, 65, 82,101,103,105,111,110, 84,121, +112,101, 0, 70,105,108,101, 71,108,111, 98, 97,108, 0, 83,116,114,105,112, 69,108,101,109, 0, 83,116,114,105,112, 67,114,111, +112, 0, 83,116,114,105,112, 84,114, 97,110,115,102,111,114,109, 0, 83,116,114,105,112, 67,111,108,111,114, 66, 97,108, 97,110, + 99,101, 0, 83,116,114,105,112, 80,114,111,120,121, 0, 83,116,114,105,112, 0, 80,108,117,103,105,110, 83,101,113, 0, 83,101, +113,117,101,110, 99,101, 0, 98, 83,111,117,110,100, 0, 77,101,116, 97, 83,116, 97, 99,107, 0, 87,105,112,101, 86, 97,114,115, + 0, 71,108,111,119, 86, 97,114,115, 0, 84,114, 97,110,115,102,111,114,109, 86, 97,114,115, 0, 83,111,108,105,100, 67,111,108, +111,114, 86, 97,114,115, 0, 83,112,101,101,100, 67,111,110,116,114,111,108, 86, 97,114,115, 0, 69,102,102,101, 99,116, 0, 66, +117,105,108,100, 69,102,102, 0, 80, 97,114,116, 69,102,102, 0, 80, 97,114,116,105, 99,108,101, 0, 87, 97,118,101, 69,102,102, + 0, 98, 80,114,111,112,101,114,116,121, 0, 98, 78,101, 97,114, 83,101,110,115,111,114, 0, 98, 77,111,117,115,101, 83,101,110, +115,111,114, 0, 98, 84,111,117, 99,104, 83,101,110,115,111,114, 0, 98, 75,101,121, 98,111, 97,114,100, 83,101,110,115,111,114, + 0, 98, 80,114,111,112,101,114,116,121, 83,101,110,115,111,114, 0, 98, 65, 99,116,117, 97,116,111,114, 83,101,110,115,111,114, + 0, 98, 68,101,108, 97,121, 83,101,110,115,111,114, 0, 98, 67,111,108,108,105,115,105,111,110, 83,101,110,115,111,114, 0, 98, + 82, 97,100, 97,114, 83,101,110,115,111,114, 0, 98, 82, 97,110,100,111,109, 83,101,110,115,111,114, 0, 98, 82, 97,121, 83,101, +110,115,111,114, 0, 98, 65,114,109, 97,116,117,114,101, 83,101,110,115,111,114, 0, 98, 77,101,115,115, 97,103,101, 83,101,110, +115,111,114, 0, 98, 83,101,110,115,111,114, 0, 98, 67,111,110,116,114,111,108,108,101,114, 0, 98, 74,111,121,115,116,105, 99, +107, 83,101,110,115,111,114, 0, 98, 69,120,112,114,101,115,115,105,111,110, 67,111,110,116, 0, 98, 80,121,116,104,111,110, 67, +111,110,116, 0, 98, 65, 99,116,117, 97,116,111,114, 0, 98, 65,100,100, 79, 98,106,101, 99,116, 65, 99,116,117, 97,116,111,114, + 0, 98, 65, 99,116,105,111,110, 65, 99,116,117, 97,116,111,114, 0, 83,111,117,110,100, 51, 68, 0, 98, 83,111,117,110,100, 65, + 99,116,117, 97,116,111,114, 0, 98, 69,100,105,116, 79, 98,106,101, 99,116, 65, 99,116,117, 97,116,111,114, 0, 98, 83, 99,101, +110,101, 65, 99,116,117, 97,116,111,114, 0, 98, 80,114,111,112,101,114,116,121, 65, 99,116,117, 97,116,111,114, 0, 98, 79, 98, +106,101, 99,116, 65, 99,116,117, 97,116,111,114, 0, 98, 73,112,111, 65, 99,116,117, 97,116,111,114, 0, 98, 67, 97,109,101,114, + 97, 65, 99,116,117, 97,116,111,114, 0, 98, 67,111,110,115,116,114, 97,105,110,116, 65, 99,116,117, 97,116,111,114, 0, 98, 71, +114,111,117,112, 65, 99,116,117, 97,116,111,114, 0, 98, 82, 97,110,100,111,109, 65, 99,116,117, 97,116,111,114, 0, 98, 77,101, +115,115, 97,103,101, 65, 99,116,117, 97,116,111,114, 0, 98, 71, 97,109,101, 65, 99,116,117, 97,116,111,114, 0, 98, 86,105,115, +105, 98,105,108,105,116,121, 65, 99,116,117, 97,116,111,114, 0, 98, 84,119,111, 68, 70,105,108,116,101,114, 65, 99,116,117, 97, +116,111,114, 0, 98, 80, 97,114,101,110,116, 65, 99,116,117, 97,116,111,114, 0, 98, 83,116, 97,116,101, 65, 99,116,117, 97,116, +111,114, 0, 98, 65,114,109, 97,116,117,114,101, 65, 99,116,117, 97,116,111,114, 0, 98, 83,116,101,101,114,105,110,103, 65, 99, +116,117, 97,116,111,114, 0, 71,114,111,117,112, 79, 98,106,101, 99,116, 0, 66,111,110,101, 0, 98, 65,114,109, 97,116,117,114, +101, 0, 98, 77,111,116,105,111,110, 80, 97,116,104, 86,101,114,116, 0, 98, 80,111,115,101, 67,104, 97,110,110,101,108, 0, 98, + 73, 75, 80, 97,114, 97,109, 0, 98, 73,116, 97,115, 99, 0, 98, 65, 99,116,105,111,110, 71,114,111,117,112, 0, 83,112, 97, 99, +101, 65, 99,116,105,111,110, 0, 98, 65, 99,116,105,111,110, 67,104, 97,110,110,101,108, 0, 98, 67,111,110,115,116,114, 97,105, +110,116, 67,104, 97,110,110,101,108, 0, 98, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 67,111,110,115,116,114, 97,105,110, +116, 84, 97,114,103,101,116, 0, 98, 80,121,116,104,111,110, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 75,105,110,101,109, + 97,116,105, 99, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83,112,108,105,110,101, 73, 75, 67,111,110,115,116,114, 97,105, +110,116, 0, 98, 84,114, 97, 99,107, 84,111, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 82,111,116, 97,116,101, 76,105,107, +101, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 76,111, 99, 97,116,101, 76,105,107,101, 67,111,110,115,116,114, 97,105,110, +116, 0, 98, 83,105,122,101, 76,105,107,101, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83, 97,109,101, 86,111,108,117,109, +101, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 84,114, 97,110,115, 76,105,107,101, 67,111,110,115,116,114, 97,105,110,116, + 0, 98, 77,105,110, 77, 97,120, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 65, 99,116,105,111,110, 67,111,110,115,116,114, + 97,105,110,116, 0, 98, 76,111, 99,107, 84,114, 97, 99,107, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 68, 97,109,112, 84, +114, 97, 99,107, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 70,111,108,108,111,119, 80, 97,116,104, 67,111,110,115,116,114, + 97,105,110,116, 0, 98, 83,116,114,101,116, 99,104, 84,111, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 82,105,103,105,100, + 66,111,100,121, 74,111,105,110,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 67,108, 97,109,112, 84,111, 67,111,110,115, +116,114, 97,105,110,116, 0, 98, 67,104,105,108,100, 79,102, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 84,114, 97,110,115, +102,111,114,109, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 80,105,118,111,116, 67,111,110,115,116,114, 97,105,110,116, 0, + 98, 76,111, 99, 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 82,111,116, 76,105,109,105,116, 67,111,110, +115,116,114, 97,105,110,116, 0, 98, 83,105,122,101, 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 68,105, +115,116, 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 83,104,114,105,110,107,119,114, 97,112, 67,111,110, +115,116,114, 97,105,110,116, 0, 98, 70,111,108,108,111,119, 84,114, 97, 99,107, 67,111,110,115,116,114, 97,105,110,116, 0, 98, + 67, 97,109,101,114, 97, 83,111,108,118,101,114, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 79, 98,106,101, 99,116, 83,111, +108,118,101,114, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 65, 99,116,105,111,110, 77,111,100,105,102,105,101,114, 0, 98, + 65, 99,116,105,111,110, 83,116,114,105,112, 0, 98, 78,111,100,101, 83,116, 97, 99,107, 0, 98, 78,111,100,101, 83,111, 99,107, +101,116, 0, 98, 78,111,100,101, 76,105,110,107, 0, 98, 78,111,100,101, 80,114,101,118,105,101,119, 0, 98, 78,111,100,101, 0, +117,105, 66,108,111, 99,107, 0, 98, 78,111,100,101, 84,121,112,101, 0, 98, 78,111,100,101, 84,114,101,101, 69,120,101, 99, 0, + 98, 78,111,100,101, 83,111, 99,107,101,116, 86, 97,108,117,101, 73,110,116, 0, 98, 78,111,100,101, 83,111, 99,107,101,116, 86, + 97,108,117,101, 70,108,111, 97,116, 0, 98, 78,111,100,101, 83,111, 99,107,101,116, 86, 97,108,117,101, 66,111,111,108,101, 97, +110, 0, 98, 78,111,100,101, 83,111, 99,107,101,116, 86, 97,108,117,101, 86,101, 99,116,111,114, 0, 98, 78,111,100,101, 83,111, + 99,107,101,116, 86, 97,108,117,101, 82, 71, 66, 65, 0, 78,111,100,101, 73,109, 97,103,101, 65,110,105,109, 0, 78,111,100,101, + 66,108,117,114, 68, 97,116, 97, 0, 78,111,100,101, 68, 66,108,117,114, 68, 97,116, 97, 0, 78,111,100,101, 66,105,108, 97,116, +101,114, 97,108, 66,108,117,114, 68, 97,116, 97, 0, 78,111,100,101, 72,117,101, 83, 97,116, 0, 78,111,100,101, 73,109, 97,103, +101, 70,105,108,101, 0, 78,111,100,101, 73,109, 97,103,101, 77,117,108,116,105, 70,105,108,101, 0, 78,111,100,101, 73,109, 97, +103,101, 77,117,108,116,105, 70,105,108,101, 83,111, 99,107,101,116, 0, 78,111,100,101, 67,104,114,111,109, 97, 0, 78,111,100, +101, 84,119,111, 88, 89,115, 0, 78,111,100,101, 84,119,111, 70,108,111, 97,116,115, 0, 78,111,100,101, 71,101,111,109,101,116, +114,121, 0, 78,111,100,101, 86,101,114,116,101,120, 67,111,108, 0, 78,111,100,101, 68,101,102,111, 99,117,115, 0, 78,111,100, +101, 83, 99,114,105,112,116, 68,105, 99,116, 0, 78,111,100,101, 71,108, 97,114,101, 0, 78,111,100,101, 84,111,110,101,109, 97, +112, 0, 78,111,100,101, 76,101,110,115, 68,105,115,116, 0, 78,111,100,101, 67,111,108,111,114, 66, 97,108, 97,110, 99,101, 0, + 78,111,100,101, 67,111,108,111,114,115,112,105,108,108, 0, 78,111,100,101, 84,101,120, 66, 97,115,101, 0, 78,111,100,101, 84, +101,120, 83,107,121, 0, 78,111,100,101, 84,101,120, 73,109, 97,103,101, 0, 78,111,100,101, 84,101,120, 67,104,101, 99,107,101, +114, 0, 78,111,100,101, 84,101,120, 69,110,118,105,114,111,110,109,101,110,116, 0, 78,111,100,101, 84,101,120, 71,114, 97,100, +105,101,110,116, 0, 78,111,100,101, 84,101,120, 78,111,105,115,101, 0, 78,111,100,101, 84,101,120, 86,111,114,111,110,111,105, + 0, 78,111,100,101, 84,101,120, 77,117,115,103,114, 97,118,101, 0, 78,111,100,101, 84,101,120, 87, 97,118,101, 0, 78,111,100, +101, 84,101,120, 77, 97,103,105, 99, 0, 78,111,100,101, 83,104, 97,100,101,114, 65,116,116,114,105, 98,117,116,101, 0, 84,101, +120, 78,111,100,101, 79,117,116,112,117,116, 0, 67,117,114,118,101, 77, 97,112, 80,111,105,110,116, 0, 67,117,114,118,101, 77, + 97,112, 0, 66,114,117,115,104, 67,108,111,110,101, 0, 67,117,115,116,111,109, 68, 97,116, 97, 76, 97,121,101,114, 0, 67,117, +115,116,111,109, 68, 97,116, 97, 69,120,116,101,114,110, 97,108, 0, 72, 97,105,114, 75,101,121, 0, 80, 97,114,116,105, 99,108, +101, 75,101,121, 0, 66,111,105,100, 80, 97,114,116,105, 99,108,101, 0, 66,111,105,100, 68, 97,116, 97, 0, 80, 97,114,116,105, + 99,108,101, 83,112,114,105,110,103, 0, 67,104,105,108,100, 80, 97,114,116,105, 99,108,101, 0, 80, 97,114,116,105, 99,108,101, + 84, 97,114,103,101,116, 0, 80, 97,114,116,105, 99,108,101, 68,117,112,108,105, 87,101,105,103,104,116, 0, 80, 97,114,116,105, + 99,108,101, 68, 97,116, 97, 0, 83, 80, 72, 70,108,117,105,100, 83,101,116,116,105,110,103,115, 0, 80, 97,114,116,105, 99,108, +101, 83,101,116,116,105,110,103,115, 0, 66,111,105,100, 83,101,116,116,105,110,103,115, 0, 80, 97,114,116,105, 99,108,101, 67, + 97, 99,104,101, 75,101,121, 0, 75, 68, 84,114,101,101, 0, 80, 97,114,116,105, 99,108,101, 68,114, 97,119, 68, 97,116, 97, 0, + 76,105,110,107, 78,111,100,101, 0, 98, 71, 80, 68,115,112,111,105,110,116, 0, 98, 71, 80, 68,115,116,114,111,107,101, 0, 98, + 71, 80, 68,102,114, 97,109,101, 0, 98, 71, 80, 68,108, 97,121,101,114, 0, 82,101,112,111,114,116, 76,105,115,116, 0,119,109, + 87,105,110,100,111,119, 77, 97,110, 97,103,101,114, 0,119,109, 87,105,110,100,111,119, 0,119,109, 75,101,121, 67,111,110,102, +105,103, 0,119,109, 69,118,101,110,116, 0,119,109, 83,117, 98, 87,105,110,100,111,119, 0,119,109, 71,101,115,116,117,114,101, + 0,119,109, 75,101,121, 77, 97,112, 73,116,101,109, 0, 80,111,105,110,116,101,114, 82, 78, 65, 0,119,109, 75,101,121, 77, 97, +112, 68,105,102,102, 73,116,101,109, 0,119,109, 75,101,121, 77, 97,112, 0,119,109, 79,112,101,114, 97,116,111,114, 84,121,112, +101, 0, 70, 77,111,100,105,102,105,101,114, 0, 70, 77,111,100, 95, 71,101,110,101,114, 97,116,111,114, 0, 70, 77,111,100, 95, + 70,117,110, 99,116,105,111,110, 71,101,110,101,114, 97,116,111,114, 0, 70, 67, 77, 95, 69,110,118,101,108,111,112,101, 68, 97, +116, 97, 0, 70, 77,111,100, 95, 69,110,118,101,108,111,112,101, 0, 70, 77,111,100, 95, 67,121, 99,108,101,115, 0, 70, 77,111, +100, 95, 80,121,116,104,111,110, 0, 70, 77,111,100, 95, 76,105,109,105,116,115, 0, 70, 77,111,100, 95, 78,111,105,115,101, 0, + 70, 77,111,100, 95, 83,116,101,112,112,101,100, 0, 68,114,105,118,101,114, 84, 97,114,103,101,116, 0, 68,114,105,118,101,114, + 86, 97,114, 0, 67,104, 97,110,110,101,108, 68,114,105,118,101,114, 0, 70, 80,111,105,110,116, 0, 70, 67,117,114,118,101, 0, + 65,110,105,109, 77, 97,112, 80, 97,105,114, 0, 65,110,105,109, 77, 97,112,112,101,114, 0, 78,108, 97, 83,116,114,105,112, 0, + 78,108, 97, 84,114, 97, 99,107, 0, 75, 83, 95, 80, 97,116,104, 0, 75,101,121,105,110,103, 83,101,116, 0, 65,110,105,109, 79, +118,101,114,114,105,100,101, 0, 73,100, 65,100,116, 84,101,109,112,108, 97,116,101, 0, 66,111,105,100, 82,117,108,101, 0, 66, +111,105,100, 82,117,108,101, 71,111, 97,108, 65,118,111,105,100, 0, 66,111,105,100, 82,117,108,101, 65,118,111,105,100, 67,111, +108,108,105,115,105,111,110, 0, 66,111,105,100, 82,117,108,101, 70,111,108,108,111,119, 76,101, 97,100,101,114, 0, 66,111,105, +100, 82,117,108,101, 65,118,101,114, 97,103,101, 83,112,101,101,100, 0, 66,111,105,100, 82,117,108,101, 70,105,103,104,116, 0, + 66,111,105,100, 83,116, 97,116,101, 0, 70, 76, 85, 73, 68, 95, 51, 68, 0, 87, 84, 85, 82, 66, 85, 76, 69, 78, 67, 69, 0, 83, +112,101, 97,107,101,114, 0, 77,111,118,105,101, 67,108,105,112, 80,114,111,120,121, 0, 77,111,118,105,101, 67,108,105,112, 67, + 97, 99,104,101, 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110,103, 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110,103, + 84,114, 97, 99,107, 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110,103, 77, 97,114,107,101,114, 0, 77,111,118,105,101, 82, +101, 99,111,110,115,116,114,117, 99,116,101,100, 67, 97,109,101,114, 97, 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110,103, + 67, 97,109,101,114, 97, 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110,103, 83,101,116,116,105,110,103,115, 0, 77,111,118, +105,101, 84,114, 97, 99,107,105,110,103, 83,116, 97, 98,105,108,105,122, 97,116,105,111,110, 0, 77,111,118,105,101, 84,114, 97, + 99,107,105,110,103, 82,101, 99,111,110,115,116,114,117, 99,116,105,111,110, 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110, +103, 79, 98,106,101, 99,116, 0, 77,111,118,105,101, 84,114, 97, 99,107,105,110,103, 83,116, 97,116,115, 0, 68,121,110, 97,109, +105, 99, 80, 97,105,110,116, 83,117,114,102, 97, 99,101, 0, 80, 97,105,110,116, 83,117,114,102, 97, 99,101, 68, 97,116, 97, 0, + 84, 76, 69, 78, 1, 0, 1, 0, 2, 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 8, 0, 8, 0, 0, 0, 16, 0, 24, 0, + 16, 0, 4, 0, 8, 0, 12, 0, 16, 0, 16, 0, 32, 0,128, 0,120, 0,152, 8, 0, 0, 40, 0,144, 0,112, 5,112, 0, 36, 0, + 56, 0,160, 0,192, 0,224, 0, 96, 0, 40, 0, 48, 0,224, 0, 16, 0,200, 0, 40, 0,216, 11, 48, 5, 0, 0, 0, 0, 0, 0, + 56, 1,168, 1,216, 4, 24, 0, 8, 3,200, 0, 0, 0,104, 0, 64, 1, 56, 4, 80, 0, 24, 1,144, 0, 56, 3, 16, 2, 88, 0, + 16, 0,128, 3,152, 0,136, 4, 0, 0,104, 0,104, 0, 0, 1, 80, 0, 8, 0, 16, 0, 32, 0, 0, 0, 8, 2, 0, 0, 0, 0, + 0, 0,232, 4, 8, 0, 12, 0, 16, 0, 8, 0, 12, 0, 4, 0, 20, 0, 48, 0, 64, 0, 20, 0, 12, 0, 16, 0, 4, 0, 8, 0, + 0, 0,176, 0,144, 1, 8, 0, 4, 0, 4, 0, 0, 1, 32, 0, 8, 0, 24, 0, 16, 0, 64, 0, 24, 0, 12, 0, 64, 0, 4, 0, +112, 0,200, 0,136, 0,192, 0,192, 0,128, 0,192, 0,192, 0,128, 0,120, 0,200, 0,120, 0,144, 0, 16, 1, 56, 0,192, 0, + 24, 1, 40, 1,120, 0,184, 0,200, 0, 64, 1,200, 0, 88, 1,112, 0,168, 0, 0, 0,152, 0, 48, 0, 40, 5,192, 0, 0, 0, +152, 0, 0, 0, 0, 0,128, 0, 8, 0, 8, 0,112, 1,144, 0,152, 2,136, 0,192, 0,120, 0,128, 0,224, 4,208, 0,200, 0, +112, 0,208, 0,144, 0, 16, 5, 0, 0, 0, 0, 48, 1,104, 1,160, 1,104, 1,136, 0,104, 0,112, 0,128, 0, 16, 0, 96, 1, + 88, 0, 0, 0,200, 0,216, 0,152, 0, 48, 0, 24, 0,120, 0,152, 0,216, 1, 0, 1,184, 0, 0, 0, 72, 0, 32, 0,176, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 12, 0, 24, 2, 40, 0,184, 0,152, 0, 64, 0, 72, 0, 32, 0,120, 0, 24, 0, 56, 9, + 64, 0, 24, 0, 16, 0, 56, 0,168, 0, 96, 0, 24, 0, 88, 6, 48, 0, 16, 0,168, 0, 96, 0, 24, 0, 56, 0,120, 0, 16, 0, +232, 1, 32, 0, 8, 0, 24, 0, 80, 8, 0, 0, 0, 0,192, 8,104, 0, 8, 0,112, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 96, 1, 56, 0,144, 0, 64, 0,240, 0,112, 0,248, 0,240, 0,160, 7,104, 0, 0, 0,168, 0, 0, 0, 24, 1, 16, 0, 16, 0, + 40, 33,128, 16, 24, 16,216, 0,160, 2,168, 5, 64, 0, 24, 0,208, 0, 48, 1, 72, 0, 40, 0,136, 1,104, 0, 48, 1, 56, 0, + 24, 4, 32, 0,232, 0, 32, 0, 32, 0, 8, 0, 80, 3,224, 1, 16, 0,168, 36, 80, 0, 56, 0,112, 38, 8, 1, 32, 0, 40, 0, + 88, 1, 0, 0, 0, 0,160, 0, 0, 0, 40, 1, 0, 0, 48, 4, 8, 1, 16, 0, 8, 0, 44, 0, 16, 4, 72, 3,200, 4, 80, 1, +208, 4, 32, 0, 12, 0, 24, 0, 32, 0, 16, 0, 24, 0, 24, 0, 32, 0,136, 1, 0, 0, 64, 0, 96, 0, 80, 0, 8, 0, 80, 0, +136, 0,200, 0, 72, 0, 8, 0,136, 0, 76, 0, 72, 0,204, 0,136, 0,136, 0,128, 0,136, 0, 92, 0,128, 0, 80, 0,112, 0, + 16, 0,168, 0, 32, 0, 72, 0,120, 0, 24, 0,144, 0,112, 0,148, 0, 32, 0,128, 0, 88, 0, 88, 0,208, 0,140, 0, 4, 0, + 24, 0, 16, 0, 8, 0,160, 0, 48, 0, 40, 0, 72, 1, 0, 1, 16, 0, 32, 2, 4, 0, 40, 0,120, 0, 72, 1,120, 0, 56, 0, +120, 0,160, 0,112, 0,184, 0, 24, 0, 88, 0, 80, 0, 80, 0, 80, 0, 8, 0, 72, 0,104, 0,104, 0, 80, 0, 80, 0, 24, 0, + 88, 0,104, 0, 16, 0,144, 0,128, 0, 88, 0, 28, 0, 28, 0, 28, 0, 88, 0, 24, 0,160, 0, 16, 0,152, 0, 72, 0,168, 0, + 48, 0,208, 0, 56, 0, 16, 0, 88, 1, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 4, 0, 24, 0, 16, 0, 16, 0, 40, 0, 28, 0, + 12, 0, 12, 0, 32, 4, 40, 4, 32, 0, 44, 0, 24, 0, 8, 0,128, 0, 64, 0, 32, 0, 16, 0, 32, 0, 32, 0, 8, 0, 96, 0, + 20, 0,200, 3,216, 3,208, 3,200, 3,208, 3,208, 3,200, 3,208, 3,208, 3,208, 3,208, 3, 64, 0, 64, 0, 12, 0, 56, 0, + 24, 0,104, 0, 0, 4, 24, 0, 56, 0, 56, 0, 20, 0, 16, 0, 64, 0, 40, 0, 32, 0,192, 0, 60, 0, 16, 3,104, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 40, 0,192, 0, 40, 0, 88, 1, 0, 1,168, 0, 0, 0, 0, 0, 0, 0,120, 0, 0, 0, + 32, 0,136, 0, 0, 0,120, 0, 24, 0, 24, 0, 16, 0, 24, 0, 8, 0, 16, 0, 24, 0, 20, 0, 20, 0, 56, 0, 24, 2, 40, 1, + 16, 0,104, 0, 0, 1, 40, 0,208, 0,104, 0,112, 0,216, 1, 32, 0,128, 0, 56, 0, 80, 0, 64, 0,104, 0, 72, 0, 64, 0, +128, 0, 0, 0, 0, 0,184, 0, 8, 3, 0, 0,248, 0,192, 0, 16, 0, 72, 0, 48, 0, 64, 0, 56, 0, 24, 0,128, 0, 0, 1, + 16, 6, 0, 0, 83, 84, 82, 67,207, 1, 0, 0, 12, 0, 2, 0, 12, 0, 0, 0, 12, 0, 1, 0, 13, 0, 3, 0, 13, 0, 0, 0, + 13, 0, 1, 0, 11, 0, 2, 0, 14, 0, 2, 0, 11, 0, 3, 0, 11, 0, 4, 0, 15, 0, 2, 0, 2, 0, 5, 0, 2, 0, 6, 0, + 16, 0, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0, 17, 0, 3, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 18, 0, 4, 0, + 4, 0, 8, 0, 4, 0, 9, 0, 4, 0, 10, 0, 4, 0, 11, 0, 19, 0, 4, 0, 7, 0, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, + 7, 0, 11, 0, 20, 0, 4, 0, 11, 0, 12, 0, 14, 0, 13, 0, 4, 0, 14, 0, 4, 0, 15, 0, 21, 0, 10, 0, 21, 0, 0, 0, + 21, 0, 1, 0, 0, 0, 16, 0, 0, 0, 17, 0, 2, 0, 18, 0, 0, 0, 19, 0, 4, 0, 20, 0, 20, 0, 21, 0, 4, 0, 22, 0, + 4, 0, 23, 0, 22, 0, 11, 0, 11, 0, 0, 0, 11, 0, 1, 0, 22, 0, 24, 0, 23, 0, 25, 0, 0, 0, 26, 0, 2, 0, 27, 0, + 2, 0, 28, 0, 2, 0, 18, 0, 4, 0, 29, 0, 4, 0, 30, 0, 21, 0, 31, 0, 23, 0, 8, 0, 22, 0, 32, 0, 22, 0, 33, 0, + 24, 0, 34, 0, 0, 0, 35, 0, 0, 0, 36, 0, 4, 0, 37, 0, 4, 0, 27, 0, 23, 0, 38, 0, 25, 0, 5, 0, 4, 0, 39, 0, + 4, 0, 40, 0, 2, 0, 41, 0, 2, 0, 42, 0, 4, 0, 43, 0, 26, 0, 6, 0, 27, 0, 44, 0, 2, 0, 45, 0, 2, 0, 46, 0, + 2, 0, 16, 0, 2, 0, 18, 0, 0, 0, 47, 0, 28, 0, 21, 0, 28, 0, 0, 0, 28, 0, 1, 0, 29, 0, 48, 0, 30, 0, 49, 0, + 19, 0, 50, 0, 19, 0, 51, 0, 2, 0, 45, 0, 2, 0, 46, 0, 2, 0, 52, 0, 2, 0, 53, 0, 2, 0, 54, 0, 2, 0, 55, 0, + 2, 0, 18, 0, 2, 0, 56, 0, 7, 0, 10, 0, 7, 0, 11, 0, 4, 0, 57, 0, 7, 0, 58, 0, 7, 0, 59, 0, 7, 0, 60, 0, + 26, 0, 61, 0, 31, 0, 7, 0, 22, 0, 32, 0, 14, 0, 62, 0, 19, 0, 63, 0, 2, 0, 45, 0, 2, 0, 64, 0, 2, 0, 65, 0, + 2, 0, 27, 0, 32, 0, 16, 0, 32, 0, 0, 0, 32, 0, 1, 0, 7, 0, 66, 0, 7, 0, 60, 0, 2, 0, 16, 0, 2, 0, 67, 0, + 2, 0, 68, 0, 2, 0, 18, 0, 4, 0, 69, 0, 4, 0, 70, 0, 11, 0, 2, 0, 7, 0, 71, 0, 0, 0, 19, 0, 0, 0, 72, 0, + 7, 0, 73, 0, 7, 0, 74, 0, 33, 0, 15, 0, 22, 0, 32, 0, 34, 0, 75, 0, 32, 0, 76, 0, 0, 0, 77, 0, 4, 0, 78, 0, + 4, 0, 27, 0, 14, 0, 79, 0, 31, 0, 80, 0, 22, 0, 81, 0, 2, 0, 16, 0, 2, 0, 82, 0, 2, 0, 83, 0, 2, 0, 18, 0, + 7, 0, 84, 0, 4, 0, 85, 0, 35, 0, 6, 0, 35, 0, 0, 0, 35, 0, 1, 0, 0, 0, 86, 0, 0, 0, 87, 0, 4, 0, 22, 0, + 4, 0, 88, 0, 36, 0, 10, 0, 36, 0, 0, 0, 36, 0, 1, 0, 4, 0, 89, 0, 4, 0, 90, 0, 4, 0, 91, 0, 4, 0, 67, 0, + 4, 0, 13, 0, 4, 0, 92, 0, 0, 0, 93, 0, 0, 0, 94, 0, 37, 0, 15, 0, 22, 0, 32, 0, 0, 0, 95, 0, 4, 0, 92, 0, + 4, 0, 96, 0, 14, 0, 97, 0, 35, 0, 98, 0, 35, 0, 99, 0, 4, 0,100, 0, 4, 0,101, 0, 14, 0,102, 0, 0, 0,103, 0, + 4, 0,104, 0, 4, 0,105, 0, 11, 0,106, 0, 8, 0,107, 0, 38, 0, 3, 0, 4, 0,108, 0, 4, 0,109, 0, 11, 0, 2, 0, + 39, 0, 20, 0, 22, 0, 32, 0, 34, 0, 75, 0, 0, 0, 16, 0, 0, 0,110, 0, 2, 0, 18, 0, 7, 0,111, 0, 7, 0,112, 0, + 7, 0,113, 0, 7, 0,114, 0, 7, 0,115, 0, 7, 0,116, 0, 7, 0,117, 0, 7, 0,118, 0, 7, 0,119, 0, 7, 0,120, 0, + 7, 0,121, 0, 31, 0, 80, 0, 27, 0,122, 0, 0, 0,123, 0, 0, 0,124, 0, 40, 0, 14, 0, 41, 0,125, 0, 4, 0,126, 0, + 4, 0,127, 0, 4, 0,128, 0, 4, 0,129, 0, 0, 0,130, 0, 0, 0,131, 0, 0, 0,132, 0, 0, 0, 27, 0, 2, 0,133, 0, + 2, 0,134, 0, 2, 0,135, 0, 2, 0, 18, 0, 4, 0, 30, 0, 42, 0, 33, 0, 22, 0, 32, 0, 0, 0, 35, 0, 14, 0,136, 0, + 43, 0,137, 0, 44, 0,138, 0, 45, 0,139, 0, 45, 0,140, 0, 2, 0,141, 0, 2, 0,142, 0, 2, 0,132, 0, 2, 0, 18, 0, + 2, 0,143, 0, 2, 0, 16, 0, 4, 0,144, 0, 2, 0,145, 0, 2, 0,146, 0, 2, 0,147, 0, 2, 0,148, 0, 2, 0,149, 0, + 2, 0,150, 0, 4, 0,151, 0, 4, 0,152, 0, 38, 0,153, 0, 25, 0,154, 0, 7, 0,155, 0, 4, 0,156, 0, 2, 0,157, 0, + 2, 0,158, 0, 2, 0,159, 0, 0, 0,160, 0, 0, 0,161, 0, 7, 0,162, 0, 7, 0,163, 0, 46, 0, 65, 0, 2, 0,164, 0, + 2, 0,165, 0, 2, 0,166, 0, 2, 0,167, 0, 27, 0,168, 0, 47, 0,169, 0, 0, 0,170, 0, 0, 0,171, 0, 0, 0,172, 0, + 0, 0,173, 0, 0, 0,174, 0, 7, 0,175, 0, 7, 0,176, 0, 7, 0,177, 0, 2, 0,178, 0, 2, 0,179, 0, 2, 0,180, 0, + 2, 0,181, 0, 2, 0,182, 0, 2, 0,183, 0, 0, 0,184, 0, 0, 0,124, 0, 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, + 7, 0,188, 0, 7, 0,189, 0, 7, 0, 56, 0, 7, 0,190, 0, 7, 0,191, 0, 7, 0,192, 0, 7, 0,193, 0, 7, 0,194, 0, + 7, 0,195, 0, 7, 0,196, 0, 7, 0,197, 0, 7, 0,198, 0, 7, 0,199, 0, 7, 0,200, 0, 7, 0,201, 0, 7, 0,202, 0, + 7, 0,203, 0, 7, 0,204, 0, 7, 0,205, 0, 7, 0,206, 0, 7, 0,207, 0, 7, 0,208, 0, 7, 0,209, 0, 7, 0,210, 0, + 7, 0,211, 0, 7, 0,212, 0, 7, 0,213, 0, 7, 0,214, 0, 7, 0,215, 0, 7, 0,216, 0, 7, 0,217, 0, 7, 0,218, 0, + 7, 0,219, 0, 7, 0,220, 0, 7, 0,221, 0, 7, 0,222, 0, 7, 0,223, 0, 7, 0,224, 0, 7, 0,225, 0, 7, 0,226, 0, + 48, 0, 15, 0, 0, 0, 35, 0, 11, 0,227, 0, 0, 0,228, 0, 0, 0,229, 0, 4, 0,230, 0, 4, 0,231, 0, 11, 0,232, 0, + 7, 0,233, 0, 7, 0,234, 0, 7, 0,235, 0, 4, 0,236, 0, 11, 0,237, 0, 11, 0,238, 0, 4, 0,239, 0, 4, 0, 27, 0, + 49, 0, 6, 0, 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, 7, 0,240, 0, 7, 0, 66, 0, 4, 0, 63, 0, 50, 0, 5, 0, + 2, 0, 18, 0, 2, 0, 37, 0, 2, 0, 63, 0, 2, 0,241, 0, 49, 0,235, 0, 51, 0, 17, 0, 27, 0,168, 0, 42, 0,242, 0, + 52, 0,243, 0, 7, 0,244, 0, 7, 0,245, 0, 2, 0, 16, 0, 2, 0,246, 0, 7, 0,112, 0, 7, 0,113, 0, 7, 0,247, 0, + 4, 0,248, 0, 2, 0,249, 0, 2, 0,250, 0, 4, 0,132, 0, 4, 0,144, 0, 2, 0,251, 0, 2, 0,252, 0, 53, 0, 25, 0, + 2, 0, 18, 0, 2, 0,253, 0, 7, 0,254, 0, 7, 0,255, 0, 2, 0,143, 0, 2, 0, 0, 1, 4, 0, 1, 1, 4, 0, 2, 1, + 27, 0,168, 0, 4, 0, 3, 1, 2, 0, 4, 1, 2, 0, 5, 1, 11, 0, 6, 1, 7, 0, 7, 1, 7, 0, 8, 1, 2, 0, 9, 1, + 2, 0, 10, 1, 2, 0, 11, 1, 2, 0, 12, 1, 7, 0, 13, 1, 7, 0, 14, 1, 7, 0, 15, 1, 7, 0, 16, 1, 50, 0, 17, 1, + 54, 0, 18, 1, 55, 0, 13, 0, 4, 0, 19, 1, 4, 0, 20, 1, 2, 0, 21, 1, 2, 0, 18, 0, 2, 0, 22, 1, 2, 0, 23, 1, + 27, 0,168, 0, 7, 0, 24, 1, 4, 0, 25, 1, 0, 0, 26, 1, 7, 0, 27, 1, 4, 0, 28, 1, 4, 0,132, 0, 56, 0, 4, 0, + 27, 0,168, 0, 0, 0, 29, 1, 4, 0, 30, 1, 4, 0, 27, 0, 47, 0, 64, 0, 22, 0, 32, 0, 34, 0, 75, 0, 7, 0, 31, 1, + 7, 0, 32, 1, 7, 0, 33, 1, 7, 0, 34, 1, 7, 0, 35, 1, 7, 0, 36, 1, 7, 0, 37, 1, 7, 0, 38, 1, 7, 0, 39, 1, + 7, 0, 30, 0, 7, 0, 40, 1, 7, 0, 41, 1, 7, 0, 42, 1, 7, 0, 43, 1, 7, 0, 44, 1, 7, 0, 45, 1, 7, 0, 46, 1, + 7, 0, 47, 1, 7, 0, 48, 1, 7, 0, 49, 1, 7, 0, 50, 1, 7, 0, 51, 1, 2, 0, 52, 1, 2, 0, 53, 1, 2, 0, 54, 1, + 2, 0, 55, 1, 2, 0, 56, 1, 2, 0, 57, 1, 2, 0, 58, 1, 2, 0, 18, 0, 2, 0, 16, 0, 2, 0,246, 0, 7, 0, 59, 1, + 7, 0, 60, 1, 7, 0, 61, 1, 7, 0, 62, 1, 4, 0, 63, 1, 4, 0, 64, 1, 2, 0, 65, 1, 2, 0, 66, 1, 2, 0, 22, 1, + 2, 0,130, 0, 4, 0, 22, 0, 4, 0,127, 0, 4, 0,128, 0, 4, 0,129, 0, 7, 0, 67, 1, 7, 0, 68, 1, 7, 0, 67, 0, + 40, 0, 69, 1, 57, 0, 70, 1, 31, 0, 80, 0, 42, 0,242, 0, 48, 0, 71, 1, 50, 0, 17, 1, 51, 0, 72, 1, 25, 0,154, 0, + 53, 0, 73, 1, 55, 0, 74, 1, 56, 0, 75, 1, 0, 0, 76, 1, 0, 0,124, 0, 58, 0, 13, 0, 7, 0, 77, 1, 7, 0, 78, 1, + 7, 0,176, 0, 4, 0, 18, 0, 0, 0,171, 0, 0, 0,172, 0, 0, 0,173, 0, 0, 0,174, 0, 4, 0, 27, 0, 7, 0, 79, 1, + 7, 0, 80, 1, 7, 0, 81, 1, 27, 0, 44, 0, 59, 0, 9, 0, 50, 0, 82, 1, 7, 0, 33, 1, 7, 0, 34, 1, 7, 0, 35, 1, + 4, 0, 18, 0, 7, 0, 83, 1, 7, 0, 84, 1, 4, 0, 85, 1, 4, 0, 86, 1, 60, 0, 74, 0, 22, 0, 32, 0, 34, 0, 75, 0, + 2, 0, 16, 0, 2, 0, 18, 0, 4, 0, 87, 1, 2, 0,179, 0, 2, 0, 88, 1, 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, + 7, 0,188, 0, 7, 0, 89, 1, 7, 0, 90, 1, 7, 0, 91, 1, 7, 0, 92, 1, 7, 0, 93, 1, 7, 0, 94, 1, 7, 0, 95, 1, + 7, 0, 96, 1, 7, 0, 97, 1, 7, 0, 98, 1, 7, 0, 99, 1, 54, 0,100, 1, 2, 0,253, 0, 2, 0, 30, 0, 7, 0,112, 0, + 7, 0,113, 0, 7, 0,101, 1, 7, 0,102, 1, 7, 0,103, 1, 7, 0,104, 1, 7, 0,105, 1, 2, 0,106, 1, 2, 0,107, 1, + 2, 0,108, 1, 2, 0,109, 1, 0, 0,110, 1, 0, 0,111, 1, 2, 0,112, 1, 2, 0,113, 1, 2, 0,114, 1, 2, 0,115, 1, + 2, 0,116, 1, 7, 0,117, 1, 7, 0,118, 1, 7, 0,119, 1, 7, 0,120, 1, 2, 0,121, 1, 2, 0, 67, 0, 2, 0,122, 1, + 2, 0,123, 1, 2, 0,124, 1, 2, 0,125, 1, 7, 0,126, 1, 7, 0,127, 1, 7, 0,128, 1, 7, 0,129, 1, 7, 0,130, 1, + 7, 0,131, 1, 7, 0,132, 1, 7, 0,133, 1, 7, 0,134, 1, 7, 0,135, 1, 7, 0,136, 1, 7, 0,137, 1, 2, 0,138, 1, + 0, 0,139, 1, 31, 0, 80, 0, 46, 0,140, 1, 2, 0,141, 1, 2, 0, 76, 1, 0, 0,142, 1, 25, 0,154, 0, 57, 0, 70, 1, + 61, 0, 18, 0, 7, 0,143, 1, 7, 0,144, 1, 7, 0,145, 1, 7, 0,146, 1, 7, 0,147, 1, 7, 0,148, 1, 7, 0,149, 1, + 7, 0,150, 1, 7, 0,151, 1, 7, 0,152, 1, 2, 0,153, 1, 2, 0,154, 1, 2, 0,155, 1, 2, 0,156, 1, 7, 0,157, 1, + 7, 0,158, 1, 7, 0,159, 1, 7, 0,160, 1, 62, 0, 4, 0, 4, 0, 18, 0, 4, 0,161, 1, 4, 0,162, 1, 4, 0, 67, 0, + 63, 0,126, 0, 22, 0, 32, 0, 34, 0, 75, 0, 2, 0,163, 1, 2, 0, 18, 0, 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, + 7, 0,164, 1, 7, 0,165, 1, 7, 0,166, 1, 7, 0,167, 1, 7, 0,168, 1, 7, 0,169, 1, 7, 0,170, 1, 7, 0,171, 1, + 7, 0,172, 1, 7, 0,173, 1, 7, 0,174, 1, 7, 0,175, 1, 7, 0,176, 1, 7, 0,177, 1, 7, 0,178, 1, 7, 0,179, 1, + 7, 0,180, 1, 7, 0,181, 1, 7, 0,182, 1, 7, 0,183, 1, 61, 0,184, 1, 62, 0,185, 1, 7, 0,186, 1, 7, 0,187, 1, + 7, 0,188, 1, 7, 0,189, 1, 7, 0,190, 1, 7, 0,191, 1, 7, 0,192, 1, 2, 0,193, 1, 2, 0,194, 1, 2, 0,195, 1, + 0, 0,196, 1, 0, 0,197, 1, 7, 0,198, 1, 7, 0,199, 1, 2, 0,200, 1, 2, 0,201, 1, 7, 0,202, 1, 7, 0,203, 1, + 7, 0,204, 1, 7, 0,205, 1, 2, 0,206, 1, 2, 0,207, 1, 4, 0, 87, 1, 4, 0,208, 1, 2, 0,209, 1, 2, 0,210, 1, + 2, 0,211, 1, 2, 0,212, 1, 7, 0,213, 1, 7, 0,214, 1, 7, 0,215, 1, 7, 0,216, 1, 7, 0,217, 1, 7, 0,218, 1, + 7, 0,219, 1, 7, 0,220, 1, 7, 0,221, 1, 7, 0,222, 1, 0, 0,223, 1, 7, 0,224, 1, 7, 0,225, 1, 7, 0,226, 1, + 4, 0,227, 1, 0, 0,228, 1, 0, 0,122, 1, 0, 0,229, 1, 0, 0, 76, 1, 2, 0,230, 1, 2, 0,231, 1, 2, 0,141, 1, + 2, 0,232, 1, 2, 0,233, 1, 2, 0,234, 1, 7, 0,235, 1, 7, 0,236, 1, 7, 0,237, 1, 7, 0,238, 1, 7, 0,239, 1, + 2, 0,164, 0, 2, 0,165, 0, 50, 0,240, 1, 50, 0,241, 1, 0, 0,242, 1, 0, 0,243, 1, 0, 0,244, 1, 0, 0,245, 1, + 2, 0,246, 1, 2, 0,247, 1, 7, 0,248, 1, 7, 0,249, 1, 46, 0,140, 1, 57, 0, 70, 1, 31, 0, 80, 0, 64, 0,250, 1, + 25, 0,154, 0, 7, 0,251, 1, 7, 0,252, 1, 7, 0,253, 1, 7, 0,254, 1, 7, 0,255, 1, 2, 0, 0, 2, 2, 0, 30, 0, + 7, 0, 1, 2, 7, 0, 2, 2, 7, 0, 3, 2, 7, 0, 4, 2, 7, 0, 5, 2, 7, 0, 6, 2, 7, 0, 7, 2, 7, 0, 8, 2, + 7, 0, 9, 2, 2, 0, 10, 2, 2, 0, 11, 2, 4, 0, 12, 2, 2, 0, 13, 2, 2, 0, 14, 2, 14, 0, 15, 2, 65, 0, 4, 0, + 22, 0, 32, 0, 0, 0, 35, 0, 66, 0, 2, 0, 38, 0,153, 0, 67, 0, 20, 0, 67, 0, 0, 0, 67, 0, 1, 0, 68, 0, 16, 2, + 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 17, 2, 2, 0, 18, 2, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 19, 2, + 7, 0, 20, 2, 7, 0, 21, 2, 7, 0, 22, 2, 7, 0, 23, 2, 7, 0, 24, 2, 7, 0, 25, 2, 7, 0, 22, 0, 7, 0, 26, 2, + 7, 0, 27, 2, 69, 0, 20, 0, 22, 0, 32, 0, 34, 0, 75, 0, 68, 0, 16, 2, 14, 0, 28, 2, 14, 0, 29, 2, 14, 0, 30, 2, + 31, 0, 80, 0, 63, 0, 31, 2, 0, 0, 18, 0, 0, 0, 32, 2, 2, 0, 33, 2, 2, 0,178, 0, 2, 0, 27, 0, 7, 0, 77, 1, + 7, 0,176, 0, 7, 0, 78, 1, 7, 0, 34, 2, 7, 0, 35, 2, 7, 0, 36, 2, 67, 0, 37, 2, 30, 0, 11, 0, 7, 0, 38, 2, + 7, 0, 39, 2, 7, 0, 40, 2, 7, 0,255, 0, 2, 0, 54, 0, 0, 0, 41, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 44, 2, + 0, 0, 45, 2, 0, 0, 46, 2, 29, 0, 7, 0, 7, 0, 47, 2, 7, 0, 39, 2, 7, 0, 40, 2, 2, 0, 43, 2, 2, 0, 46, 2, + 7, 0,255, 0, 7, 0, 27, 0, 70, 0, 21, 0, 70, 0, 0, 0, 70, 0, 1, 0, 2, 0, 16, 0, 2, 0, 48, 2, 2, 0, 46, 2, + 2, 0, 18, 0, 2, 0, 49, 2, 2, 0, 50, 2, 2, 0, 51, 2, 2, 0, 52, 2, 2, 0, 53, 2, 2, 0, 54, 2, 2, 0, 55, 2, + 2, 0, 56, 2, 7, 0, 57, 2, 7, 0, 58, 2, 29, 0, 48, 0, 30, 0, 49, 0, 2, 0, 59, 2, 2, 0, 60, 2, 4, 0, 61, 2, + 71, 0, 5, 0, 2, 0, 62, 2, 2, 0, 48, 2, 0, 0, 18, 0, 0, 0, 27, 0, 2, 0, 30, 0, 72, 0, 4, 0, 7, 0, 5, 0, + 7, 0, 6, 0, 7, 0, 63, 2, 7, 0, 64, 2, 73, 0, 4, 0, 14, 0, 65, 2, 74, 0, 66, 2, 4, 0, 67, 2, 0, 0, 94, 0, + 75, 0, 68, 0, 22, 0, 32, 0, 34, 0, 75, 0, 68, 0, 16, 2, 14, 0, 68, 2, 14, 0, 29, 2, 73, 0, 69, 2, 27, 0, 70, 2, + 27, 0, 71, 2, 27, 0, 72, 2, 31, 0, 80, 0, 76, 0, 73, 2, 33, 0, 74, 2, 63, 0, 31, 2, 14, 0, 75, 2, 7, 0, 77, 1, + 7, 0,176, 0, 7, 0, 78, 1, 2, 0, 16, 0, 2, 0,178, 0, 2, 0, 76, 2, 2, 0, 77, 2, 7, 0, 78, 2, 7, 0, 79, 2, + 4, 0, 80, 2, 2, 0, 27, 0, 2, 0, 33, 2, 2, 0, 18, 0, 2, 0, 81, 2, 7, 0, 82, 2, 7, 0, 83, 2, 7, 0, 84, 2, + 2, 0, 51, 2, 2, 0, 52, 2, 2, 0, 85, 2, 2, 0, 86, 2, 4, 0, 87, 2, 11, 0, 88, 2, 2, 0, 22, 0, 2, 0, 97, 0, + 2, 0, 66, 0, 2, 0, 89, 2, 7, 0, 90, 2, 7, 0, 91, 2, 7, 0, 92, 2, 7, 0, 93, 2, 7, 0, 94, 2, 7, 0, 95, 2, + 7, 0, 96, 2, 7, 0, 97, 2, 7, 0, 98, 2, 7, 0, 99, 2, 0, 0,100, 2, 77, 0,101, 2, 78, 0,102, 2, 0, 0,103, 2, + 65, 0,104, 2, 65, 0,105, 2, 65, 0,106, 2, 65, 0,107, 2, 4, 0,108, 2, 7, 0, 84, 0, 4, 0,109, 2, 4, 0,110, 2, + 72, 0,111, 2, 4, 0,112, 2, 4, 0,113, 2, 71, 0,114, 2, 71, 0,115, 2, 79, 0, 47, 0, 22, 0, 32, 0, 34, 0, 75, 0, + 68, 0, 16, 2, 31, 0, 80, 0, 33, 0, 74, 2, 63, 0, 31, 2, 80, 0,116, 2, 81, 0,117, 2, 82, 0,118, 2, 83, 0,119, 2, + 84, 0,120, 2, 85, 0,121, 2, 86, 0,122, 2, 87, 0,123, 2, 88, 0,124, 2, 89, 0,125, 2, 90, 0,126, 2, 91, 0,127, 2, + 92, 0,128, 2, 93, 0,129, 2, 79, 0,130, 2, 94, 0,131, 2, 95, 0,132, 2, 95, 0,133, 2, 95, 0,134, 2, 95, 0,135, 2, + 95, 0,136, 2, 4, 0, 53, 0, 4, 0,137, 2, 4, 0,138, 2, 4, 0,139, 2, 4, 0,140, 2, 4, 0,141, 2, 4, 0,142, 2, + 7, 0, 77, 1, 7, 0,176, 0, 7, 0, 78, 1, 2, 0,178, 0, 2, 0, 76, 2, 2, 0,143, 2, 2, 0, 18, 0, 2, 0,144, 2, + 2, 0,145, 2, 0, 0,146, 2, 0, 0,147, 2, 2, 0, 33, 2, 96, 0,148, 2, 88, 0, 8, 0, 11, 0,149, 2, 7, 0,150, 2, + 4, 0,151, 2, 0, 0, 18, 0, 0, 0,152, 2, 2, 0, 87, 1, 2, 0,153, 2, 2, 0,154, 2, 86, 0, 7, 0, 4, 0,155, 2, + 4, 0,156, 2, 4, 0,157, 2, 4, 0,158, 2, 2, 0, 48, 2, 0, 0,159, 2, 0, 0, 18, 0, 90, 0, 5, 0, 4, 0,155, 2, + 4, 0,156, 2, 0, 0,160, 2, 0, 0,161, 2, 2, 0, 18, 0, 97, 0, 2, 0, 4, 0,162, 2, 7, 0, 40, 2, 91, 0, 3, 0, + 97, 0,163, 2, 4, 0,164, 2, 4, 0, 18, 0, 89, 0, 4, 0, 7, 0,165, 2, 2, 0,166, 2, 0, 0, 18, 0, 0, 0,161, 2, + 92, 0, 4, 0, 0, 0,240, 0, 0, 0,185, 0, 0, 0,186, 0, 0, 0,187, 0, 81, 0, 5, 0, 4, 0,167, 2, 4, 0,141, 2, + 2, 0, 48, 2, 0, 0, 18, 0, 0, 0, 27, 0, 83, 0, 2, 0, 4, 0,168, 2, 4, 0,169, 2, 82, 0, 6, 0, 42, 0,149, 2, + 0, 0, 18, 0, 0, 0,152, 2, 2, 0, 87, 1, 2, 0,153, 2, 2, 0,154, 2, 84, 0, 2, 0, 7, 0,170, 2, 4, 0, 18, 0, + 85, 0, 4, 0, 0, 0,185, 0, 0, 0,186, 0, 0, 0,187, 0, 0, 0,240, 0, 93, 0, 1, 0, 7, 0,171, 2, 80, 0, 2, 0, + 4, 0, 14, 2, 4, 0, 16, 0, 87, 0, 7, 0, 7, 0,150, 2, 42, 0,149, 2, 0, 0, 18, 0, 0, 0,152, 2, 2, 0, 87, 1, + 2, 0,153, 2, 2, 0,154, 2, 98, 0, 1, 0, 7, 0,172, 2, 99, 0, 1, 0, 4, 0,173, 2,100, 0, 1, 0, 0, 0,174, 2, +101, 0, 1, 0, 7, 0,150, 2,102, 0, 1, 0, 7, 0,170, 2,103, 0, 4, 0, 4, 0,175, 2, 4, 0,176, 2, 7, 0,177, 2, + 4, 0,178, 2,104, 0, 4, 0, 7, 0,240, 0, 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0,105, 0, 1, 0,104, 0,151, 2, +106, 0, 5, 0, 4, 0,179, 2, 4, 0,180, 2, 0, 0, 18, 0, 0, 0, 48, 2, 0, 0,181, 2,107, 0, 2, 0, 4, 0,182, 2, + 4, 0,180, 2,108, 0, 10, 0,108, 0, 0, 0,108, 0, 1, 0,106, 0,183, 2,105, 0,184, 2,107, 0,185, 2, 4, 0, 53, 0, + 4, 0,138, 2, 4, 0,137, 2, 4, 0, 27, 0, 89, 0,186, 2, 96, 0, 14, 0, 14, 0,187, 2, 89, 0,186, 2, 0, 0,188, 2, + 0, 0,189, 2, 0, 0,190, 2, 0, 0,191, 2, 0, 0,192, 2, 0, 0,193, 2, 0, 0,194, 2, 0, 0, 18, 0, 95, 0,132, 2, + 95, 0,134, 2, 2, 0,195, 2, 0, 0,196, 2,109, 0, 1, 0, 4, 0,173, 2,110, 0, 9, 0,110, 0, 0, 0,110, 0, 1, 0, + 4, 0, 16, 0, 4, 0, 87, 1, 4, 0,197, 2, 4, 0, 27, 0, 0, 0, 19, 0, 41, 0,125, 0, 0, 0,198, 2,111, 0, 6, 0, +110, 0,199, 2, 47, 0,200, 2, 27, 0,201, 2, 0, 0,202, 2, 4, 0,203, 2, 4, 0,204, 2,112, 0, 7, 0,110, 0,199, 2, + 2, 0,205, 2, 2, 0,187, 2, 2, 0,206, 2, 2, 0, 92, 0, 11, 0,207, 2, 11, 0,208, 2,113, 0, 5, 0,110, 0,199, 2, + 27, 0,168, 0, 0, 0, 19, 0, 7, 0,209, 2, 0, 0, 94, 0,114, 0, 5, 0,110, 0,199, 2, 27, 0,168, 0, 0, 0, 19, 0, + 2, 0,210, 2, 0, 0,211, 2,115, 0, 5, 0,110, 0,199, 2, 7, 0, 90, 0, 7, 0,212, 2, 4, 0,213, 2, 4, 0,214, 2, +116, 0, 5, 0,110, 0,199, 2, 27, 0,215, 2, 0, 0, 72, 0, 4, 0, 87, 1, 4, 0, 18, 0,117, 0, 13, 0,110, 0,199, 2, + 27, 0,216, 2, 27, 0,217, 2, 27, 0,218, 2, 27, 0,219, 2, 7, 0,220, 2, 7, 0,221, 2, 7, 0,212, 2, 7, 0,222, 2, + 4, 0,223, 2, 4, 0,224, 2, 4, 0, 92, 0, 4, 0,225, 2,118, 0, 5, 0,110, 0,199, 2, 2, 0,226, 2, 2, 0, 18, 0, + 7, 0,227, 2, 27, 0,228, 2,119, 0, 3, 0,110, 0,199, 2, 7, 0,229, 2, 4, 0, 92, 0,120, 0, 10, 0,110, 0,199, 2, + 7, 0,230, 2, 4, 0,231, 2, 4, 0, 27, 0, 2, 0, 92, 0, 2, 0,232, 2, 2, 0,233, 2, 2, 0,234, 2, 7, 0,235, 2, + 0, 0,236, 2,121, 0, 3, 0,110, 0,199, 2, 7, 0, 27, 0, 4, 0, 16, 0,122, 0, 6, 0,110, 0,199, 2,123, 0,237, 2, +124, 0,238, 2,125, 0,239, 2, 7, 0,240, 2, 4, 0, 16, 0,126, 0, 11, 0,110, 0,199, 2, 47, 0,200, 2, 27, 0,201, 2, + 0, 0,202, 2, 4, 0,203, 2, 4, 0,204, 2, 7, 0,209, 2, 4, 0,241, 2, 0, 0,236, 2, 7, 0,242, 2, 4, 0, 27, 0, +127, 0, 12, 0,110, 0,199, 2, 27, 0,243, 2, 42, 0,244, 2, 4, 0, 92, 0, 4, 0,245, 2, 7, 0,246, 2, 7, 0,247, 2, + 7, 0,248, 2, 7, 0,249, 2, 0, 0,202, 2, 4, 0,203, 2, 4, 0, 27, 0,128, 0, 3, 0,110, 0,199, 2, 7, 0,250, 2, + 4, 0,251, 2,129, 0, 5, 0,110, 0,199, 2, 7, 0,252, 2, 0, 0,236, 2, 2, 0, 18, 0, 2, 0,253, 2,130, 0, 8, 0, +110, 0,199, 2, 27, 0,168, 0, 7, 0,252, 2, 7, 0,255, 0, 7, 0,108, 0, 0, 0,236, 2, 2, 0, 18, 0, 2, 0, 16, 0, +131, 0, 21, 0,110, 0,199, 2, 47, 0,200, 2, 27, 0,201, 2, 0, 0,202, 2, 4, 0,203, 2, 4, 0,204, 2, 27, 0,254, 2, + 0, 0,236, 2, 2, 0, 18, 0, 2, 0, 27, 0, 7, 0,255, 2, 7, 0, 0, 3, 7, 0, 1, 3, 7, 0, 82, 2, 7, 0, 2, 3, + 7, 0, 3, 3, 7, 0, 4, 3, 7, 0, 5, 3, 7, 0, 6, 3, 7, 0, 7, 3, 7, 0, 67, 0,132, 0, 7, 0,110, 0,199, 2, + 2, 0, 8, 3, 2, 0, 9, 3, 4, 0, 30, 0, 27, 0,168, 0, 7, 0, 10, 3, 0, 0,236, 2,133, 0, 10, 0,110, 0,199, 2, + 27, 0,168, 0, 0, 0, 11, 3, 7, 0, 12, 3, 7, 0, 13, 3, 7, 0, 5, 3, 4, 0, 14, 3, 4, 0, 15, 3, 7, 0, 16, 3, + 0, 0, 19, 0,134, 0, 1, 0,110, 0,199, 2,135, 0, 7, 0,110, 0,199, 2, 41, 0,125, 0,136, 0, 17, 3,137, 0, 18, 3, +138, 0, 19, 3,139, 0, 20, 3, 14, 0, 21, 3,140, 0, 13, 0,110, 0,199, 2, 89, 0, 22, 3, 89, 0, 23, 3, 89, 0, 24, 3, + 89, 0, 25, 3, 89, 0, 26, 3, 89, 0, 27, 3, 86, 0, 28, 3, 4, 0, 29, 3, 4, 0, 30, 3, 7, 0, 31, 3, 7, 0, 32, 3, +141, 0, 33, 3,142, 0, 7, 0,110, 0,199, 2, 89, 0, 22, 3, 89, 0, 34, 3,143, 0, 35, 3,144, 0, 33, 3, 4, 0, 36, 3, + 4, 0, 29, 3,145, 0, 4, 0,110, 0,199, 2, 27, 0,168, 0, 4, 0, 37, 3, 4, 0, 27, 0,146, 0, 2, 0, 4, 0, 38, 3, + 7, 0, 40, 2,147, 0, 2, 0, 4, 0,128, 0, 4, 0, 39, 3,148, 0, 24, 0,110, 0,199, 2, 27, 0,168, 0, 0, 0,236, 2, + 2, 0, 40, 3, 2, 0, 18, 0, 2, 0, 87, 1, 2, 0, 27, 0,146, 0, 41, 3, 4, 0, 42, 3, 7, 0, 43, 3, 4, 0, 53, 0, + 4, 0, 44, 3,147, 0, 45, 3,146, 0, 46, 3, 4, 0, 47, 3, 4, 0, 48, 3, 4, 0, 49, 3, 4, 0, 39, 3, 7, 0, 50, 3, + 7, 0, 51, 3, 7, 0, 52, 3, 7, 0, 53, 3, 7, 0, 54, 3, 11, 0, 55, 3,149, 0, 8, 0,110, 0,199, 2,150, 0, 56, 3, +143, 0, 35, 3, 4, 0, 57, 3, 4, 0, 58, 3, 4, 0, 59, 3, 2, 0, 18, 0, 2, 0, 56, 0,151, 0, 8, 0,110, 0,199, 2, + 27, 0, 44, 0, 2, 0, 3, 1, 2, 0, 18, 0, 2, 0,226, 2, 2, 0, 56, 0, 7, 0, 60, 3, 7, 0, 61, 3,152, 0, 6, 0, +110, 0,199, 2, 4, 0, 62, 3, 2, 0, 18, 0, 2, 0, 63, 3, 7, 0, 64, 3, 0, 0,170, 0,153, 0, 8, 0,110, 0,199, 2, + 0, 0, 65, 3, 0, 0, 66, 3, 0, 0,193, 2, 0, 0, 67, 3, 0, 0, 68, 3, 0, 0, 92, 0, 0, 0,181, 2,154, 0, 3, 0, +110, 0,199, 2,155, 0, 69, 3,139, 0, 20, 3,156, 0, 10, 0,110, 0,199, 2, 27, 0, 70, 3, 27, 0, 71, 3, 0, 0, 72, 3, + 7, 0, 73, 3, 2, 0, 74, 3, 2, 0, 75, 3, 0, 0, 76, 3, 0, 0, 77, 3, 0, 0,211, 2,157, 0, 9, 0,110, 0,199, 2, + 27, 0, 78, 3, 0, 0, 72, 3, 7, 0, 79, 3, 7, 0, 80, 3, 0, 0, 87, 1, 0, 0,226, 2, 0, 0, 81, 3, 0, 0, 27, 0, +158, 0, 1, 0,110, 0,199, 2,159, 0, 11, 0,110, 0,199, 2, 0, 0,236, 2, 7, 0,128, 0, 7, 0, 82, 3, 7, 0, 83, 3, + 7, 0, 84, 3, 7, 0, 85, 3, 7, 0, 86, 3, 4, 0, 18, 0, 2, 0, 87, 3, 2, 0, 88, 3,160, 0, 9, 0,110, 0,199, 2, + 27, 0, 89, 3, 4, 0, 90, 3, 4, 0, 91, 3, 4, 0, 92, 3, 7, 0, 93, 3, 7, 0, 94, 3, 2, 0,226, 2, 2, 0, 18, 0, +161, 0, 29, 0,110, 0,199, 2,162, 0, 95, 3,163, 0, 96, 3, 4, 0, 97, 3, 4, 0, 98, 3, 7, 0, 99, 3, 7, 0, 4, 3, + 7, 0,100, 3, 7, 0,250, 0, 7, 0,101, 3, 7, 0,102, 3, 7, 0,103, 3, 7, 0,104, 3, 7, 0,105, 3, 7, 0,240, 2, + 4, 0,106, 3, 4, 0,107, 3, 0, 0,108, 3, 0, 0,109, 3, 0, 0,110, 3, 0, 0,111, 3, 0, 0, 18, 0, 0, 0,112, 3, + 2, 0,113, 3, 2, 0,114, 3, 4, 0,214, 2, 7, 0,108, 0, 7, 0,115, 3, 4, 0, 27, 0,164, 0, 15, 0,110, 0,199, 2, + 47, 0,200, 2, 27, 0,201, 2, 0, 0,202, 2, 4, 0,203, 2, 4, 0,204, 2, 27, 0,116, 3, 27, 0,117, 3, 54, 0,100, 1, + 0, 0,236, 2, 7, 0,209, 2, 7, 0,118, 3, 0, 0, 18, 0, 0, 0,253, 0, 0, 0,211, 2,165, 0, 16, 0,110, 0,199, 2, + 0, 0,236, 2, 2, 0,119, 3, 2, 0,253, 0, 7, 0,120, 3, 54, 0,121, 3, 7, 0,122, 3, 7, 0,123, 3, 7, 0,124, 3, + 0, 0,125, 3, 4, 0,126, 3, 47, 0,127, 3, 27, 0,128, 3, 4, 0,129, 3, 0, 0,130, 3, 4, 0,131, 3,166, 0, 16, 0, +110, 0,199, 2, 0, 0,132, 3, 0, 0,133, 3, 7, 0,134, 3, 7, 0,135, 3, 0, 0,136, 3, 0, 0,137, 3, 0, 0,138, 3, + 7, 0,124, 3, 0, 0,125, 3, 4, 0,126, 3, 47, 0,127, 3, 27, 0,128, 3, 4, 0,129, 3, 0, 0,130, 3, 4, 0,131, 3, +167, 0, 16, 0,110, 0,199, 2, 0, 0,236, 2, 4, 0,139, 3, 4, 0,140, 3, 27, 0,141, 3, 7, 0,124, 3, 0, 0,125, 3, + 4, 0,126, 3, 47, 0,127, 3, 27, 0,128, 3, 4, 0,129, 3, 0, 0,130, 3, 7, 0,142, 3, 7, 0,143, 3, 2, 0,253, 0, + 2, 0,144, 3,168, 0, 5, 0,110, 0,199, 2,169, 0,145, 3,170, 0,146, 3, 4, 0, 16, 0, 4, 0, 27, 0,171, 0, 8, 0, +110, 0,199, 2, 7, 0,147, 3, 7, 0,148, 3, 7, 0,149, 3, 0, 0,250, 0, 0, 0, 18, 0, 0, 0, 87, 1, 0, 0, 27, 0, +172, 0, 3, 0,173, 0,150, 3, 4, 0, 67, 2, 0, 0, 94, 0,173, 0, 29, 0, 22, 0, 32, 0, 34, 0, 75, 0, 2, 0, 49, 2, + 2, 0, 50, 2, 2, 0,151, 3, 2, 0, 18, 0, 2, 0,152, 3, 2, 0,153, 3, 2, 0,154, 3, 2, 0, 30, 0, 0, 0,155, 3, + 0, 0,156, 3, 0, 0,157, 3, 0, 0,247, 1, 4, 0, 27, 0, 7, 0,158, 3, 7, 0,159, 3, 7, 0,160, 3, 7, 0,161, 3, + 7, 0,162, 3, 7, 0,163, 3, 29, 0,164, 3, 31, 0, 80, 0, 33, 0, 74, 2, 91, 0,127, 2, 0, 0, 72, 0, 7, 0,165, 3, + 7, 0,166, 3,172, 0,167, 3,174, 0, 5, 0,174, 0, 0, 0,174, 0, 1, 0, 0, 0, 19, 0, 0, 0, 18, 0, 0, 0,124, 0, + 68, 0, 3, 0, 7, 0,168, 3, 4, 0, 18, 0, 4, 0, 27, 0, 27, 0,128, 0, 22, 0, 32, 0, 34, 0, 75, 0,175, 0,169, 3, + 2, 0, 16, 0, 2, 0,170, 3, 4, 0,171, 3, 4, 0,172, 3, 4, 0,173, 3, 0, 0,174, 3, 27, 0, 38, 0, 27, 0,175, 3, + 27, 0,176, 3, 27, 0,177, 3, 27, 0,178, 3, 31, 0, 80, 0, 68, 0, 16, 2,176, 0,179, 3,176, 0,180, 3,177, 0,181, 3, + 11, 0, 2, 0,178, 0,182, 3,179, 0,183, 3,180, 0,184, 3, 14, 0,185, 3, 14, 0,186, 3, 14, 0, 29, 2, 14, 0,187, 3, + 14, 0,188, 3, 4, 0, 87, 1, 4, 0,189, 3, 63, 0, 31, 2, 0, 0,190, 3, 4, 0, 33, 2, 4, 0,191, 3, 7, 0, 77, 1, + 7, 0,192, 3, 7, 0,193, 3, 7, 0,176, 0, 7, 0,194, 3, 7, 0,195, 3, 7, 0, 78, 1, 7, 0,196, 3, 7, 0, 19, 2, + 7, 0,197, 3, 7, 0,198, 3, 7, 0,199, 3, 7, 0,200, 3, 7, 0,201, 3, 7, 0,202, 3, 7, 0, 12, 3, 7, 0,203, 3, + 7, 0,244, 0, 7, 0,204, 3, 4, 0,205, 3, 4, 0,206, 3, 2, 0, 18, 0, 2, 0,207, 3, 2, 0,208, 3, 2, 0,209, 3, + 2, 0,210, 3, 2, 0,211, 3, 2, 0,212, 3, 2, 0,213, 3, 2, 0,214, 3, 0, 0,215, 3, 0, 0,216, 3, 4, 0,217, 3, + 4, 0,218, 3, 4, 0,219, 3, 4, 0,220, 3, 7, 0,221, 3, 7, 0, 84, 0, 7, 0,222, 3, 7, 0,223, 3, 7, 0,224, 3, + 7, 0,225, 3, 7, 0,226, 3, 7, 0,220, 0, 7, 0,227, 3, 7, 0,228, 3, 7, 0,229, 3, 7, 0,230, 3, 7, 0,231, 3, + 2, 0,232, 3, 0, 0,233, 3, 0, 0,234, 3, 0, 0,235, 3, 0, 0,236, 3, 0, 0,110, 0, 0, 0,237, 3, 7, 0,238, 3, + 7, 0,239, 3, 14, 0,240, 3, 14, 0,241, 3, 14, 0,242, 3, 14, 0,243, 3, 7, 0,244, 3, 2, 0, 14, 2, 2, 0,245, 3, + 7, 0,151, 2, 4, 0,246, 3, 4, 0,247, 3,181, 0,248, 3, 2, 0,249, 3, 2, 0,251, 0, 7, 0,250, 3, 14, 0,251, 3, + 14, 0,252, 3, 14, 0,253, 3, 14, 0,254, 3,182, 0, 73, 1,183, 0,255, 3, 64, 0, 0, 4, 0, 0, 1, 4, 0, 0, 2, 4, + 2, 0, 67, 2, 7, 0,143, 2,155, 0, 3, 4,143, 0, 4, 4,143, 0, 5, 4, 10, 0, 6, 4, 10, 0, 7, 4, 4, 0, 8, 4, + 4, 0, 9, 4, 14, 0, 10, 4, 14, 0, 11, 4, 14, 0, 12, 4, 7, 0, 13, 4,184, 0, 14, 0,184, 0, 0, 0,184, 0, 1, 0, + 27, 0, 38, 0, 7, 0, 12, 3, 7, 0, 79, 1, 7, 0, 13, 3, 7, 0, 5, 3, 0, 0, 19, 0, 4, 0, 14, 3, 4, 0, 15, 3, + 4, 0, 14, 4, 2, 0, 16, 0, 2, 0, 15, 4, 7, 0, 16, 3,185, 0, 12, 0,185, 0, 0, 0,185, 0, 1, 0, 27, 0, 44, 0, + 4, 0, 16, 4, 4, 0, 14, 2, 7, 0, 79, 1, 7, 0, 17, 4, 7, 0, 18, 4, 7, 0,170, 2, 2, 0, 16, 0, 0, 0, 19, 4, + 0, 0, 20, 4,182, 0, 40, 0, 4, 0, 18, 0, 2, 0, 21, 4, 2, 0, 22, 4, 2, 0, 5, 3, 2, 0, 23, 4, 2, 0, 24, 4, + 2, 0, 25, 4, 2, 0, 26, 4, 2, 0, 27, 4, 7, 0, 28, 4, 7, 0, 29, 4, 7, 0, 30, 4, 7, 0, 31, 4, 7, 0, 32, 4, + 7, 0, 33, 4, 7, 0, 34, 4, 7, 0, 35, 4, 7, 0, 36, 4, 7, 0, 37, 4, 7, 0, 38, 4, 7, 0, 39, 4, 7, 0, 40, 4, + 7, 0, 41, 4, 7, 0, 42, 4, 7, 0, 43, 4, 7, 0, 44, 4, 7, 0, 45, 4, 7, 0, 46, 4, 7, 0, 47, 4, 7, 0, 48, 4, + 7, 0, 49, 4, 7, 0, 50, 4, 7, 0, 51, 4, 7, 0, 52, 4, 7, 0, 53, 4, 7, 0, 54, 4, 47, 0,169, 0,186, 0, 55, 4, + 7, 0, 56, 4, 4, 0,214, 2,187, 0, 5, 0, 64, 0,250, 1, 7, 0, 57, 4, 7, 0, 58, 4, 2, 0, 18, 0, 2, 0, 59, 4, +188, 0, 5, 0,188, 0, 0, 0,188, 0, 1, 0, 4, 0, 16, 0, 4, 0, 60, 4, 11, 0, 2, 0,189, 0, 9, 0,189, 0, 0, 0, +189, 0, 1, 0, 4, 0, 61, 4, 4, 0, 62, 4, 4, 0, 63, 4, 4, 0, 18, 0, 11, 0, 64, 4, 11, 0, 65, 4, 14, 0, 66, 4, +139, 0, 23, 0,139, 0, 0, 0,139, 0, 1, 0, 4, 0, 18, 0, 4, 0, 67, 4, 4, 0, 68, 4, 4, 0, 69, 4, 4, 0, 70, 4, + 4, 0, 71, 4, 4, 0, 72, 4, 4, 0, 73, 4, 4, 0, 27, 0, 4, 0, 62, 4, 4, 0, 14, 2, 2, 0, 74, 4, 2, 0, 56, 0, + 0, 0, 19, 0, 0, 0, 75, 4, 0, 0, 76, 4, 0, 0, 77, 4, 0, 0, 78, 4, 14, 0, 79, 4,190, 0, 80, 4, 11, 0, 81, 4, +191, 0, 1, 0, 7, 0, 47, 2,181, 0, 30, 0, 4, 0, 18, 0, 7, 0, 82, 4, 7, 0, 83, 4, 7, 0, 84, 4, 4, 0, 85, 4, + 4, 0, 86, 4, 4, 0, 87, 4, 4, 0, 88, 4, 7, 0, 89, 4, 7, 0, 90, 4, 7, 0, 91, 4, 7, 0, 92, 4, 7, 0, 93, 4, + 7, 0, 94, 4, 7, 0, 95, 4, 7, 0, 96, 4, 7, 0, 97, 4, 7, 0, 98, 4, 7, 0, 99, 4, 7, 0,100, 4, 7, 0,101, 4, + 7, 0,102, 4, 7, 0,103, 4, 7, 0,104, 4, 7, 0,105, 4, 7, 0,106, 4, 4, 0,107, 4, 4, 0,108, 4, 7, 0,109, 4, + 7, 0,227, 3,183, 0, 54, 0, 4, 0, 62, 4, 4, 0,110, 4,192, 0,111, 4,193, 0,112, 4, 0, 0, 27, 0, 0, 0,113, 4, + 2, 0,114, 4, 7, 0,115, 4, 0, 0,116, 4, 7, 0,117, 4, 7, 0,118, 4, 7, 0,119, 4, 7, 0,120, 4, 7, 0,121, 4, + 7, 0,122, 4, 7, 0,123, 4, 7, 0,124, 4, 7, 0,125, 4, 2, 0,126, 4, 0, 0,127, 4, 2, 0,128, 4, 7, 0,129, 4, + 7, 0,130, 4, 0, 0,131, 4, 4, 0,129, 0, 4, 0,132, 4, 4, 0,133, 4, 2, 0,134, 4, 2, 0,135, 4,191, 0,136, 4, + 4, 0,137, 4, 4, 0, 82, 0, 7, 0,138, 4, 7, 0,139, 4, 7, 0,140, 4, 7, 0,141, 4, 2, 0,142, 4, 2, 0,143, 4, + 2, 0,144, 4, 2, 0,145, 4, 2, 0,146, 4, 2, 0,147, 4, 2, 0,148, 4, 2, 0,149, 4,194, 0,150, 4, 7, 0,151, 4, + 7, 0,152, 4,139, 0,153, 4, 14, 0, 21, 3,187, 0,154, 4, 7, 0,155, 4, 7, 0,156, 4, 7, 0,157, 4, 4, 0,158, 4, +195, 0, 1, 0, 7, 0,159, 4,155, 0, 52, 0,154, 0,160, 4, 2, 0, 16, 0, 2, 0,161, 4, 2, 0,162, 4, 2, 0,163, 4, + 7, 0,164, 4, 2, 0,165, 4, 2, 0,166, 4, 7, 0,167, 4, 2, 0,168, 4, 2, 0,169, 4, 7, 0,170, 4, 7, 0,171, 4, + 7, 0,172, 4, 4, 0,173, 4, 4, 0,174, 4, 4, 0,175, 4, 4, 0, 27, 0, 7, 0,176, 4, 4, 0,177, 4, 7, 0,178, 4, + 7, 0,179, 4, 7, 0,180, 4, 79, 0,181, 4, 79, 0,182, 4, 0, 0,183, 4, 7, 0,184, 4, 7, 0,185, 4, 31, 0, 80, 0, + 2, 0,186, 4, 0, 0,187, 4, 0, 0,188, 4, 7, 0,189, 4, 4, 0,190, 4, 7, 0,191, 4, 7, 0,192, 4, 4, 0,193, 4, + 4, 0, 18, 0, 7, 0,194, 4, 7, 0,195, 4, 7, 0,196, 4,195, 0,197, 4, 4, 0, 53, 0, 7, 0,198, 4, 7, 0,199, 4, + 7, 0,200, 4, 7, 0,201, 4, 7, 0,202, 4, 7, 0,203, 4, 7, 0,204, 4, 4, 0,205, 4, 7, 0,206, 4,196, 0, 78, 0, + 22, 0, 32, 0, 34, 0, 75, 0, 2, 0,179, 0, 2, 0, 88, 1, 2, 0,122, 1, 2, 0,207, 4, 7, 0,208, 4, 7, 0,209, 4, + 7, 0,210, 4, 7, 0,211, 4, 7, 0,212, 4, 7, 0,213, 4, 7, 0,170, 1, 7, 0,172, 1, 7, 0,171, 1, 7, 0, 30, 0, + 4, 0,214, 4, 7, 0,215, 4, 7, 0,216, 4, 7, 0,217, 4, 7, 0,218, 4, 7, 0,219, 4, 7, 0,220, 4, 7, 0,221, 4, + 2, 0,222, 4, 2, 0, 87, 1, 2, 0,223, 4, 2, 0,224, 4, 2, 0,225, 4, 2, 0,226, 4, 2, 0,227, 4, 2, 0,228, 4, + 7, 0,229, 4, 7, 0,230, 4, 7, 0,231, 4, 7, 0,232, 4, 7, 0,233, 4, 7, 0,234, 4, 7, 0,235, 4, 7, 0,236, 4, + 7, 0,237, 4, 7, 0,238, 4, 7, 0,239, 4, 7, 0,240, 4, 2, 0,241, 4, 2, 0,242, 4, 2, 0,243, 4, 2, 0,244, 4, + 7, 0,245, 4, 7, 0,246, 4, 7, 0,247, 4, 7, 0,248, 4, 2, 0,249, 4, 2, 0,250, 4, 2, 0,251, 4, 2, 0,252, 4, + 7, 0,253, 4, 7, 0,254, 4, 7, 0,255, 4, 7, 0, 0, 5, 7, 0, 1, 5, 7, 0, 2, 5, 7, 0, 3, 5, 2, 0, 4, 5, + 2, 0, 5, 5, 2, 0, 6, 5, 2, 0, 7, 5, 2, 0, 8, 5, 2, 0, 18, 0, 7, 0, 9, 5, 7, 0, 10, 5, 31, 0, 80, 0, + 46, 0,140, 1, 2, 0,141, 1, 2, 0, 76, 1, 2, 0,181, 2, 25, 0,154, 0, 57, 0, 70, 1,197, 0, 8, 0,197, 0, 0, 0, +197, 0, 1, 0, 4, 0,205, 3, 4, 0, 11, 5, 4, 0, 18, 0, 2, 0, 12, 5, 2, 0, 13, 5, 27, 0,168, 0,198, 0, 13, 0, + 11, 0, 14, 5, 11, 0, 15, 5, 4, 0, 16, 5, 4, 0, 17, 5, 4, 0, 18, 5, 4, 0, 19, 5, 4, 0, 20, 5, 4, 0, 21, 5, + 4, 0, 22, 5, 4, 0, 23, 5, 4, 0, 24, 5, 4, 0, 27, 0, 0, 0, 25, 5,199, 0, 5, 0, 11, 0, 26, 5, 11, 0, 27, 5, + 4, 0, 28, 5, 4, 0, 30, 0, 0, 0, 29, 5,200, 0, 17, 0, 4, 0, 30, 5, 4, 0, 31, 5, 4, 0, 32, 5, 4, 0, 33, 5, + 4, 0, 34, 5, 4, 0, 35, 5, 4, 0, 36, 5, 4, 0, 37, 5, 4, 0, 38, 5, 4, 0, 39, 5, 4, 0, 40, 5, 4, 0, 41, 5, + 2, 0, 42, 5, 2, 0, 43, 5, 4, 0, 44, 5, 4, 0, 45, 5, 4, 0, 67, 0,201, 0, 17, 0, 4, 0, 16, 0, 4, 0, 32, 5, + 4, 0, 46, 5, 4, 0, 47, 5, 4, 0, 48, 5, 4, 0, 49, 5, 4, 0, 50, 5, 4, 0, 51, 5, 7, 0, 52, 5, 4, 0, 53, 5, + 4, 0, 92, 0, 4, 0, 54, 5, 4, 0, 55, 5, 4, 0, 56, 5, 4, 0, 57, 5, 4, 0, 58, 5, 21, 0, 31, 0,202, 0, 9, 0, + 4, 0, 59, 5, 7, 0, 60, 5, 7, 0, 61, 5, 7, 0, 62, 5, 4, 0, 63, 5, 2, 0, 18, 0, 2, 0, 27, 0, 7, 0, 84, 4, + 7, 0, 30, 0,203, 0, 11, 0,203, 0, 0, 0,203, 0, 1, 0, 0, 0, 19, 0, 63, 0, 64, 5, 64, 0, 65, 5, 4, 0,205, 3, + 4, 0, 66, 5, 4, 0, 67, 5, 4, 0, 27, 0, 4, 0, 68, 5, 4, 0, 69, 5,204, 0, 13, 0, 0, 0, 70, 5, 0, 0,250, 0, + 0, 0, 71, 5, 0, 0, 18, 0, 0, 0, 72, 5, 0, 0, 73, 5, 0, 0, 74, 5, 0, 0, 75, 5, 2, 0, 76, 5, 2, 0, 77, 5, + 7, 0, 78, 5, 0, 0, 79, 5, 0, 0,124, 0,205, 0,106, 0,204, 0, 80, 5,198, 0, 81, 5,199, 0, 82, 5,200, 0, 83, 5, +201, 0, 84, 5, 4, 0, 36, 3, 4, 0,129, 0, 4, 0,132, 4, 7, 0, 85, 5, 4, 0, 86, 5, 4, 0, 87, 5, 4, 0, 88, 5, + 4, 0, 89, 5, 2, 0, 18, 0, 2, 0, 90, 5, 7, 0, 91, 5, 7, 0, 92, 5, 7, 0, 93, 5, 7, 0, 94, 5, 7, 0, 95, 5, + 2, 0, 96, 5, 2, 0, 97, 5, 2, 0, 98, 5, 2, 0, 99, 5, 2, 0,250, 0, 2, 0,100, 5, 4, 0,101, 5, 2, 0,102, 5, + 2, 0,103, 5, 2, 0,109, 1, 2, 0,108, 0, 2, 0,104, 5, 2, 0,105, 5, 2, 0,106, 5, 2, 0,107, 5, 2, 0,108, 5, + 2, 0, 71, 5, 2, 0, 70, 5, 2, 0,109, 5, 2, 0, 72, 5, 2, 0,110, 5, 4, 0,111, 5, 4, 0, 87, 1, 4, 0,112, 5, + 2, 0,113, 5, 2, 0, 67, 0, 2, 0,114, 5, 2, 0,115, 5, 2, 0,116, 5, 2, 0,117, 5, 2, 0,118, 5, 2, 0,119, 5, + 19, 0,120, 5, 19, 0,121, 5, 18, 0,122, 5, 14, 0,123, 5, 2, 0,124, 5, 2, 0,125, 5, 7, 0,126, 5, 7, 0,127, 5, + 7, 0,128, 5, 7, 0,129, 5, 4, 0,130, 5, 7, 0,131, 5, 7, 0,132, 5, 7, 0,133, 5, 7, 0,134, 5, 2, 0,135, 5, + 2, 0,136, 5, 2, 0,137, 5, 2, 0,138, 5, 2, 0,139, 5, 2, 0,140, 5, 7, 0,141, 5, 7, 0,142, 5, 7, 0,143, 5, + 0, 0,144, 5, 4, 0,145, 5, 2, 0,146, 5, 2, 0,247, 1, 0, 0,147, 5, 7, 0,148, 5, 7, 0,149, 5, 0, 0,150, 5, + 0, 0,151, 5, 0, 0,152, 5, 0, 0,153, 5, 4, 0,154, 5, 2, 0,155, 5, 2, 0,156, 5, 7, 0,157, 5, 7, 0,158, 5, + 2, 0,159, 5, 2, 0,160, 5, 7, 0,161, 5, 2, 0,162, 5, 2, 0,163, 5, 4, 0,164, 5, 2, 0,165, 5, 2, 0,166, 5, + 2, 0,167, 5, 2, 0,168, 5, 7, 0,169, 5, 7, 0, 30, 0, 37, 0,170, 5, 0, 0,171, 5,206, 0, 9, 0,206, 0, 0, 0, +206, 0, 1, 0, 0, 0,172, 5, 2, 0,173, 5, 2, 0,174, 5, 2, 0,175, 5, 2, 0, 67, 0, 7, 0,176, 5, 7, 0, 30, 0, +207, 0, 7, 0, 2, 0,231, 2, 2, 0, 87, 1, 2, 0, 94, 3, 2, 0,177, 5, 7, 0,178, 5, 7, 0, 30, 0, 37, 0,179, 5, +208, 0, 5, 0, 7, 0,180, 5, 0, 0, 16, 0, 0, 0, 67, 0, 0, 0, 30, 0, 0, 0,247, 1,209, 0, 15, 0, 7, 0,181, 5, + 7, 0,182, 5, 7, 0,183, 5, 7, 0,184, 5, 7, 0,185, 5, 7, 0,186, 5, 7, 0,187, 5, 7, 0,188, 5, 7, 0,189, 5, + 7, 0,190, 5, 4, 0,191, 5, 7, 0,192, 5, 7, 0,193, 5, 2, 0, 67, 0, 2, 0, 30, 0,210, 0, 32, 0,208, 0,194, 5, + 2, 0,195, 5, 2, 0, 97, 5, 2, 0, 98, 5, 2, 0, 99, 5, 2, 0,250, 0, 2, 0,100, 5, 2, 0,196, 5, 2, 0,197, 5, + 2, 0,198, 5, 2, 0,199, 5,207, 0,200, 5, 2, 0,201, 5, 2, 0,102, 5, 7, 0,202, 5,209, 0,203, 5, 7, 0,220, 4, + 7, 0,221, 4, 4, 0, 18, 0, 2, 0, 87, 1, 2, 0,204, 5, 2, 0,223, 4, 2, 0,224, 4, 2, 0,205, 5, 2, 0, 27, 0, + 2, 0,225, 4, 2, 0,226, 4, 2, 0,227, 4, 2, 0,228, 4, 2, 0,206, 5, 2, 0, 67, 0, 7, 0,207, 5,211, 0, 6, 0, +211, 0, 0, 0,211, 0, 1, 0, 4, 0, 61, 4, 0, 0, 19, 0, 4, 0, 18, 0, 27, 0,208, 5,212, 0, 4, 0,213, 0,146, 3, + 11, 0,209, 5, 0, 0,210, 5, 4, 0, 92, 0,214, 0, 8, 0,212, 0,211, 5, 2, 0, 18, 0, 2, 0, 27, 0, 2, 0,212, 5, + 2, 0,213, 5, 2, 0,214, 5, 4, 0, 67, 0, 11, 0,215, 5,215, 0, 6, 0, 2, 0,108, 0, 2, 0, 67, 4, 2, 0,216, 5, + 2, 0,225, 2, 4, 0, 18, 0, 7, 0,209, 2,216, 0, 14, 0, 2, 0, 18, 0, 2, 0,217, 5, 2, 0,218, 5, 2, 0,219, 5, +215, 0,220, 5, 11, 0,215, 5, 7, 0,221, 5, 7, 0, 56, 0, 4, 0,222, 5, 4, 0,223, 5, 4, 0,224, 5, 4, 0,225, 5, + 41, 0,125, 0, 27, 0,168, 0,217, 0, 14, 0,212, 0,211, 5, 4, 0, 92, 0, 4, 0,226, 5, 7, 0,227, 5, 7, 0,228, 5, + 7, 0,229, 5, 4, 0,230, 5, 4, 0,231, 5, 7, 0,232, 5, 7, 0,233, 5, 4, 0,234, 5, 7, 0,235, 5, 7, 0,236, 5, + 4, 0, 27, 0,218, 0, 1, 0,212, 0,211, 5,219, 0, 7, 0,212, 0,211, 5, 2, 0, 18, 0, 2, 0, 27, 0, 4, 0, 37, 0, + 4, 0,237, 5, 91, 0,238, 5, 11, 0,215, 5,220, 0, 5, 0,220, 0, 0, 0,220, 0, 1, 0, 0, 0, 19, 0, 7, 0,239, 5, + 4, 0, 27, 0,221, 0, 4, 0, 4, 0,108, 0, 7, 0,240, 5, 7, 0,178, 1, 4, 0, 18, 0,222, 0, 85, 0,219, 0,241, 5, +219, 0,242, 5,217, 0,169, 3,218, 0,243, 5, 7, 0,244, 5, 2, 0,245, 5, 2, 0,246, 5, 7, 0,247, 5, 7, 0,248, 5, + 2, 0, 67, 4, 2, 0,249, 5, 7, 0,250, 5, 7, 0,251, 5, 7, 0,252, 5, 2, 0,253, 5, 2, 0,222, 5, 2, 0,254, 5, + 2, 0,255, 5, 2, 0, 0, 6, 2, 0, 1, 6, 7, 0, 2, 6, 7, 0, 3, 6, 7, 0, 4, 6, 2, 0, 5, 6, 2, 0, 6, 6, + 2, 0, 7, 6, 2, 0, 8, 6, 2, 0, 9, 6, 2, 0, 10, 6, 2, 0, 11, 6, 2, 0, 12, 6,214, 0, 13, 6,216, 0, 14, 6, + 7, 0, 15, 6, 7, 0, 16, 6, 7, 0, 17, 6, 2, 0, 18, 6, 2, 0, 19, 6, 0, 0, 20, 6, 0, 0, 21, 6, 2, 0, 22, 6, + 7, 0, 23, 6, 7, 0, 24, 6, 7, 0, 25, 6, 7, 0, 26, 6, 7, 0, 27, 6, 7, 0, 28, 6, 7, 0, 29, 6, 7, 0, 30, 6, + 7, 0, 31, 6, 7, 0, 32, 6, 2, 0, 33, 6, 0, 0, 34, 6, 0, 0, 35, 6, 0, 0, 36, 6, 0, 0, 37, 6, 27, 0, 38, 6, + 0, 0, 39, 6, 0, 0, 40, 6, 0, 0, 41, 6, 0, 0, 42, 6, 0, 0, 43, 6, 0, 0, 44, 6, 0, 0, 45, 6, 0, 0, 46, 6, + 0, 0, 47, 6, 0, 0, 48, 6, 2, 0, 49, 6, 2, 0, 50, 6, 2, 0, 51, 6, 2, 0, 52, 6, 0, 0, 53, 6, 0, 0, 54, 6, + 0, 0, 55, 6, 0, 0, 56, 6, 4, 0, 57, 6, 4, 0, 58, 6, 4, 0, 59, 6, 4, 0, 60, 6, 2, 0, 61, 6, 2, 0, 67, 0, + 4, 0, 62, 6, 7, 0, 63, 6, 7, 0, 64, 6,221, 0, 65, 6,223, 0, 8, 0, 4, 0, 66, 6, 4, 0, 67, 6, 4, 0, 68, 6, + 4, 0, 69, 6, 4, 0, 70, 6, 4, 0, 71, 6, 4, 0, 53, 0, 4, 0,138, 2,224, 0, 4, 0, 7, 0, 72, 6, 0, 0, 73, 6, + 0, 0, 74, 6, 2, 0, 18, 0,225, 0, 4, 0, 7, 0, 75, 6, 4, 0, 18, 0, 4, 0, 76, 6, 4, 0, 56, 0, 41, 0, 46, 0, + 22, 0, 32, 0, 34, 0, 75, 0, 27, 0,208, 5,196, 0, 77, 6, 41, 0, 78, 6, 14, 0, 79, 6,197, 0, 80, 6, 27, 0, 81, 6, + 7, 0, 82, 6, 7, 0, 83, 6, 7, 0, 84, 6, 7, 0, 85, 6, 4, 0,205, 3, 4, 0, 86, 6, 4, 0, 87, 6, 2, 0, 18, 0, + 2, 0, 76, 1, 57, 0, 70, 1,226, 0, 88, 6,222, 0, 89, 6,227, 0, 90, 6,205, 0,185, 0,202, 0, 91, 6, 14, 0,102, 0, + 14, 0, 92, 6, 11, 0, 93, 6, 11, 0, 94, 6, 11, 0, 95, 6, 11, 0, 96, 6, 11, 0, 97, 6,228, 0, 98, 6, 2, 0, 99, 6, + 2, 0,100, 6, 2, 0,251, 0, 2, 0,206, 3, 4, 0,216, 3, 4, 0,101, 6, 14, 0,102, 6,208, 0,194, 5,210, 0,103, 6, +224, 0,104, 6,178, 0,182, 3,225, 0,105, 6,229, 0,106, 6, 10, 0, 7, 4, 10, 0,107, 6,230, 0, 14, 0,230, 0, 0, 0, +230, 0, 1, 0, 42, 0,242, 0, 40, 0, 69, 1,229, 0,106, 6,231, 0,108, 6, 7, 0, 97, 2, 7, 0, 98, 2, 7, 0,108, 0, + 7, 0,109, 6, 2, 0,110, 6, 2, 0, 18, 0, 2, 0,143, 0, 2, 0, 27, 0,232, 0, 39, 0, 7, 0,111, 6, 7, 0,112, 6, + 7, 0,113, 6, 7, 0,114, 6, 7, 0,115, 6, 7, 0,116, 6, 7, 0,117, 6, 7, 0,118, 6, 7, 0,119, 6, 68, 0,120, 6, +178, 0,182, 3,232, 0,121, 6,233, 0,122, 6,234, 0,123, 6,235, 0,124, 6,236, 0,125, 6,237, 0,126, 6, 7, 0,127, 6, + 7, 0,128, 6, 7, 0, 94, 1, 7, 0,129, 6, 7, 0,130, 6, 7, 0,131, 6, 7, 0,132, 6, 7, 0,175, 0, 7, 0,133, 6, + 0, 0,134, 6, 0, 0,135, 6, 0, 0,110, 6, 0, 0,136, 6, 2, 0,137, 6, 2, 0,138, 6, 7, 0,139, 6, 2, 0,140, 6, + 2, 0,141, 6, 7, 0,142, 6, 7, 0,143, 6, 7, 0,144, 6, 7, 0,145, 6,238, 0, 51, 0,239, 0, 0, 0,239, 0, 1, 0, + 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, 7, 0,128, 6, 7, 0, 94, 1, 7, 0,150, 6, 2, 0,151, 6, + 0, 0,211, 2, 4, 0,152, 6, 2, 0,135, 6, 2, 0,110, 6, 27, 0,208, 5, 27, 0,153, 6, 14, 0,154, 6,230, 0,155, 6, +238, 0,121, 6, 0, 0,156, 6, 4, 0,205, 3, 4, 0, 86, 6, 2, 0,157, 6, 2, 0,158, 6, 2, 0,159, 6, 2, 0,160, 6, + 2, 0, 18, 0, 2, 0, 32, 2, 7, 0,114, 0, 7, 0,161, 6, 7, 0,162, 6, 7, 0,163, 6, 7, 0,175, 0, 7, 0, 82, 6, + 2, 0,164, 6, 2, 0,165, 6, 2, 0,166, 6, 0, 0,167, 6, 0, 0,168, 6, 0, 0,169, 6, 0, 0,170, 6, 0, 0,171, 6, + 14, 0,172, 6, 14, 0,173, 6, 14, 0,174, 6, 2, 0,175, 6, 2, 0,152, 2, 2, 0,176, 6, 0, 0,177, 6, 11, 0,178, 6, +178, 0,182, 3,240, 0, 24, 0, 19, 0, 37, 0, 19, 0, 63, 0, 18, 0,179, 6, 18, 0,180, 6, 18, 0,181, 6, 7, 0,182, 6, + 7, 0,183, 6, 7, 0,184, 6, 7, 0,185, 6, 2, 0,186, 6, 2, 0,187, 6, 2, 0,188, 6, 2, 0,189, 6, 2, 0,190, 6, + 2, 0, 18, 0, 2, 0,191, 6, 2, 0,192, 6, 2, 0,193, 6, 2, 0,194, 6, 2, 0,195, 6, 2, 0,160, 6, 7, 0,196, 6, + 4, 0,197, 6, 4, 0,198, 6,239, 0, 6, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, + 2, 0,149, 6,241, 0, 8, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, + 0, 0,199, 6, 0, 0,124, 0,242, 0, 14, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, + 2, 0,149, 6,240, 0,200, 6,243, 0,201, 6, 14, 0,202, 6, 2, 0, 87, 1, 2, 0,203, 6, 4, 0, 18, 0, 7, 0,204, 6, + 4, 0,160, 6,244, 0, 21, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, +240, 0,200, 6, 2, 0,205, 6, 2, 0,206, 6, 2, 0,207, 6, 2, 0,208, 6, 2, 0,191, 6, 2, 0,209, 6, 2, 0,210, 6, + 0, 0, 18, 0, 0, 0, 27, 0, 11, 0, 73, 2, 4, 0,211, 6, 4, 0,212, 6, 22, 0,213, 6, 11, 0,214, 6,245, 0, 18, 0, +239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6,240, 0,200, 6, 7, 0, 97, 2, + 7, 0, 98, 2, 2, 0,205, 6, 2, 0,215, 6, 2, 0,216, 6, 2, 0,217, 6, 4, 0, 18, 0, 7, 0,218, 6, 4, 0,110, 6, + 4, 0, 27, 0,178, 0,182, 3,246, 0, 16, 0, 0, 0,219, 6, 0, 0,220, 6, 0, 0,221, 6, 0, 0,222, 6, 0, 0,223, 6, + 0, 0,224, 6, 4, 0,225, 6, 4, 0,226, 6, 4, 0,227, 6, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0,228, 6, 2, 0,229, 6, + 2, 0,190, 1, 2, 0,230, 6, 0, 0,231, 6,247, 0, 16, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, + 4, 0,232, 6,246, 0,233, 6,248, 0,234, 6, 14, 0,235, 6, 14, 0,236, 6,249, 0,237, 6,237, 0,238, 6,250, 0,239, 6, + 2, 0,240, 6, 2, 0,241, 6, 2, 0,242, 6, 2, 0, 30, 0,251, 0, 15, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, + 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6,240, 0,200, 6, 14, 0,243, 6,252, 0,244, 6, 0, 0,245, 6,253, 0,246, 6, + 2, 0, 18, 0, 2, 0,247, 6, 2, 0,248, 6, 2, 0,249, 6,254, 0, 25, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, + 4, 0,147, 6, 4, 0, 18, 0, 42, 0,244, 2, 40, 0, 69, 1, 54, 0,250, 6,255, 0,251, 6, 0, 1,252, 6,178, 0,182, 3, + 7, 0,253, 6, 7, 0, 97, 2, 7, 0, 98, 2, 7, 0,218, 6, 7, 0,254, 6, 7, 0,255, 6, 2, 0, 0, 7, 2, 0, 27, 0, + 2, 0, 1, 7, 2, 0, 2, 7, 0, 0, 3, 7, 0, 0, 4, 7, 0, 0, 5, 7, 0, 0,160, 6, 1, 1, 11, 0,239, 0, 0, 0, +239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, 2, 0,203, 6, 2, 0, 18, 0, 4, 0, 27, 0, +243, 0,201, 6,240, 0,200, 6, 2, 1, 31, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, + 2, 0,149, 6, 37, 0, 6, 7, 4, 0, 7, 7, 4, 0, 8, 7, 2, 0, 92, 0, 2, 0, 9, 7, 2, 0, 10, 7, 0, 0, 11, 7, + 0, 0, 12, 7, 4, 0, 13, 7, 4, 0, 14, 7, 4, 0, 15, 7, 2, 0, 16, 7, 2, 0, 17, 7, 2, 0, 18, 7, 2, 0, 19, 7, + 7, 0, 20, 7, 18, 0, 21, 7, 18, 0, 22, 7, 4, 0, 23, 7, 4, 0, 24, 7, 0, 0, 25, 7, 0, 0, 26, 7, 2, 0, 27, 7, + 0, 0,211, 2, 11, 0, 28, 7, 3, 1, 10, 0, 22, 0, 32, 0, 11, 0, 29, 7, 11, 0, 30, 7, 11, 0, 31, 7, 11, 0, 32, 7, + 11, 0, 33, 7, 4, 0, 92, 0, 4, 0, 34, 7, 0, 0, 35, 7, 0, 0, 36, 7, 4, 1, 10, 0,239, 0, 0, 0,239, 0, 1, 0, + 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 3, 1, 37, 7, 2, 0, 92, 0, 2, 0, 9, 7, 4, 0, 67, 0, 11, 0, 38, 7, + 5, 1, 3, 0, 5, 1, 0, 0, 5, 1, 1, 0, 7, 0, 39, 7, 6, 1, 9, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, + 4, 0,147, 6, 7, 0,148, 6,240, 0,200, 6, 14, 0, 40, 7, 4, 0, 41, 7, 4, 0, 18, 0, 7, 1, 27, 0,239, 0, 0, 0, +239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6,240, 0,200, 6, 22, 0, 42, 7, 22, 0, 81, 0, + 2, 0, 18, 0, 2, 0, 67, 0, 7, 0, 43, 7, 7, 0, 97, 2, 7, 0, 98, 2, 7, 0,218, 6, 7, 0, 44, 7, 7, 0, 45, 7, + 7, 0, 46, 7, 57, 0, 70, 1, 57, 0, 47, 7, 4, 0, 48, 7, 2, 0, 49, 7, 2, 0, 50, 7, 2, 0,251, 0, 2, 0, 86, 1, + 14, 0, 51, 7,178, 0,182, 3, 8, 1, 10, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, + 2, 0,149, 6, 2, 0, 18, 0, 2, 0,214, 3, 4, 0, 27, 0,178, 0,182, 3, 9, 1, 7, 0, 9, 1, 0, 0, 9, 1, 1, 0, + 4, 0, 52, 7, 4, 0, 22, 0, 0, 0, 86, 0, 4, 0, 53, 7, 4, 0, 16, 0, 10, 1, 14, 0,239, 0, 0, 0,239, 0, 1, 0, + 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, 4, 0, 10, 7, 4, 0, 27, 0, 14, 0, 54, 7, 14, 0, 55, 7, + 0, 0, 56, 7, 0, 0, 57, 7, 4, 0, 58, 7, 4, 0, 59, 7, 11, 1, 6, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, + 4, 0,147, 6, 4, 0, 27, 0, 0, 0, 60, 7, 12, 1, 25, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, + 7, 0, 97, 2, 7, 0, 98, 2, 7, 0, 61, 7, 7, 0, 62, 7, 7, 0,218, 6,231, 0, 63, 7,229, 0,106, 6, 13, 1,251, 6, + 4, 0, 18, 0, 2, 0, 87, 1, 2, 0,110, 6, 4, 0, 64, 7, 7, 0, 65, 7, 7, 0,148, 3, 7, 0, 94, 3, 4, 0, 27, 0, + 7, 0, 66, 7, 7, 0, 67, 7, 4, 0, 68, 7, 4, 0, 30, 0, 11, 0, 69, 7, 14, 1, 7, 0, 14, 1, 0, 0, 14, 1, 1, 0, + 0, 0, 70, 7, 2, 0, 71, 7, 2, 0, 72, 7, 2, 0, 73, 7, 2, 0, 27, 0, 15, 1, 12, 0, 2, 0, 72, 7, 2, 0, 74, 7, + 2, 0, 75, 7, 0, 0,211, 2, 2, 0, 76, 7, 2, 0, 77, 7, 2, 0, 78, 7, 2, 0, 79, 7, 2, 0, 80, 7, 2, 0,191, 6, + 7, 0, 81, 7, 7, 0, 82, 7, 16, 1, 18, 0, 16, 1, 0, 0, 16, 1, 1, 0, 0, 0, 19, 0, 15, 1, 83, 7, 15, 1, 84, 7, + 15, 1, 85, 7, 15, 1, 86, 7, 7, 0, 87, 7, 2, 0, 88, 7, 2, 0, 89, 7, 2, 0, 90, 7, 2, 0, 91, 7, 2, 0, 92, 7, + 2, 0, 93, 7, 2, 0, 94, 7, 2, 0, 95, 7, 2, 0, 96, 7, 2, 0, 27, 0, 17, 1, 10, 0, 0, 0, 97, 7, 0, 0, 98, 7, + 0, 0, 99, 7, 0, 0,100, 7, 0, 0,101, 7, 0, 0,102, 7, 2, 0,103, 7, 2, 0,104, 7, 2, 0,105, 7, 2, 0,106, 7, + 18, 1, 8, 0, 0, 0,107, 7, 0, 0,108, 7, 0, 0,109, 7, 0, 0,110, 7, 0, 0,111, 7, 0, 0,112, 7, 7, 0,109, 6, + 7, 0, 27, 0, 19, 1, 3, 0, 0, 0,113, 7, 2, 0,114, 7, 2, 0, 27, 0, 20, 1, 22, 0, 17, 1,115, 7, 17, 1,116, 7, + 17, 1,117, 7, 17, 1,118, 7, 17, 1,119, 7, 17, 1,120, 7, 17, 1,121, 7, 17, 1,122, 7, 17, 1,123, 7, 17, 1,124, 7, + 17, 1,125, 7, 17, 1,126, 7, 17, 1,127, 7, 17, 1,128, 7, 17, 1,129, 7, 17, 1,130, 7, 17, 1,131, 7, 18, 1,132, 7, + 19, 1,133, 7, 0, 0,134, 7, 7, 0,135, 7, 7, 0, 27, 0, 21, 1,122, 0, 0, 0,136, 7, 0, 0,137, 7, 0, 0,101, 7, + 0, 0,138, 7, 0, 0,113, 7, 0, 0,139, 7, 0, 0,140, 7, 0, 0,141, 7, 0, 0,142, 7, 0, 0,143, 7, 0, 0,144, 7, + 0, 0,145, 7, 0, 0,146, 7, 0, 0,147, 7, 0, 0,148, 7, 0, 0,149, 7, 0, 0,150, 7, 0, 0,151, 7, 0, 0,152, 7, + 0, 0,153, 7, 0, 0,154, 7, 0, 0,155, 7, 0, 0,156, 7, 0, 0,157, 7, 0, 0,158, 7, 0, 0,159, 7, 0, 0,160, 7, + 0, 0,161, 7, 0, 0,162, 7, 0, 0,163, 7, 0, 0,164, 7, 0, 0,165, 7, 0, 0,166, 7, 0, 0,167, 7, 0, 0,168, 7, + 0, 0,169, 7, 0, 0,170, 7, 0, 0,171, 7, 0, 0,172, 7, 0, 0,173, 7, 0, 0,174, 7, 0, 0,175, 7, 0, 0,176, 7, + 0, 0,177, 7, 0, 0,178, 7, 0, 0,179, 7, 0, 0,180, 7, 0, 0,181, 7, 0, 0,182, 7, 0, 0,183, 7, 0, 0,184, 7, + 0, 0,185, 7, 0, 0,186, 7, 0, 0,187, 7, 0, 0,188, 7, 0, 0,189, 7, 0, 0,190, 7, 0, 0,191, 7, 0, 0,192, 7, + 0, 0,193, 7, 0, 0,194, 7, 0, 0,195, 7, 0, 0,196, 7, 0, 0,197, 7, 0, 0,198, 7, 0, 0,199, 7, 0, 0,200, 7, + 0, 0,201, 7, 0, 0,202, 7, 0, 0,203, 7, 0, 0,204, 7, 0, 0,205, 7, 0, 0,206, 7, 0, 0,207, 7, 0, 0,208, 7, + 0, 0,209, 7, 0, 0,210, 7, 0, 0,211, 7, 0, 0,212, 7, 0, 0,213, 7, 0, 0,214, 7, 0, 0,215, 7, 0, 0,216, 7, + 0, 0,217, 7, 0, 0,218, 7, 0, 0,219, 7, 0, 0,220, 7, 0, 0,221, 7, 0, 0,222, 7, 0, 0,223, 7, 0, 0,224, 7, + 0, 0,225, 7, 0, 0,226, 7, 0, 0,227, 7, 0, 0,228, 7, 0, 0,229, 7, 0, 0,230, 7, 0, 0,231, 7, 0, 0,232, 7, + 0, 0,233, 7, 0, 0,234, 7, 0, 0,235, 7, 0, 0,236, 7, 0, 0,237, 7, 0, 0,238, 7, 0, 0,239, 7, 0, 0,240, 7, + 0, 0,241, 7, 0, 0,242, 7, 0, 0,243, 7, 0, 0,244, 7, 0, 0,245, 7, 0, 0,246, 7, 0, 0,247, 7, 0, 0,248, 7, + 0, 0,249, 7, 0, 0,250, 7, 0, 0,251, 7, 0, 0,252, 7, 0, 0,253, 7, 0, 0,254, 7, 0, 0,255, 7, 22, 1, 5, 0, + 0, 0, 0, 8, 0, 0,159, 7, 0, 0,165, 7, 2, 0, 18, 0, 2, 0, 27, 0, 23, 1, 24, 0, 23, 1, 0, 0, 23, 1, 1, 0, + 0, 0,172, 5, 20, 1, 1, 8, 21, 1, 2, 8, 21, 1, 3, 8, 21, 1, 4, 8, 21, 1, 5, 8, 21, 1, 6, 8, 21, 1, 7, 8, + 21, 1, 8, 8, 21, 1, 9, 8, 21, 1, 10, 8, 21, 1, 11, 8, 21, 1, 12, 8, 21, 1, 13, 8, 21, 1, 14, 8, 21, 1, 15, 8, + 21, 1, 16, 8, 21, 1, 17, 8, 21, 1, 18, 8, 22, 1, 19, 8, 4, 0, 20, 8, 4, 0, 27, 0, 24, 1, 3, 0, 24, 1, 0, 0, + 24, 1, 1, 0, 0, 0, 21, 8, 25, 1, 5, 0, 4, 0, 18, 0, 4, 0, 27, 0, 7, 0,151, 2, 7, 0, 22, 8, 7, 0, 47, 2, + 26, 1, 95, 0, 4, 0, 18, 0, 4, 0, 23, 8, 4, 0, 24, 8, 0, 0, 25, 8, 0, 0, 26, 8, 0, 0, 27, 8, 0, 0, 28, 8, + 0, 0, 29, 8, 0, 0, 30, 8, 0, 0, 31, 8, 0, 0, 32, 8, 0, 0, 33, 8, 0, 0, 34, 8, 4, 0, 35, 8, 2, 0, 36, 8, + 2, 0, 37, 8, 2, 0, 38, 8, 2, 0, 39, 8, 4, 0, 40, 8, 4, 0, 41, 8, 4, 0, 42, 8, 4, 0, 43, 8, 2, 0, 44, 8, + 2, 0, 45, 8, 4, 0, 46, 8, 4, 0, 47, 8, 4, 0, 48, 8, 4, 0, 49, 8, 4, 0, 50, 8, 4, 0, 54, 7, 4, 0, 51, 8, + 2, 0, 52, 8, 2, 0, 53, 8, 2, 0, 54, 8, 2, 0, 55, 8, 14, 0, 56, 8, 14, 0, 57, 8, 14, 0, 58, 8, 14, 0, 59, 8, + 14, 0, 60, 8, 14, 0, 61, 8, 0, 0, 62, 8, 2, 0, 63, 8, 2, 0, 64, 8, 2, 0, 65, 8, 2, 0, 66, 8, 2, 0, 67, 8, + 2, 0, 68, 8, 2, 0, 69, 8, 2, 0, 70, 8, 25, 1, 71, 8, 2, 0, 72, 8, 2, 0, 73, 8, 2, 0, 74, 8, 2, 0, 75, 8, + 2, 0, 76, 8, 2, 0, 77, 8, 2, 0, 78, 8, 2, 0, 79, 8, 4, 0, 80, 8, 4, 0, 81, 8, 2, 0, 82, 8, 2, 0, 83, 8, + 2, 0, 84, 8, 2, 0, 85, 8, 2, 0, 86, 8, 2, 0, 87, 8, 2, 0, 88, 8, 2, 0, 89, 8, 2, 0, 90, 8, 2, 0, 91, 8, + 2, 0, 92, 8, 2, 0, 93, 8, 2, 0, 94, 8, 2, 0, 95, 8, 2, 0, 96, 8, 2, 0, 97, 8, 2, 0, 98, 8, 2, 0, 99, 8, + 7, 0,100, 8, 4, 0,101, 8, 7, 0,102, 8, 2, 0, 18, 6, 2, 0, 19, 6, 2, 0,103, 8, 2, 0,104, 8, 50, 0,105, 8, + 7, 0,106, 8, 2, 0,107, 8, 2, 0,247, 1, 0, 0,108, 8, 4, 0,109, 8, 4, 0,110, 8, 7, 0,111, 8, 7, 0, 27, 0, + 27, 1, 24, 0, 22, 0, 32, 0, 14, 0,112, 8, 14, 0,113, 8, 14, 0,114, 8, 14, 0,146, 6, 41, 0,125, 0, 41, 0,115, 8, + 4, 0,116, 8, 4, 0, 67, 0, 2, 0,117, 8, 2, 0,118, 8, 2, 0,119, 8, 2, 0,120, 8, 2, 0,121, 8, 2, 0,122, 8, + 2, 0,123, 8, 2, 0,124, 8, 2, 0,125, 8, 2, 0,126, 8, 2, 0,127, 8, 2, 0, 27, 0,237, 0,128, 8, 11, 0,129, 8, + 2, 0,130, 8, 28, 1, 5, 0, 28, 1, 0, 0, 28, 1, 1, 0, 28, 1,131, 8, 15, 0,132, 8, 4, 0, 18, 0, 29, 1, 7, 0, + 29, 1, 0, 0, 29, 1, 1, 0, 28, 1,133, 8, 28, 1,134, 8, 2, 0,121, 5, 2, 0, 18, 0, 4, 0, 27, 0, 30, 1, 25, 0, + 30, 1, 0, 0, 30, 1, 1, 0, 31, 1,135, 8, 32, 1,239, 6, 0, 0,136, 8, 0, 0,137, 8, 0, 0,138, 8, 2, 0,139, 8, + 2, 0,140, 8, 2, 0,141, 8, 2, 0,142, 8, 2, 0,143, 8, 2, 0, 27, 0, 2, 0, 18, 0, 2, 0,144, 8, 2, 0,145, 8, + 2, 0,146, 8, 4, 0,147, 8, 30, 1,148, 8, 11, 0,149, 8, 4, 0,150, 8, 4, 0,151, 8, 4, 0,152, 8, 4, 0,153, 8, + 0, 0,154, 8, 33, 1, 22, 0, 33, 1, 0, 0, 33, 1, 1, 0, 28, 1,133, 8, 28, 1,134, 8, 28, 1,155, 8, 28, 1,156, 8, + 27, 1,157, 8, 18, 0, 51, 0, 0, 0,147, 6, 0, 0,158, 8, 2, 0,192, 6, 2, 0,193, 6, 2, 0,159, 8, 2, 0, 27, 0, + 2, 0,121, 8, 2, 0, 53, 7, 2, 0, 18, 0, 34, 1,135, 8, 14, 0,160, 8, 14, 0,146, 6, 14, 0,161, 8, 14, 0,162, 8, + 35, 1, 24, 0, 35, 1, 0, 0, 35, 1, 1, 0,240, 0,200, 6, 18, 0,163, 8, 18, 0,164, 8, 2, 0,192, 6, 2, 0,193, 6, + 2, 0,165, 8, 2, 0,166, 8, 2, 0,167, 8, 2, 0, 18, 0, 7, 0, 93, 2, 2, 0,141, 8, 2, 0,142, 8, 2, 0,120, 8, + 2, 0,168, 8, 2, 0,125, 8, 2, 0, 86, 1, 36, 1,135, 8, 14, 0,169, 8, 14, 0,170, 8, 14, 0,161, 8, 0, 0,171, 8, + 11, 0,172, 8, 37, 1, 14, 0, 0, 0,173, 8, 2, 0,174, 8, 2, 0,175, 8, 2, 0,176, 8, 2, 0,177, 8, 2, 0,110, 5, + 2, 0,178, 8, 27, 1,179, 8, 41, 0,180, 8, 4, 0,181, 8, 4, 0,182, 8, 4, 0,183, 8, 4, 0, 27, 0, 0, 0, 70, 7, + 38, 1, 3, 0, 0, 0,184, 8, 4, 0,185, 8, 4, 0,186, 8, 39, 1, 4, 0, 4, 0, 7, 7, 4, 0,187, 8, 4, 0, 13, 7, + 4, 0,188, 8, 40, 1, 2, 0, 4, 0,189, 8, 4, 0,190, 8, 41, 1, 5, 0, 7, 0,191, 8, 7, 0,192, 8, 7, 0,193, 8, + 4, 0, 18, 0, 4, 0, 27, 0, 42, 1, 7, 0, 0, 0,194, 8, 0, 0,221, 6, 44, 0,138, 0, 2, 0,195, 8, 2, 0, 72, 5, + 2, 0,196, 8, 2, 0,197, 8, 43, 1, 12, 0, 43, 1, 0, 0, 43, 1, 1, 0, 4, 0, 28, 0, 4, 0,198, 8, 4, 0,199, 8, + 4, 0,200, 8, 38, 1,201, 8, 0, 0,194, 8, 42, 1,176, 3, 39, 1,202, 8, 40, 1,203, 8, 41, 1,204, 8, 44, 1, 12, 0, + 0, 0, 35, 0, 11, 0,227, 0, 0, 0,228, 0, 4, 0,231, 0, 4, 0,239, 0, 11, 0,232, 0, 7, 0,234, 0, 7, 0,235, 0, + 11, 0,205, 8, 11, 0,206, 8, 11, 0,236, 0, 11, 0,238, 0, 45, 1, 50, 0, 45, 1, 0, 0, 45, 1, 1, 0, 11, 0,207, 8, + 11, 0, 25, 0, 0, 0, 19, 0, 4, 0, 18, 0, 4, 0, 16, 0, 4, 0, 22, 0, 4, 0, 90, 0, 4, 0,208, 8, 4, 0,209, 8, + 4, 0,199, 8, 4, 0,200, 8, 4, 0,210, 8, 4, 0,250, 0, 4, 0,211, 8, 4, 0,212, 8, 7, 0,213, 8, 7, 0,214, 8, + 7, 0,215, 8, 2, 0,216, 8, 2, 0,217, 8, 4, 0,218, 8, 4, 0,219, 8, 43, 1,220, 8, 31, 0, 80, 0, 41, 0,125, 0, + 27, 0,221, 8, 44, 0,138, 0,229, 0,106, 6, 7, 0,222, 8, 7, 0,223, 8, 44, 1, 71, 1, 45, 1,224, 8, 45, 1,225, 8, + 45, 1,226, 8, 14, 0,227, 8, 46, 1,228, 8, 11, 0,229, 8, 7, 0, 84, 4, 7, 0,230, 8, 7, 0,231, 8, 7, 0,232, 8, + 11, 0,233, 8, 4, 0,234, 8, 4, 0,235, 8, 4, 0,236, 8, 7, 0,237, 8, 4, 0,129, 0, 4, 0, 27, 0, 47, 1, 4, 0, + 47, 1, 0, 0, 47, 1, 1, 0, 14, 0,238, 8, 45, 1,239, 8,226, 0, 11, 0, 14, 0,240, 8, 14, 0,227, 8, 14, 0,241, 8, + 45, 1,242, 8, 0, 0,243, 8, 0, 0,244, 8, 4, 0,245, 8, 4, 0,246, 8, 4, 0,247, 8, 4, 0, 27, 0, 19, 0,248, 8, + 48, 1, 4, 0, 7, 0,249, 8, 7, 0, 94, 3, 2, 0,250, 8, 2, 0,251, 8, 49, 1, 6, 0, 7, 0,252, 8, 7, 0,253, 8, + 7, 0,254, 8, 7, 0,255, 8, 4, 0, 0, 9, 4, 0, 1, 9, 50, 1, 8, 0, 7, 0, 2, 9, 7, 0, 3, 9, 7, 0, 4, 9, + 7, 0, 5, 9, 7, 0, 6, 9, 4, 0,250, 2, 4, 0, 7, 9, 4, 0, 8, 9, 51, 1, 2, 0, 7, 0,180, 5, 7, 0, 27, 0, + 52, 1, 5, 0, 7, 0, 9, 9, 7, 0, 10, 9, 4, 0, 92, 0, 4, 0,212, 2, 4, 0, 11, 9, 53, 1, 6, 0, 53, 1, 0, 0, + 53, 1, 1, 0, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 12, 9, 2, 0, 56, 0, 54, 1, 8, 0, 54, 1, 0, 0, 54, 1, 1, 0, + 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 12, 9, 2, 0, 56, 0, 7, 0, 22, 0, 7, 0,129, 0, 55, 1, 45, 0, 55, 1, 0, 0, + 55, 1, 1, 0, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 12, 9, 2, 0,246, 0, 2, 0,126, 4, 2, 0, 13, 9, 7, 0, 14, 9, + 7, 0, 91, 0, 7, 0, 7, 3, 4, 0, 15, 9, 4, 0, 82, 0, 4, 0,214, 2, 7, 0, 16, 9, 7, 0, 17, 9, 7, 0, 18, 9, + 7, 0, 19, 9, 7, 0, 20, 9, 7, 0, 21, 9, 7, 0, 4, 3, 7, 0, 68, 1, 7, 0, 22, 9, 7, 0, 23, 9, 7, 0, 27, 0, + 7, 0, 24, 9, 7, 0, 25, 9, 7, 0, 26, 9, 2, 0, 27, 9, 2, 0, 28, 9, 2, 0, 29, 9, 2, 0, 30, 9, 2, 0, 31, 9, + 2, 0, 32, 9, 2, 0, 33, 9, 2, 0, 34, 9, 2, 0, 32, 2, 2, 0, 35, 9, 2, 0, 29, 2, 2, 0, 36, 9, 0, 0, 37, 9, + 0, 0, 38, 9, 7, 0,244, 0, 56, 1, 39, 9, 64, 0,250, 1, 57, 1, 16, 0, 57, 1, 0, 0, 57, 1, 1, 0, 2, 0, 16, 0, + 2, 0, 18, 0, 2, 0, 12, 9, 2, 0,246, 0, 7, 0,255, 2, 7, 0, 0, 3, 7, 0, 1, 3, 7, 0, 82, 2, 7, 0, 2, 3, + 7, 0, 3, 3, 7, 0, 40, 9, 7, 0, 4, 3, 7, 0, 6, 3, 7, 0, 7, 3,253, 0, 5, 0, 2, 0, 16, 0, 2, 0, 41, 9, + 2, 0, 18, 0, 2, 0, 42, 9, 22, 0, 42, 7,252, 0, 3, 0, 4, 0, 69, 0, 4, 0, 43, 9,253, 0, 2, 0, 58, 1, 7, 0, + 58, 1, 0, 0, 58, 1, 1, 0, 0, 0, 19, 0, 2, 0, 16, 0, 2, 0, 18, 0, 4, 0, 21, 0, 11, 0, 44, 9, 59, 1, 5, 0, + 0, 0, 19, 0, 7, 0, 94, 1, 7, 0, 45, 9, 4, 0, 46, 9, 4, 0, 27, 0, 60, 1, 4, 0, 2, 0, 16, 0, 2, 0, 18, 0, + 2, 0, 67, 0, 2, 0, 30, 0, 61, 1, 4, 0, 0, 0, 19, 0, 63, 0, 47, 9, 7, 0, 94, 1, 7, 0, 27, 0, 62, 1, 6, 0, + 2, 0, 48, 9, 2, 0, 49, 9, 2, 0, 16, 0, 2, 0, 50, 9, 0, 0, 51, 9, 0, 0, 52, 9, 63, 1, 5, 0, 4, 0, 16, 0, + 4, 0, 27, 0, 0, 0, 19, 0, 0, 0, 53, 9, 0, 0, 54, 9, 64, 1, 3, 0, 4, 0, 16, 0, 4, 0, 27, 0, 0, 0, 19, 0, + 65, 1, 4, 0, 2, 0, 55, 9, 2, 0, 56, 9, 2, 0, 18, 0, 2, 0, 27, 0, 66, 1, 6, 0, 0, 0, 19, 0, 0, 0, 57, 9, + 2, 0, 58, 9, 2, 0, 4, 3, 2, 0, 87, 1, 2, 0, 30, 0, 67, 1, 5, 0, 0, 0, 19, 0, 7, 0, 94, 3, 7, 0,217, 4, + 2, 0, 18, 0, 2, 0,226, 2, 68, 1, 3, 0, 0, 0, 19, 0, 4, 0,214, 2, 4, 0, 55, 9, 69, 1, 7, 0, 0, 0, 19, 0, + 7, 0,217, 4, 0, 0, 59, 9, 0, 0, 60, 9, 2, 0, 87, 1, 2, 0, 67, 0, 4, 0, 61, 9, 70, 1, 4, 0, 0, 0, 62, 9, + 0, 0, 63, 9, 4, 0, 16, 0, 7, 0,230, 2, 71, 1, 3, 0, 27, 0, 64, 9, 0, 0, 65, 9, 0, 0, 66, 9, 72, 1, 18, 0, + 72, 1, 0, 0, 72, 1, 1, 0, 2, 0, 16, 0, 2, 0, 67, 9, 2, 0, 18, 0, 2, 0, 68, 9, 2, 0, 69, 9, 2, 0, 70, 9, + 2, 0, 67, 0, 2, 0, 30, 0, 0, 0, 19, 0, 11, 0, 2, 0, 73, 1, 71, 9, 27, 0, 44, 0, 2, 0,216, 5, 2, 0,176, 2, + 2, 0, 72, 9, 2, 0, 27, 0, 74, 1, 11, 0, 0, 0, 19, 0, 0, 0, 16, 0, 0, 0, 73, 9, 2, 0, 18, 0, 2, 0,226, 2, + 2, 0, 74, 9, 4, 0, 75, 9, 4, 0, 76, 9, 4, 0, 77, 9, 4, 0, 78, 9, 4, 0, 79, 9, 75, 1, 1, 0, 0, 0, 80, 9, 76, 1, 4, 0, 37, 0, 6, 7, 0, 0, 21, 8, 4, 0, 87, 1, 4, 0, 18, 0, 73, 1, 18, 0, 73, 1, 0, 0, 73, 1, 1, 0, - 73, 1, 80, 9, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 81, 9, 2, 0, 69, 9, 2, 0, 66, 9, 2, 0, 82, 9, 2, 0, 30, 0, - 2, 0, 74, 0, 0, 0, 19, 0, 11, 0, 2, 0, 77, 1, 70, 9, 72, 1, 83, 9, 2, 0, 14, 0, 2, 0, 84, 9, 4, 0, 85, 9, - 78, 1, 3, 0, 4, 0,240, 2, 4, 0, 27, 0, 27, 0, 44, 0, 79, 1, 15, 0,176, 0, 86, 9, 2, 0, 16, 0, 2, 0, 18, 0, - 7, 0, 13, 9, 7, 0, 90, 0, 0, 0, 19, 0, 0, 0, 87, 9, 2, 0, 88, 9, 2, 0, 89, 9, 2, 0,134, 0, 2, 0, 90, 9, - 2, 0, 91, 9, 2, 0, 27, 0, 7, 0, 92, 9, 7, 0, 93, 9, 80, 1, 8, 0, 7, 0, 94, 9, 7, 0, 95, 9, 7, 0, 96, 9, - 7, 0, 97, 9, 7, 0, 98, 9, 7, 0, 99, 9, 7, 0,100, 9, 7, 0,101, 9, 81, 1, 13, 0, 2, 0, 18, 0, 2, 0,102, 9, - 4, 0, 91, 0, 4, 0, 30, 0, 2, 0,177, 6, 7, 0, 84, 4, 7, 0,229, 8, 46, 1,227, 8, 80, 1,103, 9, 2, 0, 16, 0, - 2, 0,115, 5, 2, 0,216, 3, 2, 0,104, 9, 82, 1, 11, 0, 4, 0,240, 2, 2, 0, 16, 0, 2, 0, 18, 0, 27, 0, 44, 0, - 79, 0,105, 9, 0, 0, 19, 0, 7, 0,106, 9, 7, 0,107, 9, 7, 0,222, 3, 2, 0,108, 9, 2, 0,109, 9, 83, 1, 5, 0, - 2, 0, 16, 0, 2, 0, 91, 0, 4, 0, 27, 0, 41, 0,125, 0, 27, 0,208, 5, 84, 1, 5, 0, 4, 0, 27, 0, 4, 0, 16, 0, - 0, 0, 19, 0, 0, 0, 52, 9, 27, 0, 44, 0, 85, 1, 13, 0, 2, 0, 18, 0, 2, 0, 16, 0, 2, 0, 66, 9, 2, 0,223, 3, - 7, 0,110, 9, 7, 0,111, 9, 7, 0, 86, 1, 7, 0,112, 9, 7, 0,192, 3, 7, 0,196, 3, 7, 0,113, 9, 7, 0,114, 9, - 27, 0,115, 9, 86, 1, 10, 0, 2, 0, 18, 0, 2, 0, 16, 0, 7, 0, 13, 9, 7, 0, 90, 0, 0, 0, 19, 0, 0, 0, 87, 9, - 2, 0, 91, 0, 2, 0, 30, 0, 2, 0, 74, 0, 2, 0,115, 5, 87, 1, 8, 0, 27, 0, 44, 0, 7, 0, 1, 3, 7, 0,116, 9, - 7, 0,117, 9, 7, 0,223, 3, 2, 0, 91, 0, 2, 0,226, 2, 7, 0, 30, 0, 88, 1, 12, 0, 2, 0, 16, 0, 2, 0, 87, 1, - 2, 0, 18, 0, 2, 0, 4, 3, 2, 0,240, 2, 2, 0,118, 9, 4, 0, 27, 0, 7, 0,119, 9, 7, 0,120, 9, 7, 0,121, 9, - 7, 0,122, 9, 0, 0,123, 9, 89, 1, 9, 0, 2, 0, 18, 0, 2, 0, 16, 0, 4, 0, 13, 9, 4, 0, 90, 0, 0, 0, 19, 0, - 2, 0, 86, 1, 2, 0, 63, 0, 2, 0,124, 9, 2, 0,125, 9, 90, 1, 7, 0, 4, 0,214, 2, 4, 0,126, 9, 4, 0,127, 9, - 4, 0,128, 9, 7, 0,129, 9, 7, 0,130, 9, 0, 0, 58, 9, 91, 1, 7, 0, 0, 0,131, 9, 27, 0,132, 9, 0, 0, 64, 9, - 2, 0,133, 9, 2, 0, 91, 0, 4, 0, 30, 0, 0, 0, 65, 9, 92, 1, 6, 0, 2, 0, 18, 0, 2, 0, 16, 0, 4, 0, 13, 9, - 4, 0, 90, 0, 0, 0,134, 9, 0, 0,135, 9, 93, 1, 1, 0, 4, 0, 18, 0, 94, 1, 6, 0, 0, 0, 94, 0, 2, 0, 16, 0, - 2, 0, 18, 0, 4, 0,136, 9, 7, 0,137, 9, 37, 0, 6, 7, 95, 1, 4, 0, 0, 0,181, 2, 2, 0, 18, 0, 4, 0, 16, 0, - 27, 0, 44, 0, 96, 1, 2, 0, 4, 0, 16, 0, 4, 0,181, 6, 97, 1, 8, 0, 0, 0, 61, 9, 0, 0, 62, 9, 4, 0, 16, 0, - 7, 0, 39, 2, 7, 0,138, 9, 7, 0, 27, 0, 27, 0, 70, 3, 27, 0,139, 9, 98, 1, 11, 0, 0, 0, 54, 6, 0, 0, 18, 0, - 2, 0,140, 9, 4, 0, 16, 0, 7, 0, 94, 1, 7, 0,141, 9, 7, 0,142, 9, 7, 0,143, 9, 4, 0,144, 9, 27, 0, 70, 3, - 27, 0,145, 9, 77, 1, 10, 0, 77, 1, 0, 0, 77, 1, 1, 0, 77, 1, 80, 9, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 66, 9, - 2, 0,146, 9, 0, 0, 19, 0, 11, 0, 2, 0, 27, 0, 44, 0, 46, 1, 17, 0, 22, 0, 32, 0, 0, 0, 35, 0, 38, 0,153, 0, - 11, 0,227, 0, 38, 0,147, 9, 31, 0, 80, 0, 7, 0, 84, 4, 7, 0,148, 9, 7, 0,229, 8, 7, 0, 94, 9, 7, 0, 95, 9, - 7, 0,149, 9, 4, 0, 92, 0, 4, 0, 27, 0, 11, 0,150, 9, 11, 0,151, 9, 11, 0,152, 9, 99, 1, 6, 0, 99, 1, 0, 0, - 99, 1, 1, 0, 27, 0, 44, 0, 11, 0,153, 9, 2, 0,251, 0, 0, 0,211, 2, 64, 0, 4, 0, 22, 0, 32, 0, 14, 0,154, 9, - 4, 0,134, 0, 7, 0,155, 9,100, 1, 28, 0,100, 1, 0, 0,100, 1, 1, 0, 21, 0,156, 9,100, 1, 38, 0, 14, 0,157, 9, - 0, 0, 19, 0, 7, 0,158, 9, 7, 0,159, 9, 7, 0,160, 9, 7, 0,161, 9, 4, 0, 18, 0, 7, 0,162, 9, 7, 0,163, 9, - 7, 0,164, 9, 7, 0,165, 9, 7, 0, 94, 1, 7, 0, 39, 2, 7, 0,166, 9, 7, 0,212, 2, 7, 0,167, 9, 7, 0,168, 9, - 7, 0,169, 9, 7, 0,170, 9, 7, 0,171, 9, 7, 0,176, 0, 4, 0,134, 0, 2, 0,254, 5, 2, 0,172, 9,101, 1, 27, 0, - 22, 0, 32, 0, 34, 0, 75, 0, 14, 0,173, 9, 14, 0,174, 9, 14, 0,175, 9,100, 1,176, 9, 11, 0,177, 9, 11, 0,178, 9, - 4, 0, 18, 0, 4, 0,157, 6, 4, 0,179, 9, 4, 0, 27, 0, 2, 0, 8, 3, 2, 0,211, 6, 4, 0,180, 9, 4, 0,134, 0, - 4, 0,181, 9, 2, 0,182, 9, 2, 0,183, 9, 2, 0,184, 9, 2, 0,185, 9, 4, 0,186, 9, 4, 0,187, 9, 4, 0,188, 9, - 4, 0,189, 9, 4, 0,190, 9, 4, 0,191, 9,102, 1, 2, 0, 7, 0,165, 2, 4, 0, 18, 0,180, 0, 5, 0,102, 1,192, 9, - 4, 0,212, 2, 4, 0,193, 9, 4, 0,194, 9, 4, 0, 18, 0,179, 0, 16, 0, 4, 0,195, 9, 4, 0,196, 9, 4, 0,197, 9, - 4, 0,198, 9, 2, 0,199, 9, 2, 0,200, 9, 2, 0,201, 9, 2, 0,251, 0, 2, 0,202, 9, 2, 0,203, 9, 2, 0,204, 9, - 2, 0,205, 9, 4, 0,206, 9, 4, 0,207, 9, 4, 0,208, 9, 4, 0,209, 9,103, 1, 40, 0,103, 1, 0, 0,103, 1, 1, 0, - 21, 0,156, 9, 14, 0,251, 3, 0, 0, 19, 0, 2, 0, 18, 0, 2, 0,210, 9, 2, 0,209, 3, 2, 0,211, 9, 0, 0,212, 9, - 0, 0,213, 9, 0, 0,214, 9,100, 1,215, 9,103, 1, 38, 0,103, 1,216, 9, 14, 0,217, 9, 14, 0,218, 9,180, 0,184, 3, - 27, 0,219, 9,103, 1,220, 9, 7, 0, 77, 1, 7, 0,176, 0, 7, 0,221, 9, 7, 0, 18, 2, 7, 0,198, 3, 7, 0,200, 3, - 2, 0,232, 3, 2, 0, 27, 0, 7, 0,222, 9, 7, 0,223, 9, 7, 0,203, 3, 7, 0,224, 9, 7, 0,225, 9, 7, 0,226, 9, - 7, 0,227, 9, 7, 0,228, 9, 7, 0,229, 9, 7, 0,230, 9, 7, 0,231, 9, 11, 0,232, 9,177, 0, 16, 0, 14, 0,233, 9, - 74, 0,234, 9, 2, 0, 18, 0, 2, 0, 27, 0, 4, 0,235, 9, 4, 0, 91, 0, 7, 0,108, 2, 7, 0,236, 9, 7, 0,237, 9, - 14, 0,238, 9, 4, 0,239, 9, 4, 0,240, 9, 11, 0,241, 9, 11, 0,242, 9,179, 0,183, 3, 0, 0,243, 9,104, 1, 1, 0, - 4, 0,240, 9,105, 1, 12, 0, 4, 0,240, 9, 7, 0, 78, 9, 2, 0,244, 9, 2, 0,245, 9, 7, 0,246, 9, 7, 0,247, 9, - 2, 0,248, 9, 2, 0, 18, 0, 7, 0,249, 9, 7, 0,250, 9, 7, 0,251, 9, 7, 0,252, 9,106, 1, 7, 0,106, 1, 0, 0, -106, 1, 1, 0, 14, 0,253, 9, 4, 0, 18, 0, 4, 0,254, 9, 0, 0, 19, 0, 22, 1,255, 9,176, 0, 9, 0, 22, 0, 32, 0, - 14, 0, 0, 10, 14, 0,233, 9, 14, 0, 1, 10, 14, 0,102, 0, 4, 0, 18, 0, 4, 0, 2, 10, 4, 0, 3, 10, 4, 0, 27, 0, -243, 0, 8, 0, 22, 0, 4, 10, 14, 0,233, 9, 64, 0, 5, 10, 0, 0, 6, 10, 4, 0, 7, 10, 4, 0, 18, 0, 4, 0, 8, 10, + 73, 1, 81, 9, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 82, 9, 2, 0, 70, 9, 2, 0, 67, 9, 2, 0, 83, 9, 2, 0, 30, 0, + 2, 0,247, 1, 0, 0, 19, 0, 11, 0, 2, 0, 77, 1, 71, 9, 72, 1, 84, 9, 2, 0, 14, 0, 2, 0, 85, 9, 4, 0, 86, 9, + 78, 1, 3, 0, 4, 0,240, 2, 4, 0, 27, 0, 27, 0, 44, 0, 79, 1, 15, 0,176, 0, 87, 9, 2, 0, 16, 0, 2, 0, 18, 0, + 7, 0, 14, 9, 7, 0, 91, 0, 0, 0, 19, 0, 0, 0, 88, 9, 2, 0, 89, 9, 2, 0, 90, 9, 2, 0,134, 0, 2, 0, 91, 9, + 2, 0, 92, 9, 2, 0, 27, 0, 7, 0, 93, 9, 7, 0, 94, 9, 80, 1, 8, 0, 7, 0, 95, 9, 7, 0, 96, 9, 7, 0, 97, 9, + 7, 0, 98, 9, 7, 0, 99, 9, 7, 0,100, 9, 7, 0,101, 9, 7, 0,102, 9, 81, 1, 13, 0, 2, 0, 18, 0, 2, 0,103, 9, + 4, 0, 67, 0, 4, 0, 30, 0, 2, 0,177, 6, 7, 0, 84, 4, 7, 0,230, 8, 46, 1,228, 8, 80, 1,104, 9, 2, 0, 16, 0, + 2, 0,115, 5, 2, 0,216, 3, 2, 0,105, 9, 82, 1, 11, 0, 4, 0,240, 2, 2, 0, 16, 0, 2, 0, 18, 0, 27, 0, 44, 0, + 79, 0,106, 9, 0, 0, 19, 0, 7, 0,107, 9, 7, 0,108, 9, 7, 0,222, 3, 2, 0,109, 9, 2, 0,110, 9, 83, 1, 5, 0, + 2, 0, 16, 0, 2, 0, 67, 0, 4, 0, 27, 0, 41, 0,125, 0, 27, 0,208, 5, 84, 1, 5, 0, 4, 0, 27, 0, 4, 0, 16, 0, + 0, 0, 19, 0, 0, 0, 53, 9, 27, 0, 44, 0, 85, 1, 13, 0, 2, 0, 18, 0, 2, 0, 16, 0, 2, 0, 67, 9, 2, 0,223, 3, + 7, 0,111, 9, 7, 0,112, 9, 7, 0, 86, 1, 7, 0,113, 9, 7, 0,192, 3, 7, 0,196, 3, 7, 0,114, 9, 7, 0,115, 9, + 27, 0,116, 9, 86, 1, 10, 0, 2, 0, 18, 0, 2, 0, 16, 0, 7, 0, 14, 9, 7, 0, 91, 0, 0, 0, 19, 0, 0, 0, 88, 9, + 2, 0, 67, 0, 2, 0, 30, 0, 2, 0,247, 1, 2, 0,115, 5, 87, 1, 8, 0, 27, 0, 44, 0, 7, 0, 1, 3, 7, 0,117, 9, + 7, 0,118, 9, 7, 0,223, 3, 2, 0, 67, 0, 2, 0,226, 2, 7, 0, 30, 0, 88, 1, 12, 0, 2, 0, 16, 0, 2, 0, 87, 1, + 2, 0, 18, 0, 2, 0, 4, 3, 2, 0,240, 2, 2, 0,119, 9, 4, 0, 27, 0, 7, 0,120, 9, 7, 0,121, 9, 7, 0,122, 9, + 7, 0,123, 9, 0, 0,124, 9, 89, 1, 9, 0, 2, 0, 18, 0, 2, 0, 16, 0, 4, 0, 14, 9, 4, 0, 91, 0, 0, 0, 19, 0, + 2, 0, 86, 1, 2, 0, 63, 0, 2, 0,125, 9, 2, 0,126, 9, 90, 1, 7, 0, 4, 0,214, 2, 4, 0,127, 9, 4, 0,128, 9, + 4, 0,129, 9, 7, 0,130, 9, 7, 0,131, 9, 0, 0, 59, 9, 91, 1, 7, 0, 0, 0,132, 9, 27, 0,133, 9, 0, 0, 65, 9, + 2, 0,134, 9, 2, 0, 67, 0, 4, 0, 30, 0, 0, 0, 66, 9, 92, 1, 6, 0, 2, 0, 18, 0, 2, 0, 16, 0, 4, 0, 14, 9, + 4, 0, 91, 0, 0, 0,135, 9, 0, 0,136, 9, 93, 1, 1, 0, 4, 0, 18, 0, 94, 1, 6, 0, 0, 0, 94, 0, 2, 0, 16, 0, + 2, 0, 18, 0, 4, 0,137, 9, 7, 0,138, 9, 37, 0, 6, 7, 95, 1, 4, 0, 0, 0,181, 2, 2, 0, 18, 0, 4, 0, 16, 0, + 27, 0, 44, 0, 96, 1, 2, 0, 4, 0, 16, 0, 4, 0,181, 6, 97, 1, 8, 0, 0, 0, 62, 9, 0, 0, 63, 9, 4, 0, 16, 0, + 7, 0, 40, 2, 7, 0,139, 9, 7, 0, 27, 0, 27, 0, 70, 3, 27, 0,140, 9, 98, 1, 11, 0, 0, 0, 54, 6, 0, 0, 18, 0, + 2, 0,141, 9, 4, 0, 16, 0, 7, 0, 94, 1, 7, 0,142, 9, 7, 0,143, 9, 7, 0,144, 9, 4, 0,145, 9, 27, 0, 70, 3, + 27, 0,146, 9, 77, 1, 10, 0, 77, 1, 0, 0, 77, 1, 1, 0, 77, 1, 81, 9, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 67, 9, + 2, 0,147, 9, 0, 0, 19, 0, 11, 0, 2, 0, 27, 0, 44, 0, 46, 1, 17, 0, 22, 0, 32, 0, 0, 0, 35, 0, 38, 0,153, 0, + 11, 0,227, 0, 38, 0,148, 9, 31, 0, 80, 0, 7, 0, 84, 4, 7, 0,149, 9, 7, 0,230, 8, 7, 0, 95, 9, 7, 0, 96, 9, + 7, 0,150, 9, 4, 0, 92, 0, 4, 0, 27, 0, 11, 0,151, 9, 11, 0,152, 9, 11, 0,153, 9, 99, 1, 6, 0, 99, 1, 0, 0, + 99, 1, 1, 0, 27, 0, 44, 0, 11, 0,154, 9, 2, 0,251, 0, 0, 0,211, 2, 64, 0, 4, 0, 22, 0, 32, 0, 14, 0,155, 9, + 4, 0,134, 0, 7, 0,156, 9,100, 1, 28, 0,100, 1, 0, 0,100, 1, 1, 0, 21, 0,157, 9,100, 1, 38, 0, 14, 0,158, 9, + 0, 0, 19, 0, 7, 0,159, 9, 7, 0,160, 9, 7, 0,161, 9, 7, 0,162, 9, 4, 0, 18, 0, 7, 0,163, 9, 7, 0,164, 9, + 7, 0,165, 9, 7, 0,166, 9, 7, 0, 94, 1, 7, 0, 40, 2, 7, 0,167, 9, 7, 0,212, 2, 7, 0,168, 9, 7, 0,169, 9, + 7, 0,170, 9, 7, 0,171, 9, 7, 0,172, 9, 7, 0,176, 0, 4, 0,134, 0, 2, 0,254, 5, 2, 0,173, 9,101, 1, 27, 0, + 22, 0, 32, 0, 34, 0, 75, 0, 14, 0,174, 9, 14, 0,175, 9, 14, 0,176, 9,100, 1,177, 9, 11, 0,178, 9, 11, 0,179, 9, + 4, 0, 18, 0, 4, 0,157, 6, 4, 0,180, 9, 4, 0, 27, 0, 2, 0, 8, 3, 2, 0,211, 6, 4, 0,181, 9, 4, 0,134, 0, + 4, 0,182, 9, 2, 0,183, 9, 2, 0,184, 9, 2, 0,185, 9, 2, 0,186, 9, 4, 0,187, 9, 4, 0,188, 9, 4, 0,189, 9, + 4, 0,190, 9, 4, 0,191, 9, 4, 0,192, 9,102, 1, 2, 0, 7, 0,165, 2, 4, 0, 18, 0,180, 0, 5, 0,102, 1,193, 9, + 4, 0,212, 2, 4, 0,194, 9, 4, 0,195, 9, 4, 0, 18, 0,179, 0, 16, 0, 4, 0,196, 9, 4, 0,197, 9, 4, 0,198, 9, + 4, 0,199, 9, 2, 0,200, 9, 2, 0,201, 9, 2, 0,202, 9, 2, 0,251, 0, 2, 0,203, 9, 2, 0,204, 9, 2, 0,205, 9, + 2, 0,206, 9, 4, 0,207, 9, 4, 0,208, 9, 4, 0,209, 9, 4, 0,210, 9,103, 1, 40, 0,103, 1, 0, 0,103, 1, 1, 0, + 21, 0,157, 9, 14, 0,251, 3, 0, 0, 19, 0, 2, 0, 18, 0, 2, 0,211, 9, 2, 0,209, 3, 2, 0,212, 9, 0, 0,213, 9, + 0, 0,214, 9, 0, 0,215, 9,100, 1,216, 9,103, 1, 38, 0,103, 1,217, 9, 14, 0,218, 9, 14, 0,219, 9,180, 0,184, 3, + 27, 0,220, 9,103, 1,221, 9, 7, 0, 77, 1, 7, 0,176, 0, 7, 0,222, 9, 7, 0, 19, 2, 7, 0,198, 3, 7, 0,200, 3, + 2, 0,232, 3, 2, 0, 27, 0, 7, 0,223, 9, 7, 0,224, 9, 7, 0,203, 3, 7, 0,225, 9, 7, 0,226, 9, 7, 0,227, 9, + 7, 0,228, 9, 7, 0,229, 9, 7, 0,230, 9, 7, 0,231, 9, 7, 0,232, 9, 11, 0,233, 9,177, 0, 16, 0, 14, 0,234, 9, + 74, 0,235, 9, 2, 0, 18, 0, 2, 0, 27, 0, 4, 0,236, 9, 4, 0, 67, 0, 7, 0, 84, 0, 7, 0,237, 9, 7, 0,238, 9, + 14, 0,239, 9, 4, 0,240, 9, 4, 0,241, 9, 11, 0,242, 9, 11, 0,243, 9,179, 0,183, 3, 0, 0,244, 9,104, 1, 1, 0, + 4, 0,241, 9,105, 1, 12, 0, 4, 0,241, 9, 7, 0, 79, 9, 2, 0,245, 9, 2, 0,246, 9, 7, 0,247, 9, 7, 0,248, 9, + 2, 0,249, 9, 2, 0, 18, 0, 7, 0,250, 9, 7, 0,251, 9, 7, 0,252, 9, 7, 0,253, 9,106, 1, 7, 0,106, 1, 0, 0, +106, 1, 1, 0, 14, 0,254, 9, 4, 0, 18, 0, 4, 0,255, 9, 0, 0, 19, 0, 22, 1, 0, 10,176, 0, 9, 0, 22, 0, 32, 0, + 14, 0, 1, 10, 14, 0,234, 9, 14, 0, 2, 10, 14, 0,102, 0, 4, 0, 18, 0, 4, 0, 3, 10, 4, 0, 4, 10, 4, 0, 27, 0, +243, 0, 8, 0, 22, 0, 5, 10, 14, 0,234, 9, 64, 0, 6, 10, 0, 0, 7, 10, 4, 0, 8, 10, 4, 0, 18, 0, 4, 0, 9, 10, 4, 0, 27, 0,107, 1, 13, 0,239, 0, 0, 0,239, 0, 1, 0, 14, 0,146, 6, 4, 0,147, 6, 7, 0,148, 6, 2, 0,149, 6, -240, 0,200, 6,176, 0,179, 3,243, 0, 9, 10, 0, 0, 87, 1, 0, 0,203, 6, 2, 0, 18, 0, 7, 0, 10, 10,108, 1, 8, 0, -108, 1, 0, 0,108, 1, 1, 0,106, 1, 11, 10, 31, 0, 80, 0, 14, 0,185, 3, 4, 0, 18, 0, 0, 0, 19, 0, 4, 0,118, 8, -109, 1, 5, 0,109, 1, 0, 0,109, 1, 1, 0, 31, 0, 80, 0, 2, 0, 18, 0, 0, 0, 12, 10,110, 1, 14, 0,110, 1, 0, 0, -110, 1, 1, 0, 11, 0, 2, 0, 2, 0, 16, 0, 2, 0, 18, 0, 0, 0, 13, 10, 0, 0, 14, 10, 0, 0, 19, 0, 2, 0, 27, 0, - 7, 0, 15, 10, 7, 0, 16, 10, 31, 0, 80, 0, 7, 0, 17, 10, 7, 0, 18, 10,111, 1, 9, 0,111, 1, 0, 0,111, 1, 1, 0, - 27, 0, 19, 10, 0, 0, 11, 3, 7, 0, 20, 10, 2, 0, 21, 10, 2, 0, 18, 0, 2, 0, 16, 0, 2, 0, 22, 10,112, 1, 7, 0, - 37, 0, 6, 7, 21, 0,156, 9, 4, 0, 18, 0, 4, 0, 23, 10, 14, 0, 24, 10, 27, 0, 19, 10, 0, 0, 11, 3,113, 1, 15, 0, - 27, 0, 19, 10, 2, 0, 25, 10, 2, 0, 18, 0, 2, 0, 26, 10, 2, 0, 27, 10, 0, 0, 11, 3, 27, 0, 28, 10, 0, 0, 29, 10, - 7, 0, 30, 10, 7, 0, 39, 2, 7, 0, 31, 10, 7, 0, 32, 10, 2, 0, 16, 0, 2, 0, 87, 1, 7, 0, 94, 1,114, 1, 6, 0, - 27, 0, 19, 10, 7, 0,192, 9, 2, 0, 33, 10, 2, 0, 34, 10, 2, 0, 18, 0, 2, 0, 35, 10,115, 1, 6, 0, 27, 0, 19, 10, - 4, 0, 36, 10, 4, 0, 37, 10, 4, 0, 92, 0, 4, 0, 27, 0, 0, 0, 11, 3,116, 1, 4, 0, 27, 0, 19, 10, 4, 0, 18, 0, - 4, 0, 36, 10, 0, 0, 11, 3,117, 1, 4, 0, 27, 0, 19, 10, 4, 0, 18, 0, 4, 0, 36, 10, 0, 0, 11, 3,118, 1, 4, 0, - 27, 0, 19, 10, 4, 0, 18, 0, 4, 0, 36, 10, 0, 0, 11, 3,119, 1, 2, 0, 4, 0, 18, 0, 7, 0, 84, 4,120, 1, 2, 0, - 27, 0, 19, 10, 0, 0, 11, 3,121, 1, 10, 0, 27, 0, 19, 10, 4, 0, 38, 10, 7, 0,128, 0, 4, 0, 18, 0, 2, 0, 4, 7, - 2, 0, 39, 10, 2, 0, 91, 0, 2, 0, 30, 0, 7, 0, 40, 10, 0, 0, 11, 3,122, 1, 10, 0, 27, 0, 19, 10, 2, 0, 16, 0, - 2, 0,134, 4, 4, 0, 89, 0, 4, 0, 90, 0, 7, 0,116, 9, 7, 0,117, 9, 4, 0, 27, 0,176, 0, 86, 9, 0, 0, 11, 3, -123, 1, 4, 0, 27, 0, 19, 10, 4, 0,210, 3, 4, 0, 41, 10, 0, 0, 11, 3,124, 1, 4, 0, 27, 0, 19, 10, 4, 0,210, 3, - 4, 0, 27, 0, 0, 0, 11, 3,125, 1, 6, 0, 27, 0, 19, 10, 7, 0,128, 0, 7, 0, 82, 3, 4, 0, 42, 10, 2, 0,210, 3, - 2, 0,211, 3,126, 1, 6, 0, 27, 0, 19, 10, 4, 0, 43, 10, 4, 0, 44, 10, 7, 0, 45, 10, 7, 0, 46, 10, 0, 0, 11, 3, -127, 1, 16, 0, 27, 0, 19, 10, 27, 0,216, 9, 4, 0, 16, 0, 7, 0, 47, 10, 7, 0, 48, 10, 7, 0, 49, 10, 7, 0, 50, 10, - 7, 0, 51, 10, 7, 0, 52, 10, 7, 0, 53, 10, 7, 0, 54, 10, 7, 0, 55, 10, 2, 0, 18, 0, 2, 0, 27, 0, 2, 0, 91, 0, - 2, 0, 30, 0,128, 1, 3, 0, 27, 0, 19, 10, 4, 0, 18, 0, 4, 0, 31, 2,129, 1, 5, 0, 27, 0, 19, 10, 4, 0, 18, 0, - 4, 0, 27, 0, 7, 0, 56, 10, 0, 0, 11, 3,130, 1, 10, 0, 27, 0, 19, 10, 0, 0, 11, 3, 2, 0, 57, 10, 2, 0, 58, 10, - 0, 0, 59, 10, 0, 0, 60, 10, 7, 0, 61, 10, 7, 0, 62, 10, 7, 0, 63, 10, 7, 0, 64, 10,131, 1, 5, 0, 27, 0, 19, 10, - 0, 0, 11, 3, 7, 0,220, 2, 2, 0, 65, 10, 2, 0, 18, 0,132, 1, 8, 0, 7, 0, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, - 7, 0, 11, 0, 7, 0, 66, 10, 7, 0, 67, 10, 2, 0, 18, 0, 2, 0, 31, 2,133, 1, 8, 0, 7, 0, 8, 0, 7, 0, 9, 0, - 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 66, 10, 7, 0, 67, 10, 2, 0, 18, 0, 2, 0, 31, 2,134, 1, 8, 0, 7, 0, 8, 0, - 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 66, 10, 7, 0, 67, 10, 2, 0, 18, 0, 2, 0, 31, 2,135, 1, 7, 0, - 27, 0, 19, 10, 0, 0, 11, 3, 7, 0, 94, 1, 7, 0,103, 1, 2, 0, 18, 0, 2, 0, 87, 1, 4, 0, 27, 0,136, 1, 5, 0, - 27, 0, 70, 3, 7, 0, 94, 1, 2, 0, 74, 3, 0, 0, 76, 3, 0, 0, 68, 10,137, 1, 7, 0,229, 0,106, 6, 0, 0, 69, 10, - 4, 0, 18, 0, 4, 0, 27, 0, 0, 0, 70, 10, 27, 0,208, 5, 27, 0, 71, 10,138, 1, 3, 0,229, 0,106, 6, 4, 0, 18, 0, - 4, 0, 27, 0,139, 1, 6, 0,229, 0,106, 6, 4, 0, 18, 0, 4, 0, 27, 0, 0, 0, 70, 10, 7, 0, 56, 10, 27, 0,208, 5, -140, 1, 10, 0,140, 1, 0, 0,140, 1, 1, 0, 2, 0, 16, 0, 2, 0, 18, 0, 0, 0, 72, 10, 7, 0, 31, 1, 7, 0, 32, 1, - 2, 0,253, 9, 2, 0, 73, 10, 27, 0, 44, 0,141, 1, 22, 0,141, 1, 0, 0,141, 1, 1, 0, 2, 0, 18, 0, 2, 0, 87, 1, - 2, 0, 74, 10, 2, 0, 75, 10, 31, 0, 80, 0,176, 0, 86, 9, 27, 0,168, 0, 7, 0, 89, 0, 7, 0, 90, 0, 7, 0, 76, 10, - 7, 0, 77, 10, 7, 0, 78, 10, 7, 0, 79, 10, 7, 0,253, 2, 7, 0,148, 3, 7, 0, 88, 9, 7, 0, 80, 10, 0, 0, 81, 10, - 0, 0, 82, 10, 14, 0,188, 3,142, 1, 11, 0, 7, 0, 46, 2, 7, 0,116, 9, 7, 0,117, 9, 11, 0, 2, 0, 2, 0, 83, 10, - 2, 0, 84, 10, 2, 0, 85, 10, 2, 0, 86, 10, 2, 0, 87, 10, 2, 0, 88, 10, 2, 0,181, 2,143, 1, 21, 0,143, 1, 0, 0, -143, 1, 1, 0,143, 1, 89, 10, 0, 0, 19, 0, 11, 0, 90, 10, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 91, 10, 2, 0, 92, 10, - 7, 0, 93, 10, 7, 0, 94, 10, 11, 0, 95, 10, 2, 0, 96, 10, 2, 0, 97, 10, 4, 0, 74, 0, 11, 0,150, 9, 4, 0, 98, 10, - 4, 0, 99, 10,143, 1,100, 10,144, 1,101, 10,142, 1,102, 10,145, 1, 4, 0, 0, 0,103, 10, 2, 0,104, 10, 2, 0,105, 10, - 4, 0, 27, 0,146, 1, 37, 0,146, 1, 0, 0,146, 1, 1, 0,146, 1,106, 10, 0, 0, 19, 0, 2, 0, 16, 0, 2, 0, 18, 0, - 2, 0,197, 8, 2, 0,176, 2, 2, 0,107, 10, 2, 0, 9, 7, 2, 0, 96, 10, 2, 0, 40, 9, 14, 0, 81, 9, 14, 0,108, 10, -146, 1, 38, 0, 22, 0, 42, 7, 11, 0, 90, 10, 7, 0, 93, 10, 7, 0, 94, 10, 7, 0, 81, 2, 7, 0, 1, 3, 7, 0,109, 10, - 4, 0,110, 10, 0, 0,111, 10, 2, 0,112, 10, 2, 0,113, 10, 7, 0,114, 10, 7, 0,115, 10, 2, 0,116, 10, 2, 0,117, 10, - 11, 0,118, 10, 19, 0,119, 10, 19, 0,120, 10, 19, 0,121, 10,145, 1,154, 0,147, 1,122, 10,148, 1,123, 10,144, 1, 8, 0, -144, 1, 0, 0,144, 1, 1, 0,146, 1,124, 10,146, 1,125, 10,143, 1,126, 10,143, 1,127, 10, 4, 0, 18, 0, 4, 0, 27, 0, - 57, 0, 20, 0, 22, 0, 32, 0, 34, 0, 75, 0,178, 0,182, 3, 14, 0,128, 10, 14, 0,129, 10, 4, 0, 16, 0, 4, 0,130, 10, - 4, 0,131, 10, 4, 0, 18, 0, 4, 0,110, 10, 4, 0,132, 10, 14, 0, 81, 9, 14, 0,108, 10,149, 1,133, 10, 11, 0,134, 10, - 11, 0,135, 10, 4, 0,136, 10, 11, 0,137, 10, 11, 0,138, 10, 11, 0,139, 10,150, 1, 4, 0, 4, 0, 17, 0, 4, 0,230, 2, - 4, 0,116, 9, 4, 0,117, 9,151, 1, 4, 0, 4, 0, 17, 0, 7, 0,230, 2, 7, 0,116, 9, 7, 0,117, 9,152, 1, 2, 0, - 0, 0,230, 2, 0, 0, 86, 1,153, 1, 4, 0, 4, 0, 17, 0, 7, 0,140, 10, 7, 0,116, 9, 7, 0,117, 9,154, 1, 1, 0, - 7, 0,141, 10,155, 1, 6, 0, 4, 0,127, 0, 4, 0,129, 0, 4, 0, 40, 9, 0, 0,142, 10, 0, 0,143, 10, 2, 0, 27, 0, -156, 1, 16, 0, 2, 0,141, 8, 2, 0,142, 8, 2, 0,144, 10, 2, 0,145, 10, 2, 0,146, 10, 2, 0, 67, 0, 2, 0, 43, 7, - 2, 0,147, 10, 7, 0,252, 2, 7, 0,148, 10, 7, 0,149, 10, 2, 0,109, 1, 0, 0,150, 10, 0, 0,151, 10, 4, 0,152, 10, - 4, 0,153, 10,157, 1, 9, 0, 7, 0,154, 10, 7, 0,155, 10, 7, 0,149, 9, 7, 0, 94, 3, 7, 0,156, 10, 7, 0,218, 6, - 2, 0, 92, 3, 0, 0,157, 10, 0, 0, 27, 0,158, 1, 4, 0, 7, 0,158, 10, 7, 0,159, 10, 2, 0, 92, 3, 2, 0, 27, 0, -159, 1, 3, 0, 7, 0,160, 10, 7, 0,212, 8, 7, 0, 14, 0,160, 1, 4, 0, 0, 0, 35, 0,204, 0, 80, 5, 4, 0,129, 0, - 4, 0,132, 4,161, 1, 6, 0, 0, 0,161, 10,204, 0,162, 10, 4, 0,129, 0, 4, 0,132, 4, 4, 0,163, 10, 4, 0, 27, 0, -162, 1, 4, 0, 2, 0,164, 10, 2, 0,165, 10, 4, 0, 30, 0,204, 0,162, 10,163, 1, 9, 0, 7, 0,166, 10, 7, 0,167, 10, - 7, 0,168, 10, 7, 0, 92, 2, 7, 0,169, 10, 7, 0,170, 10, 7, 0,171, 10, 2, 0,172, 10, 2, 0,173, 10,164, 1, 8, 0, - 2, 0,174, 10, 2, 0,175, 10, 2, 0,176, 10, 2, 0,177, 10, 7, 0,178, 10, 7, 0,179, 10, 7, 0,180, 10, 7, 0,181, 10, -165, 1, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0,166, 1, 2, 0, 0, 0,170, 0, 0, 0,182, 10,167, 1, 1, 0, 0, 0, 19, 0, -168, 1, 12, 0, 0, 0,183, 10, 0, 0,184, 10, 0, 0,209, 6, 0, 0,185, 10, 2, 0,144, 10, 2, 0,186, 10, 7, 0,187, 10, - 7, 0,188, 10, 7, 0,189, 10, 7, 0,148, 3, 7, 0,190, 10, 7, 0,191, 10,169, 1, 2, 0, 11, 0,192, 10, 11, 0,193, 10, -170, 1, 13, 0, 0, 0, 72, 5, 0, 0, 16, 0, 0, 0, 92, 3, 0, 0, 94, 3, 0, 0,184, 10, 0, 0,108, 0, 0, 0,181, 2, - 7, 0,194, 10, 7, 0,195, 10, 7, 0,147, 3, 7, 0,196, 10, 7, 0,197, 10, 7, 0,191, 10,171, 1, 8, 0, 7, 0, 47, 9, - 7, 0,128, 0, 7, 0,151, 10, 7, 0,172, 2, 7, 0,198, 10, 7, 0,240, 0, 7, 0,199, 10, 4, 0, 16, 0,172, 1, 4, 0, - 2, 0,200, 10, 2, 0,201, 10, 2, 0,202, 10, 2, 0, 27, 0,173, 1, 8, 0, 7, 0,203, 10, 7, 0,220, 2, 7, 0,204, 10, - 7, 0,190, 8, 7, 0,191, 8, 7, 0,192, 8, 7, 0,205, 10, 7, 0,206, 10,174, 1, 6, 0, 2, 0,207, 10, 2, 0,208, 10, - 7, 0,209, 10, 7, 0,210, 10, 7, 0,211, 10, 7, 0,212, 10,175, 1, 2, 0, 58, 0,213, 10, 59, 0,214, 10,176, 1, 3, 0, -175, 1, 79, 6, 7, 0,215, 10, 7, 0,216, 10,177, 1, 3, 0,175, 1, 79, 6, 4, 0,217, 10, 4, 0, 27, 0,178, 1, 1, 0, -175, 1, 79, 6,179, 1, 3, 0,175, 1, 79, 6, 4, 0,217, 10, 4, 0,218, 10,180, 1, 3, 0,175, 1, 79, 6, 4, 0,219, 10, - 4, 0, 27, 0,181, 1, 1, 0,175, 1, 79, 6,182, 1, 3, 0,175, 1, 79, 6, 4, 0,220, 10, 4, 0, 27, 0,183, 1, 3, 0, -175, 1, 79, 6, 4, 0,221, 10, 4, 0, 27, 0,184, 1, 3, 0,175, 1, 79, 6, 4, 0,222, 10, 4, 0, 27, 0,185, 1, 3, 0, +240, 0,200, 6,176, 0,179, 3,243, 0, 10, 10, 0, 0, 87, 1, 0, 0,203, 6, 2, 0, 18, 0, 7, 0, 11, 10,108, 1, 8, 0, +108, 1, 0, 0,108, 1, 1, 0,106, 1, 12, 10, 31, 0, 80, 0, 14, 0,185, 3, 4, 0, 18, 0, 0, 0, 19, 0, 4, 0,118, 8, +109, 1, 5, 0,109, 1, 0, 0,109, 1, 1, 0, 31, 0, 80, 0, 2, 0, 18, 0, 0, 0, 13, 10,110, 1, 14, 0,110, 1, 0, 0, +110, 1, 1, 0, 11, 0, 2, 0, 2, 0, 16, 0, 2, 0, 18, 0, 0, 0, 14, 10, 0, 0, 15, 10, 0, 0, 19, 0, 2, 0, 27, 0, + 7, 0, 16, 10, 7, 0, 17, 10, 31, 0, 80, 0, 7, 0, 18, 10, 7, 0, 19, 10,111, 1, 9, 0,111, 1, 0, 0,111, 1, 1, 0, + 27, 0, 20, 10, 0, 0, 11, 3, 7, 0, 21, 10, 2, 0, 22, 10, 2, 0, 18, 0, 2, 0, 16, 0, 2, 0, 23, 10,112, 1, 7, 0, + 37, 0, 6, 7, 21, 0,157, 9, 4, 0, 18, 0, 4, 0, 24, 10, 14, 0, 25, 10, 27, 0, 20, 10, 0, 0, 11, 3,113, 1, 15, 0, + 27, 0, 20, 10, 2, 0, 26, 10, 2, 0, 18, 0, 2, 0, 27, 10, 2, 0, 28, 10, 0, 0, 11, 3, 27, 0, 29, 10, 0, 0, 30, 10, + 7, 0, 31, 10, 7, 0, 40, 2, 7, 0, 32, 10, 7, 0, 33, 10, 2, 0, 16, 0, 2, 0, 87, 1, 7, 0, 94, 1,114, 1, 6, 0, + 27, 0, 20, 10, 7, 0,193, 9, 2, 0, 34, 10, 2, 0, 35, 10, 2, 0, 18, 0, 2, 0, 36, 10,115, 1, 6, 0, 27, 0, 20, 10, + 4, 0, 37, 10, 4, 0, 38, 10, 4, 0, 92, 0, 4, 0, 27, 0, 0, 0, 11, 3,116, 1, 4, 0, 27, 0, 20, 10, 4, 0, 18, 0, + 4, 0, 37, 10, 0, 0, 11, 3,117, 1, 4, 0, 27, 0, 20, 10, 4, 0, 18, 0, 4, 0, 37, 10, 0, 0, 11, 3,118, 1, 4, 0, + 27, 0, 20, 10, 4, 0, 18, 0, 4, 0, 37, 10, 0, 0, 11, 3,119, 1, 2, 0, 4, 0, 18, 0, 7, 0, 84, 4,120, 1, 2, 0, + 27, 0, 20, 10, 0, 0, 11, 3,121, 1, 10, 0, 27, 0, 20, 10, 4, 0, 39, 10, 7, 0,128, 0, 4, 0, 18, 0, 2, 0, 4, 7, + 2, 0, 40, 10, 2, 0, 67, 0, 2, 0, 30, 0, 7, 0, 41, 10, 0, 0, 11, 3,122, 1, 10, 0, 27, 0, 20, 10, 2, 0, 16, 0, + 2, 0,134, 4, 4, 0, 90, 0, 4, 0, 91, 0, 7, 0,117, 9, 7, 0,118, 9, 4, 0, 27, 0,176, 0, 87, 9, 0, 0, 11, 3, +123, 1, 4, 0, 27, 0, 20, 10, 4, 0,210, 3, 4, 0, 42, 10, 0, 0, 11, 3,124, 1, 4, 0, 27, 0, 20, 10, 4, 0,210, 3, + 4, 0, 27, 0, 0, 0, 11, 3,125, 1, 6, 0, 27, 0, 20, 10, 7, 0,128, 0, 7, 0, 82, 3, 4, 0, 43, 10, 2, 0,210, 3, + 2, 0,211, 3,126, 1, 6, 0, 27, 0, 20, 10, 4, 0, 44, 10, 4, 0, 45, 10, 7, 0, 46, 10, 7, 0, 47, 10, 0, 0, 11, 3, +127, 1, 16, 0, 27, 0, 20, 10, 27, 0,217, 9, 4, 0, 16, 0, 7, 0, 48, 10, 7, 0, 49, 10, 7, 0, 50, 10, 7, 0, 51, 10, + 7, 0, 52, 10, 7, 0, 53, 10, 7, 0, 54, 10, 7, 0, 55, 10, 7, 0, 56, 10, 2, 0, 18, 0, 2, 0, 27, 0, 2, 0, 67, 0, + 2, 0, 30, 0,128, 1, 3, 0, 27, 0, 20, 10, 4, 0, 18, 0, 4, 0, 32, 2,129, 1, 5, 0, 27, 0, 20, 10, 4, 0, 18, 0, + 4, 0, 27, 0, 7, 0, 57, 10, 0, 0, 11, 3,130, 1, 10, 0, 27, 0, 20, 10, 0, 0, 11, 3, 2, 0, 58, 10, 2, 0, 59, 10, + 0, 0, 60, 10, 0, 0, 61, 10, 7, 0, 62, 10, 7, 0, 63, 10, 7, 0, 64, 10, 7, 0, 65, 10,131, 1, 5, 0, 27, 0, 20, 10, + 0, 0, 11, 3, 7, 0,220, 2, 2, 0, 66, 10, 2, 0, 18, 0,132, 1, 8, 0, 7, 0, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, + 7, 0, 11, 0, 7, 0, 67, 10, 7, 0, 68, 10, 2, 0, 18, 0, 2, 0, 32, 2,133, 1, 8, 0, 7, 0, 8, 0, 7, 0, 9, 0, + 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 67, 10, 7, 0, 68, 10, 2, 0, 18, 0, 2, 0, 32, 2,134, 1, 8, 0, 7, 0, 8, 0, + 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 67, 10, 7, 0, 68, 10, 2, 0, 18, 0, 2, 0, 32, 2,135, 1, 7, 0, + 27, 0, 20, 10, 0, 0, 11, 3, 7, 0, 94, 1, 7, 0,103, 1, 2, 0, 18, 0, 2, 0, 87, 1, 4, 0, 27, 0,136, 1, 5, 0, + 27, 0, 70, 3, 7, 0, 94, 1, 2, 0, 74, 3, 0, 0, 76, 3, 0, 0, 69, 10,137, 1, 7, 0,229, 0,106, 6, 0, 0, 70, 10, + 4, 0, 18, 0, 4, 0, 27, 0, 0, 0, 71, 10, 27, 0,208, 5, 27, 0, 72, 10,138, 1, 3, 0,229, 0,106, 6, 4, 0, 18, 0, + 4, 0, 27, 0,139, 1, 6, 0,229, 0,106, 6, 4, 0, 18, 0, 4, 0, 27, 0, 0, 0, 71, 10, 7, 0, 57, 10, 27, 0,208, 5, +140, 1, 10, 0,140, 1, 0, 0,140, 1, 1, 0, 2, 0, 16, 0, 2, 0, 18, 0, 0, 0, 73, 10, 7, 0, 31, 1, 7, 0, 32, 1, + 2, 0,254, 9, 2, 0, 74, 10, 27, 0, 44, 0,141, 1, 22, 0,141, 1, 0, 0,141, 1, 1, 0, 2, 0, 18, 0, 2, 0, 87, 1, + 2, 0, 75, 10, 2, 0, 76, 10, 31, 0, 80, 0,176, 0, 87, 9, 27, 0,168, 0, 7, 0, 90, 0, 7, 0, 91, 0, 7, 0, 77, 10, + 7, 0, 78, 10, 7, 0, 79, 10, 7, 0, 80, 10, 7, 0,253, 2, 7, 0,148, 3, 7, 0, 89, 9, 7, 0, 81, 10, 0, 0, 82, 10, + 0, 0, 83, 10, 14, 0,188, 3,142, 1, 11, 0, 7, 0, 47, 2, 7, 0,117, 9, 7, 0,118, 9, 11, 0, 2, 0, 2, 0, 84, 10, + 2, 0, 85, 10, 2, 0, 86, 10, 2, 0, 87, 10, 2, 0, 88, 10, 2, 0, 89, 10, 2, 0,181, 2,143, 1, 21, 0,143, 1, 0, 0, +143, 1, 1, 0,143, 1, 90, 10, 0, 0, 19, 0, 11, 0, 91, 10, 2, 0, 16, 0, 2, 0, 18, 0, 2, 0, 92, 10, 2, 0, 93, 10, + 7, 0, 94, 10, 7, 0, 95, 10, 11, 0, 96, 10, 2, 0, 97, 10, 2, 0, 98, 10, 4, 0,247, 1, 11, 0,151, 9, 4, 0, 99, 10, + 4, 0,100, 10,143, 1,101, 10,144, 1,102, 10,142, 1,103, 10,145, 1, 4, 0, 0, 0,104, 10, 2, 0,105, 10, 2, 0,106, 10, + 4, 0, 27, 0,146, 1, 37, 0,146, 1, 0, 0,146, 1, 1, 0,146, 1,107, 10, 0, 0, 19, 0, 2, 0, 16, 0, 2, 0, 18, 0, + 2, 0,198, 8, 2, 0,176, 2, 2, 0,108, 10, 2, 0, 9, 7, 2, 0, 97, 10, 2, 0, 41, 9, 14, 0, 82, 9, 14, 0,109, 10, +146, 1, 38, 0, 22, 0, 42, 7, 11, 0, 91, 10, 7, 0, 94, 10, 7, 0, 95, 10, 7, 0, 82, 2, 7, 0, 1, 3, 7, 0,110, 10, + 4, 0,111, 10, 0, 0,112, 10, 2, 0,113, 10, 2, 0,114, 10, 7, 0,115, 10, 7, 0,116, 10, 2, 0,117, 10, 2, 0,118, 10, + 11, 0,119, 10, 19, 0,120, 10, 19, 0,121, 10, 19, 0,122, 10,145, 1,154, 0,147, 1,123, 10,148, 1,124, 10,144, 1, 8, 0, +144, 1, 0, 0,144, 1, 1, 0,146, 1,125, 10,146, 1,126, 10,143, 1,127, 10,143, 1,128, 10, 4, 0, 18, 0, 4, 0, 27, 0, + 57, 0, 20, 0, 22, 0, 32, 0, 34, 0, 75, 0,178, 0,182, 3, 14, 0,129, 10, 14, 0,130, 10, 4, 0, 16, 0, 4, 0,131, 10, + 4, 0,132, 10, 4, 0, 18, 0, 4, 0,111, 10, 4, 0,133, 10, 14, 0, 82, 9, 14, 0,109, 10,149, 1,134, 10, 11, 0,135, 10, + 11, 0,136, 10, 4, 0,137, 10, 11, 0,138, 10, 11, 0,139, 10, 11, 0,140, 10,150, 1, 4, 0, 4, 0, 17, 0, 4, 0,230, 2, + 4, 0,117, 9, 4, 0,118, 9,151, 1, 4, 0, 4, 0, 17, 0, 7, 0,230, 2, 7, 0,117, 9, 7, 0,118, 9,152, 1, 2, 0, + 0, 0,230, 2, 0, 0, 86, 1,153, 1, 4, 0, 4, 0, 17, 0, 7, 0,141, 10, 7, 0,117, 9, 7, 0,118, 9,154, 1, 1, 0, + 7, 0,142, 10,155, 1, 6, 0, 4, 0,127, 0, 4, 0,129, 0, 4, 0, 41, 9, 0, 0,143, 10, 0, 0,144, 10, 2, 0, 27, 0, +156, 1, 16, 0, 2, 0,141, 8, 2, 0,142, 8, 2, 0,145, 10, 2, 0,146, 10, 2, 0,147, 10, 2, 0, 68, 0, 2, 0, 43, 7, + 2, 0,148, 10, 7, 0,252, 2, 7, 0,149, 10, 7, 0,150, 10, 2, 0,109, 1, 0, 0,151, 10, 0, 0,152, 10, 4, 0,153, 10, + 4, 0,154, 10,157, 1, 9, 0, 7, 0,155, 10, 7, 0,156, 10, 7, 0,150, 9, 7, 0, 94, 3, 7, 0,157, 10, 7, 0,218, 6, + 2, 0, 92, 3, 0, 0,158, 10, 0, 0, 27, 0,158, 1, 4, 0, 7, 0,159, 10, 7, 0,160, 10, 2, 0, 92, 3, 2, 0, 27, 0, +159, 1, 3, 0, 7, 0,161, 10, 7, 0,213, 8, 7, 0, 14, 0,160, 1, 4, 0, 0, 0, 35, 0,204, 0, 80, 5, 4, 0,129, 0, + 4, 0,132, 4,161, 1, 6, 0, 0, 0,162, 10,204, 0,163, 10, 4, 0,129, 0, 4, 0,132, 4, 4, 0,164, 10, 4, 0, 27, 0, +162, 1, 4, 0, 2, 0,165, 10, 2, 0,166, 10, 4, 0, 30, 0,204, 0,163, 10,163, 1, 9, 0, 7, 0,167, 10, 7, 0,168, 10, + 7, 0,169, 10, 7, 0, 93, 2, 7, 0,170, 10, 7, 0,171, 10, 7, 0,172, 10, 2, 0,173, 10, 2, 0,174, 10,164, 1, 8, 0, + 2, 0,175, 10, 2, 0,176, 10, 2, 0,177, 10, 2, 0,178, 10, 7, 0,179, 10, 7, 0,180, 10, 7, 0,181, 10, 7, 0,182, 10, +165, 1, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0,166, 1, 2, 0, 0, 0,170, 0, 0, 0,183, 10,167, 1, 1, 0, 0, 0, 19, 0, +168, 1, 12, 0, 0, 0,184, 10, 0, 0,185, 10, 0, 0,209, 6, 0, 0,186, 10, 2, 0,145, 10, 2, 0,187, 10, 7, 0,188, 10, + 7, 0,189, 10, 7, 0,190, 10, 7, 0,148, 3, 7, 0,191, 10, 7, 0,192, 10,169, 1, 2, 0, 11, 0,193, 10, 11, 0,194, 10, +170, 1, 13, 0, 0, 0, 72, 5, 0, 0, 16, 0, 0, 0, 92, 3, 0, 0, 94, 3, 0, 0,185, 10, 0, 0,108, 0, 0, 0,181, 2, + 7, 0,195, 10, 7, 0,196, 10, 7, 0,147, 3, 7, 0,197, 10, 7, 0,198, 10, 7, 0,192, 10,171, 1, 8, 0, 7, 0, 48, 9, + 7, 0,128, 0, 7, 0,152, 10, 7, 0,172, 2, 7, 0,199, 10, 7, 0,240, 0, 7, 0,200, 10, 4, 0, 16, 0,172, 1, 4, 0, + 2, 0,201, 10, 2, 0,202, 10, 2, 0,203, 10, 2, 0, 27, 0,173, 1, 8, 0, 7, 0,204, 10, 7, 0,220, 2, 7, 0,205, 10, + 7, 0,191, 8, 7, 0,192, 8, 7, 0,193, 8, 7, 0,206, 10, 7, 0,207, 10,174, 1, 6, 0, 2, 0,208, 10, 2, 0,209, 10, + 7, 0,210, 10, 7, 0,211, 10, 7, 0,212, 10, 7, 0,213, 10,175, 1, 2, 0, 58, 0,214, 10, 59, 0,215, 10,176, 1, 3, 0, +175, 1, 79, 6, 7, 0,216, 10, 7, 0,217, 10,177, 1, 3, 0,175, 1, 79, 6, 4, 0,218, 10, 4, 0, 27, 0,178, 1, 1, 0, +175, 1, 79, 6,179, 1, 3, 0,175, 1, 79, 6, 4, 0,218, 10, 4, 0,219, 10,180, 1, 3, 0,175, 1, 79, 6, 4, 0,220, 10, + 4, 0, 27, 0,181, 1, 1, 0,175, 1, 79, 6,182, 1, 3, 0,175, 1, 79, 6, 4, 0,221, 10, 4, 0, 27, 0,183, 1, 3, 0, +175, 1, 79, 6, 4, 0,222, 10, 4, 0, 27, 0,184, 1, 3, 0,175, 1, 79, 6, 4, 0,223, 10, 4, 0, 27, 0,185, 1, 3, 0, 175, 1, 79, 6, 4, 0,250, 0, 4, 0, 27, 0,186, 1, 1, 0, 0, 0, 19, 0,187, 1, 1, 0, 0, 0, 19, 0,188, 1, 4, 0, - 7, 0, 5, 0, 7, 0, 6, 0, 2, 0, 18, 0, 2, 0,223, 10,189, 1, 10, 0, 2, 0, 62, 4, 2, 0, 18, 0, 7, 0,217, 4, - 7, 0,224, 10, 7, 0,225, 10, 7, 0,226, 10, 7, 0,227, 10,188, 1,228, 10,188, 1,229, 10,188, 1,230, 10, 54, 0, 11, 0, - 4, 0, 18, 0, 4, 0, 63, 0, 4, 0,231, 10, 4, 0,232, 10, 19, 0,233, 10, 19, 0,234, 10,189, 1,235, 10, 7, 0,236, 10, - 7, 0,237, 10, 7, 0,238, 10, 7, 0,239, 10, 0, 1, 10, 0, 4, 0,253, 9, 4, 0,240, 10, 7, 0,241, 10, 7, 0,242, 10, - 7, 0,243, 10, 7, 0,244, 10, 7, 0, 9, 0, 7, 0, 11, 0, 4, 0, 87, 1, 4, 0, 1, 3,255, 0, 18, 0, 4, 0,132, 0, - 4, 0,245, 10, 4, 0,246, 10, 7, 0,247, 10, 4, 0,248, 10, 7, 0,249, 10, 7, 0,250, 10, 4, 0,251, 10, 7, 0,252, 10, - 4, 0,253, 10, 7, 0,254, 10, 0, 1,255, 10, 7, 0, 0, 11, 7, 0, 1, 11, 7, 0, 2, 11, 7, 0, 3, 11, 4, 0, 4, 11, - 4, 0, 27, 0,190, 1, 4, 0, 42, 0,244, 2, 7, 0, 5, 11, 7, 0,178, 1, 7, 0, 27, 0,213, 0, 34, 0, 22, 0, 32, 0, -190, 1, 6, 11, 54, 0,228, 10, 46, 0, 7, 11, 52, 0, 8, 11, 25, 0,154, 0, 0, 0, 9, 11, 7, 0, 10, 11, 2, 0,109, 6, - 2, 0, 11, 11, 4, 0,108, 0, 4, 0, 18, 0, 7, 0, 12, 11, 4, 0, 89, 2, 4, 0, 13, 11, 7, 0, 14, 11, 7, 0, 15, 11, - 7, 0, 16, 11, 7, 0,178, 1, 4, 0, 17, 11, 7, 0, 18, 11, 0, 0, 19, 11, 0, 0, 20, 11, 0, 0, 21, 11, 0, 0, 22, 11, - 7, 0, 23, 11, 7, 0, 24, 11, 7, 0, 25, 11, 7, 0, 1, 3, 7, 0, 26, 11, 4, 0, 27, 11, 7, 0,240, 5, 7, 0, 28, 11, - 7, 0, 29, 11,191, 1, 10, 0, 4, 0, 16, 0, 4, 0,128, 0, 4, 0, 18, 0, 4, 0, 15, 4, 4, 0, 30, 11, 4, 0, 31, 11, - 4, 0, 32, 11, 4, 0, 73, 0, 0, 0, 19, 0, 11, 0, 2, 0,192, 1, 1, 0, 0, 0, 70, 7, 95, 0, 8, 0,191, 1, 33, 11, - 4, 0, 34, 11, 4, 0, 35, 11, 4, 0, 36, 11, 4, 0, 37, 11, 4, 0, 30, 0, 11, 0, 38, 11,192, 1, 39, 11,193, 1, 5, 0, - 7, 0,165, 2, 7, 0,240, 2, 7, 0, 39, 2, 2, 0,147, 2, 2, 0, 27, 0,194, 1, 5, 0, 7, 0,165, 2, 7, 0,159, 4, - 7, 0, 40, 11, 7, 0, 41, 11, 7, 0,240, 2,195, 1, 5, 0, 27, 0, 42, 11,196, 1, 21, 0, 7, 0, 75, 6, 7, 0, 43, 11, - 7, 0, 56, 0,197, 1, 3, 0, 7, 0, 44, 11, 4, 0, 45, 11, 4, 0, 46, 11,198, 1, 7, 0, 4, 0, 47, 11, 4, 0, 48, 11, - 4, 0, 49, 11, 7, 0, 50, 11, 7, 0, 51, 11, 7, 0, 52, 11, 7, 0, 56, 0,199, 1, 8, 0,199, 1, 0, 0,199, 1, 1, 0, - 27, 0, 44, 0, 4, 0, 3, 1, 2, 0, 18, 0, 2, 0, 87, 1, 7, 0,240, 2, 7, 0, 55, 9,200, 1, 7, 0,200, 1, 0, 0, -200, 1, 1, 0, 27, 0, 44, 0, 2, 0,225, 2, 2, 0, 18, 0, 2, 0, 13, 2, 2, 0, 56, 0,201, 1, 17, 0,194, 1, 8, 4, -194, 1, 53, 11,193, 1, 54, 11,194, 1, 38, 9,195, 1, 55, 11, 4, 0, 82, 0, 7, 0,240, 2, 7, 0, 7, 3, 7, 0, 56, 11, - 4, 0, 47, 11, 4, 0, 57, 11, 7, 0, 51, 11, 7, 0, 52, 11, 7, 0,108, 0, 4, 0, 58, 11, 2, 0, 18, 0, 2, 0, 59, 11, -202, 1, 15, 0, 7, 0,255, 0, 7, 0, 60, 11, 7, 0, 44, 11, 7, 0, 61, 11, 7, 0, 62, 11, 7, 0, 63, 11, 7, 0, 64, 11, - 7, 0, 65, 11, 7, 0, 66, 11, 7, 0, 67, 11, 7, 0, 68, 11, 7, 0, 69, 11, 7, 0, 70, 11, 4, 0, 18, 0, 4, 0, 71, 11, -203, 1,128, 0, 22, 0, 32, 0, 34, 0, 75, 0,204, 1, 72, 11,202, 1, 73, 11,187, 0,154, 4, 4, 0, 18, 0, 4, 0, 56, 0, - 2, 0, 16, 0, 2, 0, 57, 10, 2, 0, 74, 11, 2, 0,122, 1, 2, 0, 75, 11, 2, 0,232, 3, 2, 0, 76, 11, 2, 0, 77, 11, - 2, 0, 78, 11, 2, 0, 79, 11, 2, 0, 80, 11, 2, 0, 81, 11, 2, 0, 82, 11, 2, 0, 83, 11, 2, 0, 84, 11, 2, 0,224, 5, - 2, 0, 85, 11, 2, 0, 86, 11, 2, 0, 87, 11, 2, 0, 88, 11, 2, 0, 89, 11, 2, 0, 28, 2, 2, 0, 31, 9, 2, 0, 6, 9, - 2, 0, 90, 11, 2, 0, 91, 11, 2, 0, 25, 4, 2, 0, 26, 4, 2, 0, 92, 11, 2, 0, 93, 11, 2, 0, 94, 11, 2, 0, 95, 11, - 7, 0, 96, 11, 7, 0, 97, 11, 7, 0, 98, 11, 7, 0, 99, 11, 7, 0,100, 11, 7, 0,101, 11, 7, 0,102, 11, 2, 0,154, 5, - 2, 0,103, 11, 7, 0,104, 11, 7, 0,105, 11, 7, 0,106, 11, 7, 0, 13, 9, 7, 0, 90, 0, 7, 0, 7, 3, 7, 0, 19, 9, - 7, 0,107, 11, 7, 0,108, 11, 7, 0,109, 11, 7, 0,110, 11, 7, 0,111, 11, 7, 0,112, 11, 4, 0, 14, 9, 4, 0, 12, 9, - 4, 0,113, 11, 4, 0,114, 11, 2, 0,115, 11, 2, 0,116, 11, 7, 0, 15, 9, 7, 0, 16, 9, 7, 0, 17, 9, 7, 0,117, 11, - 7, 0,118, 11, 7, 0,119, 11, 7, 0,120, 11, 7, 0,121, 11, 7, 0,122, 11, 7, 0,123, 11, 7, 0,124, 11, 7, 0,125, 11, - 7, 0,222, 3, 7, 0,108, 0, 7, 0,126, 11, 7, 0,127, 11, 7, 0,128, 11, 7, 0,129, 11, 7, 0,214, 0, 7, 0,130, 11, - 4, 0,131, 11, 4, 0,132, 11, 7, 0,133, 11, 7, 0,134, 11, 7, 0,135, 11, 7, 0,136, 11, 7, 0,137, 11, 7, 0,213, 0, - 7, 0,138, 11, 7, 0, 52, 4, 7, 0, 50, 4, 7, 0, 51, 4, 7, 0,139, 11, 7, 0,140, 11, 7, 0,141, 11, 7, 0,142, 11, - 7, 0,143, 11, 7, 0,144, 11, 7, 0,145, 11, 7, 0,146, 11, 7, 0,147, 11, 7, 0,148, 11, 7, 0,149, 11, 7, 0,150, 11, - 7, 0,151, 11, 7, 0,152, 11, 7, 0,153, 11, 7, 0,154, 11, 7, 0,155, 11, 7, 0,156, 11, 4, 0,157, 11, 4, 0,158, 11, - 46, 0,140, 1, 64, 0, 0, 4, 14, 0,159, 11, 64, 0,160, 11, 27, 0,161, 11, 27, 0,162, 11, 31, 0, 80, 0,182, 0, 73, 1, -182, 0,163, 11,150, 0, 52, 0,150, 0, 0, 0,150, 0, 1, 0,203, 1,164, 11,201, 1,165, 11,198, 1,216, 9,190, 0, 80, 4, - 11, 0, 81, 4,205, 1,166, 11,205, 1,167, 11, 14, 0,168, 11, 14, 0,169, 11,135, 0,170, 11,143, 0,171, 11,143, 0,172, 11, - 27, 0,173, 11, 27, 0,174, 11, 27, 0, 38, 0, 14, 0, 24, 10, 0, 0, 19, 0, 7, 0,244, 0, 7, 0, 36, 3, 7, 0,175, 11, - 7, 0,176, 11, 4, 0,214, 2, 4, 0,177, 11, 4, 0, 18, 0, 4, 0, 14, 9, 4, 0,178, 11, 4, 0,179, 11, 4, 0,180, 11, - 4, 0,181, 11, 2, 0,251, 0, 2, 0,182, 11, 2, 0,183, 11, 2, 0,184, 11, 0, 0,185, 11, 2, 0,186, 11, 2, 0,187, 11, - 2, 0,188, 11, 11, 0,189, 11,139, 0,153, 4, 14, 0, 21, 3, 14, 0,190, 11,197, 1,191, 11, 4, 0,192, 11, 4, 0,193, 11, -206, 1,194, 11,141, 0, 33, 3,207, 1,195, 11, 7, 0,196, 11, 7, 0,197, 11, 7, 0,198, 11,137, 0, 38, 0,208, 1,150, 9, - 7, 0,123, 4, 7, 0,199, 11, 7, 0,200, 11, 7, 0, 75, 6, 7, 0,236, 3, 7, 0,222, 3, 7, 0,201, 11, 7, 0, 91, 2, - 7, 0,202, 11, 7, 0,203, 11, 7, 0,204, 11, 7, 0,205, 11, 7, 0,206, 11, 7, 0,207, 11, 7, 0,124, 4, 7, 0,208, 11, - 7, 0,209, 11, 7, 0,210, 11, 7, 0,125, 4, 7, 0,121, 4, 7, 0,122, 4, 7, 0,211, 11, 7, 0,212, 11, 7, 0,213, 11, - 4, 0,214, 11, 4, 0, 92, 0, 4, 0,215, 11, 4, 0,216, 11, 2, 0,217, 11, 2, 0,218, 11, 2, 0,219, 11, 2, 0,220, 11, - 2, 0,221, 11, 2, 0,222, 11, 2, 0,223, 11, 2, 0, 27, 0,187, 0,154, 4,138, 0, 11, 0,208, 1,224, 11, 7, 0,225, 11, - 7, 0,226, 11, 7, 0,250, 1, 7, 0,227, 11, 7, 0,228, 11, 7, 0,229, 11, 4, 0, 92, 0, 2, 0,230, 11, 2, 0,231, 11, - 64, 0,249, 1,209, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0,232, 11,210, 1, 6, 0,210, 1, 0, 0, -210, 1, 1, 0,209, 1,192, 9, 4, 0, 1, 1, 2, 0,233, 11, 2, 0, 18, 0,211, 1, 5, 0,211, 1, 0, 0,211, 1, 1, 0, - 14, 0,234, 11, 4, 0,235, 11, 4, 0, 18, 0,212, 1, 9, 0,212, 1, 0, 0,212, 1, 1, 0, 14, 0,127, 0,211, 1,236, 11, - 4, 0, 18, 0, 2, 0,233, 11, 2, 0,237, 11, 7, 0, 93, 0, 0, 0,238, 11,178, 0, 6, 0, 22, 0, 32, 0, 14, 0,123, 5, - 4, 0, 18, 0, 2, 0,239, 11, 2, 0,240, 11, 11, 0,241, 11,213, 1, 6, 0, 14, 0,242, 11, 4, 0,243, 11, 4, 0,244, 11, - 4, 0, 18, 0, 4, 0, 27, 0,237, 0,245, 11,214, 1, 19, 0, 22, 0, 32, 0,215, 1,246, 11,215, 1,247, 11, 14, 0,248, 11, - 4, 0,249, 11, 2, 0,250, 11, 2, 0,251, 11, 14, 0,252, 11, 14, 0,253, 11,213, 1,254, 11, 14, 0,255, 11, 14, 0, 0, 12, - 14, 0, 1, 12, 14, 0, 2, 12,216, 1, 3, 12,216, 1, 4, 12,216, 1, 5, 12, 14, 0, 6, 12,237, 0, 7, 12,215, 1, 32, 0, -215, 1, 0, 0,215, 1, 1, 0, 11, 0, 8, 12, 4, 0,119, 8, 2, 0, 9, 12, 2, 0, 27, 0, 27, 1, 10, 12, 27, 1, 11, 12, - 0, 0, 12, 12, 2, 0, 13, 12, 2, 0, 14, 12, 2, 0,141, 8, 2, 0,142, 8, 2, 0, 15, 12, 2, 0, 16, 12, 2, 0, 15, 4, - 2, 0, 53, 7, 2, 0, 17, 12, 2, 0, 18, 12, 2, 0, 19, 12, 2, 0, 30, 0,217, 1, 20, 12,218, 1, 21, 12,219, 1, 22, 12, - 4, 0, 23, 12, 4, 0, 24, 12, 11, 0, 25, 12, 14, 0,253, 11, 14, 0,160, 8, 14, 0, 26, 12, 14, 0, 27, 12, 14, 0, 28, 12, -220, 1, 17, 0,220, 1, 0, 0,220, 1, 1, 0, 0, 0, 29, 12, 21, 0, 31, 0, 2, 0, 30, 12, 2, 0, 16, 0, 2, 0, 14, 0, - 2, 0, 31, 12, 2, 0, 32, 12, 2, 0, 33, 12, 2, 0, 34, 12, 2, 0, 35, 12, 2, 0, 18, 0, 2, 0, 36, 12, 2, 0, 32, 0, - 2, 0, 27, 0,221, 1, 37, 12,222, 1, 4, 0,222, 1, 0, 0,222, 1, 1, 0,220, 1, 38, 12,220, 1, 39, 12,223, 1, 11, 0, -223, 1, 0, 0,223, 1, 1, 0, 14, 0, 40, 12, 14, 0, 41, 12, 0, 0, 29, 12, 2, 0, 42, 12, 2, 0, 43, 12, 2, 0, 18, 0, - 2, 0, 44, 12, 4, 0, 45, 12, 11, 0, 46, 12,216, 1, 7, 0,216, 1, 0, 0,216, 1, 1, 0, 0, 0, 29, 12, 0, 0, 47, 12, - 14, 0, 59, 8, 4, 0, 48, 12, 4, 0, 18, 0,249, 0, 14, 0,249, 0, 0, 0,249, 0, 1, 0, 0, 0, 29, 12, 21, 0, 31, 0, -224, 1,135, 8, 11, 0, 49, 12, 11, 0, 50, 12,221, 1, 37, 12,213, 1, 51, 12, 14, 0, 52, 12,249, 0, 53, 12, 32, 1,239, 6, - 2, 0, 18, 0, 2, 0, 86, 1,225, 1, 12, 0,225, 1, 0, 0,225, 1, 1, 0, 11, 0, 2, 0, 11, 0, 54, 12, 0, 0, 19, 0, - 2, 0, 16, 0, 2, 0, 18, 0, 7, 0,138, 9, 7, 0,129, 0, 7, 0,132, 4, 7, 0, 88, 9, 7, 0, 80, 10,226, 1, 5, 0, - 7, 0, 55, 12, 4, 0, 56, 12, 4, 0, 57, 12, 4, 0, 87, 1, 4, 0, 18, 0,227, 1, 6, 0, 7, 0, 58, 12, 7, 0, 59, 12, - 7, 0, 60, 12, 7, 0, 61, 12, 4, 0, 16, 0, 4, 0, 18, 0,228, 1, 5, 0, 7, 0,116, 9, 7, 0,117, 9, 7, 0,240, 2, - 2, 0, 42, 2, 2, 0, 43, 2,229, 1, 5, 0,228, 1, 2, 0, 4, 0, 53, 0, 7, 0, 62, 12, 7, 0,116, 9, 7, 0,117, 9, -230, 1, 4, 0, 2, 0, 63, 12, 2, 0, 64, 12, 2, 0, 65, 12, 2, 0, 66, 12,231, 1, 2, 0, 37, 0, 37, 7, 21, 0,156, 9, -232, 1, 3, 0, 19, 0, 67, 12, 4, 0, 18, 0, 4, 0, 27, 0,233, 1, 6, 0, 7, 0,108, 0, 7, 0,209, 2, 7, 0, 68, 12, - 7, 0, 27, 0, 2, 0,250, 0, 2, 0, 69, 12,234, 1, 5, 0, 7, 0, 70, 12, 7, 0,128, 0, 7, 0,193, 9, 7, 0,194, 9, - 4, 0, 18, 0,235, 1, 6, 0, 22, 0, 42, 7, 0, 0, 71, 12, 0, 0, 72, 12, 2, 0, 73, 12, 2, 0, 18, 0, 4, 0, 74, 12, -236, 1, 7, 0,236, 1, 0, 0,236, 1, 1, 0, 0, 0, 19, 0,235, 1, 75, 12, 2, 0, 76, 12, 2, 0, 16, 0, 7, 0, 60, 0, -237, 1, 7, 0, 14, 0, 77, 12, 0, 0, 78, 12, 11, 0, 79, 12, 7, 0, 60, 0, 7, 0,138, 9, 4, 0, 16, 0, 4, 0, 18, 0, -238, 1, 3, 0, 7, 0, 80, 12, 4, 0, 18, 0, 4, 0, 27, 0,239, 1, 15, 0,239, 1, 0, 0,239, 1, 1, 0,106, 1, 11, 10, -237, 1, 61, 0, 14, 0,188, 3, 30, 0, 49, 0,238, 1, 81, 12, 4, 0, 53, 0, 7, 0, 60, 0, 2, 0, 18, 0, 2, 0, 22, 1, - 4, 0, 82, 12, 0, 0, 71, 12, 4, 0, 83, 12, 7, 0, 84, 12,240, 1, 2, 0, 0, 0, 85, 12, 0, 0, 86, 12,241, 1, 4, 0, -241, 1, 0, 0,241, 1, 1, 0,176, 0, 70, 3, 14, 0, 87, 12,242, 1, 25, 0,242, 1, 0, 0,242, 1, 1, 0, 14, 0, 88, 12, -176, 0, 86, 9,241, 1, 89, 12, 14, 0, 90, 12, 14, 0,188, 3, 0, 0, 19, 0, 7, 0,138, 9, 7, 0, 91, 12, 7, 0, 89, 0, - 7, 0, 90, 0, 7, 0, 76, 10, 7, 0, 77, 10, 7, 0,253, 2, 7, 0,148, 3, 7, 0, 88, 9, 7, 0, 80, 10, 2, 0, 92, 12, - 2, 0, 93, 12, 2, 0, 91, 0, 2, 0, 16, 0, 11, 0, 94, 12, 4, 0, 18, 0, 4, 0, 30, 0,243, 1, 6, 0,243, 1, 0, 0, -243, 1, 1, 0, 14, 0, 88, 12, 4, 0, 18, 0, 4, 0, 13, 2, 0, 0, 19, 0,244, 1, 11, 0,244, 1, 0, 0,244, 1, 1, 0, - 22, 0, 42, 7, 0, 0, 95, 12, 4, 0, 74, 12, 2, 0, 96, 12, 2, 0, 27, 0, 0, 0, 71, 12, 4, 0, 82, 12, 2, 0, 18, 0, - 2, 0, 97, 12,245, 1, 10, 0,245, 1, 0, 0,245, 1, 1, 0, 14, 0, 98, 12, 0, 0, 29, 12, 0, 0, 19, 0, 0, 0, 99, 12, - 0, 0,100, 12, 2, 0, 18, 0, 2, 0, 97, 12, 4, 0,101, 12,246, 1, 5, 0,246, 1, 0, 0,246, 1, 1, 0, 0, 0, 71, 12, - 4, 0, 82, 12, 7, 0,230, 2, 34, 0, 12, 0,176, 0,179, 3,176, 0,102, 12,241, 1, 89, 12, 14, 0,103, 12,242, 1,104, 12, - 14, 0,105, 12, 14, 0,106, 12, 4, 0, 18, 0, 4, 0,251, 0, 2, 0,107, 12, 2, 0,108, 12, 7, 0,109, 12,247, 1, 2, 0, + 7, 0, 5, 0, 7, 0, 6, 0, 2, 0, 18, 0, 2, 0,224, 10,189, 1, 10, 0, 2, 0, 62, 4, 2, 0, 18, 0, 7, 0,217, 4, + 7, 0,225, 10, 7, 0,226, 10, 7, 0,227, 10, 7, 0,228, 10,188, 1,229, 10,188, 1,230, 10,188, 1,231, 10, 54, 0, 11, 0, + 4, 0, 18, 0, 4, 0, 63, 0, 4, 0,232, 10, 4, 0,233, 10, 19, 0,234, 10, 19, 0,235, 10,189, 1,236, 10, 7, 0,237, 10, + 7, 0,238, 10, 7, 0,239, 10, 7, 0,240, 10, 0, 1, 10, 0, 4, 0,254, 9, 4, 0,241, 10, 7, 0,242, 10, 7, 0,243, 10, + 7, 0,244, 10, 7, 0,245, 10, 7, 0, 9, 0, 7, 0, 11, 0, 4, 0, 87, 1, 4, 0, 1, 3,255, 0, 18, 0, 4, 0,132, 0, + 4, 0,246, 10, 4, 0,247, 10, 7, 0,248, 10, 4, 0,249, 10, 7, 0,250, 10, 7, 0,251, 10, 4, 0,252, 10, 7, 0,253, 10, + 4, 0,254, 10, 7, 0,255, 10, 0, 1, 0, 11, 7, 0, 1, 11, 7, 0, 2, 11, 7, 0, 3, 11, 7, 0, 4, 11, 4, 0, 5, 11, + 4, 0, 27, 0,190, 1, 4, 0, 42, 0,244, 2, 7, 0, 6, 11, 7, 0,178, 1, 7, 0, 27, 0,213, 0, 34, 0, 22, 0, 32, 0, +190, 1, 7, 11, 54, 0,229, 10, 46, 0, 8, 11, 52, 0, 9, 11, 25, 0,154, 0, 0, 0, 10, 11, 7, 0, 11, 11, 2, 0,109, 6, + 2, 0, 12, 11, 4, 0,108, 0, 4, 0, 18, 0, 7, 0, 13, 11, 4, 0, 90, 2, 4, 0, 14, 11, 7, 0, 15, 11, 7, 0, 16, 11, + 7, 0, 17, 11, 7, 0,178, 1, 4, 0, 18, 11, 7, 0, 19, 11, 0, 0, 20, 11, 0, 0, 21, 11, 0, 0, 22, 11, 0, 0, 23, 11, + 7, 0, 24, 11, 7, 0, 25, 11, 7, 0, 26, 11, 7, 0, 1, 3, 7, 0, 27, 11, 4, 0, 28, 11, 7, 0,240, 5, 7, 0, 29, 11, + 7, 0, 30, 11,191, 1, 10, 0, 4, 0, 16, 0, 4, 0,128, 0, 4, 0, 18, 0, 4, 0, 15, 4, 4, 0, 31, 11, 4, 0, 32, 11, + 4, 0, 33, 11, 4, 0, 70, 0, 0, 0, 19, 0, 11, 0, 2, 0,192, 1, 1, 0, 0, 0, 70, 7, 95, 0, 8, 0,191, 1, 34, 11, + 4, 0, 35, 11, 4, 0, 36, 11, 4, 0, 37, 11, 4, 0, 38, 11, 4, 0, 30, 0, 11, 0, 39, 11,192, 1, 40, 11,193, 1, 5, 0, + 7, 0,165, 2, 7, 0,240, 2, 7, 0, 40, 2, 2, 0,147, 2, 2, 0, 27, 0,194, 1, 5, 0, 7, 0,165, 2, 7, 0,159, 4, + 7, 0, 41, 11, 7, 0, 42, 11, 7, 0,240, 2,195, 1, 5, 0, 27, 0, 43, 11,196, 1, 21, 0, 7, 0, 75, 6, 7, 0, 44, 11, + 7, 0, 56, 0,197, 1, 3, 0, 7, 0, 45, 11, 4, 0, 46, 11, 4, 0, 47, 11,198, 1, 7, 0, 4, 0, 48, 11, 4, 0, 49, 11, + 4, 0, 50, 11, 7, 0, 51, 11, 7, 0, 52, 11, 7, 0, 53, 11, 7, 0, 56, 0,199, 1, 8, 0,199, 1, 0, 0,199, 1, 1, 0, + 27, 0, 44, 0, 4, 0, 3, 1, 2, 0, 18, 0, 2, 0, 87, 1, 7, 0,240, 2, 7, 0, 56, 9,200, 1, 7, 0,200, 1, 0, 0, +200, 1, 1, 0, 27, 0, 44, 0, 2, 0,225, 2, 2, 0, 18, 0, 2, 0, 14, 2, 2, 0, 56, 0,201, 1, 17, 0,194, 1, 8, 4, +194, 1, 54, 11,193, 1, 55, 11,194, 1, 39, 9,195, 1, 56, 11, 4, 0, 82, 0, 7, 0,240, 2, 7, 0, 7, 3, 7, 0, 57, 11, + 4, 0, 48, 11, 4, 0, 58, 11, 7, 0, 52, 11, 7, 0, 53, 11, 7, 0,108, 0, 4, 0, 59, 11, 2, 0, 18, 0, 2, 0, 60, 11, +202, 1, 15, 0, 7, 0,255, 0, 7, 0, 61, 11, 7, 0, 45, 11, 7, 0, 62, 11, 7, 0, 63, 11, 7, 0, 64, 11, 7, 0, 65, 11, + 7, 0, 66, 11, 7, 0, 67, 11, 7, 0, 68, 11, 7, 0, 69, 11, 7, 0, 70, 11, 7, 0, 71, 11, 4, 0, 18, 0, 4, 0, 72, 11, +203, 1,128, 0, 22, 0, 32, 0, 34, 0, 75, 0,204, 1, 73, 11,202, 1, 74, 11,187, 0,154, 4, 4, 0, 18, 0, 4, 0, 56, 0, + 2, 0, 16, 0, 2, 0, 58, 10, 2, 0, 75, 11, 2, 0,122, 1, 2, 0, 76, 11, 2, 0,232, 3, 2, 0, 77, 11, 2, 0, 78, 11, + 2, 0, 79, 11, 2, 0, 80, 11, 2, 0, 81, 11, 2, 0, 82, 11, 2, 0, 83, 11, 2, 0, 84, 11, 2, 0, 85, 11, 2, 0,224, 5, + 2, 0, 86, 11, 2, 0, 87, 11, 2, 0, 88, 11, 2, 0, 89, 11, 2, 0, 90, 11, 2, 0, 29, 2, 2, 0, 32, 9, 2, 0, 7, 9, + 2, 0, 91, 11, 2, 0, 92, 11, 2, 0, 25, 4, 2, 0, 26, 4, 2, 0, 93, 11, 2, 0, 94, 11, 2, 0, 95, 11, 2, 0, 96, 11, + 7, 0, 97, 11, 7, 0, 98, 11, 7, 0, 99, 11, 7, 0,100, 11, 7, 0,101, 11, 7, 0,102, 11, 7, 0,103, 11, 2, 0,154, 5, + 2, 0,104, 11, 7, 0,105, 11, 7, 0,106, 11, 7, 0,107, 11, 7, 0, 14, 9, 7, 0, 91, 0, 7, 0, 7, 3, 7, 0, 20, 9, + 7, 0,108, 11, 7, 0,109, 11, 7, 0,110, 11, 7, 0,111, 11, 7, 0,112, 11, 7, 0,113, 11, 4, 0, 15, 9, 4, 0, 13, 9, + 4, 0,114, 11, 4, 0,115, 11, 2, 0,116, 11, 2, 0,117, 11, 7, 0, 16, 9, 7, 0, 17, 9, 7, 0, 18, 9, 7, 0,118, 11, + 7, 0,119, 11, 7, 0,120, 11, 7, 0,121, 11, 7, 0,122, 11, 7, 0,123, 11, 7, 0,124, 11, 7, 0,125, 11, 7, 0,126, 11, + 7, 0,222, 3, 7, 0,108, 0, 7, 0,127, 11, 7, 0,128, 11, 7, 0,129, 11, 7, 0,130, 11, 7, 0,214, 0, 7, 0,131, 11, + 4, 0,132, 11, 4, 0,133, 11, 7, 0,134, 11, 7, 0,135, 11, 7, 0,136, 11, 7, 0,137, 11, 7, 0,138, 11, 7, 0,213, 0, + 7, 0,139, 11, 7, 0, 52, 4, 7, 0, 50, 4, 7, 0, 51, 4, 7, 0,140, 11, 7, 0,141, 11, 7, 0,142, 11, 7, 0,143, 11, + 7, 0,144, 11, 7, 0,145, 11, 7, 0,146, 11, 7, 0,147, 11, 7, 0,148, 11, 7, 0,149, 11, 7, 0,150, 11, 7, 0,151, 11, + 7, 0,152, 11, 7, 0,153, 11, 7, 0,154, 11, 7, 0,155, 11, 7, 0,156, 11, 7, 0,157, 11, 4, 0,158, 11, 4, 0,159, 11, + 46, 0,140, 1, 64, 0, 0, 4, 14, 0,160, 11, 64, 0,161, 11, 27, 0,162, 11, 27, 0,163, 11, 31, 0, 80, 0,182, 0, 73, 1, +182, 0,164, 11,150, 0, 52, 0,150, 0, 0, 0,150, 0, 1, 0,203, 1,165, 11,201, 1,166, 11,198, 1,217, 9,190, 0, 80, 4, + 11, 0, 81, 4,205, 1,167, 11,205, 1,168, 11, 14, 0,169, 11, 14, 0,170, 11,135, 0,171, 11,143, 0,172, 11,143, 0,173, 11, + 27, 0,174, 11, 27, 0,175, 11, 27, 0, 38, 0, 14, 0, 25, 10, 0, 0, 19, 0, 7, 0,244, 0, 7, 0, 36, 3, 7, 0,176, 11, + 7, 0,177, 11, 4, 0,214, 2, 4, 0,178, 11, 4, 0, 18, 0, 4, 0, 15, 9, 4, 0,179, 11, 4, 0,180, 11, 4, 0,181, 11, + 4, 0,182, 11, 2, 0,251, 0, 2, 0,183, 11, 2, 0,184, 11, 2, 0,185, 11, 0, 0,186, 11, 2, 0,187, 11, 2, 0,188, 11, + 2, 0,189, 11, 11, 0,190, 11,139, 0,153, 4, 14, 0, 21, 3, 14, 0,191, 11,197, 1,192, 11, 4, 0,193, 11, 4, 0,194, 11, +206, 1,195, 11,141, 0, 33, 3,207, 1,196, 11, 7, 0,197, 11, 7, 0,198, 11, 7, 0,199, 11,137, 0, 38, 0,208, 1,151, 9, + 7, 0,123, 4, 7, 0,200, 11, 7, 0,201, 11, 7, 0, 75, 6, 7, 0,236, 3, 7, 0,222, 3, 7, 0,202, 11, 7, 0, 92, 2, + 7, 0,203, 11, 7, 0,204, 11, 7, 0,205, 11, 7, 0,206, 11, 7, 0,207, 11, 7, 0,208, 11, 7, 0,124, 4, 7, 0,209, 11, + 7, 0,210, 11, 7, 0,211, 11, 7, 0,125, 4, 7, 0,121, 4, 7, 0,122, 4, 7, 0,212, 11, 7, 0,213, 11, 7, 0,214, 11, + 4, 0,215, 11, 4, 0, 92, 0, 4, 0,216, 11, 4, 0,217, 11, 2, 0,218, 11, 2, 0,219, 11, 2, 0,220, 11, 2, 0,221, 11, + 2, 0,222, 11, 2, 0,223, 11, 2, 0,224, 11, 2, 0, 27, 0,187, 0,154, 4,138, 0, 11, 0,208, 1,225, 11, 7, 0,226, 11, + 7, 0,227, 11, 7, 0,251, 1, 7, 0,228, 11, 7, 0,229, 11, 7, 0,230, 11, 4, 0, 92, 0, 2, 0,231, 11, 2, 0,232, 11, + 64, 0,250, 1,209, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0,233, 11,210, 1, 6, 0,210, 1, 0, 0, +210, 1, 1, 0,209, 1,193, 9, 4, 0, 1, 1, 2, 0,234, 11, 2, 0, 18, 0,211, 1, 5, 0,211, 1, 0, 0,211, 1, 1, 0, + 14, 0,235, 11, 4, 0,236, 11, 4, 0, 18, 0,212, 1, 9, 0,212, 1, 0, 0,212, 1, 1, 0, 14, 0,127, 0,211, 1,237, 11, + 4, 0, 18, 0, 2, 0,234, 11, 2, 0,238, 11, 7, 0, 93, 0, 0, 0,239, 11,178, 0, 6, 0, 22, 0, 32, 0, 14, 0,123, 5, + 4, 0, 18, 0, 2, 0,240, 11, 2, 0,241, 11, 11, 0,242, 11,213, 1, 6, 0, 14, 0,243, 11, 4, 0,244, 11, 4, 0,245, 11, + 4, 0, 18, 0, 4, 0, 27, 0,237, 0,246, 11,214, 1, 19, 0, 22, 0, 32, 0,215, 1,247, 11,215, 1,248, 11, 14, 0,249, 11, + 4, 0,250, 11, 2, 0,251, 11, 2, 0,252, 11, 14, 0,253, 11, 14, 0,254, 11,213, 1,255, 11, 14, 0, 0, 12, 14, 0, 1, 12, + 14, 0, 2, 12, 14, 0, 3, 12,216, 1, 4, 12,216, 1, 5, 12,216, 1, 6, 12, 14, 0, 7, 12,237, 0, 8, 12,215, 1, 32, 0, +215, 1, 0, 0,215, 1, 1, 0, 11, 0, 9, 12, 4, 0,119, 8, 2, 0, 10, 12, 2, 0, 27, 0, 27, 1, 11, 12, 27, 1, 12, 12, + 0, 0, 13, 12, 2, 0, 14, 12, 2, 0, 15, 12, 2, 0,141, 8, 2, 0,142, 8, 2, 0, 16, 12, 2, 0, 17, 12, 2, 0, 15, 4, + 2, 0, 53, 7, 2, 0, 18, 12, 2, 0, 19, 12, 2, 0, 20, 12, 2, 0, 30, 0,217, 1, 21, 12,218, 1, 22, 12,219, 1, 23, 12, + 4, 0, 24, 12, 4, 0, 25, 12, 11, 0, 26, 12, 14, 0,254, 11, 14, 0,161, 8, 14, 0, 27, 12, 14, 0, 28, 12, 14, 0, 29, 12, +220, 1, 17, 0,220, 1, 0, 0,220, 1, 1, 0, 0, 0, 30, 12, 21, 0, 31, 0, 2, 0, 31, 12, 2, 0, 16, 0, 2, 0, 14, 0, + 2, 0, 32, 12, 2, 0, 33, 12, 2, 0, 34, 12, 2, 0, 35, 12, 2, 0, 36, 12, 2, 0, 18, 0, 2, 0, 37, 12, 2, 0, 32, 0, + 2, 0, 27, 0,221, 1, 38, 12,222, 1, 4, 0,222, 1, 0, 0,222, 1, 1, 0,220, 1, 39, 12,220, 1, 40, 12,223, 1, 11, 0, +223, 1, 0, 0,223, 1, 1, 0, 14, 0, 41, 12, 14, 0, 42, 12, 0, 0, 30, 12, 2, 0, 43, 12, 2, 0, 44, 12, 2, 0, 18, 0, + 2, 0, 45, 12, 4, 0, 46, 12, 11, 0, 47, 12,216, 1, 7, 0,216, 1, 0, 0,216, 1, 1, 0, 0, 0, 30, 12, 0, 0, 48, 12, + 14, 0, 59, 8, 4, 0, 49, 12, 4, 0, 18, 0,249, 0, 14, 0,249, 0, 0, 0,249, 0, 1, 0, 0, 0, 30, 12, 21, 0, 31, 0, +224, 1,135, 8, 11, 0, 50, 12, 11, 0, 51, 12,221, 1, 38, 12,213, 1, 52, 12, 14, 0, 53, 12,249, 0, 54, 12, 32, 1,239, 6, + 2, 0, 18, 0, 2, 0, 86, 1,225, 1, 12, 0,225, 1, 0, 0,225, 1, 1, 0, 11, 0, 2, 0, 11, 0, 55, 12, 0, 0, 19, 0, + 2, 0, 16, 0, 2, 0, 18, 0, 7, 0,139, 9, 7, 0,129, 0, 7, 0,132, 4, 7, 0, 89, 9, 7, 0, 81, 10,226, 1, 5, 0, + 7, 0, 56, 12, 4, 0, 57, 12, 4, 0, 58, 12, 4, 0, 87, 1, 4, 0, 18, 0,227, 1, 6, 0, 7, 0, 59, 12, 7, 0, 60, 12, + 7, 0, 61, 12, 7, 0, 62, 12, 4, 0, 16, 0, 4, 0, 18, 0,228, 1, 5, 0, 7, 0,117, 9, 7, 0,118, 9, 7, 0,240, 2, + 2, 0, 43, 2, 2, 0, 44, 2,229, 1, 5, 0,228, 1, 2, 0, 4, 0, 53, 0, 7, 0, 63, 12, 7, 0,117, 9, 7, 0,118, 9, +230, 1, 4, 0, 2, 0, 64, 12, 2, 0, 65, 12, 2, 0, 66, 12, 2, 0, 67, 12,231, 1, 2, 0, 37, 0, 37, 7, 21, 0,157, 9, +232, 1, 3, 0, 19, 0, 68, 12, 4, 0, 18, 0, 4, 0, 27, 0,233, 1, 6, 0, 7, 0,108, 0, 7, 0,209, 2, 7, 0, 69, 12, + 7, 0, 27, 0, 2, 0,250, 0, 2, 0, 70, 12,234, 1, 5, 0, 7, 0, 71, 12, 7, 0,128, 0, 7, 0,194, 9, 7, 0,195, 9, + 4, 0, 18, 0,235, 1, 6, 0, 22, 0, 42, 7, 0, 0, 72, 12, 0, 0, 73, 12, 2, 0, 74, 12, 2, 0, 18, 0, 4, 0, 75, 12, +236, 1, 7, 0,236, 1, 0, 0,236, 1, 1, 0, 0, 0, 19, 0,235, 1, 76, 12, 2, 0, 77, 12, 2, 0, 16, 0, 7, 0, 60, 0, +237, 1, 7, 0, 14, 0, 78, 12, 0, 0, 79, 12, 11, 0, 80, 12, 7, 0, 60, 0, 7, 0,139, 9, 4, 0, 16, 0, 4, 0, 18, 0, +238, 1, 3, 0, 7, 0, 81, 12, 4, 0, 18, 0, 4, 0, 27, 0,239, 1, 15, 0,239, 1, 0, 0,239, 1, 1, 0,106, 1, 12, 10, +237, 1, 61, 0, 14, 0,188, 3, 30, 0, 49, 0,238, 1, 82, 12, 4, 0, 53, 0, 7, 0, 60, 0, 2, 0, 18, 0, 2, 0, 22, 1, + 4, 0, 83, 12, 0, 0, 72, 12, 4, 0, 84, 12, 7, 0, 85, 12,240, 1, 2, 0, 0, 0, 86, 12, 0, 0, 87, 12,241, 1, 4, 0, +241, 1, 0, 0,241, 1, 1, 0,176, 0, 70, 3, 14, 0, 88, 12,242, 1, 25, 0,242, 1, 0, 0,242, 1, 1, 0, 14, 0, 89, 12, +176, 0, 87, 9,241, 1, 90, 12, 14, 0, 91, 12, 14, 0,188, 3, 0, 0, 19, 0, 7, 0,139, 9, 7, 0, 92, 12, 7, 0, 90, 0, + 7, 0, 91, 0, 7, 0, 77, 10, 7, 0, 78, 10, 7, 0,253, 2, 7, 0,148, 3, 7, 0, 89, 9, 7, 0, 81, 10, 2, 0, 93, 12, + 2, 0, 94, 12, 2, 0, 67, 0, 2, 0, 16, 0, 11, 0, 95, 12, 4, 0, 18, 0, 4, 0, 30, 0,243, 1, 6, 0,243, 1, 0, 0, +243, 1, 1, 0, 14, 0, 89, 12, 4, 0, 18, 0, 4, 0, 14, 2, 0, 0, 19, 0,244, 1, 11, 0,244, 1, 0, 0,244, 1, 1, 0, + 22, 0, 42, 7, 0, 0, 96, 12, 4, 0, 75, 12, 2, 0, 97, 12, 2, 0, 27, 0, 0, 0, 72, 12, 4, 0, 83, 12, 2, 0, 18, 0, + 2, 0, 98, 12,245, 1, 10, 0,245, 1, 0, 0,245, 1, 1, 0, 14, 0, 99, 12, 0, 0, 30, 12, 0, 0, 19, 0, 0, 0,100, 12, + 0, 0,101, 12, 2, 0, 18, 0, 2, 0, 98, 12, 4, 0,102, 12,246, 1, 5, 0,246, 1, 0, 0,246, 1, 1, 0, 0, 0, 72, 12, + 4, 0, 83, 12, 7, 0,230, 2, 34, 0, 12, 0,176, 0,179, 3,176, 0,103, 12,241, 1, 90, 12, 14, 0,104, 12,242, 1,105, 12, + 14, 0,106, 12, 14, 0,107, 12, 4, 0, 18, 0, 4, 0,251, 0, 2, 0,108, 12, 2, 0,109, 12, 7, 0,110, 12,247, 1, 2, 0, 22, 0, 32, 0, 34, 0, 75, 0,248, 1, 5, 0,248, 1, 0, 0,248, 1, 1, 0, 4, 0, 16, 0, 4, 0, 18, 0, 0, 0,172, 5, -249, 1, 6, 0,248, 1,110, 12, 27, 0, 44, 0, 4, 0,111, 12, 7, 0,112, 12, 4, 0,113, 12, 4, 0,253, 9,250, 1, 3, 0, -248, 1,110, 12, 4, 0,111, 12, 7, 0,114, 12,251, 1, 8, 0,248, 1,110, 12, 27, 0, 44, 0, 7, 0, 77, 1, 7, 0,115, 12, - 7, 0, 36, 3, 7, 0,149, 9, 4, 0,111, 12, 4, 0,116, 12,252, 1, 5, 0,248, 1,110, 12, 7, 0,117, 12, 7, 0,176, 2, - 7, 0, 3, 3, 7, 0, 56, 0,253, 1, 3, 0,248, 1,110, 12, 7, 0,149, 9, 7, 0,118, 12,196, 1, 4, 0, 7, 0,119, 12, - 7, 0,127, 11, 2, 0,120, 12, 2, 0, 87, 1,254, 1, 14, 0,254, 1, 0, 0,254, 1, 1, 0, 14, 0,121, 12, 14, 0,122, 12, - 14, 0,123, 12, 0, 0,172, 5, 4, 0, 32, 0, 4, 0, 18, 0, 4, 0,124, 12, 7, 0,125, 12, 4, 0,113, 12, 4, 0,253, 9, - 7, 0, 84, 4, 7, 0, 5, 3,204, 1, 23, 0, 4, 0,111, 12, 4, 0,126, 12, 7, 0,127, 12, 7, 0, 1, 3, 7, 0,128, 12, - 7, 0,229, 8, 7, 0,119, 12, 7, 0,129, 12, 7, 0,209, 2, 7, 0,247, 10, 7, 0,217, 4, 7, 0,130, 12, 7, 0,131, 12, - 7, 0,132, 12, 7, 0,133, 12, 7, 0,134, 12, 7, 0,135, 12, 7, 0,136, 12, 7, 0,137, 12, 7, 0,138, 12, 7, 0,139, 12, - 7, 0,140, 12, 14, 0,141, 12,123, 0, 40, 0,122, 0,142, 12,255, 1, 73, 11, 64, 0,143, 12, 64, 0,160, 11, 64, 0,144, 12, - 0, 2,145, 12, 43, 0,169, 0, 43, 0,146, 12, 43, 0,147, 12, 7, 0,148, 12, 7, 0,149, 12, 7, 0,150, 12, 7, 0,151, 12, - 7, 0,152, 12, 7, 0,118, 8, 7, 0,153, 12, 7, 0,178, 1, 7, 0,154, 12, 4, 0,155, 12, 4, 0,156, 12, 4, 0,157, 12, - 4, 0, 92, 0, 4, 0, 27, 0, 4, 0,158, 12, 2, 0,159, 12, 2, 0,160, 12, 4, 0,161, 12, 7, 0,209, 2, 4, 0,162, 12, - 7, 0,163, 12, 4, 0,164, 12, 4, 0,165, 12, 4, 0,166, 12,139, 0,167, 12, 14, 0,168, 12,187, 0,154, 4, 4, 0,169, 12, - 7, 0,170, 12, 7, 0,171, 12, 4, 0, 30, 0,124, 0, 12, 0,122, 0,142, 12,150, 0, 56, 3, 7, 0,143, 1, 7, 0,118, 8, - 7, 0,172, 12, 7, 0,173, 12, 7, 0,174, 12, 2, 0,175, 12, 2, 0,176, 12, 2, 0,177, 12, 2, 0, 16, 0, 4, 0, 92, 0, -125, 0, 13, 0,122, 0,142, 12,141, 0, 33, 3,143, 0, 35, 3, 7, 0,192, 9, 7, 0,178, 12, 7, 0,179, 12, 7, 0, 79, 1, - 7, 0,180, 12, 4, 0, 33, 10, 4, 0, 29, 3, 2, 0, 16, 0, 2, 0, 27, 0, 4, 0, 30, 0, 1, 2, 15, 0, 22, 0, 32, 0, - 34, 0, 75, 0, 46, 1,227, 8, 7, 0,181, 12, 7, 0,182, 12, 7, 0,183, 12, 7, 0,184, 12, 7, 0,148, 9, 7, 0,185, 12, - 7, 0,186, 12, 7, 0,187, 12, 7, 0, 84, 4, 7, 0,229, 8, 2, 0, 18, 0, 2, 0,112, 9,231, 0, 3, 0, 4, 0,126, 0, - 2, 0,215, 6, 2, 0,188, 12, 2, 2, 5, 0, 0, 0,193, 8, 2, 0,194, 8, 2, 0, 72, 5, 2, 0,189, 12, 2, 0,190, 12, -229, 0, 16, 0, 22, 0, 32, 0, 34, 0, 75, 0, 0, 0, 35, 0, 4, 0,143, 0, 4, 0,144, 0, 4, 0,191, 12, 7, 0,162, 0, - 7, 0,163, 0, 44, 0,138, 0, 3, 2,150, 9,178, 0,182, 3, 4, 2,192, 12, 11, 0,193, 12, 2, 2,194, 12, 4, 0, 18, 0, - 4, 0, 22, 0, 13, 1, 10, 0, 4, 0,132, 0, 4, 0,195, 12, 52, 0,196, 12, 7, 0,197, 12, 2, 0,198, 12, 0, 0,181, 2, - 4, 0,126, 0, 5, 2,175, 3, 6, 2,199, 12, 7, 0,200, 12, 7, 2, 3, 0, 4, 0,126, 0, 7, 0,201, 12, 7, 0, 79, 1, - 8, 2, 11, 0, 11, 0,202, 12, 7, 0,203, 12, 7, 0,204, 12, 7, 0, 27, 0, 7, 0,205, 12, 2, 0,206, 12, 2, 0, 91, 0, - 7, 0,207, 12, 7, 0,208, 12, 7, 0,209, 12, 7, 0,210, 12, 6, 2, 3, 0, 7, 0,211, 12, 4, 0,126, 0, 4, 0, 18, 0, - 5, 2, 24, 0, 5, 2, 0, 0, 5, 2, 1, 0, 0, 0, 19, 0, 7, 0,212, 12, 7, 0,213, 12, 7, 0,214, 12, 7, 0,215, 12, - 7, 0, 5, 11, 4, 0,216, 12, 4, 0,217, 12, 6, 2,218, 12, 7, 0,219, 12, 7, 0,201, 12, 4, 0, 18, 0, 4, 0,220, 12, - 4, 0,221, 12, 7, 0, 84, 12, 2, 0,222, 12, 2, 0,227, 3, 2, 0,223, 12, 2, 0,224, 12, 2, 0,225, 12, 2, 0, 30, 0, - 7, 0,226, 12, 9, 2, 22, 0, 4, 0, 18, 0, 2, 0,227, 12, 2, 0,228, 12, 7, 0,229, 12, 2, 0,230, 12, 2, 0,231, 12, - 2, 0,232, 12, 2, 0,233, 12, 2, 0,234, 12, 2, 0,235, 12, 2, 0,236, 12, 2, 0, 3, 3, 4, 0,237, 12, 4, 0,238, 12, - 2, 0,239, 12, 2, 0,240, 12, 7, 0, 94, 1, 4, 0,241, 12, 4, 0,242, 12, 7, 0,243, 12, 7, 0,244, 12, 4, 0, 74, 0, +249, 1, 6, 0,248, 1,111, 12, 27, 0, 44, 0, 4, 0,112, 12, 7, 0,113, 12, 4, 0,114, 12, 4, 0,254, 9,250, 1, 3, 0, +248, 1,111, 12, 4, 0,112, 12, 7, 0,115, 12,251, 1, 8, 0,248, 1,111, 12, 27, 0, 44, 0, 7, 0, 77, 1, 7, 0,116, 12, + 7, 0, 36, 3, 7, 0,150, 9, 4, 0,112, 12, 4, 0,117, 12,252, 1, 5, 0,248, 1,111, 12, 7, 0,118, 12, 7, 0,176, 2, + 7, 0, 3, 3, 7, 0, 56, 0,253, 1, 3, 0,248, 1,111, 12, 7, 0,150, 9, 7, 0,119, 12,196, 1, 4, 0, 7, 0,120, 12, + 7, 0,128, 11, 2, 0,121, 12, 2, 0, 87, 1,254, 1, 14, 0,254, 1, 0, 0,254, 1, 1, 0, 14, 0,122, 12, 14, 0,123, 12, + 14, 0,124, 12, 0, 0,172, 5, 4, 0, 32, 0, 4, 0, 18, 0, 4, 0,125, 12, 7, 0,126, 12, 4, 0,114, 12, 4, 0,254, 9, + 7, 0, 84, 4, 7, 0, 5, 3,204, 1, 23, 0, 4, 0,112, 12, 4, 0,127, 12, 7, 0,128, 12, 7, 0, 1, 3, 7, 0,129, 12, + 7, 0,230, 8, 7, 0,120, 12, 7, 0,130, 12, 7, 0,209, 2, 7, 0,248, 10, 7, 0,217, 4, 7, 0,131, 12, 7, 0,132, 12, + 7, 0,133, 12, 7, 0,134, 12, 7, 0,135, 12, 7, 0,136, 12, 7, 0,137, 12, 7, 0,138, 12, 7, 0,139, 12, 7, 0,140, 12, + 7, 0,141, 12, 14, 0,142, 12,123, 0, 40, 0,122, 0,143, 12,255, 1, 74, 11, 64, 0,144, 12, 64, 0,161, 11, 64, 0,145, 12, + 0, 2,146, 12, 43, 0,169, 0, 43, 0,147, 12, 43, 0,148, 12, 7, 0,149, 12, 7, 0,150, 12, 7, 0,151, 12, 7, 0,152, 12, + 7, 0,153, 12, 7, 0,118, 8, 7, 0,154, 12, 7, 0,178, 1, 7, 0,155, 12, 4, 0,156, 12, 4, 0,157, 12, 4, 0,158, 12, + 4, 0, 92, 0, 4, 0, 27, 0, 4, 0,159, 12, 2, 0,160, 12, 2, 0,161, 12, 4, 0,162, 12, 7, 0,209, 2, 4, 0,163, 12, + 7, 0,164, 12, 4, 0,165, 12, 4, 0,166, 12, 4, 0,167, 12,139, 0,168, 12, 14, 0,169, 12,187, 0,154, 4, 4, 0,170, 12, + 7, 0,171, 12, 7, 0,172, 12, 4, 0, 30, 0,124, 0, 12, 0,122, 0,143, 12,150, 0, 56, 3, 7, 0,143, 1, 7, 0,118, 8, + 7, 0,173, 12, 7, 0,174, 12, 7, 0,175, 12, 2, 0,176, 12, 2, 0,177, 12, 2, 0,178, 12, 2, 0, 16, 0, 4, 0, 92, 0, +125, 0, 13, 0,122, 0,143, 12,141, 0, 33, 3,143, 0, 35, 3, 7, 0,193, 9, 7, 0,179, 12, 7, 0,180, 12, 7, 0, 79, 1, + 7, 0,181, 12, 4, 0, 34, 10, 4, 0, 29, 3, 2, 0, 16, 0, 2, 0, 27, 0, 4, 0, 30, 0, 1, 2, 15, 0, 22, 0, 32, 0, + 34, 0, 75, 0, 46, 1,228, 8, 7, 0,182, 12, 7, 0,183, 12, 7, 0,184, 12, 7, 0,185, 12, 7, 0,149, 9, 7, 0,186, 12, + 7, 0,187, 12, 7, 0,188, 12, 7, 0, 84, 4, 7, 0,230, 8, 2, 0, 18, 0, 2, 0,113, 9,231, 0, 3, 0, 4, 0,126, 0, + 2, 0,215, 6, 2, 0,189, 12, 2, 2, 5, 0, 0, 0,194, 8, 2, 0,195, 8, 2, 0, 72, 5, 2, 0,190, 12, 2, 0,191, 12, +229, 0, 16, 0, 22, 0, 32, 0, 34, 0, 75, 0, 0, 0, 35, 0, 4, 0,143, 0, 4, 0,144, 0, 4, 0,192, 12, 7, 0,162, 0, + 7, 0,163, 0, 44, 0,138, 0, 3, 2,151, 9,178, 0,182, 3, 4, 2,193, 12, 11, 0,194, 12, 2, 2,195, 12, 4, 0, 18, 0, + 4, 0, 22, 0, 13, 1, 10, 0, 4, 0,132, 0, 4, 0,196, 12, 52, 0,197, 12, 7, 0,198, 12, 2, 0,199, 12, 0, 0,181, 2, + 4, 0,126, 0, 5, 2,175, 3, 6, 2,200, 12, 7, 0,201, 12, 7, 2, 3, 0, 4, 0,126, 0, 7, 0,202, 12, 7, 0, 79, 1, + 8, 2, 11, 0, 11, 0,203, 12, 7, 0,204, 12, 7, 0,205, 12, 7, 0, 27, 0, 7, 0,206, 12, 2, 0,207, 12, 2, 0, 67, 0, + 7, 0,208, 12, 7, 0,209, 12, 7, 0,210, 12, 7, 0,211, 12, 6, 2, 3, 0, 7, 0,212, 12, 4, 0,126, 0, 4, 0, 18, 0, + 5, 2, 24, 0, 5, 2, 0, 0, 5, 2, 1, 0, 0, 0, 19, 0, 7, 0,213, 12, 7, 0,214, 12, 7, 0,215, 12, 7, 0,216, 12, + 7, 0, 6, 11, 4, 0,217, 12, 4, 0,218, 12, 6, 2,219, 12, 7, 0,220, 12, 7, 0,202, 12, 4, 0, 18, 0, 4, 0,221, 12, + 4, 0,222, 12, 7, 0, 85, 12, 2, 0,223, 12, 2, 0,227, 3, 2, 0,224, 12, 2, 0,225, 12, 2, 0,226, 12, 2, 0, 30, 0, + 7, 0,227, 12, 9, 2, 22, 0, 4, 0, 18, 0, 2, 0,228, 12, 2, 0,229, 12, 7, 0,230, 12, 2, 0,231, 12, 2, 0,232, 12, + 2, 0,233, 12, 2, 0,234, 12, 2, 0,235, 12, 2, 0,236, 12, 2, 0,237, 12, 2, 0, 3, 3, 4, 0,238, 12, 4, 0,239, 12, + 2, 0,240, 12, 2, 0, 30, 0, 7, 0, 94, 1, 4, 0,241, 12, 4, 0,242, 12, 7, 0,243, 12, 7, 0,244, 12, 4, 0,247, 1, 10, 2, 12, 0, 4, 0, 18, 0, 4, 0,245, 12, 4, 0,246, 12, 7, 0,247, 12, 5, 2,248, 12, 7, 0,249, 12, 7, 0,250, 12, - 7, 0,251, 12, 4, 0,190, 1, 4, 0,132, 0, 7, 0,148, 3, 52, 0,252, 12, 11, 2, 5, 0, 4, 0, 18, 0, 7, 0,201, 12, + 7, 0,251, 12, 4, 0,190, 1, 4, 0,132, 0, 7, 0,148, 3, 52, 0,252, 12, 11, 2, 5, 0, 4, 0, 18, 0, 7, 0,202, 12, 4, 0,253, 12, 4, 0,254, 12, 7, 2,255, 12, 12, 2, 7, 0, 12, 2, 0, 0, 12, 2, 1, 0, 0, 0, 19, 0, 4, 0, 18, 0, 7, 0,148, 3, 14, 0, 0, 13, 11, 2, 1, 13, 13, 2, 1, 0, 0, 0, 2, 13, 4, 2, 10, 0, 9, 2, 3, 13, 8, 2, 4, 13, 14, 0, 0, 13, 11, 2, 1, 13, 10, 2, 5, 13, 5, 2, 6, 13, 14, 0, 7, 13, 4, 0, 8, 13, 4, 0, 9, 13, 13, 2, 90, 6, 14, 2, 48, 0, 14, 2, 0, 0, 14, 2, 1, 0,169, 0,145, 3, 15, 2, 2, 0, 64, 0, 10, 13,187, 0,154, 4,139, 0,153, 4, - 14, 0, 21, 3, 4, 0, 11, 13, 0, 0, 19, 0, 2, 0,162, 10, 2, 0, 16, 0, 2, 0, 12, 13, 2, 0, 13, 13, 2, 0, 14, 13, - 2, 0, 15, 13, 2, 0, 16, 13, 2, 0, 17, 13, 4, 0, 92, 0, 4, 0,186, 3, 4, 0, 18, 13, 4, 0, 19, 13, 4, 0,193, 9, - 4, 0,194, 9, 4, 0, 27, 0, 7, 0, 20, 13, 47, 0, 21, 13, 0, 0, 22, 13, 4, 0, 23, 13, 4, 0,161, 12, 7, 0, 24, 13, + 14, 0, 21, 3, 4, 0, 11, 13, 0, 0, 19, 0, 2, 0,163, 10, 2, 0, 16, 0, 2, 0, 12, 13, 2, 0, 13, 13, 2, 0, 14, 13, + 2, 0, 15, 13, 2, 0, 16, 13, 2, 0, 17, 13, 4, 0, 92, 0, 4, 0,186, 3, 4, 0, 18, 13, 4, 0, 19, 13, 4, 0,194, 9, + 4, 0,195, 9, 4, 0, 27, 0, 7, 0, 20, 13, 47, 0, 21, 13, 0, 0, 22, 13, 4, 0, 23, 13, 4, 0,162, 12, 7, 0, 24, 13, 7, 0, 25, 13, 7, 0, 26, 13, 7, 0, 27, 13, 7, 0, 28, 13, 7, 0, 29, 13, 7, 0, 30, 13, 7, 0, 31, 13, 7, 0, 32, 13, 7, 0, 33, 13, 7, 0, 34, 13, 7, 0, 35, 13, 7, 0, 36, 13, 7, 0, 37, 13, 0, 0,202, 2, 0, 0, 38, 13, 0, 0, 39, 13, 0, 0, 40, 13,169, 0, 7, 0,168, 0, 41, 13,143, 0, 35, 3, 14, 0, 42, 13, 2, 0, 43, 13, 2, 0, 92, 0, 4, 0, 27, 0, - 0, 0, 44, 13,170, 0, 24, 0,168, 0, 41, 13,143, 0, 35, 3,150, 0, 56, 3, 63, 0, 25, 2, 4, 0, 92, 0, 4, 0, 45, 13, + 0, 0, 44, 13,170, 0, 24, 0,168, 0, 41, 13,143, 0, 35, 3,150, 0, 56, 3, 63, 0, 26, 2, 4, 0, 92, 0, 4, 0, 45, 13, 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, 7, 0,178, 1, 7, 0, 46, 13, 7, 0, 47, 13, 7, 0, 48, 13, 7, 0, 49, 13, - 50, 0, 50, 13, 50, 0, 51, 13, 2, 0, 52, 13, 2, 0,222, 10, 2, 0, 53, 13, 2, 0, 27, 0, 7, 0, 54, 13, 7, 0, 55, 13, + 50, 0, 50, 13, 50, 0, 51, 13, 2, 0, 52, 13, 2, 0,223, 10, 2, 0, 53, 13, 2, 0, 27, 0, 7, 0, 54, 13, 7, 0, 55, 13, 7, 0, 56, 13, 7, 0, 57, 13, 69, 78, 68, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 4474ea7f281..dd306d38765 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -33,6 +33,7 @@ struct ARegion; struct bContext; +struct bScreen; struct ImBuf; struct Main; struct MovieClip; @@ -42,7 +43,7 @@ struct wmEvent; /* clip_editor.c */ int ED_space_clip_poll(struct bContext *C); -void ED_space_clip_set(struct bContext *C, struct SpaceClip *sc, struct MovieClip *clip); +void ED_space_clip_set(struct bContext *C, struct bScreen *screen, struct SpaceClip *sc, struct MovieClip *clip); struct MovieClip *ED_space_clip(struct SpaceClip *sc); void ED_space_clip_size(struct SpaceClip *sc, int *width, int *height); void ED_space_clip_zoom(struct SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 9f4a351c66d..5e754fe3619 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -864,6 +864,9 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tclip.cframe, 0x60, 0xc0, 0x40, 255); rgba_char_args_set(btheme->tclip.handle_vertex, 0x00, 0x00, 0x00, 0xff); rgba_char_args_set(btheme->tclip.handle_vertex_select, 0xff, 0xff, 0, 0xff); + rgba_char_args_set(btheme->tclip.list, 0x66, 0x66, 0x66, 0xff); + rgba_char_args_set(btheme->tclip.strip, 0x0c, 0x0a, 0x0a, 0x80); + rgba_char_args_set(btheme->tclip.strip_select, 0xff, 0x8c, 0x00, 0xff); btheme->tclip.handle_vertex_size = 4; } @@ -1776,6 +1779,17 @@ void init_userdef_do_versions(void) } } + if (bmain->versionfile < 262 || (bmain->versionfile == 262 && bmain->subversionfile < 5)) { + bTheme *btheme; + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + if (btheme->tclip.strip[0] == 0) { + rgba_char_args_set(btheme->tclip.list, 0x66, 0x66, 0x66, 0xff); + rgba_char_args_set(btheme->tclip.strip, 0x0c, 0x0a, 0x0a, 0x80); + rgba_char_args_set(btheme->tclip.strip_select, 0xff, 0x8c, 0x00, 0xff); + } + } + } + /* GL Texture Garbage Collection (variable abused above!) */ if (U.textimeout == 0) { U.texcollectrate = 60; diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt index 30d2fe57c10..ec5e81e4b2c 100644 --- a/source/blender/editors/space_clip/CMakeLists.txt +++ b/source/blender/editors/space_clip/CMakeLists.txt @@ -40,15 +40,17 @@ set(INC_SYS ) set(SRC - space_clip.c - clip_draw.c - clip_toolbar.c - clip_ops.c - clip_graph_ops.c - clip_graph_draw.c - clip_editor.c clip_buttons.c + clip_dopesheet_draw.c + clip_dopesheet_ops.c + clip_draw.c + clip_editor.c + clip_graph_draw.c + clip_graph_ops.c + clip_ops.c + clip_toolbar.c clip_utils.c + space_clip.c tracking_ops.c clip_intern.h diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index eabd64bdc4f..df6d713d82d 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -63,6 +63,13 @@ /* Panels */ +static int clip_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt)) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + return sc->view == SC_VIEW_CLIP; +} + void ED_clip_buttons_register(ARegionType *art) { PanelType *pt; @@ -72,6 +79,7 @@ void ED_clip_buttons_register(ARegionType *art) strcpy(pt->label, "Grease Pencil"); pt->draw = gpencil_panel_standard; pt->flag |= PNL_DEFAULT_CLOSED; + pt->poll = clip_grease_pencil_panel_poll; BLI_addtail(&art->paneltypes, pt); } diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c new file mode 100644 index 00000000000..3da5ec10582 --- /dev/null +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -0,0 +1,380 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_graph_draw.c + * \ingroup spclip + */ + +#include "DNA_movieclip_types.h" +#include "DNA_object_types.h" /* SELECT */ +#include "DNA_scene_types.h" + +#include "MEM_guardedalloc.h" + +#include "BKE_context.h" +#include "BKE_movieclip.h" +#include "BKE_tracking.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "ED_screen.h" +#include "ED_clip.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "WM_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "BLF_api.h" + +#include "RNA_access.h" + +#include "clip_intern.h" // own include + +static void track_channel_color(MovieTrackingTrack *track, float default_color[3], float color[3]) +{ + if (track->flag & TRACK_CUSTOMCOLOR) { + float bg[3]; + UI_GetThemeColor3fv(TH_HEADER, bg); + + interp_v3_v3v3(color, track->color, bg, 0.5); + } + else { + if (default_color) + copy_v3_v3(color, default_color); + else + UI_GetThemeColor3fv(TH_HEADER, color); + } +} + +static void draw_keyframe_shape(float x, float y, float xscale, float yscale, short sel, float alpha) +{ + /* coordinates for diamond shape */ + static const float _unit_diamond_shape[4][2] = { + {0.0f, 1.0f}, /* top vert */ + {1.0f, 0.0f}, /* mid-right */ + {0.0f, -1.0f}, /* bottom vert */ + {-1.0f, 0.0f} /* mid-left */ + }; + static GLuint displist1 = 0; + static GLuint displist2 = 0; + int hsize = STRIP_HEIGHT_HALF; + + /* initialize 2 display lists for diamond shape - one empty, one filled */ + if (displist1 == 0) { + displist1 = glGenLists(1); + glNewList(displist1, GL_COMPILE); + + glBegin(GL_LINE_LOOP); + glVertex2fv(_unit_diamond_shape[0]); + glVertex2fv(_unit_diamond_shape[1]); + glVertex2fv(_unit_diamond_shape[2]); + glVertex2fv(_unit_diamond_shape[3]); + glEnd(); + glEndList(); + } + if (displist2 == 0) { + displist2 = glGenLists(1); + glNewList(displist2, GL_COMPILE); + + glBegin(GL_QUADS); + glVertex2fv(_unit_diamond_shape[0]); + glVertex2fv(_unit_diamond_shape[1]); + glVertex2fv(_unit_diamond_shape[2]); + glVertex2fv(_unit_diamond_shape[3]); + glEnd(); + glEndList(); + } + + glPushMatrix(); + + /* adjust view transform before starting */ + glTranslatef(x, y, 0.0f); + glScalef(1.0f/xscale*hsize, 1.0f/yscale*hsize, 1.0f); + + /* anti-aliased lines for more consistent appearance */ + glEnable(GL_LINE_SMOOTH); + + if (sel) + UI_ThemeColorShadeAlpha(TH_STRIP_SELECT, 50, -255*(1.0f-alpha)); + else + glColor4f(0.91f, 0.91f, 0.91f, alpha); + + glCallList(displist2); + + /* exterior - black frame */ + glColor4f(0.0f, 0.0f, 0.0f, alpha); + glCallList(displist1); + + glDisable(GL_LINE_SMOOTH); + + /* restore view transform */ + glPopMatrix(); +} + +void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) +{ + MovieClip *clip = ED_space_clip(sc); + View2D *v2d = &ar->v2d; + + /* frame range */ + clip_draw_sfra_efra(v2d, scene); + + if (clip) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingTrack *track; + ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + float y, xscale, yscale; + float strip[4], selected_strip[4]; + + y = (float) CHANNEL_FIRST; + + UI_view2d_getscale(v2d, &xscale, &yscale); + + /* setup colors for regular and selected strips */ + UI_GetThemeColor3fv(TH_STRIP, strip); + UI_GetThemeColor3fv(TH_STRIP_SELECT, selected_strip); + + strip[3] = 0.5f; + selected_strip[3] = 1.0f; + + glEnable(GL_BLEND); + + for (track = tracksbase->first; track; track = track->next) { + float yminc = (float) (y - CHANNEL_HEIGHT_HALF); + float ymaxc = (float) (y + CHANNEL_HEIGHT_HALF); + + if (!TRACK_VIEW_SELECTED(sc, track)) + continue; + + /* check if visible */ + if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) + { + float alpha; + int i, sel = track->flag & TRACK_DOPE_SEL; + + /* selection background */ + if (sel) { + float color[4] = {0.0f, 0.0f, 0.0f, 0.3f}; + float default_color[4] = {0.8f, 0.93f, 0.8f, 0.3f}; + + track_channel_color(track, default_color, color); + glColor4fv(color); + + glRectf(v2d->cur.xmin, (float)y - CHANNEL_HEIGHT_HALF, + v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF); + } + + alpha = (track->flag & TRACK_LOCKED) ? 0.5f : 1.0f; + + /* tracked segments */ + i = 0; + while (i < track->markersnr) { + MovieTrackingMarker *marker = &track->markers[i]; + + if ((marker->flag & MARKER_DISABLED) == 0) { + MovieTrackingMarker *start_marker = marker; + int prev_fra = marker->framenr, len = 0; + + i++; + while (i < track->markersnr) { + marker = &track->markers[i]; + + if (marker->framenr != prev_fra + 1) + break; + if (marker->flag & MARKER_DISABLED) + break; + + prev_fra = marker->framenr; + len++; + i++; + } + + if (sel) + glColor4fv(selected_strip); + else + glColor4fv(strip); + + glRectf(start_marker->framenr, (float)y - STRIP_HEIGHT_HALF, + start_marker->framenr + len, (float) y + STRIP_HEIGHT_HALF); + + draw_keyframe_shape(start_marker->framenr, y, xscale, yscale, sel, alpha); + draw_keyframe_shape(start_marker->framenr + len, y, xscale, yscale, sel, alpha); + } + + i++; + } + + /* keyframes */ + i = 0; + while (i < track->markersnr) { + MovieTrackingMarker *marker = &track->markers[i]; + + if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) + draw_keyframe_shape(marker->framenr, y, xscale, yscale, sel, alpha); + + i++; + } + } + + /* adjust y-position for next one */ + y -= CHANNEL_STEP; + } + + glDisable(GL_BLEND); + } + + /* current frame */ + clip_draw_cfra(sc, ar, scene); +} + +void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) +{ + ScrArea *sa = CTX_wm_area(C); + SpaceClip *sc = CTX_wm_space_clip(C); + View2D *v2d = &ar->v2d; + MovieClip *clip = ED_space_clip(sc); + MovieTracking *tracking; + MovieTrackingTrack *track; + ListBase *tracksbase; + uiStyle *style = UI_GetStyle(); + uiBlock *block; + int fontid = style->widget.uifont_id; + int items, height; + float y; + + if (!clip) + return; + + tracking = &clip->tracking; + tracksbase = BKE_tracking_get_tracks(tracking); + items = BLI_countlist(tracksbase); + height = (items * CHANNEL_STEP) + (CHANNEL_HEIGHT * 2); + + if (height > (v2d->mask.ymax - v2d->mask.ymin)) { + /* don't use totrect set, as the width stays the same + * (NOTE: this is ok here, the configuration is pretty straightforward) + */ + v2d->tot.ymin = (float)(-height); + } + + /* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */ + UI_view2d_sync(NULL, sa, v2d, V2D_LOCK_COPY); + + /* loop through channels, and set up drawing depending on their type + * first pass: just the standard GL-drawing for backdrop + text + */ + y = (float) CHANNEL_FIRST; + + BLF_size(fontid, 11.0f, U.dpi); + + for (track = tracksbase->first; track; track = track->next) { + float yminc = (float) (y - CHANNEL_HEIGHT_HALF); + float ymaxc = (float) (y + CHANNEL_HEIGHT_HALF); + + if (!TRACK_VIEW_SELECTED(sc, track)) + continue; + + /* check if visible */ + if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) + { + float font_height, color[3]; + int sel = track->flag & TRACK_DOPE_SEL; + + track_channel_color(track, NULL, color); + glColor3fv(color); + + glRectf(v2d->cur.xmin, (float)y - CHANNEL_HEIGHT_HALF, + v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF); + + if (sel) + UI_ThemeColor(TH_TEXT_HI); + else + UI_ThemeColor(TH_TEXT); + + font_height = BLF_height(fontid, track->name); + BLF_position(fontid, v2d->cur.xmin + CHANNEL_PAD, + y - font_height / 2.0f, 0.0f); + BLF_draw(fontid, track->name, strlen(track->name)); + } + + /* adjust y-position for next one */ + y -= CHANNEL_STEP; + } + + /* second pass: widgets */ + block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); + y = (float) CHANNEL_FIRST; + + glEnable(GL_BLEND); + for (track = tracksbase->first; track; track = track->next) { + float yminc = (float)(y - CHANNEL_HEIGHT_HALF); + float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF); + + if (!TRACK_VIEW_SELECTED(sc, track)) + continue; + + /* check if visible */ + if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) + { + uiBut *but; + PointerRNA ptr; + int icon; + + RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, &ptr); + + if (track->flag & TRACK_LOCKED) + icon = ICON_LOCKED; + else + icon = ICON_UNLOCKED; + + uiBlockSetEmboss(block, UI_EMBOSSN); + but = uiDefIconButR(block, ICONTOG, 1, icon, + v2d->cur.xmax - UI_UNIT_X - CHANNEL_PAD, y - UI_UNIT_Y / 2.0f, + UI_UNIT_X, UI_UNIT_Y, &ptr, "lock", 0, 0, 0, 0, 0, NULL); + uiBlockSetEmboss(block, UI_EMBOSS); + } + + /* adjust y-position for next one */ + y -= CHANNEL_STEP; + } + glDisable(GL_BLEND); + + uiEndBlock(C, block); + uiDrawBlock(C, block); +} diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c new file mode 100644 index 00000000000..2225f01afe3 --- /dev/null +++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c @@ -0,0 +1,166 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_graph_ops.c + * \ingroup spclip + */ + +#include "DNA_object_types.h" /* SELECT */ +#include "DNA_scene_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_listbase.h" +#include "BLI_rect.h" + +#include "BKE_context.h" +#include "BKE_movieclip.h" +#include "BKE_tracking.h" +#include "BKE_depsgraph.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_clip.h" + +#include "UI_interface.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "UI_view2d.h" + +#include "clip_intern.h" // own include + +static int ED_space_clip_dopesheet_poll(bContext *C) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc && sc->clip) { + if (sc->view == SC_VIEW_DOPESHEET) { + ARegion *ar = CTX_wm_region(C); + + return ar->regiontype == RGN_TYPE_PREVIEW; + } + } + + return FALSE; +} + +/********************** select channel operator *********************/ + +static int dopesheet_select_channel_poll(bContext *C) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc && sc->clip) + return sc->view == SC_VIEW_DOPESHEET; + + return FALSE; +} + +static int dopesheet_select_channel_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + MovieTracking *tracking = &clip->tracking; + ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + MovieTrackingTrack *track; + float location[2]; + int extend = RNA_boolean_get(op->ptr, "extend"), channel, channel_index; + + RNA_float_get_array(op->ptr, "location", location); + channel = -(location[1] - (CHANNEL_FIRST + CHANNEL_HEIGHT_HALF)) / CHANNEL_STEP; + + for (track = tracksbase->first, channel_index = 0; track; track = track->next) { + if (!TRACK_VIEW_SELECTED(sc, track)) + continue; + + if (channel_index == channel) { + if (extend) + track->flag ^= TRACK_DOPE_SEL; + else + track->flag |= TRACK_DOPE_SEL; + + if (track->flag & TRACK_DOPE_SEL) { + MovieTrackingMarker *marker; + + /* make last selected in dopesheet track active in clip editor */ + tracking->act_track = track; + + /* make active track be centered to screen */ + /* XXX: doesn't work in other opened spaces */ + marker = BKE_tracking_get_marker(track, sc->user.framenr); + clip_view_center_to_point(sc, marker->pos[0], marker->pos[1]); + } + } + else if (!extend) + track->flag &= ~TRACK_DOPE_SEL; + + channel_index++; + } + + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); + + return OPERATOR_FINISHED; +} + +static int dopesheet_select_channel_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + float location[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]); + RNA_float_set_array(op->ptr, "location", location); + + return dopesheet_select_channel_exec(C, op); +} + +void CLIP_OT_dopesheet_select_channel(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Channel"; + ot->description = "Select movie tracking channel"; + ot->idname = "CLIP_OT_dopesheet_select_channel"; + + /* api callbacks */ + ot->invoke = dopesheet_select_channel_invoke; + ot->exec = dopesheet_select_channel_exec; + ot->poll = dopesheet_select_channel_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, + "Location", "Mouse location to select channel", -100.0f, 100.0f); + RNA_def_boolean(ot->srna, "extend", 0, + "Extend", "Extend selection rather than clearing the existing selection"); +} diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 40be2622f95..099c3c7532c 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -70,13 +70,38 @@ int ED_space_clip_poll(bContext *C) return FALSE; } -void ED_space_clip_set(bContext *C, SpaceClip *sc, MovieClip *clip) +void ED_space_clip_set(bContext *C, bScreen *screen, SpaceClip *sc, MovieClip *clip) { + MovieClip *old_clip; + + if (!screen && C) + screen = CTX_wm_screen(C); + + old_clip = sc->clip; sc->clip = clip; if (sc->clip && sc->clip->id.us==0) sc->clip->id.us = 1; + if (screen) { + ScrArea *area; + SpaceLink *sl; + + for (area = screen->areabase.first; area; area = area->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_CLIP) { + SpaceClip *cur_sc = (SpaceClip *) sl; + + if (cur_sc != sc) { + if (cur_sc->clip == old_clip || cur_sc->clip == NULL) { + cur_sc->clip = clip; + } + } + } + } + } + } + if (C) WM_event_add_notifier(C, NC_MOVIECLIP|NA_SELECTED, sc->clip); } diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index df14491c9c9..4825403fb4a 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -87,60 +87,6 @@ static void draw_curve_knot(float x, float y, float xscale, float yscale, float glPopMatrix(); } -static void draw_graph_cfra(SpaceClip *sc, ARegion *ar, Scene *scene) -{ - View2D *v2d = &ar->v2d; - float xscale, yscale; - float vec[2]; - - /* Draw a light green line to indicate current frame */ - vec[0] = (float)(sc->user.framenr * scene->r.framelen); - - UI_ThemeColor(TH_CFRAME); - glLineWidth(2.0); - - glBegin(GL_LINE_STRIP); - vec[1] = v2d->cur.ymin; - glVertex2fv(vec); - - vec[1] = v2d->cur.ymax; - glVertex2fv(vec); - glEnd(); - - glLineWidth(1.0); - - UI_view2d_view_orthoSpecial(ar, v2d, 1); - - /* because the frame number text is subject to the same scaling as the contents of the view */ - UI_view2d_getscale(v2d, &xscale, &yscale); - glScalef(1.0f/xscale, 1.0f, 1.0f); - - clip_draw_curfra_label(sc, (float)sc->user.framenr * xscale, 18); - - /* restore view transform */ - glScalef(xscale, 1.0, 1.0); -} - -static void draw_graph_sfra_efra(Scene *scene, View2D *v2d) -{ - UI_view2d_view_ortho(v2d); - - /* currently clip editor supposes that editing clip length is equal to scene frame range */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glColor4f(0.0f, 0.0f, 0.0f, 0.4f); - - glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax); - glRectf((float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); - glDisable(GL_BLEND); - - UI_ThemeColorShade(TH_BACK, -60); - - /* thin lines where the actual frames are */ - fdrawline((float)SFRA, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax); - fdrawline((float)EFRA, v2d->cur.ymin, (float)EFRA, v2d->cur.ymax); -} - static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track), MovieTrackingMarker *marker, int UNUSED(coord), float val) { @@ -280,8 +226,8 @@ void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene) } /* frame range */ - draw_graph_sfra_efra(scene, v2d); + clip_draw_sfra_efra(v2d, scene); /* current frame */ - draw_graph_cfra(sc, ar, scene); + clip_draw_cfra(sc, ar, scene); } diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index f8c81c2944a..a71d7f4e70a 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -66,12 +66,14 @@ static int ED_space_clip_graph_poll(bContext *C) SpaceClip *sc = CTX_wm_space_clip(C); if (sc && sc->clip) { - ARegion *ar = CTX_wm_region(C); + if (sc->view == SC_VIEW_GRAPH) { + ARegion *ar = CTX_wm_region(C); - return ar->regiontype == RGN_TYPE_PREVIEW; + return ar->regiontype == RGN_TYPE_PREVIEW; + } } - return 0; + return FALSE; } typedef struct { @@ -233,8 +235,8 @@ static int mouse_select_curve(bContext *C, float co[2], int extend) tracking->act_track = userdata.track; /* make active track be centered to screen */ + /* XXX: doesn't work in other opened spaces */ marker = BKE_tracking_get_marker(userdata.track, sc->user.framenr); - clip_view_center_to_point(sc, marker->pos[0], marker->pos[1]); /* deselect all knots on newly selected curve */ diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index 425a1da9ec5..679230f0b53 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -38,14 +38,36 @@ struct MovieClip; struct MovieTrackingMarker; struct MovieTrackingTrack; struct Scene; +struct ScrArea; struct SpaceClip; struct wmOperatorType; +/* channel heights */ +#define CHANNEL_FIRST -UI_UNIT_Y +#define CHANNEL_HEIGHT UI_UNIT_Y +#define CHANNEL_HEIGHT_HALF (UI_UNIT_Y / 2.0f) +#define CHANNEL_SKIP 2 +#define CHANNEL_STEP (CHANNEL_HEIGHT + CHANNEL_SKIP) + +#define CHANNEL_PAD 4 + +/* extra padding for lengths (to go under scrollers) */ +#define EXTRA_SCROLL_PAD 100.0f + +#define STRIP_HEIGHT_HALF 5 + /* internal exports only */ /* clip_buttons.c */ void ED_clip_buttons_register(struct ARegionType *art); +/* clip_dopesheet_draw.c */ +void clip_draw_dopesheet_main(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene); +void clip_draw_dopesheet_channels(const struct bContext *C, struct ARegion *ar); + +/* clip_dopesheet_ops.c */ +void CLIP_OT_dopesheet_select_channel(struct wmOperatorType *ot); + /* clip_draw.c */ void clip_draw_main(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene); void clip_draw_grease_pencil(struct bContext *C, int onlyv2d); @@ -81,6 +103,7 @@ void CLIP_OT_rebuild_proxy(struct wmOperatorType *ot); void CLIP_OT_mode_set(struct wmOperatorType *ot); /* clip_toolbar.c */ +struct ARegion *ED_clip_has_properties_region(struct ScrArea *sa); void CLIP_OT_tools(struct wmOperatorType *ot); void CLIP_OT_properties(struct wmOperatorType *ot); void ED_clip_tool_props_register(struct ARegionType *art); @@ -104,6 +127,9 @@ void clip_delete_marker(struct bContext *C, struct MovieClip *clip, struct ListB void clip_view_center_to_point(struct SpaceClip *sc, float x, float y); +void clip_draw_cfra(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene); +void clip_draw_sfra_efra(struct View2D *v2d, struct Scene *scene); + /* tracking_ops.c */ void CLIP_OT_select(struct wmOperatorType *ot); void CLIP_OT_select_all(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 7e1bbc254e9..5535fe268ae 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -184,7 +184,7 @@ static int open_exec(bContext *C, wmOperator *op) RNA_property_update(C, &pprop->ptr, pprop->prop); } else if (sc) { - ED_space_clip_set(C, sc, clip); + ED_space_clip_set(C, NULL, sc, clip); } WM_event_add_notifier(C, NC_MOVIECLIP|NA_ADDED, clip); diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c index b80deb8260a..da8bf8fedd9 100644 --- a/source/blender/editors/space_clip/clip_toolbar.c +++ b/source/blender/editors/space_clip/clip_toolbar.c @@ -56,7 +56,7 @@ /************************** properties ******************************/ -static ARegion *clip_has_properties_region(ScrArea *sa) +ARegion *ED_clip_has_properties_region(ScrArea *sa) { ARegion *ar, *arnew; @@ -90,9 +90,9 @@ static int properties_poll(bContext *C) static int properties_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); - ARegion *ar = clip_has_properties_region(sa); + ARegion *ar = ED_clip_has_properties_region(sa); - if (ar) + if (ar && ar->alignment != RGN_ALIGN_NONE) ED_region_toggle_hidden(C, ar); return OPERATOR_FINISHED; @@ -167,7 +167,7 @@ static int tools_exec(bContext *C, wmOperator *UNUSED(op)) ScrArea *sa = CTX_wm_area(C); ARegion *ar = clip_has_tools_region(sa); - if (ar) + if (ar && ar->alignment != RGN_ALIGN_NONE) ED_region_toggle_hidden(C, ar); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 443a1d0cdd3..c8ba8be7eae 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -29,6 +29,7 @@ * \ingroup spclip */ +#include "DNA_scene_types.h" #include "DNA_object_types.h" /* SELECT */ #include "MEM_guardedalloc.h" @@ -42,6 +43,9 @@ #include "BKE_tracking.h" #include "BKE_depsgraph.h" +#include "BIF_gl.h" +#include "BIF_glutil.h" + #include "WM_api.h" #include "WM_types.h" @@ -53,6 +57,8 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "UI_interface.h" +#include "UI_resources.h" #include "UI_view2d.h" #include "clip_intern.h" // own include @@ -220,3 +226,57 @@ void clip_view_center_to_point(SpaceClip *sc, float x, float y) sc->xof = (x - 0.5f) * width * aspx; sc->yof = (y - 0.5f) * height * aspy; } + +void clip_draw_cfra(SpaceClip *sc, ARegion *ar, Scene *scene) +{ + View2D *v2d = &ar->v2d; + float xscale, yscale; + float vec[2]; + + /* Draw a light green line to indicate current frame */ + vec[0] = (float)(sc->user.framenr * scene->r.framelen); + + UI_ThemeColor(TH_CFRAME); + glLineWidth(2.0); + + glBegin(GL_LINE_STRIP); + vec[1] = v2d->cur.ymin; + glVertex2fv(vec); + + vec[1] = v2d->cur.ymax; + glVertex2fv(vec); + glEnd(); + + glLineWidth(1.0); + + UI_view2d_view_orthoSpecial(ar, v2d, 1); + + /* because the frame number text is subject to the same scaling as the contents of the view */ + UI_view2d_getscale(v2d, &xscale, &yscale); + glScalef(1.0f/xscale, 1.0f, 1.0f); + + clip_draw_curfra_label(sc, (float)sc->user.framenr * xscale, 18); + + /* restore view transform */ + glScalef(xscale, 1.0, 1.0); +} + +void clip_draw_sfra_efra(View2D *v2d, Scene *scene) +{ + UI_view2d_view_ortho(v2d); + + /* currently clip editor supposes that editing clip length is equal to scene frame range */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glColor4f(0.0f, 0.0f, 0.0f, 0.4f); + + glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax); + glRectf((float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); + glDisable(GL_BLEND); + + UI_ThemeColorShade(TH_BACK, -60); + + /* thin lines where the actual frames are */ + fdrawline((float)SFRA, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax); + fdrawline((float)EFRA, v2d->cur.ymin, (float)EFRA, v2d->cur.ymax); +} diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 60322098250..c799a936480 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -72,31 +72,79 @@ static void init_preview_region(const bContext *C, ARegion *ar) { Scene *scene = CTX_data_scene(C); + ScrArea *sa = CTX_wm_area(C); + SpaceClip *sc = CTX_wm_space_clip(C); ar->regiontype = RGN_TYPE_PREVIEW; ar->alignment = RGN_ALIGN_TOP; ar->flag |= RGN_FLAG_HIDDEN; - ar->v2d.tot.xmin = 0.0f; - ar->v2d.tot.ymin = -10.0f; - ar->v2d.tot.xmax = (float)scene->r.efra; - ar->v2d.tot.ymax = 10.0f; + if (sc->view == SC_VIEW_DOPESHEET) { + ar->v2d.tot.xmin = -10.0f; + ar->v2d.tot.ymin = (float)(-sa->winy)/3.0f; + ar->v2d.tot.xmax = (float)(sa->winx); + ar->v2d.tot.ymax = 0.0f; - ar->v2d.cur = ar->v2d.tot; + ar->v2d.cur = ar->v2d.tot; - ar->v2d.min[0] = FLT_MIN; - ar->v2d.min[1] = FLT_MIN; + ar->v2d.min[0] = 0.0f; + ar->v2d.min[1] = 0.0f; - ar->v2d.max[0] = MAXFRAMEF; - ar->v2d.max[1] = FLT_MAX; + ar->v2d.max[0] = MAXFRAMEF; + ar->v2d.max[1] = FLT_MAX; - ar->v2d.scroll = (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL); - ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL); + ar->v2d.minzoom = 0.01f; + ar->v2d.maxzoom = 50; + ar->v2d.scroll = (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL); + ar->v2d.scroll |= (V2D_SCROLL_RIGHT); + ar->v2d.keepzoom = V2D_LOCKZOOM_Y; + ar->v2d.keepofs = V2D_KEEPOFS_Y; + ar->v2d.align = V2D_ALIGN_NO_POS_Y; + ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL; + } + else { + ar->v2d.tot.xmin = 0.0f; + ar->v2d.tot.ymin = -10.0f; + ar->v2d.tot.xmax = (float)scene->r.efra; + ar->v2d.tot.ymax = 10.0f; - ar->v2d.keeptot = 0; + ar->v2d.cur = ar->v2d.tot; + + ar->v2d.min[0] = FLT_MIN; + ar->v2d.min[1] = FLT_MIN; + + ar->v2d.max[0] = MAXFRAMEF; + ar->v2d.max[1] = FLT_MAX; + + ar->v2d.scroll = (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL); + ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL); + + ar->v2d.minzoom = 0.0f; + ar->v2d.maxzoom = 0.0f; + ar->v2d.keepzoom = 0; + ar->v2d.keepofs = 0; + ar->v2d.align = 0; + ar->v2d.flag = 0; + + ar->v2d.keeptot = 0; + } } -static ARegion *clip_has_preview_region(const bContext *C, ScrArea *sa) +static void reinit_preview_region(const bContext *C, ARegion *ar) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc->view == SC_VIEW_DOPESHEET) { + if ((ar->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL) == 0) + init_preview_region(C, ar); + } + else { + if (ar->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL) + init_preview_region(C, ar); + } +} + +static ARegion *ED_clip_has_preview_region(const bContext *C, ScrArea *sa) { ARegion *ar, *arnew; @@ -119,6 +167,33 @@ static ARegion *clip_has_preview_region(const bContext *C, ScrArea *sa) return arnew; } +static ARegion *ED_clip_has_channels_region(ScrArea *sa) +{ + ARegion *ar, *arnew; + + ar = BKE_area_find_region_type(sa, RGN_TYPE_CHANNELS); + if (ar) + return ar; + + /* add subdiv level; after header */ + ar = BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW); + + /* is error! */ + if (ar == NULL) + return NULL; + + arnew = MEM_callocN(sizeof(ARegion), "clip channels region"); + + BLI_insertlinkbefore(&sa->regionbase, ar, arnew); + arnew->regiontype = RGN_TYPE_CHANNELS; + arnew->alignment = RGN_ALIGN_LEFT; + + arnew->v2d.scroll = V2D_SCROLL_BOTTOM; + arnew->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL; + + return arnew; +} + static void clip_scopes_tag_refresh(ScrArea *sa) { SpaceClip *sc = (SpaceClip *)sa->spacedata.first; @@ -190,6 +265,16 @@ static SpaceLink *clip_new(const bContext *C) ar->regiontype = RGN_TYPE_UI; ar->alignment = RGN_ALIGN_RIGHT; + /* channels view */ + ar = MEM_callocN(sizeof(ARegion), "channels for clip"); + + BLI_addtail(&sc->regionbase, ar); + ar->regiontype = RGN_TYPE_CHANNELS; + ar->alignment = RGN_ALIGN_LEFT; + + ar->v2d.scroll = V2D_SCROLL_BOTTOM; + ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL; + /* preview view */ ar = MEM_callocN(sizeof(ARegion), "preview for clip"); @@ -394,6 +479,10 @@ static void clip_operatortypes(void) WM_operatortype_append(CLIP_OT_graph_center_current_frame); WM_operatortype_append(CLIP_OT_graph_disable_markers); + + /* ** clip_dopesheet_ops.c ** */ + + WM_operatortype_append(CLIP_OT_dopesheet_select_channel); } static void clip_keymap(struct wmKeyConfig *keyconf) @@ -612,6 +701,13 @@ static void clip_keymap(struct wmKeyConfig *keyconf) RNA_enum_set(kmi->ptr, "action", 2); /* toggle */ transform_keymap_for_space(keyconf, keymap, SPACE_CLIP); + + /* ******** Hotkeys avalaible for channels region only ******** */ + + keymap = WM_keymap_find(keyconf, "Clip Dopesheet Editor", SPACE_CLIP, 0); + + kmi = WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_select_channel", ACTIONMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */ } const char *clip_context_dir[]= {"edit_movieclip", NULL}; @@ -639,52 +735,190 @@ static void clip_refresh(const bContext *C, ScrArea *sa) Scene *scene = CTX_data_scene(C); SpaceClip *sc = (SpaceClip *)sa->spacedata.first; ARegion *ar_main = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); - ARegion *ar_preview = clip_has_preview_region(C, sa); + ARegion *ar_tools = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS); + ARegion *ar_tool_props = BKE_area_find_region_type(sa, RGN_TYPE_TOOL_PROPS); + ARegion *ar_preview = ED_clip_has_preview_region(C, sa); + ARegion *ar_properties = ED_clip_has_properties_region(sa); + ARegion *ar_channels = ED_clip_has_channels_region(sa); + int main_visible = FALSE, preview_visible = FALSE, tools_visible = FALSE; + int tool_props_visible = FALSE, properties_visible = FALSE, channels_visible = FALSE; int view_changed = FALSE; switch (sc->view) { case SC_VIEW_CLIP: - if (ar_preview && !(ar_preview->flag & RGN_FLAG_HIDDEN)) { - ar_preview->flag |= RGN_FLAG_HIDDEN; - ar_preview->v2d.flag &= ~V2D_IS_INITIALISED; - WM_event_remove_handlers((bContext*)C, &ar_preview->handlers); - view_changed = TRUE; - } - if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) { - ar_main->alignment = RGN_ALIGN_NONE; - view_changed = TRUE; - } - if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) { - /* store graph region align */ - if (ar_preview->alignment == RGN_ALIGN_TOP) - sc->runtime_flag &= ~SC_GRAPH_BOTTOM; - else - sc->runtime_flag |= SC_GRAPH_BOTTOM; - - ar_preview->alignment = RGN_ALIGN_NONE; - view_changed = TRUE; - } + main_visible = TRUE; + preview_visible = FALSE; + tools_visible = TRUE; + tool_props_visible = TRUE; + properties_visible = TRUE; + channels_visible = FALSE; break; case SC_VIEW_GRAPH: - if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) { - ar_preview->flag &= ~RGN_FLAG_HIDDEN; - ar_preview->v2d.flag &= ~V2D_IS_INITIALISED; - ar_preview->v2d.cur = ar_preview->v2d.tot; - view_changed = TRUE; - } - if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) { - ar_main->alignment = RGN_ALIGN_NONE; - view_changed = TRUE; - } - if (ar_preview && !ELEM(ar_preview->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) { - if (sc->runtime_flag & SC_GRAPH_BOTTOM) - ar_preview->alignment = RGN_ALIGN_BOTTOM; - else - ar_preview->alignment = RGN_ALIGN_TOP; + main_visible = FALSE; + preview_visible = TRUE; + tools_visible = FALSE; + tool_props_visible = FALSE; + properties_visible = FALSE; + channels_visible = FALSE; - view_changed = TRUE; - } + reinit_preview_region(C, ar_preview); break; + case SC_VIEW_DOPESHEET: + main_visible = FALSE; + preview_visible = TRUE; + tools_visible = FALSE; + tool_props_visible = FALSE; + properties_visible = FALSE; + channels_visible = TRUE; + + reinit_preview_region(C, ar_preview); + break; + } + + if (main_visible) { + if (ar_main && (ar_main->flag & RGN_FLAG_HIDDEN)) { + ar_main->flag &= ~RGN_FLAG_HIDDEN; + ar_main->v2d.flag &= ~V2D_IS_INITIALISED; + view_changed = TRUE; + } + + if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) { + ar_main->alignment = RGN_ALIGN_NONE; + view_changed = TRUE; + } + } + else { + if (ar_main && !(ar_main->flag & RGN_FLAG_HIDDEN)) { + ar_main->flag |= RGN_FLAG_HIDDEN; + ar_main->v2d.flag &= ~V2D_IS_INITIALISED; + WM_event_remove_handlers((bContext *)C, &ar_main->handlers); + view_changed = TRUE; + } + if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) { + ar_main->alignment = RGN_ALIGN_NONE; + view_changed = TRUE; + } + } + + if (properties_visible) { + if (ar_properties && (ar_properties->flag & RGN_FLAG_HIDDEN)) { + ar_properties->flag &= ~RGN_FLAG_HIDDEN; + ar_properties->v2d.flag &= ~V2D_IS_INITIALISED; + view_changed = TRUE; + } + if (ar_properties && ar_properties->alignment != RGN_ALIGN_RIGHT) { + ar_properties->alignment = RGN_ALIGN_RIGHT; + view_changed = TRUE; + } + } + else { + if (ar_properties && !(ar_properties->flag & RGN_FLAG_HIDDEN)) { + ar_properties->flag |= RGN_FLAG_HIDDEN; + ar_properties->v2d.flag &= ~V2D_IS_INITIALISED; + WM_event_remove_handlers((bContext *)C, &ar_properties->handlers); + view_changed = TRUE; + } + if (ar_properties && ar_properties->alignment != RGN_ALIGN_NONE) { + ar_properties->alignment = RGN_ALIGN_NONE; + view_changed = TRUE; + } + } + + if (tools_visible) { + if (ar_tools && (ar_tools->flag & RGN_FLAG_HIDDEN)) { + ar_tools->flag &= ~RGN_FLAG_HIDDEN; + ar_tools->v2d.flag &= ~V2D_IS_INITIALISED; + view_changed = TRUE; + } + if (ar_tools && ar_tools->alignment != RGN_ALIGN_LEFT) { + ar_tools->alignment = RGN_ALIGN_LEFT; + view_changed = TRUE; + } + } + else { + if (ar_tools && !(ar_tools->flag & RGN_FLAG_HIDDEN)) { + ar_tools->flag |= RGN_FLAG_HIDDEN; + ar_tools->v2d.flag &= ~V2D_IS_INITIALISED; + WM_event_remove_handlers((bContext *)C, &ar_tools->handlers); + view_changed = TRUE; + } + if (ar_tools && ar_tools->alignment != RGN_ALIGN_NONE) { + ar_tools->alignment = RGN_ALIGN_NONE; + view_changed = TRUE; + } + } + + if (tool_props_visible) { + if (ar_tool_props && (ar_tool_props->flag & RGN_FLAG_HIDDEN)) { + ar_tool_props->flag &= ~RGN_FLAG_HIDDEN; + ar_tool_props->v2d.flag &= ~V2D_IS_INITIALISED; + view_changed = TRUE; + } + if (ar_tool_props && (ar_tool_props->alignment != (RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV))) { + ar_tool_props->alignment = RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV; + view_changed = TRUE; + } + } + else { + if (ar_tool_props && !(ar_tool_props->flag & RGN_FLAG_HIDDEN)) { + ar_tool_props->flag |= RGN_FLAG_HIDDEN; + ar_tool_props->v2d.flag &= ~V2D_IS_INITIALISED; + WM_event_remove_handlers((bContext *)C, &ar_tool_props->handlers); + view_changed = TRUE; + } + if (ar_tool_props && ar_tool_props->alignment != RGN_ALIGN_NONE) { + ar_tool_props->alignment = RGN_ALIGN_NONE; + view_changed = TRUE; + } + } + + if (preview_visible) { + if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) { + ar_preview->flag &= ~RGN_FLAG_HIDDEN; + ar_preview->v2d.flag &= ~V2D_IS_INITIALISED; + ar_preview->v2d.cur = ar_preview->v2d.tot; + view_changed = TRUE; + } + if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) { + ar_preview->alignment = RGN_ALIGN_NONE; + view_changed = TRUE; + } + } + else { + if (ar_preview && !(ar_preview->flag & RGN_FLAG_HIDDEN)) { + ar_preview->flag |= RGN_FLAG_HIDDEN; + ar_preview->v2d.flag &= ~V2D_IS_INITIALISED; + WM_event_remove_handlers((bContext *)C, &ar_preview->handlers); + view_changed = TRUE; + } + if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) { + ar_preview->alignment = RGN_ALIGN_NONE; + view_changed = TRUE; + } + } + + if (channels_visible) { + if (ar_channels && (ar_channels->flag & RGN_FLAG_HIDDEN)) { + ar_channels->flag &= ~RGN_FLAG_HIDDEN; + ar_channels->v2d.flag &= ~V2D_IS_INITIALISED; + view_changed = TRUE; + } + if (ar_channels && ar_channels->alignment != RGN_ALIGN_LEFT) { + ar_channels->alignment = RGN_ALIGN_LEFT; + view_changed = TRUE; + } + } + else { + if (ar_channels && !(ar_channels->flag & RGN_FLAG_HIDDEN)) { + ar_channels->flag |= RGN_FLAG_HIDDEN; + ar_channels->v2d.flag &= ~V2D_IS_INITIALISED; + WM_event_remove_handlers((bContext *)C, &ar_tools->handlers); + view_changed = TRUE; + } + if (ar_channels && ar_channels->alignment != RGN_ALIGN_NONE) { + ar_channels->alignment = RGN_ALIGN_NONE; + view_changed = TRUE; + } } if (view_changed) { @@ -835,13 +1069,13 @@ static void clip_preview_area_init(wmWindowManager *wm, ARegion *ar) WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } -static void clip_preview_area_draw(const bContext *C, ARegion *ar) +static void graph_area_draw(const bContext *C, ARegion *ar) { View2D *v2d = &ar->v2d; View2DScrollers *scrollers; SpaceClip *sc = CTX_wm_space_clip(C); Scene *scene = CTX_data_scene(C); - short unitx = V2D_UNIT_FRAMESCALE, unity = V2D_UNIT_VALUES; + short unitx, unity; if (sc->flag & SC_LOCK_TIMECURSOR) ED_clip_graph_center_current_frame(scene, ar); @@ -859,15 +1093,99 @@ static void clip_preview_area_draw(const bContext *C, ARegion *ar) UI_view2d_view_restore(C); /* scrollers */ + unitx = (sc->flag & SC_SHOW_SECONDS)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES; + unity = V2D_UNIT_VALUES; scrollers = UI_view2d_scrollers_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP); UI_view2d_scrollers_draw(C, v2d, scrollers); UI_view2d_scrollers_free(scrollers); } +static void dopesheet_area_draw(const bContext *C, ARegion *ar) +{ + Scene *scene = CTX_data_scene(C); + SpaceClip *sc = CTX_wm_space_clip(C); + View2D *v2d = &ar->v2d; + View2DGrid *grid; + View2DScrollers *scrollers; + short unit = 0; + + /* clear and setup matrix */ + UI_ThemeClearColor(TH_BACK); + glClear(GL_COLOR_BUFFER_BIT); + + UI_view2d_view_ortho(v2d); + + /* time grid */ + unit = (sc->flag & SC_SHOW_SECONDS)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES; + grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy); + UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL); + UI_view2d_grid_free(grid); + + /* data... */ + clip_draw_dopesheet_main(sc, ar, scene); + + /* reset view matrix */ + UI_view2d_view_restore(C); + + /* scrollers */ + scrollers= UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); + UI_view2d_scrollers_draw(C, v2d, scrollers); + UI_view2d_scrollers_free(scrollers); +} + +static void clip_preview_area_draw(const bContext *C, ARegion *ar) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc->view == SC_VIEW_GRAPH) + graph_area_draw(C, ar); + else if (sc->view == SC_VIEW_DOPESHEET) + dopesheet_area_draw(C, ar); +} + static void clip_preview_area_listener(ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn)) { } +/****************** channels region ******************/ + +static void clip_channels_area_init(wmWindowManager *wm, ARegion *ar) +{ + wmKeyMap *keymap; + + UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); + + keymap = WM_keymap_find(wm->defaultconf, "Clip Dopesheet Editor", SPACE_CLIP, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); +} + +static void clip_channels_area_draw(const bContext *C, ARegion *ar) +{ + View2D *v2d = &ar->v2d; + View2DScrollers *scrollers; + + /* clear and setup matrix */ + UI_ThemeClearColor(TH_BACK); + glClear(GL_COLOR_BUFFER_BIT); + + UI_view2d_view_ortho(v2d); + + /* data... */ + clip_draw_dopesheet_channels(C, ar); + + /* reset view matrix */ + UI_view2d_view_restore(C); + + /* scrollers */ + scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY); + UI_view2d_scrollers_draw(C, v2d, scrollers); + UI_view2d_scrollers_free(scrollers); +} + +static void clip_channels_area_listener(ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn)) +{ +} + /****************** header region ******************/ /* add handlers, stuff you only do once or on area/region changes */ @@ -1045,4 +1363,15 @@ void ED_spacetype_clip(void) BLI_addhead(&st->regiontypes, art); BKE_spacetype_register(st); + + /* channels */ + art = MEM_callocN(sizeof(ARegionType), "spacetype clip channels region"); + art->regionid = RGN_TYPE_CHANNELS; + art->prefsizex = UI_COMPACT_PANEL_WIDTH; + art->keymapflag = ED_KEYMAP_FRAMES|ED_KEYMAP_UI; + art->listener = clip_channels_area_listener; + art->init = clip_channels_area_init; + art->draw = clip_channels_area_draw; + + BLI_addhead(&st->regiontypes, art); } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 958e8b44b9d..c2fbc611bc3 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -520,9 +520,8 @@ typedef struct SpaceClip { * defined when drawing and used for mouse position calculation */ /* movie postprocessing */ - int postproc_flag; + int postproc_flag, pad2; - int runtime_flag; /* different runtime flags */ void *draw_context; } SpaceClip; @@ -905,6 +904,7 @@ enum { #define SC_SHOW_GRAPH_TRACKS (1<<15) /*#define SC_SHOW_PYRAMID_LEVELS (1<<16) */ /* UNUSED */ #define SC_LOCK_TIMECURSOR (1<<17) +#define SC_SHOW_SECONDS (1<<18) /* SpaceClip->mode */ #define SC_MODE_TRACKING 0 @@ -914,6 +914,7 @@ enum { /* SpaceClip->view */ #define SC_VIEW_CLIP 0 #define SC_VIEW_GRAPH 1 +#define SC_VIEW_DOPESHEET 2 /* SpaceClip->runtime_flag */ #define SC_GRAPH_BOTTOM (1<<0) diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 2f099ed59f5..84d4215401b 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -230,6 +230,7 @@ enum { #define TRACK_CUSTOMCOLOR (1<<7) #define TRACK_USE_2D_STAB (1<<8) #define TRACK_PREVIEW_GRAYSCALE (1<<9) +#define TRACK_DOPE_SEL (1<<10) /* MovieTrackingTrack->tracker */ #define TRACKER_KLT 0 diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 84301c8000f..59061ac9a33 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -338,6 +338,7 @@ extern StructRNA RNA_MouseSensor; extern StructRNA RNA_MovieSequence; extern StructRNA RNA_MovieClipSequence; extern StructRNA RNA_MovieTrackingObject; +extern StructRNA RNA_MovieTrackingTrack; extern StructRNA RNA_MulticamSequence; extern StructRNA RNA_MultiresModifier; extern StructRNA RNA_MusgraveTexture; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 5e0a20c51ad..d1a776235c2 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1024,8 +1024,9 @@ static EnumPropertyItem *rna_SpaceProperties_texture_context_itemf(bContext *C, static void rna_SpaceClipEditor_clip_set(PointerRNA *ptr, PointerRNA value) { SpaceClip *sc = (SpaceClip*)(ptr->data); + bScreen *screen = (bScreen*)ptr->id.data; - ED_space_clip_set(NULL, sc, (MovieClip*)value.data); + ED_space_clip_set(NULL, screen, sc, (MovieClip*)value.data); } static void rna_SpaceClipEditor_clip_mode_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) @@ -2930,6 +2931,7 @@ static void rna_def_space_clip(BlenderRNA *brna) static EnumPropertyItem view_items[] = { {SC_VIEW_CLIP, "CLIP", ICON_SEQUENCE, "Clip", "Show editing clip preview"}, {SC_VIEW_GRAPH, "GRAPH", ICON_IPO, "Graph", "Show graph view for active element"}, + {SC_VIEW_DOPESHEET, "DOPESHEET", ICON_ACTION, "Dopesheet", "Dopesheet view for tracking data"}, {0, NULL, 0, NULL, NULL}}; srna = RNA_def_struct(brna, "SpaceClipEditor", "Space"); @@ -3104,6 +3106,12 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "postproc_flag", MOVIECLIP_PREVIEW_GRAYSCALE); RNA_def_property_ui_text(prop, "Grayscale", "Display frame in grayscale mode"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* timeline */ + prop = RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_SECONDS); + RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); } diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index dbe4aa47151..e63f05bd969 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2002,6 +2002,7 @@ static void rna_def_userdef_theme_space_clip(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Theme Clip Editor", "Theme settings for the Movie Clip Editor"); rna_def_userdef_theme_spaces_main(srna); + rna_def_userdef_theme_spaces_list_main(srna); prop = RNA_def_property(srna, "marker_outline", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "marker_outline"); @@ -2076,6 +2077,18 @@ static void rna_def_userdef_theme_space_clip(BlenderRNA *brna) RNA_def_property_range(prop, 0, 255); RNA_def_property_ui_text(prop, "Handle Vertex Size", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "strips", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "strip"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Strips", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "strips_selected", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "strip_select"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Strips Selected", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_themes(BlenderRNA *brna) From 7d573d647247acff849757988b1eed2448533b2e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 16 Apr 2012 12:57:11 +0000 Subject: [PATCH 004/360] Cycles: add "Blur Glossy" integrator option. When using a value higher than 0.0, this will blur glossy reflections after blurry bounces, to reduce noise at the cost of accuracy. 1.0 is a good starting value to tweak. Some light paths have a low probability of being found while contributing much light to the pixel. As a result these light paths will be found in some pixels and not in others, causing fireflies. An example of such a difficult path might be a small light that is causing a small specular highlight on a sharp glossy material, which we are seeing through a rough glossy material. With path tracing it is difficult to find the specular highlight, but if we increase the roughness on the material the highlight gets bigger and softer, and so easier to find. Often this blurring will be hardly noticeable, because we are seeing it through a blurry material anyway, but there are also cases where this will lead to a loss of detail in lighting. (note that this is being committed to the tomato branch, mango will be using this branch until feature freeze for 2.63 is over, then switch back) --- intern/cycles/blender/addon/properties.py | 8 ++++---- intern/cycles/blender/addon/ui.py | 8 ++++---- intern/cycles/blender/blender_sync.cpp | 2 ++ intern/cycles/kernel/kernel_path.h | 17 ++++++++++++++++- intern/cycles/kernel/kernel_types.h | 4 +--- intern/cycles/render/integrator.cpp | 4 ++++ intern/cycles/render/integrator.h | 1 + 7 files changed, 32 insertions(+), 12 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index cb99ea3b499..9fc7ee5c88e 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -85,10 +85,10 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Leave out caustics, resulting in a darker image with less noise", default=False, ) - cls.blur_caustics = FloatProperty( - name="Blur Caustics", - description="Blur caustics to reduce noise", - min=0.0, max=1.0, + cls.blur_glossy = FloatProperty( + name="Blur Glossy", + description="Adaptively blur glossy shaders after blurry bounces, to reduce noise at the cost of accuracy", + min=0.0, max=10.0, default=0.0, ) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 4a8b639b390..9174e5a3bca 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -87,11 +87,11 @@ class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel): sub.prop(cscene, "diffuse_bounces", text="Diffuse") sub.prop(cscene, "glossy_bounces", text="Glossy") sub.prop(cscene, "transmission_bounces", text="Transmission") - sub.prop(cscene, "no_caustics") - #row = col.row() - #row.prop(cscene, "blur_caustics") - #row.active = not cscene.no_caustics + col.separator() + + col.prop(cscene, "no_caustics") + col.prop(cscene, "blur_glossy") class CyclesRender_PT_film(CyclesButtonsPanel, Panel): diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 5a286298774..714110f8890 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -153,6 +153,8 @@ void BlenderSync::sync_integrator() integrator->transparent_shadows = get_boolean(cscene, "use_transparent_shadows"); integrator->no_caustics = get_boolean(cscene, "no_caustics"); + integrator->blur_glossy = get_float(cscene, "blur_glossy"); + integrator->seed = get_int(cscene, "seed"); integrator->layer_flag = render_layer.layer; diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index ff12e85375c..ed47489de0e 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -223,6 +223,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R path_radiance_init(&L, kernel_data.film.use_light_pass); + float min_ray_pdf = FLT_MAX; float ray_pdf = 0.0f; PathState state; int rng_offset = PRNG_BASE_NUM; @@ -259,6 +260,18 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput); + /* blurring of bsdf after bounces, for rays that have a small likelihood + of following this particular path (diffuse, rough glossy) */ + if(kernel_data.integrator.blur_glossy != FLT_MAX) { + float blur_pdf = kernel_data.integrator.blur_glossy*min_ray_pdf; + + if(blur_pdf < 1.0f) { + float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f; + shader_bsdf_blur(kg, &sd, blur_roughness); + } + } + + /* holdout */ #ifdef __HOLDOUT__ if((sd.flag & SD_HOLDOUT) && (state.flag & PATH_RAY_CAMERA)) { float3 holdout_weight = shader_holdout_eval(kg, &sd); @@ -378,8 +391,10 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R path_radiance_bsdf_bounce(&L, &throughput, &bsdf_eval, bsdf_pdf, state.bounce, label); /* set labels */ - if(!(label & LABEL_TRANSPARENT)) + if(!(label & LABEL_TRANSPARENT)) { ray_pdf = bsdf_pdf; + min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); + } /* update path state */ path_state_next(kg, &state, label); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 391dcd12dad..3ba8356d296 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -516,6 +516,7 @@ typedef struct KernelIntegrator { /* caustics */ int no_caustics; + float blur_glossy; /* seed */ int seed; @@ -525,9 +526,6 @@ typedef struct KernelIntegrator { /* clamp */ float sample_clamp; - - /* padding */ - int pad; } KernelIntegrator; typedef struct KernelBVH { diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index 6e6d30f3879..f1fffcdbd74 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -41,6 +41,7 @@ Integrator::Integrator() transparent_shadows = false; no_caustics = false; + blur_glossy = 0.0f; seed = 0; layer_flag = ~0; sample_clamp = 0.0f; @@ -81,6 +82,8 @@ void Integrator::device_update(Device *device, DeviceScene *dscene) kintegrator->transparent_shadows = transparent_shadows; kintegrator->no_caustics = no_caustics; + kintegrator->blur_glossy = (blur_glossy == 0.0f)? FLT_MAX: 1.0f/blur_glossy; + kintegrator->seed = hash_int(seed); kintegrator->layer_flag = layer_flag << PATH_RAY_LAYER_SHIFT; @@ -119,6 +122,7 @@ bool Integrator::modified(const Integrator& integrator) transparent_probalistic == integrator.transparent_probalistic && transparent_shadows == integrator.transparent_shadows && no_caustics == integrator.no_caustics && + blur_glossy == integrator.blur_glossy && layer_flag == integrator.layer_flag && seed == integrator.seed && sample_clamp == integrator.sample_clamp); diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h index abbbaca894c..6e292aeaf16 100644 --- a/intern/cycles/render/integrator.h +++ b/intern/cycles/render/integrator.h @@ -41,6 +41,7 @@ public: bool transparent_shadows; bool no_caustics; + float blur_glossy; int seed; int layer_flag; From cd78d3cdceae3f8659c3766767686897adb5d8a0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 17 Apr 2012 12:49:39 +0000 Subject: [PATCH 005/360] Cycles: render layer "Exclude Layers" added. Scene layers (all object that influence the render, directly or indirectly) are shared between all render layers. However sometimes it's useful to leave out some object influence for a particular render layer. That's what this option allows you to do. --- intern/cycles/blender/addon/ui.py | 14 ++++++++++---- intern/cycles/blender/blender_sync.cpp | 2 +- source/blender/makesdna/DNA_scene_types.h | 7 +++---- source/blender/makesrna/intern/rna_scene.c | 7 +++++++ source/blender/render/extern/include/RE_pipeline.h | 2 +- .../blender/render/intern/source/render_result.c | 1 + 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 9174e5a3bca..d981e661295 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -178,10 +178,7 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel): col = split.column() col.prop(scene, "layers", text="Scene") - col.label(text="Material:") - col.prop(rl, "material_override", text="") - - col.prop(rl, "use_sky", "Use Environment") + col.prop(rl, "layers_exclude", text="Exclude") col = split.column() col.prop(rl, "layers", text="Layer") @@ -190,6 +187,15 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel): split = layout.split() + col = split.column() + col.label(text="Material:") + col.prop(rl, "material_override", text="") + + col = split.column() + col.prop(rl, "use_sky", "Use Environment") + + split = layout.split() + col = split.column() col.label(text="Passes:") col.prop(rl, "use_pass_combined") diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 714110f8890..ff2b4135261 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -222,7 +222,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer) for(r.layers.begin(b_rlay); b_rlay != r.layers.end(); ++b_rlay) { if((!layer && first_layer) || (layer && b_rlay->name() == layer)) { render_layer.name = b_rlay->name(); - render_layer.scene_layer = get_layer(b_scene.layers()); + render_layer.scene_layer = get_layer(b_scene.layers()) & ~get_layer(b_rlay->layers_exclude()); render_layer.layer = get_layer(b_rlay->layers()); render_layer.holdout_layer = get_layer(b_rlay->layers_zmask()); render_layer.layer |= render_layer.holdout_layer; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 79ed1186c1a..6a0a498742b 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -176,12 +176,11 @@ typedef struct SceneRenderLayer { struct Material *mat_override; struct Group *light_override; - unsigned int lay; /* scene->lay itself has priority over this */ - unsigned int lay_zmask; /* has to be after lay, this is for Z-masking */ + unsigned int lay; /* scene->lay itself has priority over this */ + unsigned int lay_zmask; /* has to be after lay, this is for Z-masking */ + unsigned int lay_exclude; /* not used by internal, exclude */ int layflag; - int pad; - int passflag; /* pass_xor has to be after passflag */ int pass_xor; } SceneRenderLayer; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 410756ff5ea..df8d11546b4 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1905,6 +1905,13 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) if (scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + prop = RNA_def_property(srna, "layers_exclude", PROP_BOOLEAN, PROP_LAYER); + RNA_def_property_boolean_sdna(prop, NULL, "lay_exclude", 1); + RNA_def_property_array(prop, 20); + RNA_def_property_ui_text(prop, "Exclude Layers", "Exclude scene layers from having any influence"); + if (scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + /* layer options */ prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "layflag", SCE_LAY_DISABLE); diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 315995475e9..2a3c8e60638 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -82,7 +82,7 @@ typedef struct RenderLayer { /* copy of RenderData */ char name[RE_MAXNAME]; - unsigned int lay, lay_zmask; + unsigned int lay, lay_zmask, lay_exclude; int layflag, passflag, pass_xor; struct Material *mat_override; diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 37d6479e7bc..162fc160915 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -458,6 +458,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf BLI_strncpy(rl->name, srl->name, sizeof(rl->name)); rl->lay= srl->lay; rl->lay_zmask= srl->lay_zmask; + rl->lay_exclude= srl->lay_exclude; rl->layflag= srl->layflag; rl->passflag= srl->passflag; // for debugging: srl->passflag|SCE_PASS_RAYHITS; rl->pass_xor= srl->pass_xor; From cf6d854806860b4c3a29f5a7cd371e070c0aa14b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Apr 2012 15:21:46 +0000 Subject: [PATCH 006/360] Cycles: environment pass will now render environment even if film is set to transparent. --- intern/cycles/kernel/kernel_accumulate.h | 9 +++++++-- intern/cycles/kernel/kernel_path.h | 16 ++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index 9a52531eec0..6c3ade1c531 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -266,7 +266,7 @@ __device_inline void path_radiance_accum_background(PathRadiance *L, float3 thro #endif } -__device_inline float3 path_radiance_sum(PathRadiance *L) +__device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L) { #ifdef __PASSES__ if(L->use_light_pass) { @@ -283,9 +283,14 @@ __device_inline float3 path_radiance_sum(PathRadiance *L) L->indirect_glossy *= L->indirect; L->indirect_transmission *= L->indirect; - return L->emission + L->background + float3 L_sum = L->emission + L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission; + + if(!kernel_data.background.transparent) + L_sum += L->background; + + return L_sum; } else return L->emission; diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index ed47489de0e..20cba00aed8 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -240,13 +240,17 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R /* eval background shader if nothing hit */ if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) { L_transparent += average(throughput); + +#ifdef __PASSES__ + if(!(kernel_data.film.pass_flag & PASS_BACKGROUND)) +#endif + break; } + #ifdef __BACKGROUND__ - else { - /* sample background shader */ - float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf); - path_radiance_accum_background(&L, throughput, L_background, state.bounce); - } + /* sample background shader */ + float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf); + path_radiance_accum_background(&L, throughput, L_background, state.bounce); #endif break; @@ -409,7 +413,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R #endif } - float3 L_sum = path_radiance_sum(&L); + float3 L_sum = path_radiance_sum(kg, &L); #ifdef __CLAMP_SAMPLE__ path_radiance_clamp(&L, &L_sum, kernel_data.integrator.sample_clamp); From 27ffa5dfdf4eacc8bc933d58db33973950afeb7f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Apr 2012 15:23:13 +0000 Subject: [PATCH 007/360] Cycles: per render layer Samples control, leaving it to 0 will use the common scene setting. --- intern/cycles/blender/addon/ui.py | 1 + intern/cycles/blender/blender_session.cpp | 7 ++++--- intern/cycles/blender/blender_sync.cpp | 2 ++ intern/cycles/blender/blender_sync.h | 5 ++++- source/blender/makesdna/DNA_scene_types.h | 3 +++ source/blender/makesrna/intern/rna_scene.c | 6 ++++++ 6 files changed, 20 insertions(+), 4 deletions(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index d981e661295..f934ba5a651 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -192,6 +192,7 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel): col.prop(rl, "material_override", text="") col = split.column() + col.prop(rl, "samples") col.prop(rl, "use_sky", "Use Environment") split = layout.split() diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index dc6c69e2904..5ece7aa26e2 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -218,12 +218,13 @@ void BlenderSession::render() scene->film->passes = passes; scene->film->tag_update(scene); - /* update session */ - session->reset(buffer_params, session_params.samples); - /* update scene */ sync->sync_data(b_v3d, b_iter->name().c_str()); + /* update session */ + int samples = sync->get_layer_samples(); + session->reset(buffer_params, (samples == 0)? session_params.samples: samples); + /* render */ session->start(); session->wait(); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index ff2b4135261..0116422c756 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -210,6 +210,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer) render_layer.holdout_layer = 0; render_layer.material_override = PointerRNA_NULL; render_layer.use_background = true; + render_layer.samples = 0; return; } } @@ -228,6 +229,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer) render_layer.layer |= render_layer.holdout_layer; render_layer.material_override = b_rlay->material_override(); render_layer.use_background = b_rlay->use_sky(); + render_layer.samples = b_rlay->samples(); } first_layer = false; diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index d2550a1ffd7..ab8e4bd8d00 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -57,6 +57,7 @@ public: void sync_data(BL::SpaceView3D b_v3d, const char *layer = 0); void sync_camera(BL::Object b_override, int width, int height); void sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height); + int get_layer_samples() { return render_layer.samples; } /* get parameters */ static SceneParams get_scene_params(BL::Scene b_scene, bool background); @@ -108,7 +109,8 @@ private: RenderLayerInfo() : scene_layer(0), layer(0), holdout_layer(0), material_override(PointerRNA_NULL), - use_background(true) + use_background(true), + samples(0) {} string name; @@ -117,6 +119,7 @@ private: uint holdout_layer; BL::Material material_override; bool use_background; + int samples; } render_layer; }; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 6a0a498742b..f3109270ba8 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -183,6 +183,9 @@ typedef struct SceneRenderLayer { int passflag; /* pass_xor has to be after passflag */ int pass_xor; + + int samples; + int pad; } SceneRenderLayer; /* srl->layflag */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index df8d11546b4..3fc753d0578 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1912,6 +1912,12 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) if (scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + if(scene) { + prop = RNA_def_property(srna, "samples", PROP_INT, PROP_UNSIGNED); + RNA_def_property_ui_text(prop, "Samples", "Override number of render samples for this render layer, 0 will use the scene setting"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + } + /* layer options */ prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "layflag", SCE_LAY_DISABLE); From 535cf658775d634125c40511df4712d1fd2d4cb0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Apr 2012 16:11:48 +0000 Subject: [PATCH 008/360] Cycles: added a Normal output to the texture coordinate node. This currently gives the object space normal, which is the same under object animation. In the future this might become a "generated" normal so it's also stable for deforming objects, but for now it's already useful for non-deforming objects. --- intern/cycles/kernel/svm/svm_tex_coord.h | 27 + intern/cycles/kernel/svm/svm_types.h | 1 + intern/cycles/render/nodes.cpp | 7 + .../gpu/intern/gpu_shader_material.glsl | 5 +- .../gpu/intern/gpu_shader_material.glsl.c | 2921 +++++++++-------- .../shader/nodes/node_shader_tex_coord.c | 3 +- 6 files changed, 1502 insertions(+), 1462 deletions(-) diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index f494b6d66e1..98f8734aed2 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -40,6 +40,15 @@ __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack data = sd->P; break; } + case NODE_TEXCO_NORMAL: { + if(sd->object != ~0) { + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); + data = transform_direction(&tfm, sd->N); + } + else + data = sd->N; + break; + } case NODE_TEXCO_CAMERA: { Transform tfm = kernel_data.cam.worldtocamera; @@ -85,6 +94,15 @@ __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, floa data = sd->P + sd->dP.dx; break; } + case NODE_TEXCO_NORMAL: { + if(sd->object != ~0) { + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); + data = transform_direction(&tfm, sd->N); + } + else + data = sd->N; + break; + } case NODE_TEXCO_CAMERA: { Transform tfm = kernel_data.cam.worldtocamera; @@ -133,6 +151,15 @@ __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, floa data = sd->P + sd->dP.dy; break; } + case NODE_TEXCO_NORMAL: { + if(sd->object != ~0) { + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); + data = normalize(transform_direction(&tfm, sd->N)); + } + else + data = sd->N; + break; + } case NODE_TEXCO_CAMERA: { Transform tfm = kernel_data.cam.worldtocamera; diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 13d72307765..7ca852a24b6 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -119,6 +119,7 @@ typedef enum NodeLightPath { } NodeLightPath; typedef enum NodeTexCoord { + NODE_TEXCO_NORMAL, NODE_TEXCO_OBJECT, NODE_TEXCO_CAMERA, NODE_TEXCO_WINDOW, diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index db696993737..d71438ebae1 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1503,6 +1503,7 @@ TextureCoordinateNode::TextureCoordinateNode() { add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); add_output("Generated", SHADER_SOCKET_POINT); + add_output("Normal", SHADER_SOCKET_NORMAL); add_output("UV", SHADER_SOCKET_POINT); add_output("Object", SHADER_SOCKET_POINT); add_output("Camera", SHADER_SOCKET_POINT); @@ -1551,6 +1552,12 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler) } } + out = output("Normal"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(texco_node, NODE_TEXCO_NORMAL, out->stack_offset); + } + out = output("UV"); if(!out->links.empty()) { int attr = compiler.attribute(Attribute::STD_UV); diff --git a/source/blender/gpu/intern/gpu_shader_material.glsl b/source/blender/gpu/intern/gpu_shader_material.glsl index 2ac99e2eee2..76dacd4a10d 100644 --- a/source/blender/gpu/intern/gpu_shader_material.glsl +++ b/source/blender/gpu/intern/gpu_shader_material.glsl @@ -2041,12 +2041,13 @@ void node_geometry(vec3 I, vec3 N, mat4 toworld, backfacing = 0.0; } -void node_tex_coord(vec3 I, vec3 N, mat4 toworld, +void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec3 attr_orco, vec3 attr_uv, - out vec3 generated, out vec3 uv, out vec3 object, + out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object, out vec3 camera, out vec3 window, out vec3 reflection) { generated = attr_orco; + normal = normalize((obinvmat*(viewinvmat*vec4(N, 0.0))).xyz); uv = attr_uv; object = I; camera = I; diff --git a/source/blender/gpu/intern/gpu_shader_material.glsl.c b/source/blender/gpu/intern/gpu_shader_material.glsl.c index a6d962a7bb9..6a6db7eadbb 100644 --- a/source/blender/gpu/intern/gpu_shader_material.glsl.c +++ b/source/blender/gpu/intern/gpu_shader_material.glsl.c @@ -1,1484 +1,1487 @@ /* DataToC output of file */ -int datatoc_gpu_shader_material_glsl_size= 49395; -char datatoc_gpu_shader_material_glsl[]= { - 10,102,108,111, 97,116, 32,101,120,112, 95, 98,108,101,110,100,101,114, 40, -102,108,111, 97,116, 32,102, 41, 10,123, 10, 9,114,101,116,117,114,110, 32,112,111,119, 40, 50, 46, 55, 49, 56, 50, 56, 49, 56, - 50, 56, 52, 54, 44, 32,102, 41, 59, 10,125, 10, 10,118,111,105,100, 32,114,103, 98, 95,116,111, 95,104,115,118, 40,118,101, 99, - 52, 32,114,103, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, - 32, 99,109, 97,120, 44, 32, 99,109,105,110, 44, 32,104, 44, 32,115, 44, 32,118, 44, 32, 99,100,101,108,116, 97, 59, 10, 9,118, -101, 99, 51, 32, 99, 59, 10, 10, 9, 99,109, 97,120, 32, 61, 32,109, 97,120, 40,114,103, 98, 91, 48, 93, 44, 32,109, 97,120, 40, -114,103, 98, 91, 49, 93, 44, 32,114,103, 98, 91, 50, 93, 41, 41, 59, 10, 9, 99,109,105,110, 32, 61, 32,109,105,110, 40,114,103, - 98, 91, 48, 93, 44, 32,109,105,110, 40,114,103, 98, 91, 49, 93, 44, 32,114,103, 98, 91, 50, 93, 41, 41, 59, 10, 9, 99,100,101, -108,116, 97, 32, 61, 32, 99,109, 97,120, 45, 99,109,105,110, 59, 10, 10, 9,118, 32, 61, 32, 99,109, 97,120, 59, 10, 9,105,102, - 32, 40, 99,109, 97,120, 33, 61, 48, 46, 48, 41, 10, 9, 9,115, 32, 61, 32, 99,100,101,108,116, 97, 47, 99,109, 97,120, 59, 10, - 9,101,108,115,101, 32,123, 10, 9, 9,115, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, - 10, 10, 9,105,102, 32, 40,115, 32, 61, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, - 10, 9,101,108,115,101, 32,123, 10, 9, 9, 99, 32, 61, 32, 40,118,101, 99, 51, 40, 99,109, 97,120, 44, 32, 99,109, 97,120, 44, - 32, 99,109, 97,120, 41, 32, 45, 32,114,103, 98, 46,120,121,122, 41, 47, 99,100,101,108,116, 97, 59, 10, 10, 9, 9,105,102, 32, - 40,114,103, 98, 46,120, 61, 61, 99,109, 97,120, 41, 32,104, 32, 61, 32, 99, 91, 50, 93, 32, 45, 32, 99, 91, 49, 93, 59, 10, 9, - 9,101,108,115,101, 32,105,102, 32, 40,114,103, 98, 46,121, 61, 61, 99,109, 97,120, 41, 32,104, 32, 61, 32, 50, 46, 48, 32, 43, - 32, 99, 91, 48, 93, 32, 45, 32, 32, 99, 91, 50, 93, 59, 10, 9, 9,101,108,115,101, 32,104, 32, 61, 32, 52, 46, 48, 32, 43, 32, - 99, 91, 49, 93, 32, 45, 32, 99, 91, 48, 93, 59, 10, 10, 9, 9,104, 32, 47, 61, 32, 54, 46, 48, 59, 10, 10, 9, 9,105,102, 32, - 40,104, 60, 48, 46, 48, 41, 10, 9, 9, 9,104, 32, 43, 61, 32, 49, 46, 48, 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, - 32, 61, 32,118,101, 99, 52, 40,104, 44, 32,115, 44, 32,118, 44, 32,114,103, 98, 46,119, 41, 59, 10,125, 10, 10,118,111,105,100, - 32,104,115,118, 95,116,111, 95,114,103, 98, 40,118,101, 99, 52, 32,104,115,118, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111, -117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,105, 44, 32,102, 44, 32,112, 44, 32,113, 44, 32,116, 44, 32,104, - 44, 32,115, 44, 32,118, 59, 10, 9,118,101, 99, 51, 32,114,103, 98, 59, 10, 10, 9,104, 32, 61, 32,104,115,118, 91, 48, 93, 59, - 10, 9,115, 32, 61, 32,104,115,118, 91, 49, 93, 59, 10, 9,118, 32, 61, 32,104,115,118, 91, 50, 93, 59, 10, 10, 9,105,102, 40, -115, 61, 61, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,118, 44, 32,118, 41, 59, - 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,105,102, 40,104, 61, 61, 49, 46, 48, 41, 10, 9, 9, 9,104, 32, 61, 32, - 48, 46, 48, 59, 10, 9, 9, 10, 9, 9,104, 32, 42, 61, 32, 54, 46, 48, 59, 10, 9, 9,105, 32, 61, 32,102,108,111,111,114, 40, -104, 41, 59, 10, 9, 9,102, 32, 61, 32,104, 32, 45, 32,105, 59, 10, 9, 9,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,102, 44, - 32,102, 44, 32,102, 41, 59, 10, 9, 9,112, 32, 61, 32,118, 42, 40, 49, 46, 48, 45,115, 41, 59, 10, 9, 9,113, 32, 61, 32,118, - 42, 40, 49, 46, 48, 45, 40,115, 42,102, 41, 41, 59, 10, 9, 9,116, 32, 61, 32,118, 42, 40, 49, 46, 48, 45, 40,115, 42, 40, 49, - 46, 48, 45,102, 41, 41, 41, 59, 10, 9, 9, 10, 9, 9,105,102, 32, 40,105, 32, 61, 61, 32, 48, 46, 48, 41, 32,114,103, 98, 32, - 61, 32,118,101, 99, 51, 40,118, 44, 32,116, 44, 32,112, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, - 32, 49, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,113, 44, 32,118, 44, 32,112, 41, 59, 10, 9, 9,101,108,115, -101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 50, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,112, 44, 32,118, 44, - 32,116, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 51, 46, 48, 41, 32,114,103, 98, 32, 61, 32, -118,101, 99, 51, 40,112, 44, 32,113, 44, 32,118, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 52, - 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,116, 44, 32,112, 44, 32,118, 41, 59, 10, 9, 9,101,108,115,101, 32, -114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,112, 44, 32,113, 41, 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, - 32, 61, 32,118,101, 99, 52, 40,114,103, 98, 44, 32,104,115,118, 46,119, 41, 59, 10,125, 10, 10,102,108,111, 97,116, 32,115,114, -103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,102,108,111, 97,116, 32, 99, 41, 10,123, 10, 9,105,102, 40, 99, - 32, 60, 32, 48, 46, 48, 52, 48, 52, 53, 41, 10, 9, 9,114,101,116,117,114,110, 32, 40, 99, 32, 60, 32, 48, 46, 48, 41, 63, 32, - 48, 46, 48, 58, 32, 99, 32, 42, 32, 40, 49, 46, 48, 47, 49, 50, 46, 57, 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,114,101, -116,117,114,110, 32,112,111,119, 40, 40, 99, 32, 43, 32, 48, 46, 48, 53, 53, 41, 42, 40, 49, 46, 48, 47, 49, 46, 48, 53, 53, 41, - 44, 32, 50, 46, 52, 41, 59, 10,125, 10, 10,102,108,111, 97,116, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114, -103, 98, 40,102,108,111, 97,116, 32, 99, 41, 10,123, 10, 9,105,102, 40, 99, 32, 60, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, - 10, 9, 9,114,101,116,117,114,110, 32, 40, 99, 32, 60, 32, 48, 46, 48, 41, 63, 32, 48, 46, 48, 58, 32, 99, 32, 42, 32, 49, 50, - 46, 57, 50, 59, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117,114,110, 32, 49, 46, 48, 53, 53, 32, 42, 32,112,111,119, 40, - 99, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 10,125, 10, 10,118,111,105,100, 32,115,114,103, - 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,118,101, 99, 52, 32, 99,111,108, 95,102,114,111,109, 44, 32,111,117, -116, 32,118,101, 99, 52, 32, 99,111,108, 95,116,111, 41, 10,123, 10, 9, 99,111,108, 95,116,111, 46,114, 32, 61, 32,115,114,103, - 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,114, 41, 59, 10, 9, 99,111,108, - 95,116,111, 46,103, 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114, -111,109, 46,103, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 98, 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97, -114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46, 98, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 97, 32, 61, 32, 99,111, -108, 95,102,114,111,109, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115, -114,103, 98, 40,118,101, 99, 52, 32, 99,111,108, 95,102,114,111,109, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 95, -116,111, 41, 10,123, 10, 9, 99,111,108, 95,116,111, 46,114, 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115, -114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,114, 41, 59, 10, 9, 99,111,108, 95,116,111, 46,103, 32, 61, 32,108,105,110, -101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,103, 41, 59, 10, 9, 99,111,108, - 95,116,111, 46, 98, 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114, -111,109, 46, 98, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 97, 32, 61, 32, 99,111,108, 95,102,114,111,109, 46, 97, 59, 10,125, - 10, 10, 35,100,101,102,105,110,101, 32, 77, 95, 80, 73, 32, 51, 46, 49, 52, 49, 53, 57, 50, 54, 53, 51, 53, 56, 57, 55, 57, 51, - 50, 51, 56, 52, 54, 10, 35,100,101,102,105,110,101, 32, 77, 95, 49, 95, 80, 73, 32, 48, 46, 51, 49, 56, 51, 48, 57, 56, 56, 54, - 49, 56, 51, 55, 57, 48, 54, 57, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 83, 72, 65, 68, 69, 82, 32, 78, 79, - 68, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,118, 99,111,108, 95, - 97,116,116,114,105, 98,117,116,101, 40,118,101, 99, 52, 32, 97,116,116,118, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, - 32,118, 99,111,108, 41, 10,123, 10, 9,118, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 97,116,116,118, 99,111,108, 46,120, 47, - 50, 53, 53, 46, 48, 44, 32, 97,116,116,118, 99,111,108, 46,121, 47, 50, 53, 53, 46, 48, 44, 32, 97,116,116,118, 99,111,108, 46, -122, 47, 50, 53, 53, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,117,118, 95, 97,116,116,114,105, 98, -117,116,101, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 41, 10,123, 10, 9, -117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 42, 50, 46, 48, 32, 45, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, - 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,103,101,111,109, 40,118,101, 99, 51, 32, 99,111, - 44, 32,118,101, 99, 51, 32,110,111,114, 44, 32,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,118,101, 99, - 51, 32, 97,116,116,111,114, 99,111, 44, 32,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,118,101, 99, 52, 32, 97,116,116,118, - 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,103,108,111, 98, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,108, -111, 99, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,114, - 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, - 44, 32,111,117,116, 32,118,101, 99, 52, 32,118, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 99,111,108, 95, - 97,108,112,104, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102,114,111,110,116, 98, 97, 99,107, 41, 10,123, 10, 9,108, -111, 99, 97,108, 32, 61, 32, 99,111, 59, 10, 9,118,105,101,119, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108,111, 99, - 97,108, 41, 59, 10, 9,103,108,111, 98, 97,108, 32, 61, 32, 40,118,105,101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40, -108,111, 99, 97,108, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9,111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99, -111, 59, 10, 9,117,118, 95, 97,116,116,114,105, 98,117,116,101, 40, 97,116,116,117,118, 44, 32,117,118, 41, 59, 10, 9,110,111, -114,109, 97,108, 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,110,111,114, 41, 59, 9, 47, 42, 32, 98,108,101,110,100, -101,114, 32,114,101,110,100,101,114, 32,110,111,114,109, 97,108, 32,105,115, 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9, -118, 99,111,108, 95, 97,116,116,114,105, 98,117,116,101, 40, 97,116,116,118, 99,111,108, 44, 32,118, 99,111,108, 41, 59, 10, 9, -118, 99,111,108, 95, 97,108,112,104, 97, 32, 61, 32, 97,116,116,118, 99,111,108, 46, 97, 59, 10, 9,102,114,111,110,116, 98, 97, - 99,107, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118, -101, 99, 44, 32,109, 97,116, 52, 32,109, 97,116, 44, 32,118,101, 99, 51, 32,109,105,110,118,101, 99, 44, 32,118,101, 99, 51, 32, -109, 97,120,118,101, 99, 44, 32,102,108,111, 97,116, 32,100,111,109,105,110, 44, 32,102,108,111, 97,116, 32,100,111,109, 97,120, - 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32, 40, -109, 97,116, 32, 42, 32,118,101, 99, 52, 40,118,101, 99, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9,105,102, 40,100, -111,109,105,110, 32, 61, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32,109, 97,120, 40,111,117,116,118, -101, 99, 44, 32,109,105,110,118,101, 99, 41, 59, 10, 9,105,102, 40,100,111,109, 97,120, 32, 61, 61, 32, 49, 46, 48, 41, 10, 9, - 9,111,117,116,118,101, 99, 32, 61, 32,109,105,110, 40,111,117,116,118,101, 99, 44, 32,109, 97,120,118,101, 99, 41, 59, 10,125, - 10, 10,118,111,105,100, 32, 99, 97,109,101,114, 97, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32, -111,117,116,118,105,101,119, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,100,101,112,116,104, 44, 32,111,117,116, - 32,102,108,111, 97,116, 32,111,117,116,100,105,115,116, 41, 10,123, 10, 9,111,117,116,100,101,112,116,104, 32, 61, 32, 97, 98, -115, 40, 99,111, 46,122, 41, 59, 10, 9,111,117,116,100,105,115,116, 32, 61, 32,108,101,110,103,116,104, 40, 99,111, 41, 59, 10, - 9,111,117,116,118,105,101,119, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 41, 59, 10,125, 10, 10,118,111,105, -100, 32,109, 97,116,104, 95, 97,100,100, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, - 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, - 32,118, 97,108, 49, 32, 43, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,115,117, 98,116,114, - 97, 99,116, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32, -102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 45, - 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109,117,108,116,105,112,108,121, 40,102,108,111, - 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111, -117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 42, 32,118, 97,108, 50, 59, 10, -125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,100,105,118,105,100,101, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32, -102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, - 9,105,102, 32, 40,118, 97,108, 50, 32, 61, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, - 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 47, 32,118, 97,108, 50, 59, 10, -125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,115,105,110,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, - 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,115,105,110, 40,118, - 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 99,111,115,105,110,101, 40,102,108,111, 97,116, 32,118, - 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, - 61, 32, 99,111,115, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,116, 97,110,103,101,110,116, +int datatoc_gpu_shader_material_glsl_size = 49493; +char datatoc_gpu_shader_material_glsl[] = { + 10,102,108,111, 97,116, 32,101,120,112, 95, 98,108,101,110,100,101,114, 40,102,108, +111, 97,116, 32,102, 41, 10,123, 10, 9,114,101,116,117,114,110, 32,112,111,119, 40, 50, 46, 55, 49, 56, 50, 56, 49, 56, 50, 56, + 52, 54, 44, 32,102, 41, 59, 10,125, 10, 10,118,111,105,100, 32,114,103, 98, 95,116,111, 95,104,115,118, 40,118,101, 99, 52, 32, +114,103, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32, 99, +109, 97,120, 44, 32, 99,109,105,110, 44, 32,104, 44, 32,115, 44, 32,118, 44, 32, 99,100,101,108,116, 97, 59, 10, 9,118,101, 99, + 51, 32, 99, 59, 10, 10, 9, 99,109, 97,120, 32, 61, 32,109, 97,120, 40,114,103, 98, 91, 48, 93, 44, 32,109, 97,120, 40,114,103, + 98, 91, 49, 93, 44, 32,114,103, 98, 91, 50, 93, 41, 41, 59, 10, 9, 99,109,105,110, 32, 61, 32,109,105,110, 40,114,103, 98, 91, + 48, 93, 44, 32,109,105,110, 40,114,103, 98, 91, 49, 93, 44, 32,114,103, 98, 91, 50, 93, 41, 41, 59, 10, 9, 99,100,101,108,116, + 97, 32, 61, 32, 99,109, 97,120, 45, 99,109,105,110, 59, 10, 10, 9,118, 32, 61, 32, 99,109, 97,120, 59, 10, 9,105,102, 32, 40, + 99,109, 97,120, 33, 61, 48, 46, 48, 41, 10, 9, 9,115, 32, 61, 32, 99,100,101,108,116, 97, 47, 99,109, 97,120, 59, 10, 9,101, +108,115,101, 32,123, 10, 9, 9,115, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 10, + 9,105,102, 32, 40,115, 32, 61, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9, +101,108,115,101, 32,123, 10, 9, 9, 99, 32, 61, 32, 40,118,101, 99, 51, 40, 99,109, 97,120, 44, 32, 99,109, 97,120, 44, 32, 99, +109, 97,120, 41, 32, 45, 32,114,103, 98, 46,120,121,122, 41, 47, 99,100,101,108,116, 97, 59, 10, 10, 9, 9,105,102, 32, 40,114, +103, 98, 46,120, 61, 61, 99,109, 97,120, 41, 32,104, 32, 61, 32, 99, 91, 50, 93, 32, 45, 32, 99, 91, 49, 93, 59, 10, 9, 9,101, +108,115,101, 32,105,102, 32, 40,114,103, 98, 46,121, 61, 61, 99,109, 97,120, 41, 32,104, 32, 61, 32, 50, 46, 48, 32, 43, 32, 99, + 91, 48, 93, 32, 45, 32, 32, 99, 91, 50, 93, 59, 10, 9, 9,101,108,115,101, 32,104, 32, 61, 32, 52, 46, 48, 32, 43, 32, 99, 91, + 49, 93, 32, 45, 32, 99, 91, 48, 93, 59, 10, 10, 9, 9,104, 32, 47, 61, 32, 54, 46, 48, 59, 10, 10, 9, 9,105,102, 32, 40,104, + 60, 48, 46, 48, 41, 10, 9, 9, 9,104, 32, 43, 61, 32, 49, 46, 48, 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, 32, 61, + 32,118,101, 99, 52, 40,104, 44, 32,115, 44, 32,118, 44, 32,114,103, 98, 46,119, 41, 59, 10,125, 10, 10,118,111,105,100, 32,104, +115,118, 95,116,111, 95,114,103, 98, 40,118,101, 99, 52, 32,104,115,118, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, + 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,105, 44, 32,102, 44, 32,112, 44, 32,113, 44, 32,116, 44, 32,104, 44, 32, +115, 44, 32,118, 59, 10, 9,118,101, 99, 51, 32,114,103, 98, 59, 10, 10, 9,104, 32, 61, 32,104,115,118, 91, 48, 93, 59, 10, 9, +115, 32, 61, 32,104,115,118, 91, 49, 93, 59, 10, 9,118, 32, 61, 32,104,115,118, 91, 50, 93, 59, 10, 10, 9,105,102, 40,115, 61, + 61, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,118, 44, 32,118, 41, 59, 10, 9, +125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,105,102, 40,104, 61, 61, 49, 46, 48, 41, 10, 9, 9, 9,104, 32, 61, 32, 48, 46, + 48, 59, 10, 9, 9, 10, 9, 9,104, 32, 42, 61, 32, 54, 46, 48, 59, 10, 9, 9,105, 32, 61, 32,102,108,111,111,114, 40,104, 41, + 59, 10, 9, 9,102, 32, 61, 32,104, 32, 45, 32,105, 59, 10, 9, 9,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,102, 44, 32,102, + 44, 32,102, 41, 59, 10, 9, 9,112, 32, 61, 32,118, 42, 40, 49, 46, 48, 45,115, 41, 59, 10, 9, 9,113, 32, 61, 32,118, 42, 40, + 49, 46, 48, 45, 40,115, 42,102, 41, 41, 59, 10, 9, 9,116, 32, 61, 32,118, 42, 40, 49, 46, 48, 45, 40,115, 42, 40, 49, 46, 48, + 45,102, 41, 41, 41, 59, 10, 9, 9, 10, 9, 9,105,102, 32, 40,105, 32, 61, 61, 32, 48, 46, 48, 41, 32,114,103, 98, 32, 61, 32, +118,101, 99, 51, 40,118, 44, 32,116, 44, 32,112, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 49, + 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,113, 44, 32,118, 44, 32,112, 41, 59, 10, 9, 9,101,108,115,101, 32, +105,102, 32, 40,105, 32, 61, 61, 32, 50, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,112, 44, 32,118, 44, 32,116, + 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 51, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, + 99, 51, 40,112, 44, 32,113, 44, 32,118, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 52, 46, 48, + 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,116, 44, 32,112, 44, 32,118, 41, 59, 10, 9, 9,101,108,115,101, 32,114,103, + 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,112, 44, 32,113, 41, 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, 32, 61, + 32,118,101, 99, 52, 40,114,103, 98, 44, 32,104,115,118, 46,119, 41, 59, 10,125, 10, 10,102,108,111, 97,116, 32,115,114,103, 98, + 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,102,108,111, 97,116, 32, 99, 41, 10,123, 10, 9,105,102, 40, 99, 32, 60, + 32, 48, 46, 48, 52, 48, 52, 53, 41, 10, 9, 9,114,101,116,117,114,110, 32, 40, 99, 32, 60, 32, 48, 46, 48, 41, 63, 32, 48, 46, + 48, 58, 32, 99, 32, 42, 32, 40, 49, 46, 48, 47, 49, 50, 46, 57, 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117, +114,110, 32,112,111,119, 40, 40, 99, 32, 43, 32, 48, 46, 48, 53, 53, 41, 42, 40, 49, 46, 48, 47, 49, 46, 48, 53, 53, 41, 44, 32, + 50, 46, 52, 41, 59, 10,125, 10, 10,102,108,111, 97,116, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, + 40,102,108,111, 97,116, 32, 99, 41, 10,123, 10, 9,105,102, 40, 99, 32, 60, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 10, 9, + 9,114,101,116,117,114,110, 32, 40, 99, 32, 60, 32, 48, 46, 48, 41, 63, 32, 48, 46, 48, 58, 32, 99, 32, 42, 32, 49, 50, 46, 57, + 50, 59, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117,114,110, 32, 49, 46, 48, 53, 53, 32, 42, 32,112,111,119, 40, 99, 44, + 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 10,125, 10, 10,118,111,105,100, 32,115,114,103, 98, 95, +116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,118,101, 99, 52, 32, 99,111,108, 95,102,114,111,109, 44, 32,111,117,116, 32, +118,101, 99, 52, 32, 99,111,108, 95,116,111, 41, 10,123, 10, 9, 99,111,108, 95,116,111, 46,114, 32, 61, 32,115,114,103, 98, 95, +116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,114, 41, 59, 10, 9, 99,111,108, 95,116, +111, 46,103, 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, + 46,103, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 98, 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114, +103, 98, 40, 99,111,108, 95,102,114,111,109, 46, 98, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 97, 32, 61, 32, 99,111,108, 95, +102,114,111,109, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, + 98, 40,118,101, 99, 52, 32, 99,111,108, 95,102,114,111,109, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 95,116,111, + 41, 10,123, 10, 9, 99,111,108, 95,116,111, 46,114, 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, + 98, 40, 99,111,108, 95,102,114,111,109, 46,114, 41, 59, 10, 9, 99,111,108, 95,116,111, 46,103, 32, 61, 32,108,105,110,101, 97, +114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,103, 41, 59, 10, 9, 99,111,108, 95,116, +111, 46, 98, 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114,111,109, + 46, 98, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 97, 32, 61, 32, 99,111,108, 95,102,114,111,109, 46, 97, 59, 10,125, 10, 10, + 35,100,101,102,105,110,101, 32, 77, 95, 80, 73, 32, 51, 46, 49, 52, 49, 53, 57, 50, 54, 53, 51, 53, 56, 57, 55, 57, 51, 50, 51, + 56, 52, 54, 10, 35,100,101,102,105,110,101, 32, 77, 95, 49, 95, 80, 73, 32, 48, 46, 51, 49, 56, 51, 48, 57, 56, 56, 54, 49, 56, + 51, 55, 57, 48, 54, 57, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 83, 72, 65, 68, 69, 82, 32, 78, 79, 68, 69, + 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,118, 99,111,108, 95, 97,116, +116,114,105, 98,117,116,101, 40,118,101, 99, 52, 32, 97,116,116,118, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,118, + 99,111,108, 41, 10,123, 10, 9,118, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 97,116,116,118, 99,111,108, 46,120, 47, 50, 53, + 53, 46, 48, 44, 32, 97,116,116,118, 99,111,108, 46,121, 47, 50, 53, 53, 46, 48, 44, 32, 97,116,116,118, 99,111,108, 46,122, 47, + 50, 53, 53, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,117,118, 95, 97,116,116,114,105, 98,117,116, +101, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 41, 10,123, 10, 9,117,118, + 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 42, 50, 46, 48, 32, 45, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, + 48, 41, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,103,101,111,109, 40,118,101, 99, 51, 32, 99,111, 44, 32, +118,101, 99, 51, 32,110,111,114, 44, 32,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, + 97,116,116,111,114, 99,111, 44, 32,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,118,101, 99, 52, 32, 97,116,116,118, 99,111, +108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,103,108,111, 98, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,108,111, 99, + 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,114, 99,111, + 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32, +111,117,116, 32,118,101, 99, 52, 32,118, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 99,111,108, 95, 97,108, +112,104, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102,114,111,110,116, 98, 97, 99,107, 41, 10,123, 10, 9,108,111, 99, + 97,108, 32, 61, 32, 99,111, 59, 10, 9,118,105,101,119, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108,111, 99, 97,108, + 41, 59, 10, 9,103,108,111, 98, 97,108, 32, 61, 32, 40,118,105,101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40,108,111, + 99, 97,108, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9,111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, 59, + 10, 9,117,118, 95, 97,116,116,114,105, 98,117,116,101, 40, 97,116,116,117,118, 44, 32,117,118, 41, 59, 10, 9,110,111,114,109, + 97,108, 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,110,111,114, 41, 59, 9, 47, 42, 32, 98,108,101,110,100,101,114, + 32,114,101,110,100,101,114, 32,110,111,114,109, 97,108, 32,105,115, 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,118, 99, +111,108, 95, 97,116,116,114,105, 98,117,116,101, 40, 97,116,116,118, 99,111,108, 44, 32,118, 99,111,108, 41, 59, 10, 9,118, 99, +111,108, 95, 97,108,112,104, 97, 32, 61, 32, 97,116,116,118, 99,111,108, 46, 97, 59, 10, 9,102,114,111,110,116, 98, 97, 99,107, + 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118,101, 99, + 44, 32,109, 97,116, 52, 32,109, 97,116, 44, 32,118,101, 99, 51, 32,109,105,110,118,101, 99, 44, 32,118,101, 99, 51, 32,109, 97, +120,118,101, 99, 44, 32,102,108,111, 97,116, 32,100,111,109,105,110, 44, 32,102,108,111, 97,116, 32,100,111,109, 97,120, 44, 32, +111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32, 40,109, 97, +116, 32, 42, 32,118,101, 99, 52, 40,118,101, 99, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9,105,102, 40,100,111,109, +105,110, 32, 61, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32,109, 97,120, 40,111,117,116,118,101, 99, + 44, 32,109,105,110,118,101, 99, 41, 59, 10, 9,105,102, 40,100,111,109, 97,120, 32, 61, 61, 32, 49, 46, 48, 41, 10, 9, 9,111, +117,116,118,101, 99, 32, 61, 32,109,105,110, 40,111,117,116,118,101, 99, 44, 32,109, 97,120,118,101, 99, 41, 59, 10,125, 10, 10, +118,111,105,100, 32, 99, 97,109,101,114, 97, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117, +116,118,105,101,119, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,100,101,112,116,104, 44, 32,111,117,116, 32,102, +108,111, 97,116, 32,111,117,116,100,105,115,116, 41, 10,123, 10, 9,111,117,116,100,101,112,116,104, 32, 61, 32, 97, 98,115, 40, + 99,111, 46,122, 41, 59, 10, 9,111,117,116,100,105,115,116, 32, 61, 32,108,101,110,103,116,104, 40, 99,111, 41, 59, 10, 9,111, +117,116,118,105,101,119, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 41, 59, 10,125, 10, 10,118,111,105,100, 32, +109, 97,116,104, 95, 97,100,100, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, + 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, + 97,108, 49, 32, 43, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,115,117, 98,116,114, 97, 99, +116, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108, +111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 45, 32,118, + 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109,117,108,116,105,112,108,121, 40,102,108,111, 97,116, + 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, +118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 42, 32,118, 97,108, 50, 59, 10,125, 10, + 10,118,111,105,100, 32,109, 97,116,104, 95,100,105,118,105,100,101, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108, +111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105, +102, 32, 40,118, 97,108, 50, 32, 61, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10, + 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 47, 32,118, 97,108, 50, 59, 10,125, 10, + 10,118,111,105,100, 32,109, 97,116,104, 95,115,105,110,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102, +108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,115,105,110, 40,118, 97,108, + 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 99,111,115,105,110,101, 40,102,108,111, 97,116, 32,118, 97,108, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, + 99,111,115, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,116, 97,110,103,101,110,116, 40,102, +108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111, +117,116,118, 97,108, 32, 61, 32,116, 97,110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97, +115,105,110, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, + 10,123, 10, 9,105,102, 32, 40,118, 97,108, 32, 60, 61, 32, 49, 46, 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, + 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 97,115,105,110, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, + 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97, 99,111,115, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, - 9,111,117,116,118, 97,108, 32, 61, 32,116, 97,110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, - 95, 97,115,105,110, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97, -108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 32, 60, 61, 32, 49, 46, 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, - 49, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 97,115,105,110, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, - 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97, 99, -111,115, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10, -123, 10, 9,105,102, 32, 40,118, 97,108, 32, 60, 61, 32, 49, 46, 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, - 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 97, 99,111,115, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9, -111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,116, 97,110, 40, -102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9, -111,117,116,118, 97,108, 32, 61, 32, 97,116, 97,110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, - 95,112,111,119, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, - 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 49, 32, 62, 61, 32, 48, 46, - 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32,112,111,119, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10, 9, -101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116, -104, 95,108,111,103, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117, -116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 62, 32, 48, 46, 48, - 32, 32, 38, 38, 32,118, 97,108, 50, 32, 62, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 61, 32,108,111,103, 50, 40, -118, 97,108, 49, 41, 32, 47, 32,108,111,103, 50, 40,118, 97,108, 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, - 97,108, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109, 97,120, 40,102,108,111, 97,116, 32, -118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, - 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109, 97,120, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, - 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109,105,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108, -111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111, -117,116,118, 97,108, 32, 61, 32,109,105,110, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10,125, 10, 10,118,111,105,100, - 32,109, 97,116,104, 95,114,111,117,110,100, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 61, 32,102,108,111,111,114, 40,118, 97,108, 32, 43, 32, - 48, 46, 53, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,108,101,115,115, 95,116,104, 97,110, 40,102,108,111, - 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111, -117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 60, 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, - 97,108, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10, -125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,103,114,101, 97,116,101,114, 95,116,104, 97,110, 40,102,108,111, 97,116, 32, -118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, - 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 62, 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, - 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10, -118,111,105,100, 32,115,113,117,101,101,122,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,102,108,111, 97,116, 32,119,105, -100,116,104, 44, 32,102,108,111, 97,116, 32, 99,101,110,116,101,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, -118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 47, 40, 49, 46, 48, 32, 43, 32,112,111,119, 40, - 50, 46, 55, 49, 56, 50, 56, 49, 56, 51, 44, 32, 45, 40, 40,118, 97,108, 45, 99,101,110,116,101,114, 41, 42,119,105,100,116,104, - 41, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 97,100,100, 40,118,101, 99, 51, 32,118, - 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, - 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, 32, -118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 40, 97, 98,115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, - 97, 98,115, 40,111,117,116,118,101, 99, 91, 49, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, - 47, 51, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,115,117, 98, 40,118,101, 99, 51, 32, -118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117, -116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 45, - 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 40, 97, 98,115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, - 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 49, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, - 41, 47, 51, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 97,118,101,114, 97,103,101, 40, -118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, - 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, - 32,118, 49, 32, 43, 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,111,117,116,118,101, - 99, 41, 59, 10, 9,111,117,116,118,101, 99, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,118,101, 99, 41, 59, - 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,100,111,116, 40,118,101, 99, 51, 32,118, 49, 44, 32,118, -101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, - 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 51, 40, 48, 44, 32, 48, - 44, 32, 48, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,100,111,116, 40,118, 49, 44, 32,118, 50, 41, 59, 10,125, 10, 10, -118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 99,114,111,115,115, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, + 9,105,102, 32, 40,118, 97,108, 32, 60, 61, 32, 49, 46, 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, 41, 10, + 9, 9,111,117,116,118, 97,108, 32, 61, 32, 97, 99,111,115, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117, +116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,116, 97,110, 40,102,108, +111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117, +116,118, 97,108, 32, 61, 32, 97,116, 97,110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,112, +111,119, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102, +108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 49, 32, 62, 61, 32, 48, 46, 48, 41, + 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32,112,111,119, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10, 9,101,108, +115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, +108,111,103, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32, +102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 62, 32, 48, 46, 48, 32, 32, + 38, 38, 32,118, 97,108, 50, 32, 62, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 61, 32,108,111,103, 50, 40,118, 97, +108, 49, 41, 32, 47, 32,108,111,103, 50, 40,118, 97,108, 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, + 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109, 97,120, 40,102,108,111, 97,116, 32,118, 97, +108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, + 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109, 97,120, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10,125, + 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109,105,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97, +116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116, +118, 97,108, 32, 61, 32,109,105,110, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, + 97,116,104, 95,114,111,117,110,100, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111, +117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 61, 32,102,108,111,111,114, 40,118, 97,108, 32, 43, 32, 48, 46, + 53, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,108,101,115,115, 95,116,104, 97,110, 40,102,108,111, 97,116, + 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, +118, 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 60, 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, + 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, + 10,118,111,105,100, 32,109, 97,116,104, 95,103,114,101, 97,116,101,114, 95,116,104, 97,110, 40,102,108,111, 97,116, 32,118, 97, +108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, + 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 62, 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, + 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111, +105,100, 32,115,113,117,101,101,122,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,102,108,111, 97,116, 32,119,105,100,116, +104, 44, 32,102,108,111, 97,116, 32, 99,101,110,116,101,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97, +108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 47, 40, 49, 46, 48, 32, 43, 32,112,111,119, 40, 50, 46, + 55, 49, 56, 50, 56, 49, 56, 51, 44, 32, 45, 40, 40,118, 97,108, 45, 99,101,110,116,101,114, 41, 42,119,105,100,116,104, 41, 41, + 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 97,100,100, 40,118,101, 99, 51, 32,118, 49, 44, + 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102, +108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, 32,118, 50, + 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 40, 97, 98,115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, 97, 98, +115, 40,111,117,116,118,101, 99, 91, 49, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, 47, 51, + 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,115,117, 98, 40,118,101, 99, 51, 32,118, 49, + 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32, +102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 45, 32,118, + 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 40, 97, 98,115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, 97, + 98,115, 40,111,117,116,118,101, 99, 91, 49, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, 47, + 51, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 97,118,101,114, 97,103,101, 40,118,101, + 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, + 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, + 49, 32, 43, 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,111,117,116,118,101, 99, 41, + 59, 10, 9,111,117,116,118,101, 99, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,118,101, 99, 41, 59, 10,125, + 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,100,111,116, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32, 99,114,111,115,115, 40,118, 49, 44, 32,118, - 50, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, - 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,110,111,114,109, 97,108,105,122,101, 40,118,101, 99, 51, 32,118, 44, - 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, - 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,118, 41, 59, 10, 9,111,117,116,118, -101, 99, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, - 97,116,104, 95,110,101,103, 97,116,101, 40,118,101, 99, 51, 32,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, - 41, 10,123, 10, 9,111,117,116,118, 32, 61, 32, 45,118, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,114,109, 97,108, 40,118, -101, 99, 51, 32,100,105,114, 44, 32,118,101, 99, 51, 32,110,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110, -111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,100,111,116, 41, 10,123, 10, 9,111,117,116,110,111,114, 32, - 61, 32,110,111,114, 59, 10, 9,111,117,116,100,111,116, 32, 61, 32, 45,100,111,116, 40,100,105,114, 44, 32,110,111,114, 41, 59, - 10,125, 10, 10,118,111,105,100, 32, 99,117,114,118,101,115, 95,118,101, 99, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118, -101, 99, 51, 32,118,101, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, - 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 46,120, 32, 61, 32,116,101,120,116, -117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 40,118,101, 99, 46,120, 32, 43, 32, 49, 46, - 48, 41, 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,120, 59, 10, 9,111,117,116,118,101, 99, 46,121, 32, 61, 32,116,101,120, -116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 40,118,101, 99, 46,121, 32, 43, 32, 49, - 46, 48, 41, 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,121, 59, 10, 9,111,117,116,118,101, 99, 46,122, 32, 61, 32,116,101, -120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 40,118,101, 99, 46,122, 32, 43, 32, - 49, 46, 48, 41, 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,122, 59, 10, 10, 9,105,102, 32, 40,102, 97, 99, 32, 33, 61, 32, - 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32, 40,111,117,116,118,101, 99, 42,102, 97, 99, 41, 32, 43, 32, 40, -118,101, 99, 42, 40, 49, 46, 48, 45,102, 97, 99, 41, 41, 59, 10, 10,125, 10, 10,118,111,105,100, 32, 99,117,114,118,101,115, 95, -114,103, 98, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,115, 97,109,112,108,101,114, - 50, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, - 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32, -118,101, 99, 50, 40,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111, -108, 46,114, 44, 32, 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, 41, 46,114, 59, 10, 9,111,117,116, 99,111,108, 46,103, - 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,116,101,120,116, -117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111,108, 46,103, 44, 32, 48, 46, 48, 41, - 41, 46, 97, 44, 32, 48, 46, 48, 41, 41, 46,103, 59, 10, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116,101,120,116,117,114, -101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114, -118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111,108, 46, 98, 44, 32, 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, - 41, 46, 98, 59, 10, 10, 9,105,102, 32, 40,102, 97, 99, 32, 33, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 32, - 61, 32, 40,111,117,116, 99,111,108, 42,102, 97, 99, 41, 32, 43, 32, 40, 99,111,108, 42, 40, 49, 46, 48, 45,102, 97, 99, 41, 41, - 59, 10, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,115,101, -116, 95,118, 97,108,117,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, -118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101, -116, 95,114,103, 98, 40,118,101, 99, 51, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, - 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, - 98, 97, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, - 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,118, 97,108,117,101, - 95,122,101,114,111, 40,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97, -108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,118, 97,108,117,101, 95,111,110,101, 40,111, -117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, - 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 95,122,101,114,111, 40,111,117,116, 32,118,101, 99, 51, 32, -111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10,125, - 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 97, 95,122,101,114,111, 40,111,117,116, 32,118,101, 99, 52, 32,111,117, -116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118,101, 99, 52, 40, 48, 46, 48, 41, 59, 10,125, 10, 10, -118,111,105,100, 32,109,105,120, 95, 98,108,101,110,100, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99, -111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, - 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, - 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, - 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, - 97,100,100, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99, -111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99, -108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109, -105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 43, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, - 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,109,117,108,116, + 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 51, 40, 48, 44, 32, 48, 44, 32, + 48, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,100,111,116, 40,118, 49, 44, 32,118, 50, 41, 59, 10,125, 10, 10,118,111, +105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 99,114,111,115,115, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32, +118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111, +117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32, 99,114,111,115,115, 40,118, 49, 44, 32,118, 50, 41, + 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, 10,118, +111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,110,111,114,109, 97,108,105,122,101, 40,118,101, 99, 51, 32,118, 44, 32,111, +117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, + 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,118, 41, 59, 10, 9,111,117,116,118,101, 99, + 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116, +104, 95,110,101,103, 97,116,101, 40,118,101, 99, 51, 32,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 41, 10, +123, 10, 9,111,117,116,118, 32, 61, 32, 45,118, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,114,109, 97,108, 40,118,101, 99, + 51, 32,100,105,114, 44, 32,118,101, 99, 51, 32,110,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,100,111,116, 41, 10,123, 10, 9,111,117,116,110,111,114, 32, 61, 32, +110,111,114, 59, 10, 9,111,117,116,100,111,116, 32, 61, 32, 45,100,111,116, 40,100,105,114, 44, 32,110,111,114, 41, 59, 10,125, + 10, 10,118,111,105,100, 32, 99,117,114,118,101,115, 95,118,101, 99, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, + 51, 32,118,101, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, 32,118, +101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 46,120, 32, 61, 32,116,101,120,116,117,114, +101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 40,118,101, 99, 46,120, 32, 43, 32, 49, 46, 48, 41, + 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,120, 59, 10, 9,111,117,116,118,101, 99, 46,121, 32, 61, 32,116,101,120,116,117, +114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 40,118,101, 99, 46,121, 32, 43, 32, 49, 46, 48, + 41, 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,121, 59, 10, 9,111,117,116,118,101, 99, 46,122, 32, 61, 32,116,101,120,116, +117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 40,118,101, 99, 46,122, 32, 43, 32, 49, 46, + 48, 41, 42, 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,122, 59, 10, 10, 9,105,102, 32, 40,102, 97, 99, 32, 33, 61, 32, 49, 46, + 48, 41, 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32, 40,111,117,116,118,101, 99, 42,102, 97, 99, 41, 32, 43, 32, 40,118,101, + 99, 42, 40, 49, 46, 48, 45,102, 97, 99, 41, 41, 59, 10, 10,125, 10, 10,118,111,105,100, 32, 99,117,114,118,101,115, 95,114,103, + 98, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,115, 97,109,112,108,101,114, 50, 68, + 32, 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111, +117,116, 99,111,108, 46,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, + 99, 50, 40,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111,108, 46, +114, 44, 32, 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, 41, 46,114, 59, 10, 9,111,117,116, 99,111,108, 46,103, 32, 61, + 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,116,101,120,116,117,114, +101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111,108, 46,103, 44, 32, 48, 46, 48, 41, 41, 46, + 97, 44, 32, 48, 46, 48, 41, 41, 46,103, 59, 10, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116,101,120,116,117,114,101, 50, + 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101, +109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111,108, 46, 98, 44, 32, 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, 41, 46, + 98, 59, 10, 10, 9,105,102, 32, 40,102, 97, 99, 32, 33, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32, + 40,111,117,116, 99,111,108, 42,102, 97, 99, 41, 32, 43, 32, 40, 99,111,108, 42, 40, 49, 46, 48, 45,102, 97, 99, 41, 41, 59, 10, + 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95, +118, 97,108,117,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97, +108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95, +114,103, 98, 40,118,101, 99, 51, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, + 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 97, + 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111, +117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,118, 97,108,117,101, 95,122, +101,114,111, 40,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, + 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,118, 97,108,117,101, 95,111,110,101, 40,111,117,116, + 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10, +125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 95,122,101,114,111, 40,111,117,116, 32,118,101, 99, 51, 32,111,117, +116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10,125, 10, 10, +118,111,105,100, 32,115,101,116, 95,114,103, 98, 97, 95,122,101,114,111, 40,111,117,116, 32,118,101, 99, 52, 32,111,117,116,118, + 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118,101, 99, 52, 40, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111, +105,100, 32,109,105,120, 95, 98,108,101,110,100, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, + 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, + 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111, +117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111, +117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 97,100, +100, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, + 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97, +109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, + 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 43, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111, +108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,109,117,108,116, 40,102, +108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32, +111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40, +102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111, +108, 49, 44, 32, 99,111,108, 49, 32, 42, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, + 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115, 99,114,101,101,110, 40,102,108, +111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111, +117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, + 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, + 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 40, +118,101, 99, 52, 40,102, 97, 99,109, 41, 32, 43, 32,102, 97, 99, 42, 40,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 99,111, +108, 50, 41, 41, 42, 40,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9,111,117,116, 99,111,108, + 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,111,118,101,114,108, 97,121, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109, -112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, - 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 42, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, - 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115, 99,114,101,101,110, 40, -102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, - 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, - 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, - 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, - 32, 40,118,101, 99, 52, 40,102, 97, 99,109, 41, 32, 43, 32,102, 97, 99, 42, 40,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, - 99,111,108, 50, 41, 41, 42, 40,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9,111,117,116, 99, -111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,111,118,101,114,108, - 97,121, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111, -108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, - 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, - 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9, -105,102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 42, 61, - 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9,101,108,115,101, 10, 9, 9, -111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, - 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,114, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, - 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, - 46,103, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9,101,108, -115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, - 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,103, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, - 99,111,108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111, -117,116, 99,111,108, 46, 98, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46, 98, - 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, - 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46, 98, 41, 41, 42, 40, 49, 46, 48, 32, - 45, 32,111,117,116, 99,111,108, 46, 98, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115,117, 98, 40,102,108,111, - 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117, -116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, - 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, - 44, 32, 99,111,108, 49, 32, 45, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, - 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,105,118, 40,102,108,111, 97,116, 32,102, - 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, - 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, - 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, - 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,114, 32, - 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,114, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,114, - 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,114, 47, 99,111,108, 50, 46,114, 59, 10, 9,105,102, 40, 99,111,108, 50, - 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,103, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111, -108, 46,103, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,103, 47, 99,111,108, 50, 46,103, 59, 10, 9,105,102, 40, 99, -111,108, 50, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99,109, 42,111,117, -116, 99,111,108, 46, 98, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46, 98, 47, 99,111,108, 50, 46, 98, 59, 10,125, 10, - 10,118,111,105,100, 32,109,105,120, 95,100,105,102,102, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99, -111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, - 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, - 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 97, 98,115, 40, 99,111,108, 49, 32, 45, 32, 99, -111,108, 50, 41, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, -125, 10, 10,118,111,105,100, 32,109,105,120, 95,100, 97,114,107, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, - 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111, -108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, - 59, 10, 9,111,117,116, 99,111,108, 46,114,103, 98, 32, 61, 32,109,105,110, 40, 99,111,108, 49, 46,114,103, 98, 44, 32, 99,111, -108, 50, 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, - 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,108,105,103,104,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, - 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, - 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, - 48, 41, 59, 10, 9,111,117,116, 99,111,108, 46,114,103, 98, 32, 61, 32,109, 97,120, 40, 99,111,108, 49, 46,114,103, 98, 44, 32, - 99,111,108, 50, 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, - 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,111,100,103,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32, -118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111, -117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, - 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111, -108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, - 45, 32,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, - 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, - 32, 61, 32,111,117,116, 99,111,108, 46,114, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111, -108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, -116,109,112, 59, 10, 9,125, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, - 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9, - 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, - 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46,103, 47,116,109,112, - 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108, -115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109,112, 59, 10, 9,125, 10, 9,105,102, 40,111,117,116, - 99,111,108, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, - 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, - 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116, -109,112, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, - 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, 32, - 61, 32,116,109,112, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 98,117,114,110, 40,102,108,111, 97,116, +112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, + 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, + 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 42, 61, 32,102, + 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117, +116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, + 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,114, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 59, + 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, + 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9,101,108,115,101, + 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42, +102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,103, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111, +108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, + 99,111,108, 46, 98, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, + 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, + 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46, 98, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32, +111,117,116, 99,111,108, 46, 98, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115,117, 98, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32, 118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, - 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,116,109,112, 44, 32,102, 97, 99,109, 32, 61, 32, 49, - 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,116,109,112, - 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9,105,102, 40,116,109,112, 32, 60, 61, - 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, - 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 47, -116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46, 48, 59, 10, 9, -101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, - 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,109,112, 59, 10, 10, 9,116, -109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9,105,102, 40,116,109,112, 32, - 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32, -105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,103, - 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 48, 46, 48, 59, - 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, - 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109,112, 59, 10, 10, - 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9,105,102, 40,116,109, -112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115, -101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, - 46, 98, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 48, 46, - 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, - 98, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116,109,112, 59, - 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,104,117,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, + 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, + 99,111,108, 49, 32, 45, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99, +111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,105,118, 40,102,108,111, 97,116, 32,102, 97, 99, + 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, + 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, + 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, + 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,114, 32, 33, 61, + 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,114, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,114, 32, 43, + 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,114, 47, 99,111,108, 50, 46,114, 59, 10, 9,105,102, 40, 99,111,108, 50, 46,103, + 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,103, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46, +103, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,103, 47, 99,111,108, 50, 46,103, 59, 10, 9,105,102, 40, 99,111,108, + 50, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99, +111,108, 46, 98, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46, 98, 47, 99,111,108, 50, 46, 98, 59, 10,125, 10, 10,118, +111,105,100, 32,109,105,120, 95,100,105,102,102, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, + 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, + 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111, +117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 97, 98,115, 40, 99,111,108, 49, 32, 45, 32, 99,111,108, + 50, 41, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, + 10,118,111,105,100, 32,109,105,120, 95,100, 97,114,107, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99, +111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, + 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, + 9,111,117,116, 99,111,108, 46,114,103, 98, 32, 61, 32,109,105,110, 40, 99,111,108, 49, 46,114,103, 98, 44, 32, 99,111,108, 50, + 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, + 10, 10,118,111,105,100, 32,109,105,120, 95,108,105,103,104,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111, 108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, - 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, - 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 44, 32,116,109, -112, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,105,102, - 40,104,115,118, 50, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111, -117,116, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 9, 9,104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46,120, 59, 10, 9, - 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, 41, 59, 32, 10, 10, 9, 9,111,117,116, 99,111, -108, 32, 61, 32,109,105,120, 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, 32,102, 97, 99, 41, 59, 10, 9, 9,111,117,116, - 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115, - 97,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111, -108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, - 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, - 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9, -118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, 99, -111,108, 44, 32,104,115,118, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, - 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9, 9,104,115,118, 46, -121, 32, 61, 32,102, 97, 99,109, 42,104,115,118, 46,121, 32, 43, 32,102, 97, 99, 42,104,115,118, 50, 46,121, 59, 10, 9, 9,104, -115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10, 9,125, 10,125, 10, 10,118,111, -105,100, 32,109,105,120, 95,118, 97,108, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, - 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9, -102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, - 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, - 32,104,115,118, 50, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 49, 44, 32,104,115,118, 41, 59, 10, 9, -114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,104,115,118, 46,122, 32, - 61, 32,102, 97, 99,109, 42,104,115,118, 46,122, 32, 43, 32,102, 97, 99, 42,104,115,118, 50, 46,122, 59, 10, 9,104,115,118, 95, -116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, - 95, 99,111,108,111,114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, - 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, - 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, - 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, - 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 44, 32,116,109,112, 59, 10, 9,114,103, 98, 95,116,111, - 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 50, 46,121, 32, 33, 61, - 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, 99,111,108, 44, 32,104,115,118, - 41, 59, 10, 9, 9,104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46,120, 59, 10, 9, 9,104,115,118, 46,121, 32, 61, 32,104, -115,118, 50, 46,121, 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, 41, 59, 32, 10, - 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, 32,102, 97, 99, - 41, 59, 10, 9, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, 10, 10,118,111, -105,100, 32,109,105,120, 95,115,111,102,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, - 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, - 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108, -111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,118,101, 99, 52, 32,111,110,101, - 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,118,101, 99, 52, 32,115, 99,114, 61, 32,111,110,101, 32, 45, 32, 40,111, -110,101, 32, 45, 32, 99,111,108, 50, 41, 42, 40,111,110,101, 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9,111,117,116, 99,111,108, - 32, 61, 32,102, 97, 99,109, 42, 99,111,108, 49, 32, 43, 32,102, 97, 99, 42, 40, 40,111,110,101, 32, 45, 32, 99,111,108, 49, 41, - 42, 99,111,108, 50, 42, 99,111,108, 49, 32, 43, 32, 99,111,108, 49, 42,115, 99,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32, -109,105,120, 95,108,105,110,101, 97,114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, - 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9, -102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 10, 9,111,117, -116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,114, 32, 62, 32, 48, 46, 53, 41, 10, - 9, 9,111,117,116, 99,111,108, 46,114, 61, 32, 99,111,108, 49, 46,114, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99, -111,108, 50, 46,114, 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 61, - 32, 99,111,108, 49, 46,114, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,114, 41, 32, 45, 32, 49, 46, - 48, 41, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,103, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46, -103, 61, 32, 99,111,108, 49, 46,103, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,103, 32, 45, 32, 48, - 46, 53, 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 61, 32, 99,111,108, 49, 46,103, 32, 43, - 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,103, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10, 10, 9,105,102, 40, - 99,111,108, 50, 46, 98, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 61, 32, 99,111,108, 49, 46, 98, - 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46, 98, 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108, -115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 61, 32, 99,111,108, 49, 46, 98, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, - 42, 40, 99,111,108, 50, 46, 98, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118, 97,108,116,111,114, -103, 98, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,111,108,111,114,109, 97,112, - 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, - 97,108,112,104, 97, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,111,108, -111,114,109, 97,112, 44, 32,118,101, 99, 50, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 41, 59, 10, 9,111,117,116, 97,108,112,104, - 97, 32, 61, 32,111,117,116, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,114,103, 98,116,111, 98,119, 40,118,101, - 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 32, 32, 10,123, 10, - 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,108,111,114, 46,114, 42, 48, 46, 51, 53, 32, 43, 32, 99,111,108,111,114, 46,103, - 42, 48, 46, 52, 53, 32, 43, 32, 99,111,108,111,114, 46, 98, 42, 48, 46, 50, 59, 32, 47, 42, 32,107,101,101,112, 32,116,104,101, -115,101, 32,102, 97, 99,116,111,114,115, 32,105,110, 32,115,121,110, 99, 32,119,105,116,104, 32,116,101,120,116,117,114,101, 46, -104, 58, 82, 71, 66, 84, 79, 66, 87, 32, 42, 47, 10,125, 10, 10,118,111,105,100, 32,105,110,118,101,114,116, 40,102,108,111, 97, -116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, - 41, 10,123, 10, 9,111,117,116, 99,111,108, 46,120,121,122, 32, 61, 32,109,105,120, 40, 99,111,108, 46,120,121,122, 44, 32,118, -101, 99, 51, 40, 49, 46, 48, 44, 32, 49, 46, 48, 44, 32, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 46,120,121,122, 44, 32,102, 97, - 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46,119, 32, 61, 32, 99,111,108, 46,119, 59, 10,125, 10, 10,118,111,105,100, 32,104, -117,101, 95,115, 97,116, 40,102,108,111, 97,116, 32,104,117,101, 44, 32,102,108,111, 97,116, 32,115, 97,116, 44, 32,102,108,111, - 97,116, 32,118, 97,108,117,101, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111, -117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32,104,115,118, 59, 10, 10, 9,114, -103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 10, 9,104,115,118, 91, 48, 93, 32, 43, 61, - 32, 40,104,117,101, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,105,102, 40,104,115,118, 91, 48, 93, 62, 49, 46, 48, 41, 32,104,115, -118, 91, 48, 93, 45, 61, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 48, 93, 60, 48, 46, 48, 41, 32,104, -115,118, 91, 48, 93, 43, 61, 32, 49, 46, 48, 59, 10, 9,104,115,118, 91, 49, 93, 32, 42, 61, 32,115, 97,116, 59, 10, 9,105,102, - 40,104,115,118, 91, 49, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 49, 46, 48, 59, 32,101,108,115,101, 32,105, -102, 40,104,115,118, 91, 49, 93, 60, 48, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 48, 46, 48, 59, 10, 9,104,115,118, 91, - 50, 93, 32, 42, 61, 32,118, 97,108,117,101, 59, 10, 9,105,102, 40,104,115,118, 91, 50, 93, 62, 49, 46, 48, 41, 32,104,115,118, - 91, 50, 93, 61, 32, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 50, 93, 60, 48, 46, 48, 41, 32,104,115, -118, 91, 50, 93, 61, 32, 48, 46, 48, 59, 10, 10, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, - 99,111,108, 41, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 44, 32,111,117,116, 99,111,108, - 44, 32,102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,112, 97,114, 97,116,101, 95,114,103, 98, 40,118,101, 99, - 52, 32, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,103, 44, - 32,111,117,116, 32,102,108,111, 97,116, 32, 98, 41, 10,123, 10, 9,114, 32, 61, 32, 99,111,108, 46,114, 59, 10, 9,103, 32, 61, - 32, 99,111,108, 46,103, 59, 10, 9, 98, 32, 61, 32, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32, 99,111,109, 98, -105,110,101, 95,114,103, 98, 40,102,108,111, 97,116, 32,114, 44, 32,102,108,111, 97,116, 32,103, 44, 32,102,108,111, 97,116, 32, - 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 41, 10,123, 10, 9, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,114, - 44, 32,103, 44, 32, 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,111,117,116,112,117,116, 95,110,111,100, -101, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 44, 32,111,117,116, 32,118,101, 99, - 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,114,103, 98, 46,114, -103, 98, 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 84, 69, 88, 84, - 85, 82, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,116,101,120,116, -117,114,101, 95,102,108,105,112, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, - 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 46,121,120,122, 59, 10,125, - 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95, 98,108,101,110,100, 95,108,105,110, 40,118,101, 99, 51, 32,118,101, - 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, - 32, 40, 49, 46, 48, 43,118,101, 99, 46,120, 41, 47, 50, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114, -101, 95, 98,108,101,110,100, 95,113,117, 97,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109, 97,120, 40, 40, 49, 46, 48, 43,118,101, - 99, 46,120, 41, 47, 50, 46, 48, 44, 32, 48, 46, 48, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 42, 61, 32,111,117,116,118, 97, -108, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,119,111,111,100, 95,115,105,110, 40,118,101, 99, 51, - 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, - 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, 9,102,108,111, 97,116, - 32, 97, 32, 61, 32,115,113,114,116, 40,118,101, 99, 46,120, 42,118,101, 99, 46,120, 32, 43, 32,118,101, 99, 46,121, 42,118,101, - 99, 46,121, 32, 43, 32,118,101, 99, 46,122, 42,118,101, 99, 46,122, 41, 42, 50, 48, 46, 48, 59, 10, 9,102,108,111, 97,116, 32, -119,105, 32, 61, 32, 48, 46, 53, 32, 43, 32, 48, 46, 53, 42,115,105,110, 40, 97, 41, 59, 10, 10, 9,118, 97,108,117,101, 32, 61, - 32,119,105, 59, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40,119,105, 44, 32,119,105, 44, 32,119,105, 44, 32, 49, - 46, 48, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, - 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,105,109, 97,103,101, 40,118,101, 99, 51, 32,118, -101, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108, -117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114, -109, 97,108, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 40, -118,101, 99, 46,120,121, 32, 43, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 41, 42, 48, 46, 53, 41, 59, 10, 9, -118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 59, 10, 10, 9,110,111,114,109, 97,108, 46,120, 32, 61, 32, 50, 46, 48, 42, 40, 99, -111,108,111,114, 46,114, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,110,111,114,109, 97,108, 46,121, 32, 61, 32, 50, 46, 48, 42, 40, - 48, 46, 53, 32, 45, 32, 99,111,108,111,114, 46,103, 41, 59, 10, 9,110,111,114,109, 97,108, 46,122, 32, 61, 32, 50, 46, 48, 42, - 40, 99,111,108,111,114, 46, 98, 32, 45, 32, 48, 46, 53, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 32, 77, 84, 69, 88, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, - 32,116,101,120, 99,111, 95,111,114, 99,111, 40,118,101, 99, 51, 32, 97,116,116,111,114, 99,111, 44, 32,111,117,116, 32,118,101, - 99, 51, 32,111,114, 99,111, 41, 10,123, 10, 9,111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, 59, 10,125, 10, 10,118, -111,105,100, 32,116,101,120, 99,111, 95,117,118, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117,116, 32,118,101, 99, - 51, 32,117,118, 41, 10,123, 10, 9, 47, 42, 32,100,105,115, 97, 98,108,101,100, 32,102,111,114, 32,110,111,119, 44, 32,119,111, -114,107,115, 32,116,111,103,101,116,104,101,114, 32,119,105,116,104, 32,108,101, 97,118,105,110,103, 32,111,117,116, 32,109,116, -101,120, 95, 50,100, 95,109, 97,112,112,105,110,103, 10, 9, 32, 32, 32,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117, -118, 42, 50, 46, 48, 32, 45, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, 59, 32, 42, 47, - 10, 9,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, - 32,116,101,120, 99,111, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, - 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 99,111,114,114,101,115,112,111,110,100,115, 32,116, -111, 32,115,104,105, 45, 62,111,114,110, 44, 32,119,104,105, 99,104, 32,105,115, 32,110,101,103, 97,116,101,100, 32,115,111, 32, - 99, 97,110, 99,101,108,115, 10, 9, 32, 32, 32,111,117,116, 32, 98,108,101,110,100,101,114, 32,110,111,114,109, 97,108, 32,110, -101,103, 97,116,105,111,110, 32, 42, 47, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122, -101, 40,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,116, 97,110,103,101,110,116, - 40,118,101, 99, 52, 32,116, 97,110,103,101,110,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116, 97,110,103,101, -110,116, 41, 10,123, 10, 9,111,117,116,116, 97,110,103,101,110,116, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,116, 97, -110,103,101,110,116, 46,120,121,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,103,108,111, 98, 97,108, - 40,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118, -101, 99, 51, 32,103,108,111, 98, 97,108, 41, 10,123, 10, 9,103,108,111, 98, 97,108, 32, 61, 32, 40,118,105,101,119,105,110,118, -109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10,125, 10, 10,118,111,105,100, 32, -116,101,120, 99,111, 95,111, 98,106,101, 99,116, 40,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,109, 97, -116, 52, 32,111, 98,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111, - 98,106,101, 99,116, 41, 10,123, 10, 9,111, 98,106,101, 99,116, 32, 61, 32, 40,111, 98,105,110,118,109, 97,116, 42, 40,118,105, -101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 41, 46,120,121,122, 59, 10,125, 10, - 10,118,111,105,100, 32,116,101,120, 99,111, 95,114,101,102,108, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,118, -105,101,119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,114,101,102, 41, 10,123, 10, 9,114,101,102, 32, 61, 32,118,105,101,119, - 32, 45, 32, 50, 46, 48, 42,100,111,116, 40,118,110, 44, 32,118,105,101,119, 41, 42,118,110, 59, 10,125, 10, 10,118,111,105,100, - 32,115,104, 97,100,101, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, - 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 98,108,101,110,100,101,114, 32,114,101,110,100,101, -114, 32,110,111,114,109, 97,108, 32,105,115, 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,111,117,116,110,111,114,109, 97, -108, 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32, -109,116,101,120, 95,114,103, 98, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, - 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, - 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, - 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, - 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,102, 97, 99,109, 42,111, -117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,109,117,108, 40,118,101, 99, 51, - 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, - 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, - 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, - 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32, 40,102, 97, 99,109, 32, 43, - 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, -101,120, 95,114,103, 98, 95,115, 99,114,101,101,110, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32, -116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32, -111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, - 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, - 10, 10, 9,105,110, 99,111,108, 32, 61, 32,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32, 40,118,101, 99, 51, 40,102, 97, 99, -109, 41, 32, 43, 32,102, 97, 99,116, 42, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,116,101,120, 99,111,108, 41, 41, 42, - 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, -101,120, 95,114,103, 98, 95,111,118,101,114,108, 97,121, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, - 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, - 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, - 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, - 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46,114, - 32, 61, 32,111,117,116, 99,111,108, 46,114, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, - 99,111,108, 46,114, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 32, 45, 32, - 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46,114, - 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, - 46,103, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99,111,108, 46,103, 42, 40, -102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, 41, 59, 10, 9,101,108,115,101, - 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, - 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46,103, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, - 99,111,108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105, -110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, - 99,116, 42,116,101,120, 99,111,108, 46, 98, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46, 98, 32, 61, 32, - 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101, -120, 99,111,108, 46, 98, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 59, 10,125, 10, 10,118,111, -105,100, 32,109,116,101,120, 95,114,103, 98, 95,115,117, 98, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, - 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, - 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, 32, 61, 32, 45,102, 97, - 99,116, 42,102, 97, 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, - 32,109,116,101,120, 95,114,103, 98, 95, 97,100,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32, -116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32, -111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42, -102, 97, 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, -101,120, 95,114,103, 98, 95,100,105,118, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, - 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, - 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, - 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9, -105,102, 40,116,101,120, 99,111,108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32,102, 97, - 99,109, 42,111,117,116, 99,111,108, 46,114, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, 46,114, 47,116,101,120, 99, -111,108, 46,114, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99,111,108, - 46,103, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,103, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, - 46,103, 47,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46, 98, 32, 33, 61, 32, 48, 46, 48, - 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46, 98, 32, 43, 32,102, 97, 99,116, - 42,111,117,116, 99,111,108, 46, 98, 47,116,101,120, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, - 95,114,103, 98, 95,100,105,102,102, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99, -111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32, -118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99, -116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105, -110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42, 97, 98,115, 40,116,101, -120, 99,111,108, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, - 95,100, 97,114,107, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32, -102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, - 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 44, 32, 99,111,108, 59, 10, 10, 9,102, 97, - 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9, - 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111, -117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99, -111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, - 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 46,103, 41, 32,105,110, 99,111,108, - 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99,111,108, 46, -103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 59, 10, 9,105,102, 40, 99,111,108, - 32, 60, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, - 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101, -120, 95,114,103, 98, 95,108,105,103,104,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101, + 59, 10, 9,111,117,116, 99,111,108, 46,114,103, 98, 32, 61, 32,109, 97,120, 40, 99,111,108, 49, 46,114,103, 98, 44, 32, 99,111, +108, 50, 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, + 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,111,100,103,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, + 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, + 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, + 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, +114, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32, +102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9, +111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, + 32,111,117,116, 99,111,108, 46,114, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46, +114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,109, +112, 59, 10, 9,125, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102, +108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9, 9,105, +102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, + 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46,103, 47,116,109,112, 41, 32, + 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, + 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109,112, 59, 10, 9,125, 10, 9,105,102, 40,111,117,116, 99,111, +108, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, + 45, 32,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, + 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, + 32, 61, 32,111,117,116, 99,111,108, 46, 98, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111, +108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, +116,109,112, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 98,117,114,110, 40,102,108,111, 97,116, 32,102, + 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, + 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, + 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,116,109,112, 44, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, + 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,116,109,112, 32, 61, + 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, + 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 40, +116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 47,116,109, +112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108, +115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, + 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,109,112, 59, 10, 10, 9,116,109,112, + 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9,105,102, 40,116,109,112, 32, 60, 61, + 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, + 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,103, 41, 47, +116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 48, 46, 48, 59, 10, 9, +101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, + 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109,112, 59, 10, 10, 9,116, +109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9,105,102, 40,116,109,112, 32, + 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32, +105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, + 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 48, 46, 48, 59, + 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, + 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116,109,112, 59, 10,125, + 10, 10,118,111,105,100, 32,109,105,120, 95,104,117,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99, +111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, + 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, + 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111, +108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 44, 32,116,109,112, 59, + 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,105,102, 40,104, +115,118, 50, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, + 99,111,108, 44, 32,104,115,118, 41, 59, 10, 9, 9,104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46,120, 59, 10, 9, 9,104, +115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, 41, 59, 32, 10, 10, 9, 9,111,117,116, 99,111,108, 32, + 61, 32,109,105,120, 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, 32,102, 97, 99, 41, 59, 10, 9, 9,111,117,116, 99,111, +108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115, 97,116, + 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, + 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109, +112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, + 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118,101, + 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, 99,111,108, + 44, 32,104,115,118, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114, +103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9, 9,104,115,118, 46,121, 32, + 61, 32,102, 97, 99,109, 42,104,115,118, 46,121, 32, 43, 32,102, 97, 99, 42,104,115,118, 50, 46,121, 59, 10, 9, 9,104,115,118, + 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, + 32,109,105,120, 95,118, 97,108, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118, +101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, + 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, + 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104, +115,118, 50, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 49, 44, 32,104,115,118, 41, 59, 10, 9,114,103, + 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,104,115,118, 46,122, 32, 61, 32, +102, 97, 99,109, 42,104,115,118, 46,122, 32, 43, 32,102, 97, 99, 42,104,115,118, 50, 46,122, 59, 10, 9,104,115,118, 95,116,111, + 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 99, +111,108,111,114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, + 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, + 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99, +109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, + 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 44, 32,116,109,112, 59, 10, 9,114,103, 98, 95,116,111, 95,104, +115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 50, 46,121, 32, 33, 61, 32, 48, + 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, 99,111,108, 44, 32,104,115,118, 41, 59, + 10, 9, 9,104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46,120, 59, 10, 9, 9,104,115,118, 46,121, 32, 61, 32,104,115,118, + 50, 46,121, 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, 41, 59, 32, 10, 10, 9, + 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, 32,102, 97, 99, 41, 59, + 10, 9, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, + 32,109,105,120, 95,115,111,102,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32, +118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, + 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97, +116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,118,101, 99, 52, 32,111,110,101, 61, 32, +118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,118,101, 99, 52, 32,115, 99,114, 61, 32,111,110,101, 32, 45, 32, 40,111,110,101, + 32, 45, 32, 99,111,108, 50, 41, 42, 40,111,110,101, 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, + 32,102, 97, 99,109, 42, 99,111,108, 49, 32, 43, 32,102, 97, 99, 42, 40, 40,111,110,101, 32, 45, 32, 99,111,108, 49, 41, 42, 99, +111,108, 50, 42, 99,111,108, 49, 32, 43, 32, 99,111,108, 49, 42,115, 99,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105, +120, 95,108,105,110,101, 97,114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118, +101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, + 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 10, 9,111,117,116, 99, +111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,114, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9, +111,117,116, 99,111,108, 46,114, 61, 32, 99,111,108, 49, 46,114, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, + 50, 46,114, 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 61, 32, 99, +111,108, 49, 46,114, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,114, 41, 32, 45, 32, 49, 46, 48, 41, + 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,103, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 61, + 32, 99,111,108, 49, 46,103, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,103, 32, 45, 32, 48, 46, 53, + 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 61, 32, 99,111,108, 49, 46,103, 32, 43, 32,102, + 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,103, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10, 10, 9,105,102, 40, 99,111, +108, 50, 46, 98, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 61, 32, 99,111,108, 49, 46, 98, 32, 43, + 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46, 98, 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108,115,101, + 10, 9, 9,111,117,116, 99,111,108, 46, 98, 61, 32, 99,111,108, 49, 46, 98, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, + 99,111,108, 50, 46, 98, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118, 97,108,116,111,114,103, 98, + 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,111,108,111,114,109, 97,112, 44, 32, +111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, 97,108, +112,104, 97, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,111,108,111,114, +109, 97,112, 44, 32,118,101, 99, 50, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 41, 59, 10, 9,111,117,116, 97,108,112,104, 97, 32, + 61, 32,111,117,116, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,114,103, 98,116,111, 98,119, 40,118,101, 99, 52, + 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 32, 32, 10,123, 10, 9,111, +117,116,118, 97,108, 32, 61, 32, 99,111,108,111,114, 46,114, 42, 48, 46, 51, 53, 32, 43, 32, 99,111,108,111,114, 46,103, 42, 48, + 46, 52, 53, 32, 43, 32, 99,111,108,111,114, 46, 98, 42, 48, 46, 50, 59, 32, 47, 42, 32,107,101,101,112, 32,116,104,101,115,101, + 32,102, 97, 99,116,111,114,115, 32,105,110, 32,115,121,110, 99, 32,119,105,116,104, 32,116,101,120,116,117,114,101, 46,104, 58, + 82, 71, 66, 84, 79, 66, 87, 32, 42, 47, 10,125, 10, 10,118,111,105,100, 32,105,110,118,101,114,116, 40,102,108,111, 97,116, 32, +102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10, +123, 10, 9,111,117,116, 99,111,108, 46,120,121,122, 32, 61, 32,109,105,120, 40, 99,111,108, 46,120,121,122, 44, 32,118,101, 99, + 51, 40, 49, 46, 48, 44, 32, 49, 46, 48, 44, 32, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 46,120,121,122, 44, 32,102, 97, 99, 41, + 59, 10, 9,111,117,116, 99,111,108, 46,119, 32, 61, 32, 99,111,108, 46,119, 59, 10,125, 10, 10,118,111,105,100, 32,104,117,101, + 95,115, 97,116, 40,102,108,111, 97,116, 32,104,117,101, 44, 32,102,108,111, 97,116, 32,115, 97,116, 44, 32,102,108,111, 97,116, + 32,118, 97,108,117,101, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, + 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32,104,115,118, 59, 10, 10, 9,114,103, 98, + 95,116,111, 95,104,115,118, 40, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 10, 9,104,115,118, 91, 48, 93, 32, 43, 61, 32, 40, +104,117,101, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,105,102, 40,104,115,118, 91, 48, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, + 48, 93, 45, 61, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 48, 93, 60, 48, 46, 48, 41, 32,104,115,118, + 91, 48, 93, 43, 61, 32, 49, 46, 48, 59, 10, 9,104,115,118, 91, 49, 93, 32, 42, 61, 32,115, 97,116, 59, 10, 9,105,102, 40,104, +115,118, 91, 49, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40, +104,115,118, 91, 49, 93, 60, 48, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 48, 46, 48, 59, 10, 9,104,115,118, 91, 50, 93, + 32, 42, 61, 32,118, 97,108,117,101, 59, 10, 9,105,102, 40,104,115,118, 91, 50, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, 50, + 93, 61, 32, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 50, 93, 60, 48, 46, 48, 41, 32,104,115,118, 91, + 50, 93, 61, 32, 48, 46, 48, 59, 10, 10, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111, +108, 41, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 44, 32,111,117,116, 99,111,108, 44, 32, +102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,112, 97,114, 97,116,101, 95,114,103, 98, 40,118,101, 99, 52, 32, + 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,103, 44, 32,111, +117,116, 32,102,108,111, 97,116, 32, 98, 41, 10,123, 10, 9,114, 32, 61, 32, 99,111,108, 46,114, 59, 10, 9,103, 32, 61, 32, 99, +111,108, 46,103, 59, 10, 9, 98, 32, 61, 32, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32, 99,111,109, 98,105,110, +101, 95,114,103, 98, 40,102,108,111, 97,116, 32,114, 44, 32,102,108,111, 97,116, 32,103, 44, 32,102,108,111, 97,116, 32, 98, 44, + 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 41, 10,123, 10, 9, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,114, 44, 32, +103, 44, 32, 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,111,117,116,112,117,116, 95,110,111,100,101, 40, +118,101, 99, 52, 32,114,103, 98, 44, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 44, 32,111,117,116, 32,118,101, 99, 52, 32, +111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,114,103, 98, 46,114,103, 98, + 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 84, 69, 88, 84, 85, 82, + 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,116,101,120,116,117,114, +101, 95,102,108,105,112, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32, +111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 46,121,120,122, 59, 10,125, 10, 10, +118,111,105,100, 32,116,101,120,116,117,114,101, 95, 98,108,101,110,100, 95,108,105,110, 40,118,101, 99, 51, 32,118,101, 99, 44, + 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 40, + 49, 46, 48, 43,118,101, 99, 46,120, 41, 47, 50, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95, + 98,108,101,110,100, 95,113,117, 97,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111, +117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109, 97,120, 40, 40, 49, 46, 48, 43,118,101, 99, 46, +120, 41, 47, 50, 46, 48, 44, 32, 48, 46, 48, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 42, 61, 32,111,117,116,118, 97,108, 59, + 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,119,111,111,100, 95,115,105,110, 40,118,101, 99, 51, 32,118, +101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111, +108,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32, 97, + 32, 61, 32,115,113,114,116, 40,118,101, 99, 46,120, 42,118,101, 99, 46,120, 32, 43, 32,118,101, 99, 46,121, 42,118,101, 99, 46, +121, 32, 43, 32,118,101, 99, 46,122, 42,118,101, 99, 46,122, 41, 42, 50, 48, 46, 48, 59, 10, 9,102,108,111, 97,116, 32,119,105, + 32, 61, 32, 48, 46, 53, 32, 43, 32, 48, 46, 53, 42,115,105,110, 40, 97, 41, 59, 10, 10, 9,118, 97,108,117,101, 32, 61, 32,119, +105, 59, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40,119,105, 44, 32,119,105, 44, 32,119,105, 44, 32, 49, 46, 48, + 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 41, + 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,105,109, 97,103,101, 40,118,101, 99, 51, 32,118,101, 99, + 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, + 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97, +108, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 40,118,101, + 99, 46,120,121, 32, 43, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 41, 42, 48, 46, 53, 41, 59, 10, 9,118, 97, +108,117,101, 32, 61, 32, 49, 46, 48, 59, 10, 10, 9,110,111,114,109, 97,108, 46,120, 32, 61, 32, 50, 46, 48, 42, 40, 99,111,108, +111,114, 46,114, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,110,111,114,109, 97,108, 46,121, 32, 61, 32, 50, 46, 48, 42, 40, 48, 46, + 53, 32, 45, 32, 99,111,108,111,114, 46,103, 41, 59, 10, 9,110,111,114,109, 97,108, 46,122, 32, 61, 32, 50, 46, 48, 42, 40, 99, +111,108,111,114, 46, 98, 32, 45, 32, 48, 46, 53, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 32, 77, 84, 69, 88, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,116, +101,120, 99,111, 95,111,114, 99,111, 40,118,101, 99, 51, 32, 97,116,116,111,114, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, + 32,111,114, 99,111, 41, 10,123, 10, 9,111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, 59, 10,125, 10, 10,118,111,105, +100, 32,116,101,120, 99,111, 95,117,118, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32, +117,118, 41, 10,123, 10, 9, 47, 42, 32,100,105,115, 97, 98,108,101,100, 32,102,111,114, 32,110,111,119, 44, 32,119,111,114,107, +115, 32,116,111,103,101,116,104,101,114, 32,119,105,116,104, 32,108,101, 97,118,105,110,103, 32,111,117,116, 32,109,116,101,120, + 95, 50,100, 95,109, 97,112,112,105,110,103, 10, 9, 32, 32, 32,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 42, + 50, 46, 48, 32, 45, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, 59, 32, 42, 47, 10, 9, +117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116, +101,120, 99,111, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32, +111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 99,111,114,114,101,115,112,111,110,100,115, 32,116,111, 32, +115,104,105, 45, 62,111,114,110, 44, 32,119,104,105, 99,104, 32,105,115, 32,110,101,103, 97,116,101,100, 32,115,111, 32, 99, 97, +110, 99,101,108,115, 10, 9, 32, 32, 32,111,117,116, 32, 98,108,101,110,100,101,114, 32,110,111,114,109, 97,108, 32,110,101,103, + 97,116,105,111,110, 32, 42, 47, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, +110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,116, 97,110,103,101,110,116, 40,118, +101, 99, 52, 32,116, 97,110,103,101,110,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116, 97,110,103,101,110,116, + 41, 10,123, 10, 9,111,117,116,116, 97,110,103,101,110,116, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,116, 97,110,103, +101,110,116, 46,120,121,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,103,108,111, 98, 97,108, 40,109, + 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, + 51, 32,103,108,111, 98, 97,108, 41, 10,123, 10, 9,103,108,111, 98, 97,108, 32, 61, 32, 40,118,105,101,119,105,110,118,109, 97, +116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10,125, 10, 10,118,111,105,100, 32,116,101, +120, 99,111, 95,111, 98,106,101, 99,116, 40,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,109, 97,116, 52, + 32,111, 98,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111, 98,106, +101, 99,116, 41, 10,123, 10, 9,111, 98,106,101, 99,116, 32, 61, 32, 40,111, 98,105,110,118,109, 97,116, 42, 40,118,105,101,119, +105,110,118,109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 41, 46,120,121,122, 59, 10,125, 10, 10,118, +111,105,100, 32,116,101,120, 99,111, 95,114,101,102,108, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,118,105,101, +119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,114,101,102, 41, 10,123, 10, 9,114,101,102, 32, 61, 32,118,105,101,119, 32, 45, + 32, 50, 46, 48, 42,100,111,116, 40,118,110, 44, 32,118,105,101,119, 41, 42,118,110, 59, 10,125, 10, 10,118,111,105,100, 32,115, +104, 97,100,101, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32, +111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 98,108,101,110,100,101,114, 32,114,101,110,100,101,114, 32, +110,111,114,109, 97,108, 32,105,115, 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,111,117,116,110,111,114,109, 97,108, 32, + 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, +101,120, 95,114,103, 98, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116, +101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111, +117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9, +102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, + 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,102, 97, 99,109, 42,111,117,116, + 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,109,117,108, 40,118,101, 99, 51, 32,111, +117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32, +102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102, +108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, + 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32, 40,102, 97, 99,109, 32, 43, 32,102, + 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95,114,103, 98, 95,115, 99,114,101,101,110, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101, 120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117, -116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 44, 32, 99,111,108, - 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, - 99,116, 59, 10, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40, 99, -111,108, 32, 62, 32,111,117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,108, 59, 32,101,108, -115,101, 32,105,110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, - 99,116, 42,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46,103, 41, - 32,105,110, 99,111,108, 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,103, 32, 61, 32,111, -117,116, 99,111,108, 46,103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 59, 10, 9, -105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32, 99,111,108, - 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111, -105,100, 32,109,116,101,120, 95,114,103, 98, 95,104,117,101, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, - 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, - 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, - 9,109,105,120, 95,104,117,101, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, - 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, - 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, -101,120, 95,114,103, 98, 95,115, 97,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, - 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, - 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95, -115, 97,116, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, - 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111, -108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, - 98, 95,118, 97,108, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32, -102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, - 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95,118, 97,108, 40,102, - 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, - 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, - 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, 99,111,108, -111,114, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, - 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, - 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95, 99,111,108,111,114, 40,102, 97, - 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, - 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, - 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97, -114,115, 40,105,110,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, - 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,109, 41, 10,123, 10, 9,102, 97, 99,116, 32, 42, 61, 32, 97, 98,115, 40, -102, 97, 99,103, 41, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,102, 40,102, 97, - 99,103, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32,102, 97, 99,116, 59, 10, - 9, 9,102, 97, 99,116, 32, 61, 32,102, 97, 99,109, 59, 10, 9, 9,102, 97, 99,109, 32, 61, 32,116,109,112, 59, 10, 9,125, 10, -125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 98,108,101,110,100, 40,102,108,111, 97,116, 32,111, -117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, - 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, - 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, - 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42, -116,101,120, 99,111,108, 32, 43, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, -101,120, 95,118, 97,108,117,101, 95,109,117,108, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, - 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, - 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, - 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, - 99,109, 41, 59, 10, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99,103, 59, 10, 9,105,110, 99,111,108, - 32, 61, 32, 40,102, 97, 99,109, 32, 43, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111,108, 59, 10, -125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115, 99,114,101,101,110, 40,102,108,111, 97,116, 32, -111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, - 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, - 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, - 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, - 32,102, 97, 99,103, 59, 10, 9,105,110, 99,111,108, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32,102, 97, - 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, - 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,117, 98, 40,102,108,111, 97,116, 32, -111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, - 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, - 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, - 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32, 45,102, 97, 99,116, - 59, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, - 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 97,100,100, 40,102,108,111, 97,116, 32,111,117, +116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, + 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, + 9,105,110, 99,111,108, 32, 61, 32,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32, 40,118,101, 99, 51, 40,102, 97, 99,109, 41, + 32, 43, 32,102, 97, 99,116, 42, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,116,101,120, 99,111,108, 41, 41, 42, 40,118, +101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95,114,103, 98, 95,111,118,101,114,108, 97,121, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116, +101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111, +117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9, +102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, + 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46,114, 32, 61, + 32,111,117,116, 99,111,108, 46,114, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111, +108, 46,114, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, + 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46,114, 41, 41, + 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, + 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99,111,108, 46,103, 42, 40,102, 97, + 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, 41, 59, 10, 9,101,108,115,101, 10, 9, + 9,105,110, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, +116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46,103, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111, +108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99, +111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, + 42,116,101,120, 99,111,108, 46, 98, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46, 98, 32, 61, 32, 49, 46, + 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99, +111,108, 46, 98, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,114,103, 98, 95,115,117, 98, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32, +116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32, +111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, 32, 61, 32, 45,102, 97, 99,116, + 42,102, 97, 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109, +116,101,120, 95,114,103, 98, 95, 97,100,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101, +120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117, +116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,102, 97, + 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95,114,103, 98, 95,100,105,118, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111, +108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118, +101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, + 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,102, + 40,116,101,120, 99,111,108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32,102, 97, 99,109, + 42,111,117,116, 99,111,108, 46,114, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, 46,114, 47,116,101,120, 99,111,108, + 46,114, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46,103, + 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,103, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, 46,103, + 47,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32, +105,110, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46, 98, 32, 43, 32,102, 97, 99,116, 42,111, +117,116, 99,111,108, 46, 98, 47,116,101,120, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114, +103, 98, 95,100,105,102,102, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, + 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, + 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, + 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,110, 99, +111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42, 97, 98,115, 40,116,101,120, 99, +111,108, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,100, + 97,114,107, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108, +111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105, +110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 44, 32, 99,111,108, 59, 10, 10, 9,102, 97, 99,116, + 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9, 99,111, +108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, + 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, + 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111, +108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 46,103, 41, 32,105,110, 99,111,108, 46,103, + 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99,111,108, 46,103, 59, + 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, + 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105, +110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, +114,103, 98, 95,108,105,103,104,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99, +111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32, +118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 44, 32, 99,111,108, 59, 10, + 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, + 59, 10, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40, 99,111,108, + 32, 62, 32,111,117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, + 32,105,110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, + 42,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46,103, 41, 32,105, +110, 99,111,108, 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, + 99,111,108, 46,103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 59, 10, 9,105,102, + 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32, 99,111,108, 59, 32, +101,108,115,101, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,114,103, 98, 95,104,117,101, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32, +116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32, +111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109, +105,120, 95,104,117,101, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, + 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105, +110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95,114,103, 98, 95,115, 97,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111, +108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118, +101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95,115, 97, +116, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, +118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46, +114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, +118, 97,108, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108, +111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105, +110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95,118, 97,108, 40,102, 97, 99, +116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40, +116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, + 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, 99,111,108,111,114, + 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, + 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111, +108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95, 99,111,108,111,114, 40,102, 97, 99,116, + 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116, +101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, + 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, + 40,105,110,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111, +117,116, 32,102,108,111, 97,116, 32,102, 97, 99,109, 41, 10,123, 10, 9,102, 97, 99,116, 32, 42, 61, 32, 97, 98,115, 40,102, 97, + 99,103, 41, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,102, 40,102, 97, 99,103, + 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32,102, 97, 99,116, 59, 10, 9, 9, +102, 97, 99,116, 32, 61, 32,102, 97, 99,109, 59, 10, 9, 9,102, 97, 99,109, 32, 61, 32,116,109,112, 59, 10, 9,125, 10,125, 10, + 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 98,108,101,110,100, 40,102,108,111, 97,116, 32,111,117,116, + 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102, +108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102, +108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, + 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101, +120, 99,111,108, 32, 43, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95,118, 97,108,117,101, 95,109,117,108, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116, +101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111, +117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9, +109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, + 41, 59, 10, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99,103, 59, 10, 9,105,110, 99,111,108, 32, 61, + 32, 40,102, 97, 99,109, 32, 43, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111,108, 59, 10,125, 10, + 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115, 99,114,101,101,110, 40,102,108,111, 97,116, 32,111,117, 116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32, 102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9, 102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99, -116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32,102, 97, 99,116, 59, 10, 9, -105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, - 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,118, 40,102,108,111, 97,116, 32,111,117,116, 99,111, -108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, - 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, - 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32, -102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,102, 40,116,101,120, 99,111,108, 32, 33, 61, 32, 48, 46, 48, 41, - 10, 9, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42,111,117, -116, 99,111,108, 47,116,101,120, 99,111,108, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 32, 61, 32, 48, 46, 48, - 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,102,102, 40,102,108,111, 97,116, 32, -111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, - 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, - 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, - 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, - 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42, 97, 98,115, 40,116,101,120, 99,111,108, 32, 45, 32,111,117,116, 99, -111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100, 97,114,107, 40,102,108,111, - 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, - 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, - 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114, -115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, 97,116, 32, 99,111,108, - 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, - 41, 32,105,110, 99,111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32,111,117,116, 99, -111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,108,105,103,104,116, 40,102,108,111, - 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, - 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, - 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114, -115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, 97,116, 32, 99,111,108, - 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, - 41, 32,105,110, 99,111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32,111,117,116, 99, -111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, 95,112,111,115, -105,116,105,118,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, - 99, 41, 10,123, 10, 9,111,117,116,102, 97, 99, 32, 61, 32,109, 97,120, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, - 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, 40,102,108,111, 97,116, 32,102, 97, 99, - 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,111,117,116,102, 97, 99, 32, 61, 32, - 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, -101,120, 95,104, 97,114, 95,100,105,118,105,100,101, 40,102,108,111, 97,116, 32,104, 97,114, 44, 32,111,117,116, 32,102,108,111, - 97,116, 32,111,117,116,104, 97,114, 41, 10,123, 10, 9,111,117,116,104, 97,114, 32, 61, 32,104, 97,114, 47, 49, 50, 56, 46, 48, - 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,104, 97,114, 95,109,117,108,116,105,112,108,121, 95, 99,108, 97,109, -112, 40,102,108,111, 97,116, 32,104, 97,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,104, 97,114, 41, 10,123, - 10, 9,104, 97,114, 32, 42, 61, 32, 49, 50, 56, 46, 48, 59, 10, 10, 9,105,102, 40,104, 97,114, 32, 60, 32, 49, 46, 48, 41, 32, -111,117,116,104, 97,114, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,104, 97,114, 32, 62, 32, 53, 49, 49, - 46, 48, 41, 32,111,117,116,104, 97,114, 32, 61, 32, 53, 49, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,111,117,116,104, 97,114, - 32, 61, 32,104, 97,114, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 97,108,112,104, 97, 95,102,114,111,109, 95, - 99,111,108, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 41, 10,123, - 10, 9, 97,108,112,104, 97, 32, 61, 32, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 97,108, -112,104, 97, 95,116,111, 95, 99,111,108, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, - 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118, -101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101, -120, 95,114,103, 98,116,111,105,110,116, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105, -110,116,101,110,115,105,116,121, 41, 10,123, 10, 9,105,110,116,101,110,115,105,116,121, 32, 61, 32,100,111,116, 40,118,101, 99, - 51, 40, 48, 46, 51, 53, 44, 32, 48, 46, 52, 53, 44, 32, 48, 46, 50, 41, 44, 32,114,103, 98, 46,114,103, 98, 41, 59, 10,125, 10, - 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,105,110,118,101,114,116, 40,102,108,111, 97,116, 32,105,110, -118, 97,108,117,101, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108,117,101, 41, 10,123, 10, 9,111,117, -116,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 32, 45, 32,105,110,118, 97,108,117,101, 59, 10,125, 10, 10,118,111,105,100, 32, -109,116,101,120, 95,114,103, 98, 95,105,110,118,101,114,116, 40,118,101, 99, 52, 32,105,110,114,103, 98, 44, 32,111,117,116, 32, -118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,118,101, - 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,105,110,114,103, 98, 46,114,103, 98, 44, 32,105,110,114,103, 98, 46, 97, 41, 59, 10,125, - 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,116,101,110, 99,105,108, 40,102,108,111, 97,116, 32, -115,116,101,110, 99,105,108, 44, 32,102,108,111, 97,116, 32,105,110,116,101,110,115,105,116,121, 44, 32,111,117,116, 32,102,108, -111, 97,116, 32,111,117,116,115,116,101,110, 99,105,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105,110,116, -101,110,115,105,116,121, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,116, 32, 61, 32,105,110,116,101,110,115,105,116, -121, 59, 10, 9,111,117,116,105,110,116,101,110,115,105,116,121, 32, 61, 32,105,110,116,101,110,115,105,116,121, 42,115,116,101, -110, 99,105,108, 59, 10, 9,111,117,116,115,116,101,110, 99,105,108, 32, 61, 32,115,116,101,110, 99,105,108, 42,102, 97, 99,116, - 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115,116,101,110, 99,105,108, 40,102,108,111, 97,116, - 32,115,116,101,110, 99,105,108, 44, 32,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117, -116,115,116,101,110, 99,105,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,102,108, -111, 97,116, 32,102, 97, 99,116, 32, 61, 32,114,103, 98, 46, 97, 59, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, - 40,114,103, 98, 46,114,103, 98, 44, 32,114,103, 98, 46, 97, 42,115,116,101,110, 99,105,108, 41, 59, 10, 9,111,117,116,115,116, -101,110, 99,105,108, 32, 61, 32,115,116,101,110, 99,105,108, 42,102, 97, 99,116, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, -101,120, 95,109, 97,112,112,105,110,103, 95,111,102,115, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118,101, 99, 51, 32, -111,102,115, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111,117,116,116,101, -120, 99,111, 32, 61, 32,116,101,120, 99,111, 32, 43, 32,111,102,115, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, -109, 97,112,112,105,110,103, 95,115,105,122,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118,101, 99, 51, 32,115,105, -122,101, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111,117,116,116,101,120, - 99,111, 32, 61, 32,115,105,122,101, 42,116,101,120, 99,111, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 50,100, - 95,109, 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, -101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 51, 40,118,101, 99, 46,120,121, 42, 48, 46, 53, 32, - 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 32, 48, 46, 53, 41, 44, 32,118,101, 99, 46,122, 41, 59, 10,125, 10, 10,118,111,105, -100, 32,109,116,101,120, 95,105,109, 97,103,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, - 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, - 52, 32, 99,111,108,111,114, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, - 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118, -111,105,100, 32,109,116,101,120, 95,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112, -108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, - 47, 32, 84,104,101, 32,105,110,118,101,114,116, 32,111,102, 32,116,104,101, 32,114,101,100, 32, 99,104, 97,110,110,101,108, 32, -105,115, 32,116,111, 32,109, 97,107,101, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32,109, 97,112, 32, 99,111, -109,112,108,105, 97,110,116, 32,119,105,116,104, 32,116,104,101, 32,111,117,116,115,105,100,101, 32,119,111,114,108,100, 46, 10, - 9, 47, 47, 32, 73,116, 32,110,101,101,100,115, 32,116,111, 32, 98,101, 32,100,111,110,101, 32, 98,101, 99, 97,117,115,101, 32, -105,110, 32, 66,108,101,110,100,101,114, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32,117,115,101,100, 32,112, -111,105,110,116,115, 32,105,110,119, 97,114,100, 46, 10, 9, 47, 47, 32, 83,104,111,117,108,100, 32,116,104,105,115, 32,101,118, -101,114, 32, 99,104, 97,110,103,101, 32,116,104,105,115, 32,110,101,103, 97,116,101, 32,109,117,115,116, 32, 98,101, 32,114,101, -109,111,118,101,100, 46, 10, 32, 32, 32, 32,118,101, 99, 52, 32, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, - 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32, 50, 46, 48, 42, - 40,118,101, 99, 51, 40, 45, 99,111,108,111,114, 46,114, 44, 32, 99,111,108,111,114, 46,103, 44, 32, 99,111,108,111,114, 46, 98, - 41, 32, 45, 32,118,101, 99, 51, 40, 45, 48, 46, 53, 44, 32, 48, 46, 53, 44, 32, 48, 46, 53, 41, 41, 59, 10,125, 10, 10,118,111, -105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,110,111,114,109, 97,108,115, 95,105,110,105,116, 40, 32,118,101, 99, 51, 32, -118, 78, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78,111,114,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, - 99, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 32, 41, 10,123, - 10, 9,118, 78,111,114,103, 32, 61, 32,118, 78, 59, 10, 9,118, 78, 97, 99, 99, 32, 61, 32,118, 78, 59, 10, 9,102, 80,114,101, -118, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10, 47, 42, 42, 32,104,101,108,112,101,114, 32, -109,101,116,104,111,100, 32,116,111, 32,101,120,116,114, 97, 99,116, 32,116,104,101, 32,117,112,112,101,114, 32,108,101,102,116, - 32, 51,120, 51, 32,109, 97,116,114,105,120, 32,102,114,111,109, 32, 97, 32, 52,120, 52, 32,109, 97,116,114,105,120, 32, 42, 47, - 10,109, 97,116, 51, 32,116,111, 95,109, 97,116, 51, 40,109, 97,116, 52, 32,109, 52, 41, 10,123, 10, 9,109, 97,116, 51, 32,109, - 51, 59, 10, 9,109, 51, 91, 48, 93, 32, 61, 32,109, 52, 91, 48, 93, 46,120,121,122, 59, 10, 9,109, 51, 91, 49, 93, 32, 61, 32, -109, 52, 91, 49, 93, 46,120,121,122, 59, 10, 9,109, 51, 91, 50, 93, 32, 61, 32,109, 52, 91, 50, 93, 46,120,121,122, 59, 10, 9, -114,101,116,117,114,110, 32,109, 51, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,105,110,105, -116, 95,111, 98,106,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111,115, 44, 32,118,101, 99, 51, 32, -115,117,114,102, 95,110,111,114,109, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,109, 97,116, 52, 32,109, 86,105,101,119, 44, 32, -109, 97,116, 52, 32,109, 86,105,101,119, 73,110,118, 44, 32,109, 97,116, 52, 32,109, 79, 98,106, 44, 32,109, 97,116, 52, 32,109, - 79, 98,106, 73,110,118, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103, -110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, - 9, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 44, - 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,111, -117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102, -108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9,109, 97,116, 51, 32,111, 98,106, 50,118,105,101,119, 32, 61, 32, -116,111, 95,109, 97,116, 51, 40,103,108, 95, 77,111,100,101,108, 86,105,101,119, 77, 97,116,114,105,120, 41, 59, 10, 9,109, 97, -116, 51, 32,118,105,101,119, 50,111, 98,106, 32, 61, 32,116,111, 95,109, 97,116, 51, 40,103,108, 95, 77,111,100,101,108, 86,105, -101,119, 77, 97,116,114,105,120, 73,110,118,101,114,115,101, 41, 59, 10, 9, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, - 83, 32, 61, 32,118,105,101,119, 50,111, 98,106, 32, 42, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, - 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,118,105,101,119, 50,111, 98,106, 32, 42, 32,100, 70,100,121, - 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,110,111,114,109, 97,108,105, -122,101, 40, 32,115,117,114,102, 95,110,111,114,109, 32, 42, 32,111, 98,106, 50,118,105,101,119, 32, 41, 59, 10, 10, 9,118, 82, - 49, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 83,105,103,109, 97, 84, 44, 32,118, 78, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, - 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 59, 10, 9,102, 68,101,116, 32, 61, 32, -100,111,116, 32, 40, 32,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 32, 41, 59, 10, 9, 10, 9, 47, 42, 32,112,114,101,116, -114, 97,110,115,102,111,114,109, 32,118, 78, 97, 99, 99, 32, 40,105,110, 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112, -108,121, 41, 32,117,115,105,110,103, 32,116,104,101, 32,105,110,118,101,114,115,101, 32,116,114, 97,110,115,112,111,115,101,100, - 32, 42, 47, 10, 9,118, 82, 49, 32, 61, 32,118, 82, 49, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, 9,118, 82, 50, 32, - 61, 32,118, 82, 50, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, 9,118, 78, 32, 61, 32,118, 78, 32, 42, 32,118,105,101, -119, 50,111, 98,106, 59, 10, 9, 10, 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, - 40,102, 68,101,116, 41, 32, 42, 32,108,101,110,103,116,104, 40,118, 78, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, - 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80,114,101,118, - 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111, -117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117, -109,112, 95,105,110,105,116, 95,116,101,120,116,117,114,101,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95, -112,111,115, 44, 32,118,101, 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32, -102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, - 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101, -118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111, -117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, - 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9, -118,101, 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, - 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,100, 70,100,121, 40, 32,115,117,114,102, 95,112,111,115, 32, - 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,115,117,114,102, 95,110,111,114,109, 59, 32, 47, 42, 32,110,111,114,109, - 97,108,105,122,101,100, 32,105,110,116,101,114,112,111,108, 97,116,101,100, 32,118,101,114,116,101,120, 32,110,111,114,109, 97, -108, 32, 42, 47, 10, 9, 10, 9,118, 82, 49, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32, 99,114,111,115,115, 40, 32, -118, 83,105,103,109, 97, 84, 44, 32,118, 78, 32, 41, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32,110,111,114,109, 97,108,105,122, -101, 40, 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 41, 59, 10, 9,102, 68,101,116, - 32, 61, 32,115,105,103,110, 40, 32,100,111,116, 40,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 41, 32, 41, 59, 10, 9, 10, - 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, 68,101,116, 41, 59, 10, 9, -118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117, -100,101, 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, - 97,103,110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, 10, 10,118,111, -105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,105,110,105,116, 95,118,105,101,119,115,112, 97, 99,101, 40, 32,118,101, 99, - 51, 32,115,117,114,102, 95,112,111,115, 44, 32,118,101, 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 32, 10, 9, 9, 9, - 9, 9, 9, 9, 32, 32, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32, -118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,102,108,111, - 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32, -118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, - 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, - 32, 41, 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,100, 70,100,120, 40, 32,115,117,114,102, - 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,100, 70,100,121, 40, 32,115,117, -114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,115,117,114,102, 95,110,111,114,109, 59, 32, - 47, 42, 32,110,111,114,109, 97,108,105,122,101,100, 32,105,110,116,101,114,112,111,108, 97,116,101,100, 32,118,101,114,116,101, -120, 32,110,111,114,109, 97,108, 32, 42, 47, 10, 9, 10, 9,118, 82, 49, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 83,105,103, -109, 97, 84, 44, 32,118, 78, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105, -103,109, 97, 83, 32, 41, 32, 59, 10, 9,102, 68,101,116, 32, 61, 32,100,111,116, 32, 40, 32,118, 83,105,103,109, 97, 83, 44, 32, -118, 82, 49, 32, 41, 59, 10, 9, 10, 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, - 40,102, 68,101,116, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, - 40,102, 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, - 59, 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117, -100,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,116, 97,112, 51, 40, 32,118,101, 99, 51, - 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,104, 83, 99, - 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102, -108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,118,101, - 99, 50, 32, 83, 84,108,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, 59, 10, 9,118,101, 99, 50, 32, 83, 84,108,114, 32, 61, - 32,116,101,120, 99,111, 46,120,121, 32, 43, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 32, 59, 10, 9,118,101, - 99, 50, 32, 83, 84,117,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32,100, 70,100,121, 40,116,101,120, 99,111, 46, -120,121, 41, 32, 59, 10, 9, 10, 9,102,108,111, 97,116, 32, 72,108,108, 44, 72,108,114, 44, 72,117,108, 59, 10, 9,114,103, 98, -116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108,108, 41, 44, 32, 72,108,108, 32, - 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108,114, - 41, 44, 32, 72,108,114, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, - 97, 44, 32, 83, 84,117,108, 41, 44, 32, 72,117,108, 32, 41, 59, 10, 9, 10, 9,100, 66,115, 32, 61, 32,104, 83, 99, 97,108,101, - 32, 42, 32, 40, 72,108,114, 32, 45, 32, 72,108,108, 41, 59, 10, 9,100, 66,116, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, - 40, 72,117,108, 32, 45, 32, 72,108,108, 41, 59, 10,125, 10, 10, 35,105,102,100,101,102, 32, 66, 85, 77, 80, 95, 66, 73, 67, 85, - 66, 73, 67, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95, 98,105, 99,117, 98,105, 99, 40, 32,118,101, 99, - 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,104, 83, - 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32, -102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,102, -108,111, 97,116, 32, 72,108, 59, 10, 9,102,108,111, 97,116, 32, 72,114, 59, 10, 9,102,108,111, 97,116, 32, 72,100, 59, 10, 9, -102,108,111, 97,116, 32, 72,117, 59, 10, 9, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116, -101,120, 99,111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, - 99,111, 46,120,121, 41, 59, 10, 32, 10, 9,118,101, 99, 50, 32, 83, 84,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, - 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,114, 32, 61, 32,116,101,120, 99,111, - 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,100, 32, 61, 32, -116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, 10, 9,118,101, 99, 50, 32, 83, - 84,117, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, 10, 9, 10, - 9,114,103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108, 41, 44, 32, 72,108, - 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,114, 41, 44, - 32, 72,114, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84, -100, 41, 44, 32, 72,100, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, - 32, 83, 84,117, 41, 44, 32, 72,117, 41, 59, 10, 9, 10, 9,118,101, 99, 50, 32,100, 72,100,120,121, 32, 61, 32,118,101, 99, 50, - 40, 72,114, 32, 45, 32, 72,108, 44, 32, 72,117, 32, 45, 32, 72,100, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 66,108,101,110, -100, 32, 61, 32, 99,108, 97,109,112, 40, 49, 46, 48, 45,116,101,120,116,117,114,101, 81,117,101,114,121, 76, 79, 68, 40,105,109, - 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 46,120, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,105,102, 40,102, - 66,108,101,110,100, 33, 61, 48, 46, 48, 41, 10, 9,123, 10, 9, 9, 47, 47, 32,116,104,101, 32,100,101,114,105,118, 97,116,105, -118,101, 32,111,102, 32,116,104,101, 32, 98,105, 99,117, 98,105, 99, 32,115, 97,109,112,108,105,110,103, 32,111,102, 32,108,101, -118,101,108, 32, 48, 10, 9, 9,105,118,101, 99, 50, 32,118, 68,105,109, 59, 10, 9, 9,118, 68,105,109, 32, 61, 32,116,101,120, -116,117,114,101, 83,105,122,101, 40,105,109, 97, 44, 32, 48, 41, 59, 10, 10, 9, 9, 47, 47, 32,116, 97,107,105,110,103, 32,116, -104,101, 32,102,114, 97, 99,116, 32,112, 97,114,116, 32,111,102, 32,116,104,101, 32,116,101,120,116,117,114,101, 32, 99,111,111, -114,100,105,110, 97,116,101, 32,105,115, 32, 97, 32,104, 97,114,100, 99,111,100,101,100, 32,119,114, 97,112, 32,109,111,100,101, - 46, 10, 9, 9, 47, 47, 32,116,104,105,115, 32,105,115, 32, 97, 99, 99,101,112,116, 97, 98,108,101, 32, 97,115, 32,116,101,120, -116,117,114,101,115, 32,117,115,101, 32,119,114, 97,112, 32,109,111,100,101, 32,101,120, 99,108,117,115,105,118,101,108,121, 32, -105,110, 32, 51, 68, 32,118,105,101,119, 32,101,108,115,101,119,104,101,114,101, 32,105,110, 32, 98,108,101,110,100,101,114, 46, - 32, 10, 9, 9, 47, 47, 32,116,104,105,115, 32,105,115, 32,100,111,110,101, 32,115,111, 32,116,104, 97,116, 32,119,101, 32, 99, - 97,110, 32,115,116,105,108,108, 32,103,101,116, 32, 97, 32,118, 97,108,105,100, 32,116,101,120,101,108, 32,119,105,116,104, 32, -117,118,115, 32,111,117,116,115,105,100,101, 32,116,104,101, 32, 48, 44, 49, 32,114, 97,110,103,101, 10, 9, 9, 47, 47, 32, 98, -121, 32,116,101,120,101,108, 70,101,116, 99,104, 32, 98,101,108,111,119, 44, 32, 97,115, 32, 99,111,111,114,100,105,110, 97,116, -101,115, 32, 97,114,101, 32, 99,108, 97,109,112,101,100, 32,119,104,101,110, 32,117,115,105,110,103, 32,116,104,105,115, 32,102, -117,110, 99,116,105,111,110, 46, 10, 9, 9,118,101, 99, 50, 32,102, 84,101,120, 76,111, 99, 32, 61, 32,118, 68,105,109, 42,102, -114, 97, 99,116, 40,116,101,120, 99,111, 46,120,121, 41, 32, 45, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 32, 48, 46, 53, 41, 59, - 10, 9, 9,105,118,101, 99, 50, 32,105, 84,101,120, 76,111, 99, 32, 61, 32,105,118,101, 99, 50, 40,102,108,111,111,114, 40,102, - 84,101,120, 76,111, 99, 41, 41, 59, 10, 9, 9,118,101, 99, 50, 32,116, 32, 61, 32, 99,108, 97,109,112, 40,102, 84,101,120, 76, -111, 99, 32, 45, 32,105, 84,101,120, 76,111, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 9, 9, 47, 47, 32,115, 97,116, - 32,106,117,115,116, 32,116,111, 32, 98,101, 32,112,101,100, 97,110,116,105, 99, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, +116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, + 97, 99,103, 59, 10, 9,105,110, 99,111,108, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32,102, 97, 99,116, + 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 41, 59, + 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,117, 98, 40,102,108,111, 97,116, 32,111,117, +116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32, +102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9, +102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99, +116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32, 45,102, 97, 99,116, 59, 10, + 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, + 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 97,100,100, 40,102,108,111, 97,116, 32,111,117,116, 99, +111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108, +111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108, +111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, + 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32,102, 97, 99,116, 59, 10, 9,105,110, + 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118, +111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,118, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, + 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, + 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, + 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, + 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,102, 40,116,101,120, 99,111,108, 32, 33, 61, 32, 48, 46, 48, 41, 10, 9, + 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99, +111,108, 47,116,101,120, 99,111,108, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 32, 61, 32, 48, 46, 48, 59, 10, +125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,102,102, 40,102,108,111, 97,116, 32,111,117, +116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32, +102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9, +102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99, +116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111, +117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42, 97, 98,115, 40,116,101,120, 99,111,108, 32, 45, 32,111,117,116, 99,111,108, + 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100, 97,114,107, 40,102,108,111, 97,116, + 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99, +116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10, +123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40, +102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, 97,116, 32, 99,111,108, 32, 61, + 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 41, 32, +105,110, 99,111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32,111,117,116, 99,111,108, + 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,108,105,103,104,116, 40,102,108,111, 97,116, + 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99, +116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10, +123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40, +102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, 97,116, 32, 99,111,108, 32, 61, + 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 41, 32, +105,110, 99,111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32,111,117,116, 99,111,108, + 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, 95,112,111,115,105,116, +105,118,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, + 10,123, 10, 9,111,117,116,102, 97, 99, 32, 61, 32,109, 97,120, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118, +111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32, +111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,111,117,116,102, 97, 99, 32, 61, 32, 99,108, + 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95,104, 97,114, 95,100,105,118,105,100,101, 40,102,108,111, 97,116, 32,104, 97,114, 44, 32,111,117,116, 32,102,108,111, 97,116, + 32,111,117,116,104, 97,114, 41, 10,123, 10, 9,111,117,116,104, 97,114, 32, 61, 32,104, 97,114, 47, 49, 50, 56, 46, 48, 59, 10, +125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,104, 97,114, 95,109,117,108,116,105,112,108,121, 95, 99,108, 97,109,112, 40, +102,108,111, 97,116, 32,104, 97,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,104, 97,114, 41, 10,123, 10, 9, +104, 97,114, 32, 42, 61, 32, 49, 50, 56, 46, 48, 59, 10, 10, 9,105,102, 40,104, 97,114, 32, 60, 32, 49, 46, 48, 41, 32,111,117, +116,104, 97,114, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,104, 97,114, 32, 62, 32, 53, 49, 49, 46, 48, + 41, 32,111,117,116,104, 97,114, 32, 61, 32, 53, 49, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,111,117,116,104, 97,114, 32, 61, + 32,104, 97,114, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 97,108,112,104, 97, 95,102,114,111,109, 95, 99,111, +108, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 41, 10,123, 10, 9, + 97,108,112,104, 97, 32, 61, 32, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 97,108,112,104, + 97, 95,116,111, 95, 99,111,108, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 44, 32, +111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, + 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, +114,103, 98,116,111,105,110,116, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,116, +101,110,115,105,116,121, 41, 10,123, 10, 9,105,110,116,101,110,115,105,116,121, 32, 61, 32,100,111,116, 40,118,101, 99, 51, 40, + 48, 46, 51, 53, 44, 32, 48, 46, 52, 53, 44, 32, 48, 46, 50, 41, 44, 32,114,103, 98, 46,114,103, 98, 41, 59, 10,125, 10, 10,118, +111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,105,110,118,101,114,116, 40,102,108,111, 97,116, 32,105,110,118, 97, +108,117,101, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108,117,101, 41, 10,123, 10, 9,111,117,116,118, + 97,108,117,101, 32, 61, 32, 49, 46, 48, 32, 45, 32,105,110,118, 97,108,117,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, +101,120, 95,114,103, 98, 95,105,110,118,101,114,116, 40,118,101, 99, 52, 32,105,110,114,103, 98, 44, 32,111,117,116, 32,118,101, + 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,118,101, 99, 51, + 40, 49, 46, 48, 41, 32, 45, 32,105,110,114,103, 98, 46,114,103, 98, 44, 32,105,110,114,103, 98, 46, 97, 41, 59, 10,125, 10, 10, +118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,116,101,110, 99,105,108, 40,102,108,111, 97,116, 32,115,116, +101,110, 99,105,108, 44, 32,102,108,111, 97,116, 32,105,110,116,101,110,115,105,116,121, 44, 32,111,117,116, 32,102,108,111, 97, +116, 32,111,117,116,115,116,101,110, 99,105,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105,110,116,101,110, +115,105,116,121, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,116, 32, 61, 32,105,110,116,101,110,115,105,116,121, 59, + 10, 9,111,117,116,105,110,116,101,110,115,105,116,121, 32, 61, 32,105,110,116,101,110,115,105,116,121, 42,115,116,101,110, 99, +105,108, 59, 10, 9,111,117,116,115,116,101,110, 99,105,108, 32, 61, 32,115,116,101,110, 99,105,108, 42,102, 97, 99,116, 59, 10, +125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115,116,101,110, 99,105,108, 40,102,108,111, 97,116, 32,115, +116,101,110, 99,105,108, 44, 32,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,115, +116,101,110, 99,105,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,102,108,111, 97, +116, 32,102, 97, 99,116, 32, 61, 32,114,103, 98, 46, 97, 59, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,114, +103, 98, 46,114,103, 98, 44, 32,114,103, 98, 46, 97, 42,115,116,101,110, 99,105,108, 41, 59, 10, 9,111,117,116,115,116,101,110, + 99,105,108, 32, 61, 32,115,116,101,110, 99,105,108, 42,102, 97, 99,116, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95,109, 97,112,112,105,110,103, 95,111,102,115, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118,101, 99, 51, 32,111,102, +115, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111,117,116,116,101,120, 99, +111, 32, 61, 32,116,101,120, 99,111, 32, 43, 32,111,102,115, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,109, 97, +112,112,105,110,103, 95,115,105,122,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118,101, 99, 51, 32,115,105,122,101, + 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111,117,116,116,101,120, 99,111, + 32, 61, 32,115,105,122,101, 42,116,101,120, 99,111, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 50,100, 95,109, + 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, + 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 51, 40,118,101, 99, 46,120,121, 42, 48, 46, 53, 32, 43, 32, +118,101, 99, 50, 40, 48, 46, 53, 44, 32, 48, 46, 53, 41, 44, 32,118,101, 99, 46,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32, +109,116,101,120, 95,105,109, 97,103,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, + 32,105,109, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, + 99,111,108,111,114, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, + 32,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105, +100, 32,109,116,101,120, 95,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101, +114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 47, 32, + 84,104,101, 32,105,110,118,101,114,116, 32,111,102, 32,116,104,101, 32,114,101,100, 32, 99,104, 97,110,110,101,108, 32,105,115, + 32,116,111, 32,109, 97,107,101, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32,109, 97,112, 32, 99,111,109,112, +108,105, 97,110,116, 32,119,105,116,104, 32,116,104,101, 32,111,117,116,115,105,100,101, 32,119,111,114,108,100, 46, 10, 9, 47, + 47, 32, 73,116, 32,110,101,101,100,115, 32,116,111, 32, 98,101, 32,100,111,110,101, 32, 98,101, 99, 97,117,115,101, 32,105,110, + 32, 66,108,101,110,100,101,114, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32,117,115,101,100, 32,112,111,105, +110,116,115, 32,105,110,119, 97,114,100, 46, 10, 9, 47, 47, 32, 83,104,111,117,108,100, 32,116,104,105,115, 32,101,118,101,114, + 32, 99,104, 97,110,103,101, 32,116,104,105,115, 32,110,101,103, 97,116,101, 32,109,117,115,116, 32, 98,101, 32,114,101,109,111, +118,101,100, 46, 10, 32, 32, 32, 32,118,101, 99, 52, 32, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, +105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32, 50, 46, 48, 42, 40,118, +101, 99, 51, 40, 45, 99,111,108,111,114, 46,114, 44, 32, 99,111,108,111,114, 46,103, 44, 32, 99,111,108,111,114, 46, 98, 41, 32, + 45, 32,118,101, 99, 51, 40, 45, 48, 46, 53, 44, 32, 48, 46, 53, 44, 32, 48, 46, 53, 41, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95, 98,117,109,112, 95,110,111,114,109, 97,108,115, 95,105,110,105,116, 40, 32,118,101, 99, 51, 32,118, 78, + 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78,111,114,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 32, 41, 10,123, 10, 9, +118, 78,111,114,103, 32, 61, 32,118, 78, 59, 10, 9,118, 78, 97, 99, 99, 32, 61, 32,118, 78, 59, 10, 9,102, 80,114,101,118, 77, + 97,103,110,105,116,117,100,101, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10, 47, 42, 42, 32,104,101,108,112,101,114, 32,109,101, +116,104,111,100, 32,116,111, 32,101,120,116,114, 97, 99,116, 32,116,104,101, 32,117,112,112,101,114, 32,108,101,102,116, 32, 51, +120, 51, 32,109, 97,116,114,105,120, 32,102,114,111,109, 32, 97, 32, 52,120, 52, 32,109, 97,116,114,105,120, 32, 42, 47, 10,109, + 97,116, 51, 32,116,111, 95,109, 97,116, 51, 40,109, 97,116, 52, 32,109, 52, 41, 10,123, 10, 9,109, 97,116, 51, 32,109, 51, 59, + 10, 9,109, 51, 91, 48, 93, 32, 61, 32,109, 52, 91, 48, 93, 46,120,121,122, 59, 10, 9,109, 51, 91, 49, 93, 32, 61, 32,109, 52, + 91, 49, 93, 46,120,121,122, 59, 10, 9,109, 51, 91, 50, 93, 32, 61, 32,109, 52, 91, 50, 93, 46,120,121,122, 59, 10, 9,114,101, +116,117,114,110, 32,109, 51, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,105,110,105,116, 95, +111, 98,106,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111,115, 44, 32,118,101, 99, 51, 32,115,117, +114,102, 95,110,111,114,109, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,109, 97,116, 52, 32,109, 86,105,101,119, 44, 32,109, 97, +116, 52, 32,109, 86,105,101,119, 73,110,118, 44, 32,109, 97,116, 52, 32,109, 79, 98,106, 44, 32,109, 97,116, 52, 32,109, 79, 98, +106, 73,110,118, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105, +116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, + 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 44, 32,111, +117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, + 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102,108,111, + 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9,109, 97,116, 51, 32,111, 98,106, 50,118,105,101,119, 32, 61, 32,116,111, + 95,109, 97,116, 51, 40,103,108, 95, 77,111,100,101,108, 86,105,101,119, 77, 97,116,114,105,120, 41, 59, 10, 9,109, 97,116, 51, + 32,118,105,101,119, 50,111, 98,106, 32, 61, 32,116,111, 95,109, 97,116, 51, 40,103,108, 95, 77,111,100,101,108, 86,105,101,119, + 77, 97,116,114,105,120, 73,110,118,101,114,115,101, 41, 59, 10, 9, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 83, 32, + 61, 32,118,105,101,119, 50,111, 98,106, 32, 42, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9, +118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,118,105,101,119, 50,111, 98,106, 32, 42, 32,100, 70,100,121, 40, 32, +115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,110,111,114,109, 97,108,105,122,101, + 40, 32,115,117,114,102, 95,110,111,114,109, 32, 42, 32,111, 98,106, 50,118,105,101,119, 32, 41, 59, 10, 10, 9,118, 82, 49, 32, + 61, 32, 99,114,111,115,115, 40, 32,118, 83,105,103,109, 97, 84, 44, 32,118, 78, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32, 99, +114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 59, 10, 9,102, 68,101,116, 32, 61, 32,100,111, +116, 32, 40, 32,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 32, 41, 59, 10, 9, 10, 9, 47, 42, 32,112,114,101,116,114, 97, +110,115,102,111,114,109, 32,118, 78, 97, 99, 99, 32, 40,105,110, 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, + 41, 32,117,115,105,110,103, 32,116,104,101, 32,105,110,118,101,114,115,101, 32,116,114, 97,110,115,112,111,115,101,100, 32, 42, + 47, 10, 9,118, 82, 49, 32, 61, 32,118, 82, 49, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, 9,118, 82, 50, 32, 61, 32, +118, 82, 50, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, 9,118, 78, 32, 61, 32,118, 78, 32, 42, 32,118,105,101,119, 50, +111, 98,106, 59, 10, 9, 10, 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, + 68,101,116, 41, 32, 42, 32,108,101,110,103,116,104, 40,118, 78, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32, +118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80,114,101,118, 77, 97, +103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, + 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, + 95,105,110,105,116, 95,116,101,120,116,117,114,101,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111, +115, 44, 32,118,101, 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,102,108, +111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, + 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, + 97,103,110,105,116,117,100,101, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, + 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118, +101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9,118,101, + 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9, +118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,100, 70,100,121, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, + 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,115,117,114,102, 95,110,111,114,109, 59, 32, 47, 42, 32,110,111,114,109, 97,108, +105,122,101,100, 32,105,110,116,101,114,112,111,108, 97,116,101,100, 32,118,101,114,116,101,120, 32,110,111,114,109, 97,108, 32, + 42, 47, 10, 9, 10, 9,118, 82, 49, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32, 99,114,111,115,115, 40, 32,118, 83, +105,103,109, 97, 84, 44, 32,118, 78, 32, 41, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, + 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 41, 59, 10, 9,102, 68,101,116, 32, 61, + 32,115,105,103,110, 40, 32,100,111,116, 40,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 41, 32, 41, 59, 10, 9, 10, 9,102, +108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, 68,101,116, 41, 59, 10, 9,118, 78, + 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117,100,101, + 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, 97,103, +110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95, 98,117,109,112, 95,105,110,105,116, 95,118,105,101,119,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32, +115,117,114,102, 95,112,111,115, 44, 32,118,101, 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 32, 10, 9, 9, 9, 9, 9, + 9, 9, 32, 32, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, + 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, + 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, + 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, + 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, + 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112, +111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,100, 70,100,121, 40, 32,115,117,114,102, + 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,115,117,114,102, 95,110,111,114,109, 59, 32, 47, 42, + 32,110,111,114,109, 97,108,105,122,101,100, 32,105,110,116,101,114,112,111,108, 97,116,101,100, 32,118,101,114,116,101,120, 32, +110,111,114,109, 97,108, 32, 42, 47, 10, 9, 10, 9,118, 82, 49, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 83,105,103,109, 97, + 84, 44, 32,118, 78, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, + 97, 83, 32, 41, 32, 59, 10, 9,102, 68,101,116, 32, 61, 32,100,111,116, 32, 40, 32,118, 83,105,103,109, 97, 83, 44, 32,118, 82, + 49, 32, 41, 59, 10, 9, 10, 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, + 68,101,116, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, + 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, + 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, + 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,116, 97,112, 51, 40, 32,118,101, 99, 51, 32,116, +101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97,108, +101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108,111, + 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,118,101, 99, 50, + 32, 83, 84,108,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, 59, 10, 9,118,101, 99, 50, 32, 83, 84,108,114, 32, 61, 32,116, +101,120, 99,111, 46,120,121, 32, 43, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 32, 59, 10, 9,118,101, 99, 50, + 32, 83, 84,117,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, + 41, 32, 59, 10, 9, 10, 9,102,108,111, 97,116, 32, 72,108,108, 44, 72,108,114, 44, 72,117,108, 59, 10, 9,114,103, 98,116,111, + 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108,108, 41, 44, 32, 72,108,108, 32, 41, 59, + 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108,114, 41, 44, + 32, 72,108,114, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, + 32, 83, 84,117,108, 41, 44, 32, 72,117,108, 32, 41, 59, 10, 9, 10, 9,100, 66,115, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, + 32, 40, 72,108,114, 32, 45, 32, 72,108,108, 41, 59, 10, 9,100, 66,116, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72, +117,108, 32, 45, 32, 72,108,108, 41, 59, 10,125, 10, 10, 35,105,102,100,101,102, 32, 66, 85, 77, 80, 95, 66, 73, 67, 85, 66, 73, + 67, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95, 98,105, 99,117, 98,105, 99, 40, 32,118,101, 99, 51, 32, +116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97, +108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108, +111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,102,108,111, + 97,116, 32, 72,108, 59, 10, 9,102,108,111, 97,116, 32, 72,114, 59, 10, 9,102,108,111, 97,116, 32, 72,100, 59, 10, 9,102,108, +111, 97,116, 32, 72,117, 59, 10, 9, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, + 99,111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, + 46,120,121, 41, 59, 10, 32, 10, 9,118,101, 99, 50, 32, 83, 84,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, + 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,114, 32, 61, 32,116,101,120, 99,111, 46,120, +121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,100, 32, 61, 32,116,101, +120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,117, + 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, 10, 9, 10, 9,114, +103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108, 41, 44, 32, 72,108, 41, 59, + 10, 9,114,103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,114, 41, 44, 32, 72, +114, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,100, 41, + 44, 32, 72,100, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, + 84,117, 41, 44, 32, 72,117, 41, 59, 10, 9, 10, 9,118,101, 99, 50, 32,100, 72,100,120,121, 32, 61, 32,118,101, 99, 50, 40, 72, +114, 32, 45, 32, 72,108, 44, 32, 72,117, 32, 45, 32, 72,100, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 66,108,101,110,100, 32, + 61, 32, 99,108, 97,109,112, 40, 49, 46, 48, 45,116,101,120,116,117,114,101, 81,117,101,114,121, 76, 79, 68, 40,105,109, 97, 44, + 32,116,101,120, 99,111, 46,120,121, 41, 46,120, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,105,102, 40,102, 66,108, +101,110,100, 33, 61, 48, 46, 48, 41, 10, 9,123, 10, 9, 9, 47, 47, 32,116,104,101, 32,100,101,114,105,118, 97,116,105,118,101, + 32,111,102, 32,116,104,101, 32, 98,105, 99,117, 98,105, 99, 32,115, 97,109,112,108,105,110,103, 32,111,102, 32,108,101,118,101, +108, 32, 48, 10, 9, 9,105,118,101, 99, 50, 32,118, 68,105,109, 59, 10, 9, 9,118, 68,105,109, 32, 61, 32,116,101,120,116,117, +114,101, 83,105,122,101, 40,105,109, 97, 44, 32, 48, 41, 59, 10, 10, 9, 9, 47, 47, 32,116, 97,107,105,110,103, 32,116,104,101, + 32,102,114, 97, 99,116, 32,112, 97,114,116, 32,111,102, 32,116,104,101, 32,116,101,120,116,117,114,101, 32, 99,111,111,114,100, +105,110, 97,116,101, 32,105,115, 32, 97, 32,104, 97,114,100, 99,111,100,101,100, 32,119,114, 97,112, 32,109,111,100,101, 46, 10, + 9, 9, 47, 47, 32,116,104,105,115, 32,105,115, 32, 97, 99, 99,101,112,116, 97, 98,108,101, 32, 97,115, 32,116,101,120,116,117, +114,101,115, 32,117,115,101, 32,119,114, 97,112, 32,109,111,100,101, 32,101,120, 99,108,117,115,105,118,101,108,121, 32,105,110, + 32, 51, 68, 32,118,105,101,119, 32,101,108,115,101,119,104,101,114,101, 32,105,110, 32, 98,108,101,110,100,101,114, 46, 32, 10, + 9, 9, 47, 47, 32,116,104,105,115, 32,105,115, 32,100,111,110,101, 32,115,111, 32,116,104, 97,116, 32,119,101, 32, 99, 97,110, + 32,115,116,105,108,108, 32,103,101,116, 32, 97, 32,118, 97,108,105,100, 32,116,101,120,101,108, 32,119,105,116,104, 32,117,118, +115, 32,111,117,116,115,105,100,101, 32,116,104,101, 32, 48, 44, 49, 32,114, 97,110,103,101, 10, 9, 9, 47, 47, 32, 98,121, 32, +116,101,120,101,108, 70,101,116, 99,104, 32, 98,101,108,111,119, 44, 32, 97,115, 32, 99,111,111,114,100,105,110, 97,116,101,115, + 32, 97,114,101, 32, 99,108, 97,109,112,101,100, 32,119,104,101,110, 32,117,115,105,110,103, 32,116,104,105,115, 32,102,117,110, + 99,116,105,111,110, 46, 10, 9, 9,118,101, 99, 50, 32,102, 84,101,120, 76,111, 99, 32, 61, 32,118, 68,105,109, 42,102,114, 97, + 99,116, 40,116,101,120, 99,111, 46,120,121, 41, 32, 45, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 32, 48, 46, 53, 41, 59, 10, 9, + 9,105,118,101, 99, 50, 32,105, 84,101,120, 76,111, 99, 32, 61, 32,105,118,101, 99, 50, 40,102,108,111,111,114, 40,102, 84,101, +120, 76,111, 99, 41, 41, 59, 10, 9, 9,118,101, 99, 50, 32,116, 32, 61, 32, 99,108, 97,109,112, 40,102, 84,101,120, 76,111, 99, + 32, 45, 32,105, 84,101,120, 76,111, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 9, 9, 47, 47, 32,115, 97,116, 32,106, +117,115,116, 32,116,111, 32, 98,101, 32,112,101,100, 97,110,116,105, 99, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10, 32, 42, 32, 84,104,105,115, 32, 98,108,111, 99,107, - 32,119,105,108,108, 32,114,101,112,108, 97, 99,101, 32,116,104,101, 32,111,110,101, 32, 98,101,108,111,119, 32,119,104,101,110, - 32,111,110,101, 32, 99,104, 97,110,110,101,108, 32,116,101,120,116,117,114,101,115, 32, 97,114,101, 32,112,114,111,112,101,114, -108,121, 32,115,117,112,112,111,114,116,101,100, 46, 32, 42, 10, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10, 32, 42, 32, 84,104,105,115, 32, 98,108,111, 99,107, 32,119, +105,108,108, 32,114,101,112,108, 97, 99,101, 32,116,104,101, 32,111,110,101, 32, 98,101,108,111,119, 32,119,104,101,110, 32,111, +110,101, 32, 99,104, 97,110,110,101,108, 32,116,101,120,116,117,114,101,115, 32, 97,114,101, 32,112,114,111,112,101,114,108,121, + 32,115,117,112,112,111,114,116,101,100, 46, 32, 42, 10, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10, 9, 9,118,101, 99, 52, 32,118, 83, 97,109,112,108,101,115, 85, 76, 32, 61, - 32,116,101,120,116,117,114,101, 71, 97,116,104,101,114, 40,105,109, 97, 44, 32, 40,105, 84,101,120, 76,111, 99, 43,105,118,101, - 99, 50, 40, 45, 49, 44, 45, 49, 41, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 48, 46, 53, 41, 41, 47,118, 68,105,109, 32, - 41, 59, 10, 9, 9,118,101, 99, 52, 32,118, 83, 97,109,112,108,101,115, 85, 82, 32, 61, 32,116,101,120,116,117,114,101, 71, 97, -116,104,101,114, 40,105,109, 97, 44, 32, 40,105, 84,101,120, 76,111, 99, 43,105,118,101, 99, 50, 40, 49, 44, 45, 49, 41, 32, 43, - 32,118,101, 99, 50, 40, 48, 46, 53, 44, 48, 46, 53, 41, 41, 47,118, 68,105,109, 32, 41, 59, 10, 9, 9,118,101, 99, 52, 32,118, - 83, 97,109,112,108,101,115, 76, 76, 32, 61, 32,116,101,120,116,117,114,101, 71, 97,116,104,101,114, 40,105,109, 97, 44, 32, 40, -105, 84,101,120, 76,111, 99, 43,105,118,101, 99, 50, 40, 45, 49, 44, 49, 41, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 48, - 46, 53, 41, 41, 47,118, 68,105,109, 32, 41, 59, 10, 9, 9,118,101, 99, 52, 32,118, 83, 97,109,112,108,101,115, 76, 82, 32, 61, - 32,116,101,120,116,117,114,101, 71, 97,116,104,101,114, 40,105,109, 97, 44, 32, 40,105, 84,101,120, 76,111, 99, 43,105,118,101, - 99, 50, 40, 49, 44, 49, 41, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 48, 46, 53, 41, 41, 47,118, 68,105,109, 32, 41, 59, - 10, 10, 9, 9,109, 97,116, 52, 32, 72, 32, 61, 32,109, 97,116, 52, 40,118, 83, 97,109,112,108,101,115, 85, 76, 46,119, 44, 32, -118, 83, 97,109,112,108,101,115, 85, 76, 46,120, 44, 32,118, 83, 97,109,112,108,101,115, 76, 76, 46,119, 44, 32,118, 83, 97,109, -112,108,101,115, 76, 76, 46,120, 44, 10, 9, 9, 9, 9, 9,118, 83, 97,109,112,108,101,115, 85, 76, 46,122, 44, 32,118, 83, 97, -109,112,108,101,115, 85, 76, 46,121, 44, 32,118, 83, 97,109,112,108,101,115, 76, 76, 46,122, 44, 32,118, 83, 97,109,112,108,101, -115, 76, 76, 46,121, 44, 10, 9, 9, 9, 9, 9,118, 83, 97,109,112,108,101,115, 85, 82, 46,119, 44, 32,118, 83, 97,109,112,108, -101,115, 85, 82, 46,120, 44, 32,118, 83, 97,109,112,108,101,115, 76, 82, 46,119, 44, 32,118, 83, 97,109,112,108,101,115, 76, 82, - 46,120, 44, 10, 9, 9, 9, 9, 9,118, 83, 97,109,112,108,101,115, 85, 82, 46,122, 44, 32,118, 83, 97,109,112,108,101,115, 85, - 82, 46,121, 44, 32,118, 83, 97,109,112,108,101,115, 76, 82, 46,122, 44, 32,118, 83, 97,109,112,108,101,115, 76, 82, 46,121, 41, - 59, 10, 42, 47, 9, 10, 9, 9,105,118,101, 99, 50, 32,105, 84,101,120, 76,111, 99, 77,111,100, 32, 61, 32,105, 84,101,120, 76, -111, 99, 32, 43, 32,105,118,101, 99, 50, 40, 45, 49, 44, 32, 45, 49, 41, 59, 10, 10, 9, 9,109, 97,116, 52, 32, 72, 59, 10, 9, - 9, 10, 9, 9,102,111,114, 40,105,110,116, 32,105, 32, 61, 32, 48, 59, 32,105, 32, 60, 32, 52, 59, 32,105, 43, 43, 41,123, 10, - 9, 9, 9,102,111,114, 40,105,110,116, 32,106, 32, 61, 32, 48, 59, 32,106, 32, 60, 32, 52, 59, 32,106, 43, 43, 41,123, 10, 9, - 9, 9, 9,105,118,101, 99, 50, 32,105, 84,101,120, 84,109,112, 32, 61, 32,105, 84,101,120, 76,111, 99, 77,111,100, 32, 43, 32, -105,118,101, 99, 50, 40,105, 44,106, 41, 59, 10, 9, 9, 9, 9, 10, 9, 9, 9, 9, 47, 47, 32,119,114, 97,112, 32,116,101,120, -116,117,114,101, 32, 99,111,111,114,100,105,110, 97,116,101,115, 32,109, 97,110,117, 97,108,108,121, 32,102,111,114, 32,116,101, -120,101,108, 70,101,116, 99,104, 32,116,111, 32,119,111,114,107, 32,111,110, 32,117,118,115, 32,111,105,116,115,105,100,101, 32, -116,104,101, 32, 48, 44, 49, 32,114, 97,110,103,101, 46, 10, 9, 9, 9, 9, 47, 47, 32,116,104,105,115, 32,105,115, 32,103,117, - 97,114, 97,110,116,101,101,100, 32,116,111, 32,119,111,114,107, 32,115,105,110, 99,101, 32,119,101, 32,116, 97,107,101, 32,116, -104,101, 32,102,114, 97, 99,116,105,111,110, 97,108, 32,112, 97,114,116, 32,111,102, 32,116,104,101, 32,117,118, 32, 97, 98,111, -118,101, 46, 10, 9, 9, 9, 9,105, 84,101,120, 84,109,112, 46,120, 32, 61, 32, 40,105, 84,101,120, 84,109,112, 46,120, 32, 60, - 32, 48, 41, 63, 32,105, 84,101,120, 84,109,112, 46,120, 32, 43, 32,118, 68,105,109, 46,120, 32, 58, 32, 40, 40,105, 84,101,120, - 84,109,112, 46,120, 32, 62, 61, 32,118, 68,105,109, 46,120, 41, 63, 32,105, 84,101,120, 84,109,112, 46,120, 32, 45, 32,118, 68, -105,109, 46,120, 32, 58, 32,105, 84,101,120, 84,109,112, 46,120, 41, 59, 10, 9, 9, 9, 9,105, 84,101,120, 84,109,112, 46,121, - 32, 61, 32, 40,105, 84,101,120, 84,109,112, 46,121, 32, 60, 32, 48, 41, 63, 32,105, 84,101,120, 84,109,112, 46,121, 32, 43, 32, -118, 68,105,109, 46,121, 32, 58, 32, 40, 40,105, 84,101,120, 84,109,112, 46,121, 32, 62, 61, 32,118, 68,105,109, 46,121, 41, 63, - 32,105, 84,101,120, 84,109,112, 46,121, 32, 45, 32,118, 68,105,109, 46,121, 32, 58, 32,105, 84,101,120, 84,109,112, 46,121, 41, - 59, 10, 10, 9, 9, 9, 9,114,103, 98,116,111, 98,119, 40,116,101,120,101,108, 70,101,116, 99,104, 40,105,109, 97, 44, 32,105, - 84,101,120, 84,109,112, 44, 32, 48, 41, 44, 32, 72, 91,105, 93, 91,106, 93, 41, 59, 10, 9, 9, 9,125, 10, 9, 9,125, 10, 9, - 9, 10, 9, 9,102,108,111, 97,116, 32,120, 32, 61, 32,116, 46,120, 44, 32,121, 32, 61, 32,116, 46,121, 59, 10, 9, 9,102,108, -111, 97,116, 32,120, 50, 32, 61, 32,120, 32, 42, 32,120, 44, 32,120, 51, 32, 61, 32,120, 50, 32, 42, 32,120, 44, 32,121, 50, 32, - 61, 32,121, 32, 42, 32,121, 44, 32,121, 51, 32, 61, 32,121, 50, 32, 42, 32,121, 59, 10, 10, 9, 9,118,101, 99, 52, 32, 88, 32, - 61, 32,118,101, 99, 52, 40, 45, 48, 46, 53, 42, 40,120, 51, 43,120, 41, 43,120, 50, 44, 9, 9, 49, 46, 53, 42,120, 51, 45, 50, - 46, 53, 42,120, 50, 43, 49, 44, 9, 45, 49, 46, 53, 42,120, 51, 43, 50, 42,120, 50, 43, 48, 46, 53, 42,120, 44, 9, 9, 48, 46, - 53, 42, 40,120, 51, 45,120, 50, 41, 41, 59, 10, 9, 9,118,101, 99, 52, 32, 89, 32, 61, 32,118,101, 99, 52, 40, 45, 48, 46, 53, - 42, 40,121, 51, 43,121, 41, 43,121, 50, 44, 9, 9, 49, 46, 53, 42,121, 51, 45, 50, 46, 53, 42,121, 50, 43, 49, 44, 9, 45, 49, - 46, 53, 42,121, 51, 43, 50, 42,121, 50, 43, 48, 46, 53, 42,121, 44, 9, 9, 48, 46, 53, 42, 40,121, 51, 45,121, 50, 41, 41, 59, - 10, 9, 9,118,101, 99, 52, 32,100, 88, 32, 61, 32,118,101, 99, 52, 40, 45, 49, 46, 53, 42,120, 50, 43, 50, 42,120, 45, 48, 46, - 53, 44, 9, 9, 52, 46, 53, 42,120, 50, 45, 53, 42,120, 44, 9, 9, 9, 45, 52, 46, 53, 42,120, 50, 43, 52, 42,120, 43, 48, 46, - 53, 44, 9, 9, 49, 46, 53, 42,120, 50, 45,120, 41, 59, 10, 9, 9,118,101, 99, 52, 32,100, 89, 32, 61, 32,118,101, 99, 52, 40, - 45, 49, 46, 53, 42,121, 50, 43, 50, 42,121, 45, 48, 46, 53, 44, 9, 9, 52, 46, 53, 42,121, 50, 45, 53, 42,121, 44, 9, 9, 9, - 45, 52, 46, 53, 42,121, 50, 43, 52, 42,121, 43, 48, 46, 53, 44, 9, 9, 49, 46, 53, 42,121, 50, 45,121, 41, 59, 10, 9, 10, 9, - 9, 47, 47, 32, 99,111,109,112,108,101,116,101, 32,100,101,114,105,118, 97,116,105,118,101, 32,105,110, 32,110,111,114,109, 97, -108,105,122,101,100, 32, 99,111,111,114,100,105,110, 97,116,101,115, 32, 40,109,117,108, 32, 98,121, 32,118, 68,105,109, 41, 10, - 9, 9,118,101, 99, 50, 32,100, 72,100, 83, 84, 32, 61, 32,118, 68,105,109, 32, 42, 32,118,101, 99, 50, 40,100,111,116, 40, 89, - 44, 32, 72, 32, 42, 32,100, 88, 41, 44, 32,100,111,116, 40,100, 89, 44, 32, 72, 32, 42, 32, 88, 41, 41, 59, 10, 10, 9, 9, 47, - 47, 32,116,114, 97,110,115,102,111,114,109, 32,100,101,114,105,118, 97,116,105,118,101, 32,116,111, 32,115, 99,114,101,101,110, - 45,115,112, 97, 99,101, 10, 9, 9,118,101, 99, 50, 32,100, 72,100,120,121, 95, 98,105, 99,117, 98,105, 99, 32, 61, 32,118,101, - 99, 50, 40, 32,100, 72,100, 83, 84, 46,120, 32, 42, 32, 84,101,120, 68,120, 46,120, 32, 43, 32,100, 72,100, 83, 84, 46,121, 32, - 42, 32, 84,101,120, 68,120, 46,121, 44, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,100, 72,100, 83, 84, 46,120, 32, 42, 32, - 84,101,120, 68,121, 46,120, 32, 43, 32,100, 72,100, 83, 84, 46,121, 32, 42, 32, 84,101,120, 68,121, 46,121, 32, 41, 59, 10, 10, - 9, 9, 47, 47, 32, 98,108,101,110,100, 32, 98,101,116,119,101,101,110, 32,116,104,101, 32,116,119,111, 10, 9, 9,100, 72,100, -120,121, 32, 61, 32,100, 72,100,120,121, 42, 40, 49, 45,102, 66,108,101,110,100, 41, 32, 43, 32,100, 72,100,120,121, 95, 98,105, - 99,117, 98,105, 99, 42,102, 66,108,101,110,100, 59, 10, 9,125, 10, 10, 9,100, 66,115, 32, 61, 32,104, 83, 99, 97,108,101, 32, - 42, 32,100, 72,100,120,121, 46,120, 59, 10, 9,100, 66,116, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32,100, 72,100,120,121, - 46,121, 59, 10,125, 10, 10, 35,101,110,100,105,102, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,116, 97, -112, 53, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102, -108,111, 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, - 41, 32, 10,123, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, - 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 59, - 10, 10, 9,118,101, 99, 50, 32, 83, 84, 99, 32, 61, 32,116,101,120, 99,111, 46,120,121, 59, 10, 9,118,101, 99, 50, 32, 83, 84, -108, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, - 99, 50, 32, 83, 84,114, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, - 59, 10, 9,118,101, 99, 50, 32, 83, 84,100, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84, -101,120, 68,121, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,117, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, - 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, 10, 9, 10, 9,102,108,111, 97,116, 32, 72, 99, 44, 72,108, 44, 72,114, 44, 72,100, - 44, 72,117, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84, - 99, 41, 44, 32, 72, 99, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, - 97, 44, 32, 83, 84,108, 41, 44, 32, 72,108, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, - 50, 68, 40,105,109, 97, 44, 32, 83, 84,114, 41, 44, 32, 72,114, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101, -120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,100, 41, 44, 32, 72,100, 32, 41, 59, 10, 9,114,103, 98,116,111, 98, -119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,117, 41, 44, 32, 72,117, 32, 41, 59, 10, 9, 10, - 9,100, 66,115, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,114, 32, 45, 32, 72,108, 41, 59, 10, 9,100, 66,116, 32, - 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,117, 32, 45, 32, 72,100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, -101,120, 95, 98,117,109,112, 95,100,101,114,105,118, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108, -101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,120, 44, 32,102,108,111, 97,116, 32,105,109, 97, - 95,121, 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,102,108,111, 97,116, 32,115, 32, 61, 32, 49, 46, 48, 59, 9, 9, 47, 47, 32,110,101, -103, 97,116,101, 32,116,104,105,115, 32,105,102, 32,102,108,105,112,112,101,100, 32,116,101,120,116,117,114,101, 32, 99,111,111, -114,100,105,110, 97,116,101, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, - 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120, -121, 41, 59, 10, 9, 10, 9, 47, 47, 32,116,104,105,115, 32,118, 97,114,105, 97,110,116, 32,117,115,105,110,103, 32, 97, 32,100, -101,114,105,118, 97,116,105,118,101, 32,109, 97,112, 32,105,115, 32,100,101,115, 99,114,105, 98,101,100, 32,104,101,114,101, 10, - 9, 47, 47, 32,104,116,116,112, 58, 47, 47,109,109,105,107,107,101,108,115,101,110, 51,100, 46, 98,108,111,103,115,112,111,116, - 46, 99,111,109, 47, 50, 48, 49, 49, 47, 48, 55, 47,100,101,114,105,118, 97,116,105,118,101, 45,109, 97,112,115, 46,104,116,109, -108, 10, 9,118,101, 99, 50, 32,100,105,109, 32, 61, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 44, 32,105,109, 97, 95,121, 41, - 59, 10, 9,118,101, 99, 50, 32,100, 66,100,117,118, 32, 61, 32,104, 83, 99, 97,108,101, 42,100,105,109, 42, 40, 50, 46, 48, 42, -116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 46,120,121, 45, 49, 46, 48, 41, - 59, 10, 9, 10, 9,100, 66,115, 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84,101,120, 68,120, 46,120, 32, 43, 32,115, 42,100, - 66,100,117,118, 46,121, 42, 84,101,120, 68,120, 46,121, 59, 10, 9,100, 66,116, 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84, -101,120, 68,121, 46,120, 32, 43, 32,115, 42,100, 66,100,117,118, 46,121, 42, 84,101,120, 68,121, 46,121, 59, 10,125, 10, 10,118, -111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, 40, 32,102,108,111, 97,116, 32,102, 68,101,116, 44, - 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,102,108,111, 97,116, 32,100, 66,116, 44, 32,118,101, 99, 51, 32,118, 82, 49, 44, - 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 32, - 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112,101, -114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 41, 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83,117,114,102, 71,114, 97, -100, 32, 61, 32,115,105,103,110, 40,102, 68,101,116, 41, 32, 42, 32, 40, 32,100, 66,115, 32, 42, 32,118, 82, 49, 32, 43, 32,100, - 66,116, 32, 42, 32,118, 82, 50, 32, 41, 59, 10, 9, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, - 95,105,110, 32, 45, 32,118, 83,117,114,102, 71,114, 97,100, 59, 10, 9,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, - 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32,118, 78, 97, 99, 99, 95,111,117,116, 32, 41, 59, 10,125, 10, 10,118,111, -105,100, 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, 95,116,101,120,115,112, 97, 99,101, 40, 32,102,108,111, - 97,116, 32,102, 68,101,116, 44, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,102,108,111, 97,116, 32,100, 66,116, 44, 32,118, -101, 99, 51, 32,118, 82, 49, 44, 32,118,101, 99, 51, 32,118, 82, 50, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, - 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,120, 44, 32,102,108,111, 97,116, 32, -105,109, 97, 95,121, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32, -111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112,101,114, -116,117,114, 98,101,100, 95,110,111,114,109, 32, 41, 32, 10,123, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, - 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100, -121, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 10, 9,118,101, 99, 51, 32,118, 83,117,114,102, 71,114, 97,100, 32, 61, 32, -115,105,103,110, 40,102, 68,101,116, 41, 32, 42, 32, 40, 32, 10, 9, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,100, 66,115, - 32, 47, 32,108,101,110,103,116,104, 40, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 42, 84,101,120, 68,120, 46,120, 44, 32,105, -109, 97, 95,121, 42, 84,101,120, 68,120, 46,121, 41, 32, 41, 32, 42, 32,118, 82, 49, 32, 43, 32, 10, 9, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,100, 66,116, 32, 47, 32,108,101,110,103,116,104, 40, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 42, 84, -101,120, 68,121, 46,120, 44, 32,105,109, 97, 95,121, 42, 84,101,120, 68,121, 46,121, 41, 32, 41, 32, 42, 32,118, 82, 50, 32, 41, - 59, 10, 9, 9, 9, 9, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 45, 32,118, - 83,117,114,102, 71,114, 97,100, 59, 10, 9,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 61, 32,110,111,114,109, - 97,108,105,122,101, 40, 32,118, 78, 97, 99, 99, 95,111,117,116, 32, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, - 95,110,101,103, 97,116,101, 95,116,101,120,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111, -117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9,111,117,116,110,111,114,109, 97,108, 32, - 61, 32,118,101, 99, 51, 40, 45,110,111,114,109, 97,108, 46,120, 44, 32, 45,110,111,114,109, 97,108, 46,121, 44, 32,110,111,114, -109, 97,108, 46,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,115,112, 97, 99,101, 95,116, 97,110,103, -101,110,116, 40,118,101, 99, 52, 32,116, 97,110,103,101,110,116, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118, -101, 99, 51, 32,116,101,120,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97, -108, 41, 10,123, 10, 9,118,101, 99, 51, 32, 66, 32, 61, 32,116, 97,110,103,101,110,116, 46,119, 32, 42, 32, 99,114,111,115,115, - 40,110,111,114,109, 97,108, 44, 32,116, 97,110,103,101,110,116, 46,120,121,122, 41, 59, 10, 10, 9,111,117,116,110,111,114,109, - 97,108, 32, 61, 32,116,101,120,110,111,114,109, 97,108, 46,120, 42,116, 97,110,103,101,110,116, 46,120,121,122, 32, 43, 32,116, -101,120,110,111,114,109, 97,108, 46,121, 42, 66, 32, 43, 32,116,101,120,110,111,114,109, 97,108, 46,122, 42,110,111,114,109, 97, -108, 59, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,110,111,114, -109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,108,101,110,100, 95,110,111,114,109, 97,108, 40, -102,108,111, 97,116, 32,110,111,114,102, 97, 99, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118,101, 99, 51, 32, -110,101,119,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, - 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32,110,111,114,102, 97, 99, 41, 42,110,111,114, -109, 97,108, 32, 43, 32,110,111,114,102, 97, 99, 42,110,101,119,110,111,114,109, 97,108, 59, 10, 9,111,117,116,110,111,114,109, - 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10, 47, 42, - 42, 42, 42, 42, 42, 42, 32, 77, 65, 84, 69, 82, 73, 65, 76, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, - 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,117,110, 95,104,101,109,105, 40,118,101, 99, 51, 32,108, - 97,109,112,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, -105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, 32, -108, 97,109,112,118,101, 99, 59, 10, 9,100,105,115,116, 32, 61, 32, 49, 46, 48, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 61, - 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,111,116, -104,101,114, 40,118,101, 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111, 44, 32,111,117,116, 32,118,101, - 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, 32, 99,111, 32, 45, 32,108, 97,109,112, 99,111, 59, 10, 9, -100,105,115,116, 32, 61, 32,108,101,110,103,116,104, 40,108,118, 41, 59, 10, 9,108,118, 32, 61, 32,110,111,114,109, 97,108,105, -122,101, 40,108,118, 41, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32, -108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,105,110,118,108,105,110,101, 97,114, 40,102,108,111, 97,116, 32,108, 97,109, -112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115, -105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109, -112,100,105,115,116, 32, 43, 32,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108, -111,102,102, 95,105,110,118,115,113,117, 97,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108, -111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9, -118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,100, -105,115,116, 42,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95, -115,108,105,100,101,114,115, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,108,100, - 49, 44, 32,102,108,111, 97,116, 32,108,100, 50, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108, -111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116,107,119, - 32, 61, 32,108, 97,109,112,100,105,115,116, 42,108, 97,109,112,100,105,115,116, 59, 10, 10, 9,118,105,115,105,102, 97, 99, 32, - 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,108,100, 49, 42,100,105,115,116, 41, - 59, 10, 9,118,105,115,105,102, 97, 99, 32, 42, 61, 32,108, 97,109,112,100,105,115,116,107,119, 47, 40,108, 97,109,112,100,105, -115,116,107,119, 32, 43, 32,108,100, 50, 42,100,105,115,116, 42,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, - 97,109,112, 95,102, 97,108,108,111,102,102, 95, 99,117,114,118,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, - 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,102,108,111, 97,116, 32,100,105,115,116, - 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, - 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,100,105,115,116, 47, -108, 97,109,112,100,105,115,116, 44, 32, 48, 46, 48, 41, 41, 46,120, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95, -118,105,115,105, 98,105,108,105,116,121, 95,115,112,104,101,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, - 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, - 32,102,108,111, 97,116, 32,111,117,116,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116, 61, 32,108, - 97,109,112,100,105,115,116, 32, 45, 32,100,105,115,116, 59, 10, 10, 9,111,117,116,118,105,115,105,102, 97, 99, 61, 32,118,105, -115,105,102, 97, 99, 42,109, 97,120, 40,116, 44, 32, 48, 46, 48, 41, 47,108, 97,109,112,100,105,115,116, 59, 10,125, 10, 10,118, -111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 95,115,113,117, 97,114,101, 40, -118,101, 99, 51, 32,108, 97,109,112,118,101, 99, 44, 32,109, 97,116, 52, 32,108, 97,109,112,105,109, 97,116, 44, 32,118,101, 99, - 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112,114, 41, 10,123, 10, 9,105,102, 40,100,111,116, 40, -108,118, 44, 32,108, 97,109,112,118,101, 99, 41, 32, 62, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,118,101, 99, 51, 32,108,118,114, -111,116, 32, 61, 32, 40,108, 97,109,112,105,109, 97,116, 42,118,101, 99, 52, 40,108,118, 44, 32, 48, 46, 48, 41, 41, 46,120,121, -122, 59, 10, 9, 9,102,108,111, 97,116, 32,120, 32, 61, 32,109, 97,120, 40, 97, 98,115, 40,108,118,114,111,116, 46,120, 47,108, -118,114,111,116, 46,122, 41, 44, 32, 97, 98,115, 40,108,118,114,111,116, 46,121, 47,108,118,114,111,116, 46,122, 41, 41, 59, 10, - 10, 9, 9,105,110,112,114, 32, 61, 32, 49, 46, 48, 47,115,113,114,116, 40, 49, 46, 48, 32, 43, 32,120, 42,120, 41, 59, 10, 9, -125, 10, 9,101,108,115,101, 10, 9, 9,105,110,112,114, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97, -109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 95, 99,105,114, 99,108,101, 40,118,101, 99, 51, 32,108, - 97,109,112,118,101, 99, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112,114, 41, - 10,123, 10, 9,105,110,112,114, 32, 61, 32,100,111,116, 40,108,118, 44, 32,108, 97,109,112,118,101, 99, 41, 59, 10,125, 10, 10, -118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 40,102,108,111, 97,116, 32, -115,112,111,116,115,105, 44, 32,102,108,111, 97,116, 32,115,112,111,116, 98,108, 44, 32,102,108,111, 97,116, 32,105,110,112,114, - 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118,105, -115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116, 32, 61, 32,115,112,111,116,115,105, 59, 10, 10, 9,105,102, - 40,105,110,112,114, 32, 60, 61, 32,116, 41, 32,123, 10, 9, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, 32, 48, 46, 48, - 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,116, 32, 61, 32,105,110,112,114, 32, 45, 32,116, 59, 10, 10, 9, 9, - 47, 42, 32,115,111,102,116, 32, 97,114,101, 97, 32, 42, 47, 10, 9, 9,105,102, 40,115,112,111,116, 98,108, 32, 33, 61, 32, 48, - 46, 48, 41, 10, 9, 9, 9,105,110,112,114, 32, 42, 61, 32,115,109,111,111,116,104,115,116,101,112, 40, 48, 46, 48, 44, 32, 49, - 46, 48, 44, 32,116, 47,115,112,111,116, 98,108, 41, 59, 10, 10, 9, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, 32,118, -105,115,105,102, 97, 99, 42,105,110,112,114, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115, -105, 98,105,108,105,116,121, 95, 99,108, 97,109,112, 40,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, - 32,102,108,111, 97,116, 32,111,117,116,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,111,117,116,118,105,115,105,102, 97, 99, - 32, 61, 32, 40,118,105,115,105,102, 97, 99, 32, 60, 32, 48, 46, 48, 48, 49, 41, 63, 32, 48, 46, 48, 58, 32,118,105,115,105,102, - 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,118,105,101,119, 40,118,101, 99, 51, 32, 99,111, 44, 32, -111,117,116, 32,118,101, 99, 51, 32,118,105,101,119, 41, 10,123, 10, 9, 47, 42, 32,104, 97,110,100,108,101, 32,112,101,114,115, -112,101, 99,116,105,118,101, 47,111,114,116,104,111,103,114, 97,112,104,105, 99, 32, 42, 47, 10, 9,118,105,101,119, 32, 61, 32, - 40,103,108, 95, 80,114,111,106,101, 99,116,105,111,110, 77, 97,116,114,105,120, 91, 51, 93, 91, 51, 93, 32, 61, 61, 32, 48, 46, - 48, 41, 63, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 41, 58, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, - 44, 32, 45, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,116, 97,110,103,101,110,116, 95,118, - 40,118,101, 99, 51, 32,108,118, 44, 32,118,101, 99, 51, 32,116, 97,110,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,110, - 41, 10,123, 10, 9,118,101, 99, 51, 32, 99, 32, 61, 32, 99,114,111,115,115, 40,108,118, 44, 32,116, 97,110,103, 41, 59, 10, 9, -118,101, 99, 51, 32,118,110,111,114, 32, 61, 32, 99,114,111,115,115, 40, 99, 44, 32,116, 97,110,103, 41, 59, 10, 10, 9,118,110, - 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,118,110,111,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97, -100,101, 95,105,110,112, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, - 97,116, 32,105,110,112, 41, 10,123, 10, 9,105,110,112, 32, 61, 32,100,111,116, 40,118,110, 44, 32,108,118, 41, 59, 10,125, 10, - 10,118,111,105,100, 32,115,104, 97,100,101, 95,105,115, 95,110,111, 95,100,105,102,102,117,115,101, 40,111,117,116, 32,102,108, -111, 97,116, 32,105,115, 41, 10,123, 10, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97, -100,101, 95,105,115, 95,104,101,109,105, 40,102,108,111, 97,116, 32,105,110,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, -105,115, 41, 10,123, 10, 9,105,115, 32, 61, 32, 48, 46, 53, 42,105,110,112, 32, 43, 32, 48, 46, 53, 59, 10,125, 10, 10,102,108, -111, 97,116, 32, 97,114,101, 97, 95,108, 97,109,112, 95,101,110,101,114,103,121, 40,109, 97,116, 52, 32, 97,114,101, 97, 44, 32, -118,101, 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,118,110, 41, 10,123, 10, 9,118,101, 99, 51, 32,118,101, 99, 91, 52, 93, - 44, 32, 99, 91, 52, 93, 59, 10, 9,102,108,111, 97,116, 32,114, 97,100, 91, 52, 93, 44, 32,102, 97, 99, 59, 10, 9, 10, 9,118, -101, 99, 91, 48, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 48, 93, 46,120, -121,122, 41, 59, 10, 9,118,101, 99, 91, 49, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114, -101, 97, 91, 49, 93, 46,120,121,122, 41, 59, 10, 9,118,101, 99, 91, 50, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, - 99,111, 32, 45, 32, 97,114,101, 97, 91, 50, 93, 46,120,121,122, 41, 59, 10, 9,118,101, 99, 91, 51, 93, 32, 61, 32,110,111,114, -109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 51, 93, 46,120,121,122, 41, 59, 10, 10, 9, 99, 91, 48, 93, - 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 48, 93, 44, 32,118,101, 99, 91, 49, - 93, 41, 41, 59, 10, 9, 99, 91, 49, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, - 91, 49, 93, 44, 32,118,101, 99, 91, 50, 93, 41, 41, 59, 10, 9, 99, 91, 50, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, - 40, 99,114,111,115,115, 40,118,101, 99, 91, 50, 93, 44, 32,118,101, 99, 91, 51, 93, 41, 41, 59, 10, 9, 99, 91, 51, 93, 32, 61, - 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 51, 93, 44, 32,118,101, 99, 91, 48, 93, 41, - 41, 59, 10, 10, 9,114, 97,100, 91, 48, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 48, 93, 44, 32,118, -101, 99, 91, 49, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 49, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, - 49, 93, 44, 32,118,101, 99, 91, 50, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 50, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, - 40,118,101, 99, 91, 50, 93, 44, 32,118,101, 99, 91, 51, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 51, 93, 32, 61, 32, 97, 99,111, -115, 40,100,111,116, 40,118,101, 99, 91, 51, 93, 44, 32,118,101, 99, 91, 48, 93, 41, 41, 59, 10, 10, 9,102, 97, 99, 61, 32, 32, -114, 97,100, 91, 48, 93, 42,100,111,116, 40,118,110, 44, 32, 99, 91, 48, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, - 91, 49, 93, 42,100,111,116, 40,118,110, 44, 32, 99, 91, 49, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 50, 93, - 42,100,111,116, 40,118,110, 44, 32, 99, 91, 50, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 51, 93, 42,100,111, -116, 40,118,110, 44, 32, 99, 91, 51, 93, 41, 59, 10, 10, 9,114,101,116,117,114,110, 32,109, 97,120, 40,102, 97, 99, 44, 32, 48, - 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,105,110,112, 95, 97,114,101, 97, 40,118,101, 99, 51, - 32,112,111,115,105,116,105,111,110, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111, 44, 32,118,101, 99, 51, 32,108, 97,109, -112,118,101, 99, 44, 32,118,101, 99, 51, 32,118,110, 44, 32,109, 97,116, 52, 32, 97,114,101, 97, 44, 32,102,108,111, 97,116, 32, - 97,114,101, 97,115,105,122,101, 44, 32,102,108,111, 97,116, 32,107, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112, - 41, 10,123, 10, 9,118,101, 99, 51, 32, 99,111, 32, 61, 32,112,111,115,105,116,105,111,110, 59, 10, 9,118,101, 99, 51, 32,118, -101, 99, 32, 61, 32, 99,111, 32, 45, 32,108, 97,109,112, 99,111, 59, 10, 10, 9,105,102, 40,100,111,116, 40,118,101, 99, 44, 32, -108, 97,109,112,118,101, 99, 41, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,110,112, 32, 61, 32, 48, 46, 48, 59, 10, 9, -125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,105,110,116,101,110,115, 32, 61, 32, 97,114,101, 97, 95, -108, 97,109,112, 95,101,110,101,114,103,121, 40, 97,114,101, 97, 44, 32, 99,111, 44, 32,118,110, 41, 59, 10, 10, 9, 9,105,110, -112, 32, 61, 32,112,111,119, 40,105,110,116,101,110,115, 42, 97,114,101, 97,115,105,122,101, 44, 32,107, 41, 59, 10, 9,125, 10, -125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,111,114,101,110, 95,110, 97,121,101,114, - 40,102,108,111, 97,116, 32,110,108, 44, 32,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32, -118, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, - 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32,108, 41, 59, 10, 9,102,108,111, - 97,116, 32,110,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,104, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9,102,108, -111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9,102, -108,111, 97,116, 32,114,101, 97,108,110,108, 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 10, 9,105,102, 40,114,101, - 97,108,110,108, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108, -115,101, 32,105,102, 40,110,108, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, - 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,118,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,118, 44, - 32,104, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 76,105,116, 95, 65, 32, 61, 32, 97, 99,111,115, 40, -114,101, 97,108,110,108, 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 86,105,101,119, 95, 65, 32, 61, 32, 97, 99,111,115, 40,110, -118, 41, 59, 10, 10, 9, 9,118,101, 99, 51, 32, 76,105,116, 95, 66, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, - 45, 32,114,101, 97,108,110,108, 42,110, 41, 59, 10, 9, 9,118,101, 99, 51, 32, 86,105,101,119, 95, 66, 32, 61, 32,110,111,114, -109, 97,108,105,122,101, 40,118, 32, 45, 32,110,118, 42,110, 41, 59, 10, 10, 9, 9,102,108,111, 97,116, 32,116, 32, 61, 32,109, - 97,120, 40,100,111,116, 40, 76,105,116, 95, 66, 44, 32, 86,105,101,119, 95, 66, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, 9, 9, -102,108,111, 97,116, 32, 97, 44, 32, 98, 59, 10, 10, 9, 9,105,102, 40, 76,105,116, 95, 65, 32, 62, 32, 86,105,101,119, 95, 65, - 41, 32,123, 10, 9, 9, 9, 97, 32, 61, 32, 76,105,116, 95, 65, 59, 10, 9, 9, 9, 98, 32, 61, 32, 86,105,101,119, 95, 65, 59, - 10, 9, 9,125, 10, 9, 9,101,108,115,101, 32,123, 10, 9, 9, 9, 97, 32, 61, 32, 86,105,101,119, 95, 65, 59, 10, 9, 9, 9, - 98, 32, 61, 32, 76,105,116, 95, 65, 59, 10, 9, 9,125, 10, 10, 9, 9,102,108,111, 97,116, 32, 65, 32, 61, 32, 49, 46, 48, 32, - 45, 32, 40, 48, 46, 53, 42, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 47, 40, 40,114,111,117,103,104, 42,114,111, -117,103,104, 41, 32, 43, 32, 48, 46, 51, 51, 41, 41, 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 66, 32, 61, 32, 48, 46, 52, 53, - 42, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 47, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 32, 43, - 32, 48, 46, 48, 57, 41, 41, 59, 10, 10, 9, 9, 98, 32, 42, 61, 32, 48, 46, 57, 53, 59, 10, 9, 9,105,115, 32, 61, 32,110,108, - 42, 40, 65, 32, 43, 32, 40, 66, 32, 42, 32,116, 32, 42, 32,115,105,110, 40, 97, 41, 32, 42, 32,116, 97,110, 40, 98, 41, 41, 41, - 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,116,111,111,110, 40, -118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,115,105, -122,101, 44, 32,102,108,111, 97,116, 32,116,115,109,111,111,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, - 10,123, 10, 9,102,108,111, 97,116, 32,114,115,108,116, 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 9,102,108,111, - 97,116, 32, 97,110,103, 32, 61, 32, 97, 99,111,115, 40,114,115,108,116, 41, 59, 10, 10, 9,105,102, 40, 97,110,103, 32, 60, 32, -115,105,122,101, 41, 32,105,115, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 97,110,103, 32, 62, 32, 40, -115,105,122,101, 32, 43, 32,116,115,109,111,111,116,104, 41, 32,124,124, 32,116,115,109,111,111,116,104, 32, 61, 61, 32, 48, 46, - 48, 41, 32,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,115, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 40, - 97,110,103, 32, 45, 32,115,105,122,101, 41, 47,116,115,109,111,111,116,104, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, - 97,100,101, 95,100,105,102,102,117,115,101, 95,109,105,110,110, 97,101,114,116, 40,102,108,111, 97,116, 32,110,108, 44, 32,118, -101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,100, 97,114,107,110,101,115,115, 44, 32,111, -117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,105,102, 40,110,108, 32, 60, 61, 32, 48, 46, 48, 41, 32,123, 10, - 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,110, -118, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, 9, 9,105,102, 40,100, - 97,114,107,110,101,115,115, 32, 60, 61, 32, 49, 46, 48, 41, 10, 9, 9, 9,105,115, 32, 61, 32,110,108, 42,112,111,119, 40,109, - 97,120, 40,110,118, 42,110,108, 44, 32, 48, 46, 49, 41, 44, 32,100, 97,114,107,110,101,115,115, 32, 45, 32, 49, 46, 48, 41, 59, - 10, 9, 9,101,108,115,101, 10, 9, 9, 9,105,115, 32, 61, 32,110,108, 42,112,111,119, 40, 49, 46, 48, 48, 48, 49, 32, 45, 32, -110,118, 44, 32,100, 97,114,107,110,101,115,115, 32, 45, 32, 49, 46, 48, 41, 59, 10, 9,125, 10,125, 10, 10,102,108,111, 97,116, - 32,102,114,101,115,110,101,108, 95,102, 97, 99, 40,118,101, 99, 51, 32,118,105,101,119, 44, 32,118,101, 99, 51, 32,118,110, 44, - 32,102,108,111, 97,116, 32,103,114, 97,100, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, - 32,116, 49, 44, 32,116, 50, 59, 10, 9,102,108,111, 97,116, 32,102,102, 97, 99, 59, 10, 10, 9,105,102, 40,102, 97, 99, 61, 61, - 48, 46, 48, 41, 32,123, 10, 9, 9,102,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, - 9, 9,116, 49, 61, 32,100,111,116, 40,118,105,101,119, 44, 32,118,110, 41, 59, 10, 9, 9,105,102, 40,116, 49, 62, 48, 46, 48, - 41, 32, 32,116, 50, 61, 32, 49, 46, 48, 43,116, 49, 59, 10, 9, 9,101,108,115,101, 32,116, 50, 61, 32, 49, 46, 48, 45,116, 49, - 59, 10, 10, 9, 9,116, 50, 61, 32,103,114, 97,100, 32, 43, 32, 40, 49, 46, 48, 45,103,114, 97,100, 41, 42,112,111,119, 40,116, - 50, 44, 32,102, 97, 99, 41, 59, 10, 10, 9, 9,105,102, 40,116, 50, 60, 48, 46, 48, 41, 32,102,102, 97, 99, 32, 61, 32, 48, 46, - 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40,116, 50, 62, 49, 46, 48, 41, 32,102,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, - 10, 9, 9,101,108,115,101, 32,102,102, 97, 99, 32, 61, 32,116, 50, 59, 10, 9,125, 10, 10, 9,114,101,116,117,114,110, 32,102, -102, 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,102,114,101,115,110, -101,108, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32, -102,108,111, 97,116, 32,102, 97, 99, 95,105, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97, -116, 32,105,115, 41, 10,123, 10, 9,105,115, 32, 61, 32,102,114,101,115,110,101,108, 95,102, 97, 99, 40,108,118, 44, 32,118,110, - 44, 32,102, 97, 99, 95,105, 44, 32,102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 99,117, 98, -105, 99, 40,102,108,111, 97,116, 32,105,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105,115, 41, 10,123, 10, - 9,105,102, 40,105,115, 62, 48, 46, 48, 32, 38, 38, 32,105,115, 60, 49, 46, 48, 41, 10, 9, 9,111,117,116,105,115, 61, 32,115, -109,111,111,116,104,115,116,101,112, 40, 48, 46, 48, 44, 32, 49, 46, 48, 44, 32,105,115, 41, 59, 10, 9,101,108,115,101, 10, 9, - 9,111,117,116,105,115, 61, 32,105,115, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,118,105,115,105,102, 97, - 99, 40,102,108,111, 97,116, 32,105, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,102,108,111, 97,116, 32, -114,101,102,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105, 41, 10,123, 10, 9, 47, 42,105,102, 40,105, 32, - 62, 32, 48, 46, 48, 41, 42, 47, 10, 9, 9,111,117,116,105, 32, 61, 32,109, 97,120, 40,105, 42,118,105,115,105,102, 97, 99, 42, -114,101,102,108, 44, 32, 48, 46, 48, 41, 59, 10, 9, 47, 42,101,108,115,101, 10, 9, 9,111,117,116,105, 32, 61, 32,105, 59, 42, - 47, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,116, 97,110,103,101,110,116, 95,118, 95,115,112,101, 99, 40,118, -101, 99, 51, 32,116, 97,110,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,110, 41, 10,123, 10, 9,118,110, 32, 61, 32,116, - 97,110,103, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, 95,116,111, 95,100,105,102,102,117,115, -101, 40,102,108,111, 97,116, 32,105, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111,108, 44, 32,118,101, 99, 51, 32, 99,111, -108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,105,102, 40,105, 32, 62, 32, 48, 46, - 48, 41, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,105, 42,108, 97,109,112, 99,111,108, 42, 99,111,108, 59, 10, 9,101,108, -115,101, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, - 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,104,101,109,105, 95,115,112,101, 99, 40,118,101, 99, 51, 32, -118,110, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,102,108,111, 97,116, 32,115,112, -101, 99, 44, 32,102,108,111, 97,116, 32,104, 97,114,100, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111, -117,116, 32,102,108,111, 97,116, 32,116, 41, 10,123, 10, 9,108,118, 32, 43, 61, 32,118,105,101,119, 59, 10, 9,108,118, 32, 61, - 32,110,111,114,109, 97,108,105,122,101, 40,108,118, 41, 59, 10, 10, 9,116, 32, 61, 32,100,111,116, 40,118,110, 44, 32,108,118, - 41, 59, 10, 9,116, 32, 61, 32, 48, 46, 53, 42,116, 32, 43, 32, 48, 46, 53, 59, 10, 10, 9,116, 32, 61, 32,118,105,115,105,102, - 97, 99, 42,115,112,101, 99, 42,112,111,119, 40,116, 44, 32,104, 97,114,100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, - 97,100,101, 95,112,104,111,110,103, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118, -101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,104, 97,114,100, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, - 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 43, 32, -118, 41, 59, 10, 9,102,108,111, 97,116, 32,114,115,108,116, 32, 61, 32,109, 97,120, 40,100,111,116, 40,104, 44, 32,110, 41, 44, - 32, 48, 46, 48, 41, 59, 10, 10, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,112,111,119, 40,114,115,108,116, 44, 32,104, 97,114, -100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 99,111,111,107,116,111,114,114, 95,115,112,101, 99, 40, -118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,104, 97, -114,100, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, - 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32,108, 41, 59, 10, 9,102,108,111, 97,116, 32,110,104, 32, 61, - 32,100,111,116, 40,110, 44, 32,104, 41, 59, 10, 10, 9,105,102, 40,110,104, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,115, -112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, - 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9,102,108,111, - 97,116, 32,105, 32, 61, 32,112,111,119, 40,110,104, 44, 32,104, 97,114,100, 41, 59, 10, 10, 9, 9,105, 32, 61, 32,105, 47, 40, - 48, 46, 49, 43,110,118, 41, 59, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,105, 59, 10, 9,125, 10,125, 10, 10,118,111, -105,100, 32,115,104, 97,100,101, 95, 98,108,105,110,110, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, - 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,114,101,102,114, 97, 99, 44, 32,102,108,111, 97,116, 32, -115,112,101, 99, 95,112,111,119,101,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, - 10, 9,105,102, 40,114,101,102,114, 97, 99, 32, 60, 32, 49, 46, 48, 41, 32,123, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, - 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,105,102, 40,115,112,101, 99, 95,112,111,119,101,114, 32, 61, 61, 32, - 48, 46, 48, 41, 32,123, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, - 32,123, 10, 9, 9,105,102, 40,115,112,101, 99, 95,112,111,119,101,114, 60, 49, 48, 48, 46, 48, 41, 10, 9, 9, 9,115,112,101, - 99, 95,112,111,119,101,114, 61, 32,115,113,114,116, 40, 49, 46, 48, 47,115,112,101, 99, 95,112,111,119,101,114, 41, 59, 10, 9, - 9,101,108,115,101, 10, 9, 9, 9,115,112,101, 99, 95,112,111,119,101,114, 61, 32, 49, 48, 46, 48, 47,115,112,101, 99, 95,112, -111,119,101,114, 59, 10, 10, 9, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32, -108, 41, 59, 10, 9, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32,100,111,116, 40,110, 44, 32,104, 41, 59, 10, 9, 9,105,102, - 40,110,104, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9, - 9,125, 10, 9, 9,101,108,115,101, 32,123, 10, 9, 9, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111, -116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 49, 41, 59, 10, 9, 9, 9,102,108,111, 97,116, 32,110,108, 32, 61, 32,100,111, -116, 40,110, 44, 32,108, 41, 59, 10, 9, 9, 9,105,102, 40,110,108, 32, 60, 61, 32, 48, 46, 48, 49, 41, 32,123, 10, 9, 9, 9, - 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9, 9,125, 10, 9, 9, 9,101,108,115,101, 32,123, 10, 9, - 9, 9, 9,102,108,111, 97,116, 32,118,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,118, 44, 32,104, 41, 44, 32, 48, 46, 48, - 49, 41, 59, 10, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, 97, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9, 9, 9,102,108,111, 97, -116, 32, 98, 32, 61, 32, 40, 50, 46, 48, 42,110,104, 42,110,118, 41, 47,118,104, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, - 99, 32, 61, 32, 40, 50, 46, 48, 42,110,104, 42,110,108, 41, 47,118,104, 59, 10, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,103, - 32, 61, 32, 48, 46, 48, 59, 10, 10, 9, 9, 9, 9,105,102, 40, 97, 32, 60, 32, 98, 32, 38, 38, 32, 97, 32, 60, 32, 99, 41, 32, -103, 32, 61, 32, 97, 59, 10, 9, 9, 9, 9,101,108,115,101, 32,105,102, 40, 98, 32, 60, 32, 97, 32, 38, 38, 32, 98, 32, 60, 32, - 99, 41, 32,103, 32, 61, 32, 98, 59, 10, 9, 9, 9, 9,101,108,115,101, 32,105,102, 40, 99, 32, 60, 32, 97, 32, 38, 38, 32, 99, - 32, 60, 32, 98, 41, 32,103, 32, 61, 32, 99, 59, 10, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,112, 32, 61, 32,115,113,114,116, - 40, 40, 40,114,101,102,114, 97, 99, 32, 42, 32,114,101,102,114, 97, 99, 41, 43, 40,118,104, 42,118,104, 41, 45, 49, 46, 48, 41, - 41, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,102, 32, 61, 32, 40, 40, 40,112, 45,118,104, 41, 42, 40,112, 45,118,104, 41, - 41, 47, 40, 40,112, 43,118,104, 41, 42, 40,112, 43,118,104, 41, 41, 41, 42, 40, 49, 46, 48, 43, 40, 40, 40, 40,118,104, 42, 40, -112, 43,118,104, 41, 41, 45, 49, 46, 48, 41, 42, 40, 40,118,104, 42, 40,112, 43,118,104, 41, 41, 45, 49, 46, 48, 41, 41, 47, 40, - 40, 40,118,104, 42, 40,112, 45,118,104, 41, 41, 43, 49, 46, 48, 41, 42, 40, 40,118,104, 42, 40,112, 45,118,104, 41, 41, 43, 49, - 46, 48, 41, 41, 41, 41, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, 97,110,103, 32, 61, 32, 97, 99,111,115, 40,110,104, 41, - 59, 10, 10, 9, 9, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,109, 97,120, 40,102, 42,103, 42,101,120,112, 95, 98,108,101, -110,100,101,114, 40, 40, 45, 40, 97,110,103, 42, 97,110,103, 41, 47, 40, 50, 46, 48, 42,115,112,101, 99, 95,112,111,119,101,114, - 42,115,112,101, 99, 95,112,111,119,101,114, 41, 41, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9, 9,125, 10, 9, 9,125, 10, 9, -125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,119, 97,114,100,105,115,111, 95,115,112,101, 99, 40,118,101, 99, - 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,114,109,115, 44, 32, -111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110, -111,114,109, 97,108,105,122,101, 40,108, 32, 43, 32,118, 41, 59, 10, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32,109, 97,120, - 40,100,111,116, 40,110, 44, 32,104, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32, -109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, 32,110,108, - 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,108, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, - 32, 97,110,103,108,101, 32, 61, 32,116, 97,110, 40, 97, 99,111,115, 40,110,104, 41, 41, 59, 10, 9,102,108,111, 97,116, 32, 97, -108,112,104, 97, 32, 61, 32,109, 97,120, 40,114,109,115, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 10, 9,115,112,101, 99,102, 97, - 99, 61, 32,110,108, 32, 42, 32, 40, 49, 46, 48, 47, 40, 52, 46, 48, 42, 77, 95, 80, 73, 42, 97,108,112,104, 97, 42, 97,108,112, -104, 97, 41, 41, 42, 40,101,120,112, 95, 98,108,101,110,100,101,114, 40, 45, 40, 97,110,103,108,101, 42, 97,110,103,108,101, 41, - 47, 40, 97,108,112,104, 97, 42, 97,108,112,104, 97, 41, 41, 47, 40,115,113,114,116, 40,110,118, 42,110,108, 41, 41, 41, 59, 10, -125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,116,111,111,110, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32, -118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,115,105,122,101, 44, 32,102,108,111, 97, -116, 32,116,115,109,111,111,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, - 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 43, 32,118, 41, 59, 10, 9,102,108,111, - 97,116, 32,114,115,108,116, 32, 61, 32,100,111,116, 40,104, 44, 32,110, 41, 59, 10, 9,102,108,111, 97,116, 32, 97,110,103, 32, - 61, 32, 97, 99,111,115, 40,114,115,108,116, 41, 59, 10, 10, 9,105,102, 40, 97,110,103, 32, 60, 32,115,105,122,101, 41, 32,114, -115,108,116, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 97,110,103, 32, 62, 61, 32, 40,115,105,122,101, - 32, 43, 32,116,115,109,111,111,116,104, 41, 32,124,124, 32,116,115,109,111,111,116,104, 32, 61, 61, 32, 48, 46, 48, 41, 32,114, -115,108,116, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,114,115,108,116, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 40, - 97,110,103, 32, 45, 32,115,105,122,101, 41, 47,116,115,109,111,111,116,104, 41, 59, 10, 10, 9,115,112,101, 99,102, 97, 99, 32, - 61, 32,114,115,108,116, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,115,112,101, 99, 95, 97,114,101, 97, 95, -105,110,112, 40,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 44, 32,102,108,111, 97,116, 32,105,110,112, 44, 32,111,117, -116, 32,102,108,111, 97,116, 32,111,117,116,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,111,117,116,115,112,101, 99,102, 97, - 99, 32, 61, 32,115,112,101, 99,102, 97, 99, 42,105,110,112, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,115, -112,101, 99, 95,116, 40,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,102,108,111, 97,116, 32,115,112,101, 99, 44, - 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 44, 32,111, -117,116, 32,102,108,111, 97,116, 32,116, 41, 10,123, 10, 9,116, 32, 61, 32,115,104, 97,100,102, 97, 99, 42,115,112,101, 99, 42, -118,105,115,105,102, 97, 99, 42,115,112,101, 99,102, 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97, -100,100, 95,115,112,101, 99, 40,102,108,111, 97,116, 32,116, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111,108, 44, 32,118, -101, 99, 51, 32,115,112,101, 99, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, - 9,111,117,116, 99,111,108, 32, 61, 32,116, 42,108, 97,109,112, 99,111,108, 42,115,112,101, 99, 99,111,108, 59, 10,125, 10, 10, -118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, 40,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99, -111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, - 61, 32, 99,111,108, 49, 32, 43, 32, 99,111,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, 97,100, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10, 9, 9,118,101, 99, 52, 32,118, 83, 97,109,112,108,101,115, 85, 76, 32, 61, 32,116, +101,120,116,117,114,101, 71, 97,116,104,101,114, 40,105,109, 97, 44, 32, 40,105, 84,101,120, 76,111, 99, 43,105,118,101, 99, 50, + 40, 45, 49, 44, 45, 49, 41, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 48, 46, 53, 41, 41, 47,118, 68,105,109, 32, 41, 59, + 10, 9, 9,118,101, 99, 52, 32,118, 83, 97,109,112,108,101,115, 85, 82, 32, 61, 32,116,101,120,116,117,114,101, 71, 97,116,104, +101,114, 40,105,109, 97, 44, 32, 40,105, 84,101,120, 76,111, 99, 43,105,118,101, 99, 50, 40, 49, 44, 45, 49, 41, 32, 43, 32,118, +101, 99, 50, 40, 48, 46, 53, 44, 48, 46, 53, 41, 41, 47,118, 68,105,109, 32, 41, 59, 10, 9, 9,118,101, 99, 52, 32,118, 83, 97, +109,112,108,101,115, 76, 76, 32, 61, 32,116,101,120,116,117,114,101, 71, 97,116,104,101,114, 40,105,109, 97, 44, 32, 40,105, 84, +101,120, 76,111, 99, 43,105,118,101, 99, 50, 40, 45, 49, 44, 49, 41, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 48, 46, 53, + 41, 41, 47,118, 68,105,109, 32, 41, 59, 10, 9, 9,118,101, 99, 52, 32,118, 83, 97,109,112,108,101,115, 76, 82, 32, 61, 32,116, +101,120,116,117,114,101, 71, 97,116,104,101,114, 40,105,109, 97, 44, 32, 40,105, 84,101,120, 76,111, 99, 43,105,118,101, 99, 50, + 40, 49, 44, 49, 41, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 48, 46, 53, 41, 41, 47,118, 68,105,109, 32, 41, 59, 10, 10, + 9, 9,109, 97,116, 52, 32, 72, 32, 61, 32,109, 97,116, 52, 40,118, 83, 97,109,112,108,101,115, 85, 76, 46,119, 44, 32,118, 83, + 97,109,112,108,101,115, 85, 76, 46,120, 44, 32,118, 83, 97,109,112,108,101,115, 76, 76, 46,119, 44, 32,118, 83, 97,109,112,108, +101,115, 76, 76, 46,120, 44, 10, 9, 9, 9, 9, 9,118, 83, 97,109,112,108,101,115, 85, 76, 46,122, 44, 32,118, 83, 97,109,112, +108,101,115, 85, 76, 46,121, 44, 32,118, 83, 97,109,112,108,101,115, 76, 76, 46,122, 44, 32,118, 83, 97,109,112,108,101,115, 76, + 76, 46,121, 44, 10, 9, 9, 9, 9, 9,118, 83, 97,109,112,108,101,115, 85, 82, 46,119, 44, 32,118, 83, 97,109,112,108,101,115, + 85, 82, 46,120, 44, 32,118, 83, 97,109,112,108,101,115, 76, 82, 46,119, 44, 32,118, 83, 97,109,112,108,101,115, 76, 82, 46,120, + 44, 10, 9, 9, 9, 9, 9,118, 83, 97,109,112,108,101,115, 85, 82, 46,122, 44, 32,118, 83, 97,109,112,108,101,115, 85, 82, 46, +121, 44, 32,118, 83, 97,109,112,108,101,115, 76, 82, 46,122, 44, 32,118, 83, 97,109,112,108,101,115, 76, 82, 46,121, 41, 59, 10, + 42, 47, 9, 10, 9, 9,105,118,101, 99, 50, 32,105, 84,101,120, 76,111, 99, 77,111,100, 32, 61, 32,105, 84,101,120, 76,111, 99, + 32, 43, 32,105,118,101, 99, 50, 40, 45, 49, 44, 32, 45, 49, 41, 59, 10, 10, 9, 9,109, 97,116, 52, 32, 72, 59, 10, 9, 9, 10, + 9, 9,102,111,114, 40,105,110,116, 32,105, 32, 61, 32, 48, 59, 32,105, 32, 60, 32, 52, 59, 32,105, 43, 43, 41,123, 10, 9, 9, + 9,102,111,114, 40,105,110,116, 32,106, 32, 61, 32, 48, 59, 32,106, 32, 60, 32, 52, 59, 32,106, 43, 43, 41,123, 10, 9, 9, 9, + 9,105,118,101, 99, 50, 32,105, 84,101,120, 84,109,112, 32, 61, 32,105, 84,101,120, 76,111, 99, 77,111,100, 32, 43, 32,105,118, +101, 99, 50, 40,105, 44,106, 41, 59, 10, 9, 9, 9, 9, 10, 9, 9, 9, 9, 47, 47, 32,119,114, 97,112, 32,116,101,120,116,117, +114,101, 32, 99,111,111,114,100,105,110, 97,116,101,115, 32,109, 97,110,117, 97,108,108,121, 32,102,111,114, 32,116,101,120,101, +108, 70,101,116, 99,104, 32,116,111, 32,119,111,114,107, 32,111,110, 32,117,118,115, 32,111,105,116,115,105,100,101, 32,116,104, +101, 32, 48, 44, 49, 32,114, 97,110,103,101, 46, 10, 9, 9, 9, 9, 47, 47, 32,116,104,105,115, 32,105,115, 32,103,117, 97,114, + 97,110,116,101,101,100, 32,116,111, 32,119,111,114,107, 32,115,105,110, 99,101, 32,119,101, 32,116, 97,107,101, 32,116,104,101, + 32,102,114, 97, 99,116,105,111,110, 97,108, 32,112, 97,114,116, 32,111,102, 32,116,104,101, 32,117,118, 32, 97, 98,111,118,101, + 46, 10, 9, 9, 9, 9,105, 84,101,120, 84,109,112, 46,120, 32, 61, 32, 40,105, 84,101,120, 84,109,112, 46,120, 32, 60, 32, 48, + 41, 63, 32,105, 84,101,120, 84,109,112, 46,120, 32, 43, 32,118, 68,105,109, 46,120, 32, 58, 32, 40, 40,105, 84,101,120, 84,109, +112, 46,120, 32, 62, 61, 32,118, 68,105,109, 46,120, 41, 63, 32,105, 84,101,120, 84,109,112, 46,120, 32, 45, 32,118, 68,105,109, + 46,120, 32, 58, 32,105, 84,101,120, 84,109,112, 46,120, 41, 59, 10, 9, 9, 9, 9,105, 84,101,120, 84,109,112, 46,121, 32, 61, + 32, 40,105, 84,101,120, 84,109,112, 46,121, 32, 60, 32, 48, 41, 63, 32,105, 84,101,120, 84,109,112, 46,121, 32, 43, 32,118, 68, +105,109, 46,121, 32, 58, 32, 40, 40,105, 84,101,120, 84,109,112, 46,121, 32, 62, 61, 32,118, 68,105,109, 46,121, 41, 63, 32,105, + 84,101,120, 84,109,112, 46,121, 32, 45, 32,118, 68,105,109, 46,121, 32, 58, 32,105, 84,101,120, 84,109,112, 46,121, 41, 59, 10, + 10, 9, 9, 9, 9,114,103, 98,116,111, 98,119, 40,116,101,120,101,108, 70,101,116, 99,104, 40,105,109, 97, 44, 32,105, 84,101, +120, 84,109,112, 44, 32, 48, 41, 44, 32, 72, 91,105, 93, 91,106, 93, 41, 59, 10, 9, 9, 9,125, 10, 9, 9,125, 10, 9, 9, 10, + 9, 9,102,108,111, 97,116, 32,120, 32, 61, 32,116, 46,120, 44, 32,121, 32, 61, 32,116, 46,121, 59, 10, 9, 9,102,108,111, 97, +116, 32,120, 50, 32, 61, 32,120, 32, 42, 32,120, 44, 32,120, 51, 32, 61, 32,120, 50, 32, 42, 32,120, 44, 32,121, 50, 32, 61, 32, +121, 32, 42, 32,121, 44, 32,121, 51, 32, 61, 32,121, 50, 32, 42, 32,121, 59, 10, 10, 9, 9,118,101, 99, 52, 32, 88, 32, 61, 32, +118,101, 99, 52, 40, 45, 48, 46, 53, 42, 40,120, 51, 43,120, 41, 43,120, 50, 44, 9, 9, 49, 46, 53, 42,120, 51, 45, 50, 46, 53, + 42,120, 50, 43, 49, 44, 9, 45, 49, 46, 53, 42,120, 51, 43, 50, 42,120, 50, 43, 48, 46, 53, 42,120, 44, 9, 9, 48, 46, 53, 42, + 40,120, 51, 45,120, 50, 41, 41, 59, 10, 9, 9,118,101, 99, 52, 32, 89, 32, 61, 32,118,101, 99, 52, 40, 45, 48, 46, 53, 42, 40, +121, 51, 43,121, 41, 43,121, 50, 44, 9, 9, 49, 46, 53, 42,121, 51, 45, 50, 46, 53, 42,121, 50, 43, 49, 44, 9, 45, 49, 46, 53, + 42,121, 51, 43, 50, 42,121, 50, 43, 48, 46, 53, 42,121, 44, 9, 9, 48, 46, 53, 42, 40,121, 51, 45,121, 50, 41, 41, 59, 10, 9, + 9,118,101, 99, 52, 32,100, 88, 32, 61, 32,118,101, 99, 52, 40, 45, 49, 46, 53, 42,120, 50, 43, 50, 42,120, 45, 48, 46, 53, 44, + 9, 9, 52, 46, 53, 42,120, 50, 45, 53, 42,120, 44, 9, 9, 9, 45, 52, 46, 53, 42,120, 50, 43, 52, 42,120, 43, 48, 46, 53, 44, + 9, 9, 49, 46, 53, 42,120, 50, 45,120, 41, 59, 10, 9, 9,118,101, 99, 52, 32,100, 89, 32, 61, 32,118,101, 99, 52, 40, 45, 49, + 46, 53, 42,121, 50, 43, 50, 42,121, 45, 48, 46, 53, 44, 9, 9, 52, 46, 53, 42,121, 50, 45, 53, 42,121, 44, 9, 9, 9, 45, 52, + 46, 53, 42,121, 50, 43, 52, 42,121, 43, 48, 46, 53, 44, 9, 9, 49, 46, 53, 42,121, 50, 45,121, 41, 59, 10, 9, 10, 9, 9, 47, + 47, 32, 99,111,109,112,108,101,116,101, 32,100,101,114,105,118, 97,116,105,118,101, 32,105,110, 32,110,111,114,109, 97,108,105, +122,101,100, 32, 99,111,111,114,100,105,110, 97,116,101,115, 32, 40,109,117,108, 32, 98,121, 32,118, 68,105,109, 41, 10, 9, 9, +118,101, 99, 50, 32,100, 72,100, 83, 84, 32, 61, 32,118, 68,105,109, 32, 42, 32,118,101, 99, 50, 40,100,111,116, 40, 89, 44, 32, + 72, 32, 42, 32,100, 88, 41, 44, 32,100,111,116, 40,100, 89, 44, 32, 72, 32, 42, 32, 88, 41, 41, 59, 10, 10, 9, 9, 47, 47, 32, +116,114, 97,110,115,102,111,114,109, 32,100,101,114,105,118, 97,116,105,118,101, 32,116,111, 32,115, 99,114,101,101,110, 45,115, +112, 97, 99,101, 10, 9, 9,118,101, 99, 50, 32,100, 72,100,120,121, 95, 98,105, 99,117, 98,105, 99, 32, 61, 32,118,101, 99, 50, + 40, 32,100, 72,100, 83, 84, 46,120, 32, 42, 32, 84,101,120, 68,120, 46,120, 32, 43, 32,100, 72,100, 83, 84, 46,121, 32, 42, 32, + 84,101,120, 68,120, 46,121, 44, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,100, 72,100, 83, 84, 46,120, 32, 42, 32, 84,101, +120, 68,121, 46,120, 32, 43, 32,100, 72,100, 83, 84, 46,121, 32, 42, 32, 84,101,120, 68,121, 46,121, 32, 41, 59, 10, 10, 9, 9, + 47, 47, 32, 98,108,101,110,100, 32, 98,101,116,119,101,101,110, 32,116,104,101, 32,116,119,111, 10, 9, 9,100, 72,100,120,121, + 32, 61, 32,100, 72,100,120,121, 42, 40, 49, 45,102, 66,108,101,110,100, 41, 32, 43, 32,100, 72,100,120,121, 95, 98,105, 99,117, + 98,105, 99, 42,102, 66,108,101,110,100, 59, 10, 9,125, 10, 10, 9,100, 66,115, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, +100, 72,100,120,121, 46,120, 59, 10, 9,100, 66,116, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32,100, 72,100,120,121, 46,121, + 59, 10,125, 10, 10, 35,101,110,100,105,102, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,116, 97,112, 53, + 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, + 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, + 10,123, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 59, + 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 10, + 9,118,101, 99, 50, 32, 83, 84, 99, 32, 61, 32,116,101,120, 99,111, 46,120,121, 59, 10, 9,118,101, 99, 50, 32, 83, 84,108, 32, + 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, + 32, 83, 84,114, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, + 9,118,101, 99, 50, 32, 83, 84,100, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, + 68,121, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,117, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, + 42, 32, 84,101,120, 68,121, 32, 59, 10, 9, 10, 9,102,108,111, 97,116, 32, 72, 99, 44, 72,108, 44, 72,114, 44, 72,100, 44, 72, +117, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84, 99, 41, + 44, 32, 72, 99, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, + 32, 83, 84,108, 41, 44, 32, 72,108, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, + 40,105,109, 97, 44, 32, 83, 84,114, 41, 44, 32, 72,114, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116, +117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,100, 41, 44, 32, 72,100, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, + 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,117, 41, 44, 32, 72,117, 32, 41, 59, 10, 9, 10, 9,100, + 66,115, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,114, 32, 45, 32, 72,108, 41, 59, 10, 9,100, 66,116, 32, 61, 32, +104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,117, 32, 45, 32, 72,100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95, 98,117,109,112, 95,100,101,114,105,118, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, + 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,120, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,121, + 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, + 66,116, 32, 41, 32, 10,123, 10, 9,102,108,111, 97,116, 32,115, 32, 61, 32, 49, 46, 48, 59, 9, 9, 47, 47, 32,110,101,103, 97, +116,101, 32,116,104,105,115, 32,105,102, 32,102,108,105,112,112,101,100, 32,116,101,120,116,117,114,101, 32, 99,111,111,114,100, +105,110, 97,116,101, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120, +121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, + 59, 10, 9, 10, 9, 47, 47, 32,116,104,105,115, 32,118, 97,114,105, 97,110,116, 32,117,115,105,110,103, 32, 97, 32,100,101,114, +105,118, 97,116,105,118,101, 32,109, 97,112, 32,105,115, 32,100,101,115, 99,114,105, 98,101,100, 32,104,101,114,101, 10, 9, 47, + 47, 32,104,116,116,112, 58, 47, 47,109,109,105,107,107,101,108,115,101,110, 51,100, 46, 98,108,111,103,115,112,111,116, 46, 99, +111,109, 47, 50, 48, 49, 49, 47, 48, 55, 47,100,101,114,105,118, 97,116,105,118,101, 45,109, 97,112,115, 46,104,116,109,108, 10, + 9,118,101, 99, 50, 32,100,105,109, 32, 61, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 44, 32,105,109, 97, 95,121, 41, 59, 10, + 9,118,101, 99, 50, 32,100, 66,100,117,118, 32, 61, 32,104, 83, 99, 97,108,101, 42,100,105,109, 42, 40, 50, 46, 48, 42,116,101, +120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 46,120,121, 45, 49, 46, 48, 41, 59, 10, + 9, 10, 9,100, 66,115, 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84,101,120, 68,120, 46,120, 32, 43, 32,115, 42,100, 66,100, +117,118, 46,121, 42, 84,101,120, 68,120, 46,121, 59, 10, 9,100, 66,116, 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84,101,120, + 68,121, 46,120, 32, 43, 32,115, 42,100, 66,100,117,118, 46,121, 42, 84,101,120, 68,121, 46,121, 59, 10,125, 10, 10,118,111,105, +100, 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, 40, 32,102,108,111, 97,116, 32,102, 68,101,116, 44, 32,102, +108,111, 97,116, 32,100, 66,115, 44, 32,102,108,111, 97,116, 32,100, 66,116, 44, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,118, +101, 99, 51, 32,118, 82, 50, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 32, 32,111, +117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112,101,114,116, +117,114, 98,101,100, 95,110,111,114,109, 32, 41, 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83,117,114,102, 71,114, 97,100, 32, + 61, 32,115,105,103,110, 40,102, 68,101,116, 41, 32, 42, 32, 40, 32,100, 66,115, 32, 42, 32,118, 82, 49, 32, 43, 32,100, 66,116, + 32, 42, 32,118, 82, 50, 32, 41, 59, 10, 9, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105, +110, 32, 45, 32,118, 83,117,114,102, 71,114, 97,100, 59, 10, 9,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 61, + 32,110,111,114,109, 97,108,105,122,101, 40, 32,118, 78, 97, 99, 99, 95,111,117,116, 32, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, 95,116,101,120,115,112, 97, 99,101, 40, 32,102,108,111, 97,116, + 32,102, 68,101,116, 44, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,102,108,111, 97,116, 32,100, 66,116, 44, 32,118,101, 99, + 51, 32,118, 82, 49, 44, 32,118,101, 99, 51, 32,118, 82, 50, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,118, +101, 99, 51, 32,116,101,120, 99,111, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,120, 44, 32,102,108,111, 97,116, 32,105,109, + 97, 95,121, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117, +116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112,101,114,116,117, +114, 98,101,100, 95,110,111,114,109, 32, 41, 32, 10,123, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100, +120, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40, +116,101,120, 99,111, 46,120,121, 41, 59, 10, 10, 9,118,101, 99, 51, 32,118, 83,117,114,102, 71,114, 97,100, 32, 61, 32,115,105, +103,110, 40,102, 68,101,116, 41, 32, 42, 32, 40, 32, 10, 9, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,100, 66,115, 32, 47, + 32,108,101,110,103,116,104, 40, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 42, 84,101,120, 68,120, 46,120, 44, 32,105,109, 97, + 95,121, 42, 84,101,120, 68,120, 46,121, 41, 32, 41, 32, 42, 32,118, 82, 49, 32, 43, 32, 10, 9, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,100, 66,116, 32, 47, 32,108,101,110,103,116,104, 40, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 42, 84,101,120, + 68,121, 46,120, 44, 32,105,109, 97, 95,121, 42, 84,101,120, 68,121, 46,121, 41, 32, 41, 32, 42, 32,118, 82, 50, 32, 41, 59, 10, + 9, 9, 9, 9, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 45, 32,118, 83,117, +114,102, 71,114, 97,100, 59, 10, 9,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 61, 32,110,111,114,109, 97,108, +105,122,101, 40, 32,118, 78, 97, 99, 99, 95,111,117,116, 32, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110, +101,103, 97,116,101, 95,116,101,120,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, + 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32, +118,101, 99, 51, 40, 45,110,111,114,109, 97,108, 46,120, 44, 32, 45,110,111,114,109, 97,108, 46,121, 44, 32,110,111,114,109, 97, +108, 46,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,115,112, 97, 99,101, 95,116, 97,110,103,101,110, +116, 40,118,101, 99, 52, 32,116, 97,110,103,101,110,116, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118,101, 99, + 51, 32,116,101,120,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, + 10,123, 10, 9,118,101, 99, 51, 32, 66, 32, 61, 32,116, 97,110,103,101,110,116, 46,119, 32, 42, 32, 99,114,111,115,115, 40,110, +111,114,109, 97,108, 44, 32,116, 97,110,103,101,110,116, 46,120,121,122, 41, 59, 10, 10, 9,111,117,116,110,111,114,109, 97,108, + 32, 61, 32,116,101,120,110,111,114,109, 97,108, 46,120, 42,116, 97,110,103,101,110,116, 46,120,121,122, 32, 43, 32,116,101,120, +110,111,114,109, 97,108, 46,121, 42, 66, 32, 43, 32,116,101,120,110,111,114,109, 97,108, 46,122, 42,110,111,114,109, 97,108, 59, + 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,110,111,114,109, 97, +108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,108,101,110,100, 95,110,111,114,109, 97,108, 40,102,108, +111, 97,116, 32,110,111,114,102, 97, 99, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118,101, 99, 51, 32,110,101, +119,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, +111,117,116,110,111,114,109, 97,108, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32,110,111,114,102, 97, 99, 41, 42,110,111,114,109, 97, +108, 32, 43, 32,110,111,114,102, 97, 99, 42,110,101,119,110,111,114,109, 97,108, 59, 10, 9,111,117,116,110,111,114,109, 97,108, + 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, + 42, 42, 42, 42, 32, 77, 65, 84, 69, 82, 73, 65, 76, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,108, + 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,117,110, 95,104,101,109,105, 40,118,101, 99, 51, 32,108, 97,109, +112,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100,105,115, +116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, 32,108, 97, +109,112,118,101, 99, 59, 10, 9,100,105,115,116, 32, 61, 32, 49, 46, 48, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32, 49, + 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,111,116,104,101, +114, 40,118,101, 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, + 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, +105,115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, 32, 99,111, 32, 45, 32,108, 97,109,112, 99,111, 59, 10, 9,100,105, +115,116, 32, 61, 32,108,101,110,103,116,104, 40,108,118, 41, 59, 10, 9,108,118, 32, 61, 32,110,111,114,109, 97,108,105,122,101, + 40,108,118, 41, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97, +109,112, 95,102, 97,108,108,111,102,102, 95,105,110,118,108,105,110,101, 97,114, 40,102,108,111, 97,116, 32,108, 97,109,112,100, +105,115,116, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, + 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100, +105,115,116, 32, 43, 32,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102, +102, 95,105,110,118,115,113,117, 97,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97, +116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105, +115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,100,105,115, +116, 42,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,115,108, +105,100,101,114,115, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,108,100, 49, 44, + 32,102,108,111, 97,116, 32,108,100, 50, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97, +116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116,107,119, 32, 61, + 32,108, 97,109,112,100,105,115,116, 42,108, 97,109,112,100,105,115,116, 59, 10, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32, +108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,108,100, 49, 42,100,105,115,116, 41, 59, 10, + 9,118,105,115,105,102, 97, 99, 32, 42, 61, 32,108, 97,109,112,100,105,115,116,107,119, 47, 40,108, 97,109,112,100,105,115,116, +107,119, 32, 43, 32,108,100, 50, 42,100,105,115,116, 42,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109, +112, 95,102, 97,108,108,111,102,102, 95, 99,117,114,118,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32, +115, 97,109,112,108,101,114, 50, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32, +111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32, +116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,100,105,115,116, 47,108, 97, +109,112,100,105,115,116, 44, 32, 48, 46, 48, 41, 41, 46,120, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105, +115,105, 98,105,108,105,116,121, 95,115,112,104,101,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32, +102,108,111, 97,116, 32,100,105,115,116, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102, +108,111, 97,116, 32,111,117,116,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116, 61, 32,108, 97,109, +112,100,105,115,116, 32, 45, 32,100,105,115,116, 59, 10, 10, 9,111,117,116,118,105,115,105,102, 97, 99, 61, 32,118,105,115,105, +102, 97, 99, 42,109, 97,120, 40,116, 44, 32, 48, 46, 48, 41, 47,108, 97,109,112,100,105,115,116, 59, 10,125, 10, 10,118,111,105, +100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 95,115,113,117, 97,114,101, 40,118,101, + 99, 51, 32,108, 97,109,112,118,101, 99, 44, 32,109, 97,116, 52, 32,108, 97,109,112,105,109, 97,116, 44, 32,118,101, 99, 51, 32, +108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112,114, 41, 10,123, 10, 9,105,102, 40,100,111,116, 40,108,118, + 44, 32,108, 97,109,112,118,101, 99, 41, 32, 62, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,118,101, 99, 51, 32,108,118,114,111,116, + 32, 61, 32, 40,108, 97,109,112,105,109, 97,116, 42,118,101, 99, 52, 40,108,118, 44, 32, 48, 46, 48, 41, 41, 46,120,121,122, 59, + 10, 9, 9,102,108,111, 97,116, 32,120, 32, 61, 32,109, 97,120, 40, 97, 98,115, 40,108,118,114,111,116, 46,120, 47,108,118,114, +111,116, 46,122, 41, 44, 32, 97, 98,115, 40,108,118,114,111,116, 46,121, 47,108,118,114,111,116, 46,122, 41, 41, 59, 10, 10, 9, + 9,105,110,112,114, 32, 61, 32, 49, 46, 48, 47,115,113,114,116, 40, 49, 46, 48, 32, 43, 32,120, 42,120, 41, 59, 10, 9,125, 10, + 9,101,108,115,101, 10, 9, 9,105,110,112,114, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, + 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 95, 99,105,114, 99,108,101, 40,118,101, 99, 51, 32,108, 97,109, +112,118,101, 99, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112,114, 41, 10,123, + 10, 9,105,110,112,114, 32, 61, 32,100,111,116, 40,108,118, 44, 32,108, 97,109,112,118,101, 99, 41, 59, 10,125, 10, 10,118,111, +105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 40,102,108,111, 97,116, 32,115,112, +111,116,115,105, 44, 32,102,108,111, 97,116, 32,115,112,111,116, 98,108, 44, 32,102,108,111, 97,116, 32,105,110,112,114, 44, 32, +102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118,105,115,105, +102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116, 32, 61, 32,115,112,111,116,115,105, 59, 10, 10, 9,105,102, 40,105, +110,112,114, 32, 60, 61, 32,116, 41, 32,123, 10, 9, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, + 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,116, 32, 61, 32,105,110,112,114, 32, 45, 32,116, 59, 10, 10, 9, 9, 47, 42, + 32,115,111,102,116, 32, 97,114,101, 97, 32, 42, 47, 10, 9, 9,105,102, 40,115,112,111,116, 98,108, 32, 33, 61, 32, 48, 46, 48, + 41, 10, 9, 9, 9,105,110,112,114, 32, 42, 61, 32,115,109,111,111,116,104,115,116,101,112, 40, 48, 46, 48, 44, 32, 49, 46, 48, + 44, 32,116, 47,115,112,111,116, 98,108, 41, 59, 10, 10, 9, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, 32,118,105,115, +105,102, 97, 99, 42,105,110,112,114, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98, +105,108,105,116,121, 95, 99,108, 97,109,112, 40,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102, +108,111, 97,116, 32,111,117,116,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, + 32, 40,118,105,115,105,102, 97, 99, 32, 60, 32, 48, 46, 48, 48, 49, 41, 63, 32, 48, 46, 48, 58, 32,118,105,115,105,102, 97, 99, + 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,118,105,101,119, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117, +116, 32,118,101, 99, 51, 32,118,105,101,119, 41, 10,123, 10, 9, 47, 42, 32,104, 97,110,100,108,101, 32,112,101,114,115,112,101, + 99,116,105,118,101, 47,111,114,116,104,111,103,114, 97,112,104,105, 99, 32, 42, 47, 10, 9,118,105,101,119, 32, 61, 32, 40,103, +108, 95, 80,114,111,106,101, 99,116,105,111,110, 77, 97,116,114,105,120, 91, 51, 93, 91, 51, 93, 32, 61, 61, 32, 48, 46, 48, 41, + 63, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 41, 58, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, + 45, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,116, 97,110,103,101,110,116, 95,118, 40,118, +101, 99, 51, 32,108,118, 44, 32,118,101, 99, 51, 32,116, 97,110,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,110, 41, 10, +123, 10, 9,118,101, 99, 51, 32, 99, 32, 61, 32, 99,114,111,115,115, 40,108,118, 44, 32,116, 97,110,103, 41, 59, 10, 9,118,101, + 99, 51, 32,118,110,111,114, 32, 61, 32, 99,114,111,115,115, 40, 99, 44, 32,116, 97,110,103, 41, 59, 10, 10, 9,118,110, 32, 61, + 32, 45,110,111,114,109, 97,108,105,122,101, 40,118,110,111,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, + 95,105,110,112, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, + 32,105,110,112, 41, 10,123, 10, 9,105,110,112, 32, 61, 32,100,111,116, 40,118,110, 44, 32,108,118, 41, 59, 10,125, 10, 10,118, +111,105,100, 32,115,104, 97,100,101, 95,105,115, 95,110,111, 95,100,105,102,102,117,115,101, 40,111,117,116, 32,102,108,111, 97, +116, 32,105,115, 41, 10,123, 10, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, + 95,105,115, 95,104,101,109,105, 40,102,108,111, 97,116, 32,105,110,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, + 41, 10,123, 10, 9,105,115, 32, 61, 32, 48, 46, 53, 42,105,110,112, 32, 43, 32, 48, 46, 53, 59, 10,125, 10, 10,102,108,111, 97, +116, 32, 97,114,101, 97, 95,108, 97,109,112, 95,101,110,101,114,103,121, 40,109, 97,116, 52, 32, 97,114,101, 97, 44, 32,118,101, + 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,118,110, 41, 10,123, 10, 9,118,101, 99, 51, 32,118,101, 99, 91, 52, 93, 44, 32, + 99, 91, 52, 93, 59, 10, 9,102,108,111, 97,116, 32,114, 97,100, 91, 52, 93, 44, 32,102, 97, 99, 59, 10, 9, 10, 9,118,101, 99, + 91, 48, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 48, 93, 46,120,121,122, + 41, 59, 10, 9,118,101, 99, 91, 49, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, + 91, 49, 93, 46,120,121,122, 41, 59, 10, 9,118,101, 99, 91, 50, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, + 32, 45, 32, 97,114,101, 97, 91, 50, 93, 46,120,121,122, 41, 59, 10, 9,118,101, 99, 91, 51, 93, 32, 61, 32,110,111,114,109, 97, +108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 51, 93, 46,120,121,122, 41, 59, 10, 10, 9, 99, 91, 48, 93, 32, 61, + 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 48, 93, 44, 32,118,101, 99, 91, 49, 93, 41, + 41, 59, 10, 9, 99, 91, 49, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 49, + 93, 44, 32,118,101, 99, 91, 50, 93, 41, 41, 59, 10, 9, 99, 91, 50, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99, +114,111,115,115, 40,118,101, 99, 91, 50, 93, 44, 32,118,101, 99, 91, 51, 93, 41, 41, 59, 10, 9, 99, 91, 51, 93, 32, 61, 32,110, +111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 51, 93, 44, 32,118,101, 99, 91, 48, 93, 41, 41, 59, + 10, 10, 9,114, 97,100, 91, 48, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 48, 93, 44, 32,118,101, 99, + 91, 49, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 49, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 49, 93, + 44, 32,118,101, 99, 91, 50, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 50, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118, +101, 99, 91, 50, 93, 44, 32,118,101, 99, 91, 51, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 51, 93, 32, 61, 32, 97, 99,111,115, 40, +100,111,116, 40,118,101, 99, 91, 51, 93, 44, 32,118,101, 99, 91, 48, 93, 41, 41, 59, 10, 10, 9,102, 97, 99, 61, 32, 32,114, 97, +100, 91, 48, 93, 42,100,111,116, 40,118,110, 44, 32, 99, 91, 48, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 49, + 93, 42,100,111,116, 40,118,110, 44, 32, 99, 91, 49, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 50, 93, 42,100, +111,116, 40,118,110, 44, 32, 99, 91, 50, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 51, 93, 42,100,111,116, 40, +118,110, 44, 32, 99, 91, 51, 93, 41, 59, 10, 10, 9,114,101,116,117,114,110, 32,109, 97,120, 40,102, 97, 99, 44, 32, 48, 46, 48, + 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,105,110,112, 95, 97,114,101, 97, 40,118,101, 99, 51, 32,112, +111,115,105,116,105,111,110, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111, 44, 32,118,101, 99, 51, 32,108, 97,109,112,118, +101, 99, 44, 32,118,101, 99, 51, 32,118,110, 44, 32,109, 97,116, 52, 32, 97,114,101, 97, 44, 32,102,108,111, 97,116, 32, 97,114, +101, 97,115,105,122,101, 44, 32,102,108,111, 97,116, 32,107, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112, 41, 10, +123, 10, 9,118,101, 99, 51, 32, 99,111, 32, 61, 32,112,111,115,105,116,105,111,110, 59, 10, 9,118,101, 99, 51, 32,118,101, 99, + 32, 61, 32, 99,111, 32, 45, 32,108, 97,109,112, 99,111, 59, 10, 10, 9,105,102, 40,100,111,116, 40,118,101, 99, 44, 32,108, 97, +109,112,118,101, 99, 41, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,110,112, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, + 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,105,110,116,101,110,115, 32, 61, 32, 97,114,101, 97, 95,108, 97, +109,112, 95,101,110,101,114,103,121, 40, 97,114,101, 97, 44, 32, 99,111, 44, 32,118,110, 41, 59, 10, 10, 9, 9,105,110,112, 32, + 61, 32,112,111,119, 40,105,110,116,101,110,115, 42, 97,114,101, 97,115,105,122,101, 44, 32,107, 41, 59, 10, 9,125, 10,125, 10, + 10,118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,111,114,101,110, 95,110, 97,121,101,114, 40,102, +108,111, 97,116, 32,110,108, 44, 32,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, + 32,102,108,111, 97,116, 32,114,111,117,103,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,118, +101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32,108, 41, 59, 10, 9,102,108,111, 97,116, + 32,110,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,104, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9,102,108,111, 97, +116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9,102,108,111, + 97,116, 32,114,101, 97,108,110,108, 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 10, 9,105,102, 40,114,101, 97,108, +110,108, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, + 32,105,102, 40,110,108, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9, +101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,118,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,118, 44, 32,104, + 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 76,105,116, 95, 65, 32, 61, 32, 97, 99,111,115, 40,114,101, + 97,108,110,108, 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 86,105,101,119, 95, 65, 32, 61, 32, 97, 99,111,115, 40,110,118, 41, + 59, 10, 10, 9, 9,118,101, 99, 51, 32, 76,105,116, 95, 66, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 45, 32, +114,101, 97,108,110,108, 42,110, 41, 59, 10, 9, 9,118,101, 99, 51, 32, 86,105,101,119, 95, 66, 32, 61, 32,110,111,114,109, 97, +108,105,122,101, 40,118, 32, 45, 32,110,118, 42,110, 41, 59, 10, 10, 9, 9,102,108,111, 97,116, 32,116, 32, 61, 32,109, 97,120, + 40,100,111,116, 40, 76,105,116, 95, 66, 44, 32, 86,105,101,119, 95, 66, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, 9, 9,102,108, +111, 97,116, 32, 97, 44, 32, 98, 59, 10, 10, 9, 9,105,102, 40, 76,105,116, 95, 65, 32, 62, 32, 86,105,101,119, 95, 65, 41, 32, +123, 10, 9, 9, 9, 97, 32, 61, 32, 76,105,116, 95, 65, 59, 10, 9, 9, 9, 98, 32, 61, 32, 86,105,101,119, 95, 65, 59, 10, 9, + 9,125, 10, 9, 9,101,108,115,101, 32,123, 10, 9, 9, 9, 97, 32, 61, 32, 86,105,101,119, 95, 65, 59, 10, 9, 9, 9, 98, 32, + 61, 32, 76,105,116, 95, 65, 59, 10, 9, 9,125, 10, 10, 9, 9,102,108,111, 97,116, 32, 65, 32, 61, 32, 49, 46, 48, 32, 45, 32, + 40, 48, 46, 53, 42, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 47, 40, 40,114,111,117,103,104, 42,114,111,117,103, +104, 41, 32, 43, 32, 48, 46, 51, 51, 41, 41, 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 66, 32, 61, 32, 48, 46, 52, 53, 42, 40, + 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 47, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 32, 43, 32, 48, + 46, 48, 57, 41, 41, 59, 10, 10, 9, 9, 98, 32, 42, 61, 32, 48, 46, 57, 53, 59, 10, 9, 9,105,115, 32, 61, 32,110,108, 42, 40, + 65, 32, 43, 32, 40, 66, 32, 42, 32,116, 32, 42, 32,115,105,110, 40, 97, 41, 32, 42, 32,116, 97,110, 40, 98, 41, 41, 41, 59, 10, + 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,116,111,111,110, 40,118,101, + 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,115,105,122,101, + 44, 32,102,108,111, 97,116, 32,116,115,109,111,111,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, + 10, 9,102,108,111, 97,116, 32,114,115,108,116, 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 9,102,108,111, 97,116, + 32, 97,110,103, 32, 61, 32, 97, 99,111,115, 40,114,115,108,116, 41, 59, 10, 10, 9,105,102, 40, 97,110,103, 32, 60, 32,115,105, +122,101, 41, 32,105,115, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 97,110,103, 32, 62, 32, 40,115,105, +122,101, 32, 43, 32,116,115,109,111,111,116,104, 41, 32,124,124, 32,116,115,109,111,111,116,104, 32, 61, 61, 32, 48, 46, 48, 41, + 32,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,115, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 40, 97,110, +103, 32, 45, 32,115,105,122,101, 41, 47,116,115,109,111,111,116,104, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100, +101, 95,100,105,102,102,117,115,101, 95,109,105,110,110, 97,101,114,116, 40,102,108,111, 97,116, 32,110,108, 44, 32,118,101, 99, + 51, 32,110, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,100, 97,114,107,110,101,115,115, 44, 32,111,117,116, + 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,105,102, 40,110,108, 32, 60, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9, +105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,110,118, 32, + 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, 9, 9,105,102, 40,100, 97,114, +107,110,101,115,115, 32, 60, 61, 32, 49, 46, 48, 41, 10, 9, 9, 9,105,115, 32, 61, 32,110,108, 42,112,111,119, 40,109, 97,120, + 40,110,118, 42,110,108, 44, 32, 48, 46, 49, 41, 44, 32,100, 97,114,107,110,101,115,115, 32, 45, 32, 49, 46, 48, 41, 59, 10, 9, + 9,101,108,115,101, 10, 9, 9, 9,105,115, 32, 61, 32,110,108, 42,112,111,119, 40, 49, 46, 48, 48, 48, 49, 32, 45, 32,110,118, + 44, 32,100, 97,114,107,110,101,115,115, 32, 45, 32, 49, 46, 48, 41, 59, 10, 9,125, 10,125, 10, 10,102,108,111, 97,116, 32,102, +114,101,115,110,101,108, 95,102, 97, 99, 40,118,101, 99, 51, 32,118,105,101,119, 44, 32,118,101, 99, 51, 32,118,110, 44, 32,102, +108,111, 97,116, 32,103,114, 97,100, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116, + 49, 44, 32,116, 50, 59, 10, 9,102,108,111, 97,116, 32,102,102, 97, 99, 59, 10, 10, 9,105,102, 40,102, 97, 99, 61, 61, 48, 46, + 48, 41, 32,123, 10, 9, 9,102,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9, +116, 49, 61, 32,100,111,116, 40,118,105,101,119, 44, 32,118,110, 41, 59, 10, 9, 9,105,102, 40,116, 49, 62, 48, 46, 48, 41, 32, + 32,116, 50, 61, 32, 49, 46, 48, 43,116, 49, 59, 10, 9, 9,101,108,115,101, 32,116, 50, 61, 32, 49, 46, 48, 45,116, 49, 59, 10, + 10, 9, 9,116, 50, 61, 32,103,114, 97,100, 32, 43, 32, 40, 49, 46, 48, 45,103,114, 97,100, 41, 42,112,111,119, 40,116, 50, 44, + 32,102, 97, 99, 41, 59, 10, 10, 9, 9,105,102, 40,116, 50, 60, 48, 46, 48, 41, 32,102,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, + 10, 9, 9,101,108,115,101, 32,105,102, 40,116, 50, 62, 49, 46, 48, 41, 32,102,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10, 9, + 9,101,108,115,101, 32,102,102, 97, 99, 32, 61, 32,116, 50, 59, 10, 9,125, 10, 10, 9,114,101,116,117,114,110, 32,102,102, 97, + 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,102,114,101,115,110,101,108, + 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,102,108, +111, 97,116, 32,102, 97, 99, 95,105, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, +105,115, 41, 10,123, 10, 9,105,115, 32, 61, 32,102,114,101,115,110,101,108, 95,102, 97, 99, 40,108,118, 44, 32,118,110, 44, 32, +102, 97, 99, 95,105, 44, 32,102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 99,117, 98,105, 99, + 40,102,108,111, 97,116, 32,105,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105,115, 41, 10,123, 10, 9,105, +102, 40,105,115, 62, 48, 46, 48, 32, 38, 38, 32,105,115, 60, 49, 46, 48, 41, 10, 9, 9,111,117,116,105,115, 61, 32,115,109,111, +111,116,104,115,116,101,112, 40, 48, 46, 48, 44, 32, 49, 46, 48, 44, 32,105,115, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111, +117,116,105,115, 61, 32,105,115, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,118,105,115,105,102, 97, 99, 40, +102,108,111, 97,116, 32,105, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,102,108,111, 97,116, 32,114,101, +102,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105, 41, 10,123, 10, 9, 47, 42,105,102, 40,105, 32, 62, 32, + 48, 46, 48, 41, 42, 47, 10, 9, 9,111,117,116,105, 32, 61, 32,109, 97,120, 40,105, 42,118,105,115,105,102, 97, 99, 42,114,101, +102,108, 44, 32, 48, 46, 48, 41, 59, 10, 9, 47, 42,101,108,115,101, 10, 9, 9,111,117,116,105, 32, 61, 32,105, 59, 42, 47, 10, +125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,116, 97,110,103,101,110,116, 95,118, 95,115,112,101, 99, 40,118,101, 99, + 51, 32,116, 97,110,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,110, 41, 10,123, 10, 9,118,110, 32, 61, 32,116, 97,110, +103, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, 95,116,111, 95,100,105,102,102,117,115,101, 40, +102,108,111, 97,116, 32,105, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111,108, 44, 32,118,101, 99, 51, 32, 99,111,108, 44, + 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,105,102, 40,105, 32, 62, 32, 48, 46, 48, 41, + 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,105, 42,108, 97,109,112, 99,111,108, 42, 99,111,108, 59, 10, 9,101,108,115,101, + 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 41, 59, + 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,104,101,109,105, 95,115,112,101, 99, 40,118,101, 99, 51, 32,118,110, + 44, 32,118,101, 99, 51, 32,108,118, 44, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,102,108,111, 97,116, 32,115,112,101, 99, + 44, 32,102,108,111, 97,116, 32,104, 97,114,100, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, + 32,102,108,111, 97,116, 32,116, 41, 10,123, 10, 9,108,118, 32, 43, 61, 32,118,105,101,119, 59, 10, 9,108,118, 32, 61, 32,110, +111,114,109, 97,108,105,122,101, 40,108,118, 41, 59, 10, 10, 9,116, 32, 61, 32,100,111,116, 40,118,110, 44, 32,108,118, 41, 59, + 10, 9,116, 32, 61, 32, 48, 46, 53, 42,116, 32, 43, 32, 48, 46, 53, 59, 10, 10, 9,116, 32, 61, 32,118,105,115,105,102, 97, 99, + 42,115,112,101, 99, 42,112,111,119, 40,116, 44, 32,104, 97,114,100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100, +101, 95,112,104,111,110,103, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, + 51, 32,118, 44, 32,102,108,111, 97,116, 32,104, 97,114,100, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, + 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 43, 32,118, 41, + 59, 10, 9,102,108,111, 97,116, 32,114,115,108,116, 32, 61, 32,109, 97,120, 40,100,111,116, 40,104, 44, 32,110, 41, 44, 32, 48, + 46, 48, 41, 59, 10, 10, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,112,111,119, 40,114,115,108,116, 44, 32,104, 97,114,100, 41, + 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 99,111,111,107,116,111,114,114, 95,115,112,101, 99, 40,118,101, + 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,104, 97,114,100, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, + 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32,108, 41, 59, 10, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32,100, +111,116, 40,110, 44, 32,104, 41, 59, 10, 10, 9,105,102, 40,110,104, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,115,112,101, + 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,110, +118, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9,102,108,111, 97,116, + 32,105, 32, 61, 32,112,111,119, 40,110,104, 44, 32,104, 97,114,100, 41, 59, 10, 10, 9, 9,105, 32, 61, 32,105, 47, 40, 48, 46, + 49, 43,110,118, 41, 59, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,105, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, + 32,115,104, 97,100,101, 95, 98,108,105,110,110, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, + 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,114,101,102,114, 97, 99, 44, 32,102,108,111, 97,116, 32,115,112, +101, 99, 95,112,111,119,101,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9, +105,102, 40,114,101,102,114, 97, 99, 32, 60, 32, 49, 46, 48, 41, 32,123, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, + 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,105,102, 40,115,112,101, 99, 95,112,111,119,101,114, 32, 61, 61, 32, 48, 46, + 48, 41, 32,123, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, + 10, 9, 9,105,102, 40,115,112,101, 99, 95,112,111,119,101,114, 60, 49, 48, 48, 46, 48, 41, 10, 9, 9, 9,115,112,101, 99, 95, +112,111,119,101,114, 61, 32,115,113,114,116, 40, 49, 46, 48, 47,115,112,101, 99, 95,112,111,119,101,114, 41, 59, 10, 9, 9,101, +108,115,101, 10, 9, 9, 9,115,112,101, 99, 95,112,111,119,101,114, 61, 32, 49, 48, 46, 48, 47,115,112,101, 99, 95,112,111,119, +101,114, 59, 10, 10, 9, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32,108, 41, + 59, 10, 9, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32,100,111,116, 40,110, 44, 32,104, 41, 59, 10, 9, 9,105,102, 40,110, +104, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9,125, + 10, 9, 9,101,108,115,101, 32,123, 10, 9, 9, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116, 40, +110, 44, 32,118, 41, 44, 32, 48, 46, 48, 49, 41, 59, 10, 9, 9, 9,102,108,111, 97,116, 32,110,108, 32, 61, 32,100,111,116, 40, +110, 44, 32,108, 41, 59, 10, 9, 9, 9,105,102, 40,110,108, 32, 60, 61, 32, 48, 46, 48, 49, 41, 32,123, 10, 9, 9, 9, 9,115, +112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9, 9,125, 10, 9, 9, 9,101,108,115,101, 32,123, 10, 9, 9, 9, + 9,102,108,111, 97,116, 32,118,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,118, 44, 32,104, 41, 44, 32, 48, 46, 48, 49, 41, + 59, 10, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, 97, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, + 98, 32, 61, 32, 40, 50, 46, 48, 42,110,104, 42,110,118, 41, 47,118,104, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, 99, 32, + 61, 32, 40, 50, 46, 48, 42,110,104, 42,110,108, 41, 47,118,104, 59, 10, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,103, 32, 61, + 32, 48, 46, 48, 59, 10, 10, 9, 9, 9, 9,105,102, 40, 97, 32, 60, 32, 98, 32, 38, 38, 32, 97, 32, 60, 32, 99, 41, 32,103, 32, + 61, 32, 97, 59, 10, 9, 9, 9, 9,101,108,115,101, 32,105,102, 40, 98, 32, 60, 32, 97, 32, 38, 38, 32, 98, 32, 60, 32, 99, 41, + 32,103, 32, 61, 32, 98, 59, 10, 9, 9, 9, 9,101,108,115,101, 32,105,102, 40, 99, 32, 60, 32, 97, 32, 38, 38, 32, 99, 32, 60, + 32, 98, 41, 32,103, 32, 61, 32, 99, 59, 10, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,112, 32, 61, 32,115,113,114,116, 40, 40, + 40,114,101,102,114, 97, 99, 32, 42, 32,114,101,102,114, 97, 99, 41, 43, 40,118,104, 42,118,104, 41, 45, 49, 46, 48, 41, 41, 59, + 10, 9, 9, 9, 9,102,108,111, 97,116, 32,102, 32, 61, 32, 40, 40, 40,112, 45,118,104, 41, 42, 40,112, 45,118,104, 41, 41, 47, + 40, 40,112, 43,118,104, 41, 42, 40,112, 43,118,104, 41, 41, 41, 42, 40, 49, 46, 48, 43, 40, 40, 40, 40,118,104, 42, 40,112, 43, +118,104, 41, 41, 45, 49, 46, 48, 41, 42, 40, 40,118,104, 42, 40,112, 43,118,104, 41, 41, 45, 49, 46, 48, 41, 41, 47, 40, 40, 40, +118,104, 42, 40,112, 45,118,104, 41, 41, 43, 49, 46, 48, 41, 42, 40, 40,118,104, 42, 40,112, 45,118,104, 41, 41, 43, 49, 46, 48, + 41, 41, 41, 41, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, 97,110,103, 32, 61, 32, 97, 99,111,115, 40,110,104, 41, 59, 10, + 10, 9, 9, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,109, 97,120, 40,102, 42,103, 42,101,120,112, 95, 98,108,101,110,100, +101,114, 40, 40, 45, 40, 97,110,103, 42, 97,110,103, 41, 47, 40, 50, 46, 48, 42,115,112,101, 99, 95,112,111,119,101,114, 42,115, +112,101, 99, 95,112,111,119,101,114, 41, 41, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9, 9,125, 10, 9, 9,125, 10, 9,125, 10, +125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,119, 97,114,100,105,115,111, 95,115,112,101, 99, 40,118,101, 99, 51, 32, +110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,114,109,115, 44, 32,111,117, +116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114, +109, 97,108,105,122,101, 40,108, 32, 43, 32,118, 41, 59, 10, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32,109, 97,120, 40,100, +111,116, 40,110, 44, 32,104, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97, +120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, 32,110,108, 32, 61, + 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,108, 41, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, 32, 97, +110,103,108,101, 32, 61, 32,116, 97,110, 40, 97, 99,111,115, 40,110,104, 41, 41, 59, 10, 9,102,108,111, 97,116, 32, 97,108,112, +104, 97, 32, 61, 32,109, 97,120, 40,114,109,115, 44, 32, 48, 46, 48, 48, 49, 41, 59, 10, 10, 9,115,112,101, 99,102, 97, 99, 61, + 32,110,108, 32, 42, 32, 40, 49, 46, 48, 47, 40, 52, 46, 48, 42, 77, 95, 80, 73, 42, 97,108,112,104, 97, 42, 97,108,112,104, 97, + 41, 41, 42, 40,101,120,112, 95, 98,108,101,110,100,101,114, 40, 45, 40, 97,110,103,108,101, 42, 97,110,103,108,101, 41, 47, 40, + 97,108,112,104, 97, 42, 97,108,112,104, 97, 41, 41, 47, 40,115,113,114,116, 40,110,118, 42,110,108, 41, 41, 41, 59, 10,125, 10, + 10,118,111,105,100, 32,115,104, 97,100,101, 95,116,111,111,110, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, + 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,115,105,122,101, 44, 32,102,108,111, 97,116, 32, +116,115,109,111,111,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118, +101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 43, 32,118, 41, 59, 10, 9,102,108,111, 97,116, + 32,114,115,108,116, 32, 61, 32,100,111,116, 40,104, 44, 32,110, 41, 59, 10, 9,102,108,111, 97,116, 32, 97,110,103, 32, 61, 32, + 97, 99,111,115, 40,114,115,108,116, 41, 59, 10, 10, 9,105,102, 40, 97,110,103, 32, 60, 32,115,105,122,101, 41, 32,114,115,108, +116, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 97,110,103, 32, 62, 61, 32, 40,115,105,122,101, 32, 43, + 32,116,115,109,111,111,116,104, 41, 32,124,124, 32,116,115,109,111,111,116,104, 32, 61, 61, 32, 48, 46, 48, 41, 32,114,115,108, +116, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,114,115,108,116, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 40, 97,110, +103, 32, 45, 32,115,105,122,101, 41, 47,116,115,109,111,111,116,104, 41, 59, 10, 10, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, +114,115,108,116, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,115,112,101, 99, 95, 97,114,101, 97, 95,105,110, +112, 40,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 44, 32,102,108,111, 97,116, 32,105,110,112, 44, 32,111,117,116, 32, +102,108,111, 97,116, 32,111,117,116,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,111,117,116,115,112,101, 99,102, 97, 99, 32, + 61, 32,115,112,101, 99,102, 97, 99, 42,105,110,112, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,115,112,101, + 99, 95,116, 40,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,102,108,111, 97,116, 32,115,112,101, 99, 44, 32,102, +108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 44, 32,111,117,116, + 32,102,108,111, 97,116, 32,116, 41, 10,123, 10, 9,116, 32, 61, 32,115,104, 97,100,102, 97, 99, 42,115,112,101, 99, 42,118,105, +115,105,102, 97, 99, 42,115,112,101, 99,102, 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, + 95,115,112,101, 99, 40,102,108,111, 97,116, 32,116, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111,108, 44, 32,118,101, 99, + 51, 32,115,112,101, 99, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111, +117,116, 99,111,108, 32, 61, 32,116, 42,108, 97,109,112, 99,111,108, 42,115,112,101, 99, 99,111,108, 59, 10,125, 10, 10,118,111, +105,100, 32,115,104, 97,100,101, 95, 97,100,100, 40,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, + 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, + 99,111,108, 49, 32, 43, 32, 99,111,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, 97,100,100, 40, +118,101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32, +111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, + 32, 43, 32, 99,111,108, 49, 42, 99,111,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, 95, + 99,108, 97,109,112,101,100, 40,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117, +116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 32, + 43, 32,109, 97,120, 40, 99,111,108, 50, 44, 32,118,101, 99, 52, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, + 48, 46, 48, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, 97,100,100, 95, 99,108, 97,109,112,101, 100, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99, -111,108, 32, 43, 32, 99,111,108, 49, 42, 99,111,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,100, -100, 95, 99,108, 97,109,112,101,100, 40,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32, -111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, - 49, 32, 43, 32,109, 97,120, 40, 99,111,108, 50, 44, 32,118,101, 99, 52, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, - 44, 32, 48, 46, 48, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, 97,100,100, 95, 99,108, 97,109, -112,101,100, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111, -108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, - 32, 99,111,108, 32, 43, 32,109, 97,120, 40, 99,111,108, 49, 42, 99,111,108, 50, 44, 32,118,101, 99, 52, 40, 48, 46, 48, 44, 32, - 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, - 97,100,100,102, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 44, 32,118,101, 99, 52, 32, 99,111,108, - 49, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, - 99,111,108, 32, 43, 32,102, 42, 99,111,108, 49, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109,117,108, 40, -118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111, -117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 42, 99,111,108, 50, 59, 10,125, 10, - 10,118,111,105,100, 32,115,104, 97,100,101, 95,109,117,108, 95,118, 97,108,117,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, - 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111, -117,116, 99,111,108, 32, 61, 32, 99,111,108, 42,102, 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111, - 98, 99,111,108,111,114, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32,111, 98, 99,111,108, 44, 32,111,117,116, - 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99, -111,108, 46,114,103, 98, 42,111, 98, 99,111,108, 46,114,103, 98, 44, 32, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10,118,111,105, -100, 32,114, 97,109,112, 95,114,103, 98,116,111, 98,119, 40,118,101, 99, 51, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102, -108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,108,111,114, 46,114, - 42, 48, 46, 51, 32, 43, 32, 99,111,108,111,114, 46,103, 42, 48, 46, 53, 56, 32, 43, 32, 99,111,108,111,114, 46, 98, 42, 48, 46, - 49, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, 97,100,111,119, 40,102,108, -111, 97,116, 32,105, 44, 32,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,102,108,111, 97,116, 32,101,110,101,114, -103,121, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,115,104, 97,100,102, 97, 99, 41, 10,123, 10, 9,111,117,116, -115,104, 97,100,102, 97, 99, 32, 61, 32,105, 42,101,110,101,114,103,121, 42, 40, 49, 46, 48, 32, 45, 32,115,104, 97,100,102, 97, - 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, 97,100,111,119, 95,100,105, -102,102,117,115,101, 40,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,118,101, 99, 51, 32,114,103, 98, 44, 32,118, -101, 99, 52, 32,100,105,102,102, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,100,105,102,102, 41, 10,123, 10, 9,111, -117,116,100,105,102,102, 32, 61, 32,100,105,102,102, 32, 45, 32,118,101, 99, 52, 40,114,103, 98, 42,115,104, 97,100,102, 97, 99, - 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, 97,100,111, -119, 95,115,112,101, 99,117,108, 97,114, 40,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,118,101, 99, 51, 32,115, -112,101, 99,114,103, 98, 44, 32,118,101, 99, 52, 32,115,112,101, 99, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,115, -112,101, 99, 41, 10,123, 10, 9,111,117,116,115,112,101, 99, 32, 61, 32,115,112,101, 99, 32, 45, 32,118,101, 99, 52, 40,115,112, -101, 99,114,103, 98, 42,115,104, 97,100,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,115, -116, 95,115,104, 97,100,111,119, 98,117,102, 40,118,101, 99, 51, 32,114, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 83, -104, 97,100,111,119, 32,115,104, 97,100,111,119,109, 97,112, 44, 32,109, 97,116, 52, 32,115,104, 97,100,111,119,112,101,114,115, -109, 97,116, 44, 32,102,108,111, 97,116, 32,115,104, 97,100,111,119, 98,105, 97,115, 44, 32,102,108,111, 97,116, 32,105,110,112, - 44, 32,111,117,116, 32,102,108,111, 97,116, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,105,102, 40,105,110,112, 32, 60, 61, - 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,101,115,117,108,116, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, - 32,123, 10, 9, 9,118,101, 99, 52, 32, 99,111, 32, 61, 32,115,104, 97,100,111,119,112,101,114,115,109, 97,116, 42,118,101, 99, - 52, 40,114, 99,111, 44, 32, 49, 46, 48, 41, 59, 10, 10, 9, 9, 47, 47,102,108,111, 97,116, 32, 98,105, 97,115, 32, 61, 32, 40, - 49, 46, 53, 32, 45, 32,105,110,112, 42,105,110,112, 41, 42,115,104, 97,100,111,119, 98,105, 97,115, 59, 10, 9, 9, 99,111, 46, -122, 32, 45, 61, 32,115,104, 97,100,111,119, 98,105, 97,115, 42, 99,111, 46,119, 59, 10, 10, 9, 9,114,101,115,117,108,116, 32, - 61, 32,115,104, 97,100,111,119, 50, 68, 80,114,111,106, 40,115,104, 97,100,111,119,109, 97,112, 44, 32, 99,111, 41, 46,120, 59, - 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,101,120,112,111,115,117,114,101, 95, 99,111,114,114,101, - 99,116, 40,118,101, 99, 51, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32,108,105,110,102, 97, 99, 44, 32,102,108,111, 97,116, - 32,108,111,103,102, 97, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, - 99,111,108, 32, 61, 32,108,105,110,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32,101,120,112, 40, 99,111,108, 42,108,111,103,102, - 97, 99, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109,105,115,116, 95,102, 97, 99,116,111,114, 40, -118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, 32,109,105,115,116,115,116, 97, 44, 32,102,108,111, 97,116, 32,109,105, -115,116,100,105,115,116, 44, 32,102,108,111, 97,116, 32,109,105,115,116,116,121,112,101, 44, 32,102,108,111, 97,116, 32,109,105, -115,105, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, - 97, 99, 44, 32,122, 99,111,114, 59, 10, 10, 9,122, 99,111,114, 32, 61, 32, 40,103,108, 95, 80,114,111,106,101, 99,116,105,111, -110, 77, 97,116,114,105,120, 91, 51, 93, 91, 51, 93, 32, 61, 61, 32, 48, 46, 48, 41, 63, 32,108,101,110,103,116,104, 40, 99,111, - 41, 58, 32, 45, 99,111, 91, 50, 93, 59, 10, 9, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40, 40,122, 99,111,114, 45, -109,105,115,116,115,116, 97, 41, 47,109,105,115,116,100,105,115,116, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,105, -102, 40,109,105,115,116,116,121,112,101, 32, 61, 61, 32, 48, 46, 48, 41, 32,102, 97, 99, 32, 42, 61, 32,102, 97, 99, 59, 10, 9, -101,108,115,101, 32,105,102, 40,109,105,115,116,116,121,112,101, 32, 61, 61, 32, 49, 46, 48, 41, 59, 10, 9,101,108,115,101, 32, -102, 97, 99, 32, 61, 32,115,113,114,116, 40,102, 97, 99, 41, 59, 10, 10, 9,111,117,116,102, 97, 99, 32, 61, 32, 49, 46, 48, 32, - 45, 32, 40, 49, 46, 48, 45,102, 97, 99, 41, 42, 40, 49, 46, 48, 45,109,105,115,105, 41, 59, 10,125, 10, 10,118,111,105,100, 32, -115,104, 97,100,101, 95,119,111,114,108,100, 95,109,105,120, 40,118,101, 99, 51, 32,104,111,114, 44, 32,118,101, 99, 52, 32, 99, -111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, - 99, 32, 61, 32, 99,108, 97,109,112, 40, 99,111,108, 46, 97, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, - 99,111,108, 32, 61, 32,118,101, 99, 52, 40,109,105,120, 40,104,111,114, 44, 32, 99,111,108, 46,114,103, 98, 44, 32,102, 97, 99, - 41, 44, 32, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,108,112,104, 97, 95,111, -112, 97,113,117,101, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, - 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 49, 46, 48, 41, 59, - 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,108,112,104, 97, 95,111, 98, 99,111,108,111,114, 40,118,101, 99, - 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32,111, 98, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99, -111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 99,111, -108, 46, 97, 42,111, 98, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 78, 69, - 87, 32, 83, 72, 65, 68, 69, 82, 32, 85, 84, 73, 76, 73, 84, 73, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 47, 10, 10,102,108,111, 97,116, 32,102,114,101,115,110,101,108, 95,100,105,101,108,101, 99,116,114,105, 99, 40,118,101, 99, - 51, 32, 73,110, 99,111,109,105,110,103, 44, 32,118,101, 99, 51, 32, 78,111,114,109, 97,108, 44, 32,102,108,111, 97,116, 32,101, -116, 97, 41, 10,123, 10, 32, 32, 32, 32, 47, 42, 32, 99,111,109,112,117,116,101, 32,102,114,101,115,110,101,108, 32,114,101,102, -108,101, 99,116, 97,110, 99,101, 32,119,105,116,104,111,117,116, 32,101,120,112,108,105, 99,105,116,108,121, 32, 99,111,109,112, -117,116,105,110,103, 10, 32, 32, 32, 32, 32, 32, 32,116,104,101, 32,114,101,102,114, 97, 99,116,101,100, 32,100,105,114,101, 99, -116,105,111,110, 32, 42, 47, 10, 32, 32, 32, 32,102,108,111, 97,116, 32, 99, 32, 61, 32, 97, 98,115, 40,100,111,116, 40, 73,110, - 99,111,109,105,110,103, 44, 32, 78,111,114,109, 97,108, 41, 41, 59, 10, 32, 32, 32, 32,102,108,111, 97,116, 32,103, 32, 61, 32, -101,116, 97, 32, 42, 32,101,116, 97, 32, 45, 32, 49, 46, 48, 32, 43, 32, 99, 32, 42, 32, 99, 59, 10, 32, 32, 32, 32,102,108,111, - 97,116, 32,114,101,115,117,108,116, 59, 10, 10, 32, 32, 32, 32,105,102, 40,103, 32, 62, 32, 48, 46, 48, 41, 32,123, 10, 32, 32, - 32, 32, 32, 32, 32, 32,103, 32, 61, 32,115,113,114,116, 40,103, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,108,111, 97,116, - 32, 65, 32, 61, 40,103, 32, 45, 32, 99, 41, 47, 40,103, 32, 43, 32, 99, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,108,111, - 97,116, 32, 66, 32, 61, 40, 99, 32, 42, 40,103, 32, 43, 32, 99, 41, 45, 32, 49, 46, 48, 41, 47, 40, 99, 32, 42, 40,103, 32, 45, - 32, 99, 41, 43, 32, 49, 46, 48, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,115,117,108,116, 32, 61, 32, 48, 46, 53, 32, - 42, 32, 65, 32, 42, 32, 65, 32, 42, 40, 49, 46, 48, 32, 43, 32, 66, 32, 42, 32, 66, 41, 59, 10, 32, 32, 32, 32,125, 10, 32, 32, - 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,115,117,108,116, 32, 61, 32, 49, 46, 48, 59, 32, 32, 47, 42, - 32, 84, 73, 82, 32, 40,110,111, 32,114,101,102,114, 97, 99,116,101,100, 32, 99,111,109,112,111,110,101,110,116, 41, 32, 42, 47, - 10, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,114,101,115,117,108,116, 59, 10,125, 10, 10,102,108,111, 97,116, 32,104,121, -112,111,116, 40,102,108,111, 97,116, 32,120, 44, 32,102,108,111, 97,116, 32,121, 41, 10,123, 10, 9,114,101,116,117,114,110, 32, -115,113,114,116, 40,120, 42,120, 32, 43, 32,121, 42,121, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 32, 78, 69, 87, 32, 83, 72, 65, 68, 69, 82, 32, 78, 79, 68, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 47, 10, 10, 35,100,101,102,105,110,101, 32, 78, 85, 77, 95, 76, 73, 71, 72, 84, 83, 32, 51, 10, 10, 47, 42, 32, 98,115,100, -102,115, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,100,105,102,102,117,115,101, 40,118,101, - 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 44, 32,118,101, 99, 51, 32, - 78, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9, 47, 42, 32, 97,109, 98,105,101,110, -116, 32,108,105,103,104,116, 32, 42, 47, 10, 9,118,101, 99, 51, 32, 76, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 50, 41, 59, 10, - 10, 9, 47, 42, 32,100,105,114,101, 99,116,105,111,110, 97,108, 32,108,105,103,104,116,115, 32, 42, 47, 10, 9,102,111,114, 40, -105,110,116, 32,105, 32, 61, 32, 48, 59, 32,105, 32, 60, 32, 78, 85, 77, 95, 76, 73, 71, 72, 84, 83, 59, 32,105, 43, 43, 41, 32, -123, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 32, 61, 32,103,108, 95, 76,105,103, -104,116, 83,111,117,114, 99,101, 91,105, 93, 46,112,111,115,105,116,105,111,110, 46,120,121,122, 59, 10, 9, 9,118,101, 99, 51, - 32,108,105,103,104,116, 95,100,105,102,102,117,115,101, 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91, -105, 93, 46,100,105,102,102,117,115,101, 46,114,103, 98, 59, 10, 10, 9, 9,102,108,111, 97,116, 32, 98,115,100,102, 32, 61, 32, -109, 97,120, 40,100,111,116, 40, 78, 44, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 41, 44, 32, 48, 46, 48, 41, - 59, 10, 9, 9, 76, 32, 43, 61, 32,108,105,103,104,116, 95,100,105,102,102,117,115,101, 42, 98,115,100,102, 59, 10, 9,125, 10, - 10, 9,114,101,115,117,108,116, 32, 61, 32,118,101, 99, 52, 40, 76, 42, 99,111,108,111,114, 46,114,103, 98, 44, 32, 49, 46, 48, - 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,103,108,111,115,115,121, 40,118,101, 99, 52, +111,108, 32, 43, 32,109, 97,120, 40, 99,111,108, 49, 42, 99,111,108, 50, 44, 32,118,101, 99, 52, 40, 48, 46, 48, 44, 32, 48, 46, + 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, 97,100, +100,102, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, + 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111, +108, 32, 43, 32,102, 42, 99,111,108, 49, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109,117,108, 40,118,101, + 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, + 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 42, 99,111,108, 50, 59, 10,125, 10, 10,118, +111,105,100, 32,115,104, 97,100,101, 95,109,117,108, 95,118, 97,108,117,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118, +101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, + 99,111,108, 32, 61, 32, 99,111,108, 42,102, 97, 99, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111, 98, 99, +111,108,111,114, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32,111, 98, 99,111,108, 44, 32,111,117,116, 32,118, +101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, + 46,114,103, 98, 42,111, 98, 99,111,108, 46,114,103, 98, 44, 32, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32, +114, 97,109,112, 95,114,103, 98,116,111, 98,119, 40,118,101, 99, 51, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, + 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,108,111,114, 46,114, 42, 48, + 46, 51, 32, 43, 32, 99,111,108,111,114, 46,103, 42, 48, 46, 53, 56, 32, 43, 32, 99,111,108,111,114, 46, 98, 42, 48, 46, 49, 50, + 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, 97,100,111,119, 40,102,108,111, 97, +116, 32,105, 44, 32,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,102,108,111, 97,116, 32,101,110,101,114,103,121, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,115,104, 97,100,102, 97, 99, 41, 10,123, 10, 9,111,117,116,115,104, + 97,100,102, 97, 99, 32, 61, 32,105, 42,101,110,101,114,103,121, 42, 40, 49, 46, 48, 32, 45, 32,115,104, 97,100,102, 97, 99, 41, + 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, 97,100,111,119, 95,100,105,102,102, +117,115,101, 40,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,118,101, 99, 51, 32,114,103, 98, 44, 32,118,101, 99, + 52, 32,100,105,102,102, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,100,105,102,102, 41, 10,123, 10, 9,111,117,116, +100,105,102,102, 32, 61, 32,100,105,102,102, 32, 45, 32,118,101, 99, 52, 40,114,103, 98, 42,115,104, 97,100,102, 97, 99, 44, 32, + 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111,110,108,121, 95,115,104, 97,100,111,119, 95, +115,112,101, 99,117,108, 97,114, 40,102,108,111, 97,116, 32,115,104, 97,100,102, 97, 99, 44, 32,118,101, 99, 51, 32,115,112,101, + 99,114,103, 98, 44, 32,118,101, 99, 52, 32,115,112,101, 99, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,115,112,101, + 99, 41, 10,123, 10, 9,111,117,116,115,112,101, 99, 32, 61, 32,115,112,101, 99, 32, 45, 32,118,101, 99, 52, 40,115,112,101, 99, +114,103, 98, 42,115,104, 97,100,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,115,116, 95, +115,104, 97,100,111,119, 98,117,102, 40,118,101, 99, 51, 32,114, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 83,104, 97, +100,111,119, 32,115,104, 97,100,111,119,109, 97,112, 44, 32,109, 97,116, 52, 32,115,104, 97,100,111,119,112,101,114,115,109, 97, +116, 44, 32,102,108,111, 97,116, 32,115,104, 97,100,111,119, 98,105, 97,115, 44, 32,102,108,111, 97,116, 32,105,110,112, 44, 32, +111,117,116, 32,102,108,111, 97,116, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,105,102, 40,105,110,112, 32, 60, 61, 32, 48, + 46, 48, 41, 32,123, 10, 9, 9,114,101,115,117,108,116, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, + 10, 9, 9,118,101, 99, 52, 32, 99,111, 32, 61, 32,115,104, 97,100,111,119,112,101,114,115,109, 97,116, 42,118,101, 99, 52, 40, +114, 99,111, 44, 32, 49, 46, 48, 41, 59, 10, 10, 9, 9, 47, 47,102,108,111, 97,116, 32, 98,105, 97,115, 32, 61, 32, 40, 49, 46, + 53, 32, 45, 32,105,110,112, 42,105,110,112, 41, 42,115,104, 97,100,111,119, 98,105, 97,115, 59, 10, 9, 9, 99,111, 46,122, 32, + 45, 61, 32,115,104, 97,100,111,119, 98,105, 97,115, 42, 99,111, 46,119, 59, 10, 10, 9, 9,114,101,115,117,108,116, 32, 61, 32, +115,104, 97,100,111,119, 50, 68, 80,114,111,106, 40,115,104, 97,100,111,119,109, 97,112, 44, 32, 99,111, 41, 46,120, 59, 10, 9, +125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,101,120,112,111,115,117,114,101, 95, 99,111,114,114,101, 99,116, + 40,118,101, 99, 51, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32,108,105,110,102, 97, 99, 44, 32,102,108,111, 97,116, 32,108, +111,103,102, 97, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111, +108, 32, 61, 32,108,105,110,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32,101,120,112, 40, 99,111,108, 42,108,111,103,102, 97, 99, + 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109,105,115,116, 95,102, 97, 99,116,111,114, 40,118,101, + 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, 32,109,105,115,116,115,116, 97, 44, 32,102,108,111, 97,116, 32,109,105,115,116, +100,105,115,116, 44, 32,102,108,111, 97,116, 32,109,105,115,116,116,121,112,101, 44, 32,102,108,111, 97,116, 32,109,105,115,105, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99, + 44, 32,122, 99,111,114, 59, 10, 10, 9,122, 99,111,114, 32, 61, 32, 40,103,108, 95, 80,114,111,106,101, 99,116,105,111,110, 77, + 97,116,114,105,120, 91, 51, 93, 91, 51, 93, 32, 61, 61, 32, 48, 46, 48, 41, 63, 32,108,101,110,103,116,104, 40, 99,111, 41, 58, + 32, 45, 99,111, 91, 50, 93, 59, 10, 9, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40, 40,122, 99,111,114, 45,109,105, +115,116,115,116, 97, 41, 47,109,105,115,116,100,105,115,116, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,105,102, 40, +109,105,115,116,116,121,112,101, 32, 61, 61, 32, 48, 46, 48, 41, 32,102, 97, 99, 32, 42, 61, 32,102, 97, 99, 59, 10, 9,101,108, +115,101, 32,105,102, 40,109,105,115,116,116,121,112,101, 32, 61, 61, 32, 49, 46, 48, 41, 59, 10, 9,101,108,115,101, 32,102, 97, + 99, 32, 61, 32,115,113,114,116, 40,102, 97, 99, 41, 59, 10, 10, 9,111,117,116,102, 97, 99, 32, 61, 32, 49, 46, 48, 32, 45, 32, + 40, 49, 46, 48, 45,102, 97, 99, 41, 42, 40, 49, 46, 48, 45,109,105,115,105, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, + 97,100,101, 95,119,111,114,108,100, 95,109,105,120, 40,118,101, 99, 51, 32,104,111,114, 44, 32,118,101, 99, 52, 32, 99,111,108, + 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99, 32, + 61, 32, 99,108, 97,109,112, 40, 99,111,108, 46, 97, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111, +108, 32, 61, 32,118,101, 99, 52, 40,109,105,120, 40,104,111,114, 44, 32, 99,111,108, 46,114,103, 98, 44, 32,102, 97, 99, 41, 44, + 32, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,108,112,104, 97, 95,111,112, 97, +113,117,101, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, + 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 49, 46, 48, 41, 59, 10,125, + 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,108,112,104, 97, 95,111, 98, 99,111,108,111,114, 40,118,101, 99, 52, 32, + 99,111,108, 44, 32,118,101, 99, 52, 32,111, 98, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, + 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 99,111,108, 46, + 97, 42,111, 98, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 78, 69, 87, 32, + 83, 72, 65, 68, 69, 82, 32, 85, 84, 73, 76, 73, 84, 73, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, + 10, 10,102,108,111, 97,116, 32,102,114,101,115,110,101,108, 95,100,105,101,108,101, 99,116,114,105, 99, 40,118,101, 99, 51, 32, + 73,110, 99,111,109,105,110,103, 44, 32,118,101, 99, 51, 32, 78,111,114,109, 97,108, 44, 32,102,108,111, 97,116, 32,101,116, 97, + 41, 10,123, 10, 32, 32, 32, 32, 47, 42, 32, 99,111,109,112,117,116,101, 32,102,114,101,115,110,101,108, 32,114,101,102,108,101, + 99,116, 97,110, 99,101, 32,119,105,116,104,111,117,116, 32,101,120,112,108,105, 99,105,116,108,121, 32, 99,111,109,112,117,116, +105,110,103, 10, 32, 32, 32, 32, 32, 32, 32,116,104,101, 32,114,101,102,114, 97, 99,116,101,100, 32,100,105,114,101, 99,116,105, +111,110, 32, 42, 47, 10, 32, 32, 32, 32,102,108,111, 97,116, 32, 99, 32, 61, 32, 97, 98,115, 40,100,111,116, 40, 73,110, 99,111, +109,105,110,103, 44, 32, 78,111,114,109, 97,108, 41, 41, 59, 10, 32, 32, 32, 32,102,108,111, 97,116, 32,103, 32, 61, 32,101,116, + 97, 32, 42, 32,101,116, 97, 32, 45, 32, 49, 46, 48, 32, 43, 32, 99, 32, 42, 32, 99, 59, 10, 32, 32, 32, 32,102,108,111, 97,116, + 32,114,101,115,117,108,116, 59, 10, 10, 32, 32, 32, 32,105,102, 40,103, 32, 62, 32, 48, 46, 48, 41, 32,123, 10, 32, 32, 32, 32, + 32, 32, 32, 32,103, 32, 61, 32,115,113,114,116, 40,103, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,108,111, 97,116, 32, 65, + 32, 61, 40,103, 32, 45, 32, 99, 41, 47, 40,103, 32, 43, 32, 99, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,108,111, 97,116, + 32, 66, 32, 61, 40, 99, 32, 42, 40,103, 32, 43, 32, 99, 41, 45, 32, 49, 46, 48, 41, 47, 40, 99, 32, 42, 40,103, 32, 45, 32, 99, + 41, 43, 32, 49, 46, 48, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,115,117,108,116, 32, 61, 32, 48, 46, 53, 32, 42, 32, + 65, 32, 42, 32, 65, 32, 42, 40, 49, 46, 48, 32, 43, 32, 66, 32, 42, 32, 66, 41, 59, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, +101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,115,117,108,116, 32, 61, 32, 49, 46, 48, 59, 32, 32, 47, 42, 32, 84, + 73, 82, 32, 40,110,111, 32,114,101,102,114, 97, 99,116,101,100, 32, 99,111,109,112,111,110,101,110,116, 41, 32, 42, 47, 10, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,114,101,115,117,108,116, 59, 10,125, 10, 10,102,108,111, 97,116, 32,104,121,112,111, +116, 40,102,108,111, 97,116, 32,120, 44, 32,102,108,111, 97,116, 32,121, 41, 10,123, 10, 9,114,101,116,117,114,110, 32,115,113, +114,116, 40,120, 42,120, 32, 43, 32,121, 42,121, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 78, + 69, 87, 32, 83, 72, 65, 68, 69, 82, 32, 78, 79, 68, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, + 10, 10, 35,100,101,102,105,110,101, 32, 78, 85, 77, 95, 76, 73, 71, 72, 84, 83, 32, 51, 10, 10, 47, 42, 32, 98,115,100,102,115, + 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,100,105,102,102,117,115,101, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 44, 32,118,101, 99, 51, 32, 78, 44, - 32,118,101, 99, 51, 32, 73, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9, 47, 42, 32, - 97,109, 98,105,101,110,116, 32,108,105,103,104,116, 32, 42, 47, 10, 9,118,101, 99, 51, 32, 76, 32, 61, 32,118,101, 99, 51, 40, - 48, 46, 50, 41, 59, 10, 10, 9, 47, 42, 32,100,105,114,101, 99,116,105,111,110, 97,108, 32,108,105,103,104,116,115, 32, 42, 47, - 10, 9,102,111,114, 40,105,110,116, 32,105, 32, 61, 32, 48, 59, 32,105, 32, 60, 32, 78, 85, 77, 95, 76, 73, 71, 72, 84, 83, 59, - 32,105, 43, 43, 41, 32,123, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 32, 61, 32, -103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,112,111,115,105,116,105,111,110, 46,120,121,122, 59, 10, - 9, 9,118,101, 99, 51, 32, 72, 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,104, 97,108, -102, 86,101, 99,116,111,114, 46,120,121,122, 59, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,100,105,102,102,117,115, -101, 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,100,105,102,102,117,115,101, 46,114,103, - 98, 59, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,115,112,101, 99,117,108, 97,114, 32, 61, 32,103,108, 95, 76,105, -103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,115,112,101, 99,117,108, 97,114, 46,114,103, 98, 59, 10, 10, 9, 9, 47, 42, - 32,119,101, 32,109,105,120, 32,105,110, 32,115,111,109,101, 32,100,105,102,102,117,115,101, 32,115,111, 32,108,111,119, 32,114, -111,117,103,104,110,101,115,115, 32,115,116,105,108,108, 32,115,104,111,119,115, 32,117,112, 32, 42, 47, 10, 9, 9,102,108,111, - 97,116, 32, 98,115,100,102, 32, 61, 32, 48, 46, 53, 42,112,111,119, 40,109, 97,120, 40,100,111,116, 40, 78, 44, 32, 72, 41, 44, - 32, 48, 46, 48, 41, 44, 32, 49, 46, 48, 47,114,111,117,103,104,110,101,115,115, 41, 59, 10, 9, 9, 98,115,100,102, 32, 43, 61, - 32, 48, 46, 53, 42,109, 97,120, 40,100,111,116, 40, 78, 44, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 41, 44, - 32, 48, 46, 48, 41, 59, 10, 9, 9, 76, 32, 43, 61, 32,108,105,103,104,116, 95,115,112,101, 99,117,108, 97,114, 42, 98,115,100, -102, 59, 10, 9,125, 10, 10, 9,114,101,115,117,108,116, 32, 61, 32,118,101, 99, 52, 40, 76, 42, 99,111,108,111,114, 46,114,103, - 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95, 97,110,105,115,111, -116,114,111,112,105, 99, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101, -115,115, 85, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 86, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118, -101, 99, 51, 32, 73, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, - 98,115,100,102, 95,100,105,102,102,117,115,101, 40, 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117, -108,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,103,108, 97,115,115, 40,118,101, 99, - 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 44, 32,102,108,111, 97,116, 32, -105,111,114, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118,101, 99, 51, 32, 73, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101, -115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115,100,102, 95,100,105,102,102,117,115,101, 40, 99,111,108,111,114, - 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117,108,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, - 98,115,100,102, 95,116,114, 97,110,115,108,117, 99,101,110,116, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,118,101, 99, - 51, 32, 78, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115, + 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9, 47, 42, 32, 97,109, 98,105,101,110,116, 32, +108,105,103,104,116, 32, 42, 47, 10, 9,118,101, 99, 51, 32, 76, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 50, 41, 59, 10, 10, 9, + 47, 42, 32,100,105,114,101, 99,116,105,111,110, 97,108, 32,108,105,103,104,116,115, 32, 42, 47, 10, 9,102,111,114, 40,105,110, +116, 32,105, 32, 61, 32, 48, 59, 32,105, 32, 60, 32, 78, 85, 77, 95, 76, 73, 71, 72, 84, 83, 59, 32,105, 43, 43, 41, 32,123, 10, + 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 32, 61, 32,103,108, 95, 76,105,103,104,116, + 83,111,117,114, 99,101, 91,105, 93, 46,112,111,115,105,116,105,111,110, 46,120,121,122, 59, 10, 9, 9,118,101, 99, 51, 32,108, +105,103,104,116, 95,100,105,102,102,117,115,101, 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, + 46,100,105,102,102,117,115,101, 46,114,103, 98, 59, 10, 10, 9, 9,102,108,111, 97,116, 32, 98,115,100,102, 32, 61, 32,109, 97, +120, 40,100,111,116, 40, 78, 44, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 41, 44, 32, 48, 46, 48, 41, 59, 10, + 9, 9, 76, 32, 43, 61, 32,108,105,103,104,116, 95,100,105,102,102,117,115,101, 42, 98,115,100,102, 59, 10, 9,125, 10, 10, 9, +114,101,115,117,108,116, 32, 61, 32,118,101, 99, 52, 40, 76, 42, 99,111,108,111,114, 46,114,103, 98, 44, 32, 49, 46, 48, 41, 59, + 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,103,108,111,115,115,121, 40,118,101, 99, 52, 32, 99, +111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118, +101, 99, 51, 32, 73, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9, 47, 42, 32, 97,109, + 98,105,101,110,116, 32,108,105,103,104,116, 32, 42, 47, 10, 9,118,101, 99, 51, 32, 76, 32, 61, 32,118,101, 99, 51, 40, 48, 46, + 50, 41, 59, 10, 10, 9, 47, 42, 32,100,105,114,101, 99,116,105,111,110, 97,108, 32,108,105,103,104,116,115, 32, 42, 47, 10, 9, +102,111,114, 40,105,110,116, 32,105, 32, 61, 32, 48, 59, 32,105, 32, 60, 32, 78, 85, 77, 95, 76, 73, 71, 72, 84, 83, 59, 32,105, + 43, 43, 41, 32,123, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 32, 61, 32,103,108, + 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,112,111,115,105,116,105,111,110, 46,120,121,122, 59, 10, 9, 9, +118,101, 99, 51, 32, 72, 32, 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,104, 97,108,102, 86, +101, 99,116,111,114, 46,120,121,122, 59, 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,100,105,102,102,117,115,101, 32, + 61, 32,103,108, 95, 76,105,103,104,116, 83,111,117,114, 99,101, 91,105, 93, 46,100,105,102,102,117,115,101, 46,114,103, 98, 59, + 10, 9, 9,118,101, 99, 51, 32,108,105,103,104,116, 95,115,112,101, 99,117,108, 97,114, 32, 61, 32,103,108, 95, 76,105,103,104, +116, 83,111,117,114, 99,101, 91,105, 93, 46,115,112,101, 99,117,108, 97,114, 46,114,103, 98, 59, 10, 10, 9, 9, 47, 42, 32,119, +101, 32,109,105,120, 32,105,110, 32,115,111,109,101, 32,100,105,102,102,117,115,101, 32,115,111, 32,108,111,119, 32,114,111,117, +103,104,110,101,115,115, 32,115,116,105,108,108, 32,115,104,111,119,115, 32,117,112, 32, 42, 47, 10, 9, 9,102,108,111, 97,116, + 32, 98,115,100,102, 32, 61, 32, 48, 46, 53, 42,112,111,119, 40,109, 97,120, 40,100,111,116, 40, 78, 44, 32, 72, 41, 44, 32, 48, + 46, 48, 41, 44, 32, 49, 46, 48, 47,114,111,117,103,104,110,101,115,115, 41, 59, 10, 9, 9, 98,115,100,102, 32, 43, 61, 32, 48, + 46, 53, 42,109, 97,120, 40,100,111,116, 40, 78, 44, 32,108,105,103,104,116, 95,112,111,115,105,116,105,111,110, 41, 44, 32, 48, + 46, 48, 41, 59, 10, 9, 9, 76, 32, 43, 61, 32,108,105,103,104,116, 95,115,112,101, 99,117,108, 97,114, 42, 98,115,100,102, 59, + 10, 9,125, 10, 10, 9,114,101,115,117,108,116, 32, 61, 32,118,101, 99, 52, 40, 76, 42, 99,111,108,111,114, 46,114,103, 98, 44, + 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95, 97,110,105,115,111,116,114, +111,112,105, 99, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, + 85, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 86, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118,101, 99, + 51, 32, 73, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115, 100,102, 95,100,105,102,102,117,115,101, 40, 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117,108,116, - 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,116,114, 97,110,115,112, 97,114,101,110,116, - 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, - 9, 47, 42, 32,116,104,105,115, 32,105,115,110, 39,116, 32,114,105,103,104,116, 32, 42, 47, 10, 9,114,101,115,117,108,116, 46, -114, 32, 61, 32, 99,111,108,111,114, 46,114, 59, 10, 9,114,101,115,117,108,116, 46,103, 32, 61, 32, 99,111,108,111,114, 46,103, - 59, 10, 9,114,101,115,117,108,116, 46, 98, 32, 61, 32, 99,111,108,111,114, 46, 98, 59, 10, 9,114,101,115,117,108,116, 46, 97, - 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,118,101,108,118,101,116, - 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,115,105,103,109, 97, 44, 32,118,101, 99, 51, 32, 78, - 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115,100,102, 95, -100,105,102,102,117,115,101, 40, 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117,108,116, 41, 59, 10, -125, 10, 10, 47, 42, 32,101,109,105,115,115,105,111,110, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,101,109,105, -115,115,105,111,110, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,115,116,114,101,110,103,116,104, - 44, 32,118,101, 99, 51, 32, 78, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,114,101, -115,117,108,116, 32, 61, 32, 99,111,108,111,114, 42,115,116,114,101,110,103,116,104, 59, 10,125, 10, 10, 47, 42, 32, 99,108,111, -115,117,114,101,115, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,109,105,120, 95,115,104, 97,100,101,114, 40,102, -108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 49, 44, 32,118,101, 99, 52, 32,115,104, 97, -100,101,114, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 41, 10,123, 10, 9,115,104, 97,100,101,114, - 32, 61, 32,109,105,120, 40,115,104, 97,100,101,114, 49, 44, 32,115,104, 97,100,101,114, 50, 44, 32,102, 97, 99, 41, 59, 10,125, - 10, 10,118,111,105,100, 32,110,111,100,101, 95, 97,100,100, 95,115,104, 97,100,101,114, 40,118,101, 99, 52, 32,115,104, 97,100, -101,114, 49, 44, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,115,104, 97,100, -101,114, 41, 10,123, 10, 9,115,104, 97,100,101,114, 32, 61, 32,115,104, 97,100,101,114, 49, 32, 43, 32,115,104, 97,100,101,114, - 50, 59, 10,125, 10, 10, 47, 42, 32,102,114,101,115,110,101,108, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,102, -114,101,115,110,101,108, 40,102,108,111, 97,116, 32,105,111,114, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118,101, 99, 51, 32, 73, - 44, 32,111,117,116, 32,102,108,111, 97,116, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,102,108,111, 97,116, 32,101,116, 97, - 32, 61, 32,109, 97,120, 40,105,111,114, 44, 32, 48, 46, 48, 48, 48, 48, 49, 41, 59, 10, 9,114,101,115,117,108,116, 32, 61, 32, -102,114,101,115,110,101,108, 95,100,105,101,108,101, 99,116,114,105, 99, 40, 73, 44, 32, 78, 44, 32,101,116, 97, 41, 59, 32, 47, - 47, 98, 97, 99,107,102, 97, 99,105,110,103, 40, 41, 63, 32, 49, 46, 48, 47,101,116, 97, 58, 32,101,116, 97, 41, 59, 10,125, 10, - 10, 47, 42, 32,103,101,111,109,101,116,114,121, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,103,101,111,109,101, -116,114,121, 40,118,101, 99, 51, 32, 73, 44, 32,118,101, 99, 51, 32, 78, 44, 32,109, 97,116, 52, 32,116,111,119,111,114,108,100, - 44, 10, 9,111,117,116, 32,118,101, 99, 51, 32,112,111,115,105,116,105,111,110, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110, -111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,116, 97,110,103,101,110,116, 44, 10, 9,111,117,116, 32,118,101, - 99, 51, 32,116,114,117,101, 95,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,109,105,110, -103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112, 97,114, 97,109,101,116,114,105, 99, 44, 10, 9,111,117,116, 32,102,108,111, - 97,116, 32, 98, 97, 99,107,102, 97, 99,105,110,103, 41, 10,123, 10, 9,112,111,115,105,116,105,111,110, 32, 61, 32, 40,116,111, -119,111,114,108,100, 42,118,101, 99, 52, 40, 73, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9,110,111,114,109, 97,108, - 32, 61, 32, 78, 59, 10, 9,116, 97,110,103,101,110,116, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10, 9,116,114,117, -101, 95,110,111,114,109, 97,108, 32, 61, 32, 78, 59, 10, 9,105,110, 99,111,109,105,110,103, 32, 61, 32, 73, 59, 10, 9,112, 97, -114, 97,109,101,116,114,105, 99, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10, 9, 98, 97, 99,107,102, 97, 99,105,110, -103, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95, 99,111,111,114,100, 40, -118,101, 99, 51, 32, 73, 44, 32,118,101, 99, 51, 32, 78, 44, 32,109, 97,116, 52, 32,116,111,119,111,114,108,100, 44, 10, 9,118, -101, 99, 51, 32, 97,116,116,114, 95,111,114, 99,111, 44, 32,118,101, 99, 51, 32, 97,116,116,114, 95,117,118, 44, 10, 9,111,117, -116, 32,118,101, 99, 51, 32,103,101,110,101,114, 97,116,101,100, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 44, 32,111, -117,116, 32,118,101, 99, 51, 32,111, 98,106,101, 99,116, 44, 10, 9,111,117,116, 32,118,101, 99, 51, 32, 99, 97,109,101,114, 97, - 44, 32,111,117,116, 32,118,101, 99, 51, 32,119,105,110,100,111,119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,114,101,102,108, -101, 99,116,105,111,110, 41, 10,123, 10, 9,103,101,110,101,114, 97,116,101,100, 32, 61, 32, 97,116,116,114, 95,111,114, 99,111, + 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,103,108, 97,115,115, 40,118,101, 99, 52, 32, + 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,114,111,117,103,104,110,101,115,115, 44, 32,102,108,111, 97,116, 32,105,111, +114, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118,101, 99, 51, 32, 73, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117, +108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115,100,102, 95,100,105,102,102,117,115,101, 40, 99,111,108,111,114, 44, 32, + 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117,108,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115, +100,102, 95,116,114, 97,110,115,108,117, 99,101,110,116, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,118,101, 99, 51, 32, + 78, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115,100,102, + 95,100,105,102,102,117,115,101, 40, 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117,108,116, 41, 59, + 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,116,114, 97,110,115,112, 97,114,101,110,116, 40,118, +101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9, 47, + 42, 32,116,104,105,115, 32,105,115,110, 39,116, 32,114,105,103,104,116, 32, 42, 47, 10, 9,114,101,115,117,108,116, 46,114, 32, + 61, 32, 99,111,108,111,114, 46,114, 59, 10, 9,114,101,115,117,108,116, 46,103, 32, 61, 32, 99,111,108,111,114, 46,103, 59, 10, + 9,114,101,115,117,108,116, 46, 98, 32, 61, 32, 99,111,108,111,114, 46, 98, 59, 10, 9,114,101,115,117,108,116, 46, 97, 32, 61, + 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95, 98,115,100,102, 95,118,101,108,118,101,116, 40,118, +101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,115,105,103,109, 97, 44, 32,118,101, 99, 51, 32, 78, 44, 32, +111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,110,111,100,101, 95, 98,115,100,102, 95,100,105, +102,102,117,115,101, 40, 99,111,108,111,114, 44, 32, 48, 46, 48, 44, 32, 78, 44, 32,114,101,115,117,108,116, 41, 59, 10,125, 10, + 10, 47, 42, 32,101,109,105,115,115,105,111,110, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,101,109,105,115,115, +105,111,110, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,102,108,111, 97,116, 32,115,116,114,101,110,103,116,104, 44, 32, +118,101, 99, 51, 32, 78, 44, 32,111,117,116, 32,118,101, 99, 52, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,114,101,115,117, +108,116, 32, 61, 32, 99,111,108,111,114, 42,115,116,114,101,110,103,116,104, 59, 10,125, 10, 10, 47, 42, 32, 99,108,111,115,117, +114,101,115, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,109,105,120, 95,115,104, 97,100,101,114, 40,102,108,111, + 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 49, 44, 32,118,101, 99, 52, 32,115,104, 97,100,101, +114, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 41, 10,123, 10, 9,115,104, 97,100,101,114, 32, 61, + 32,109,105,120, 40,115,104, 97,100,101,114, 49, 44, 32,115,104, 97,100,101,114, 50, 44, 32,102, 97, 99, 41, 59, 10,125, 10, 10, +118,111,105,100, 32,110,111,100,101, 95, 97,100,100, 95,115,104, 97,100,101,114, 40,118,101, 99, 52, 32,115,104, 97,100,101,114, + 49, 44, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,115,104, 97,100,101,114, + 41, 10,123, 10, 9,115,104, 97,100,101,114, 32, 61, 32,115,104, 97,100,101,114, 49, 32, 43, 32,115,104, 97,100,101,114, 50, 59, + 10,125, 10, 10, 47, 42, 32,102,114,101,115,110,101,108, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,102,114,101, +115,110,101,108, 40,102,108,111, 97,116, 32,105,111,114, 44, 32,118,101, 99, 51, 32, 78, 44, 32,118,101, 99, 51, 32, 73, 44, 32, +111,117,116, 32,102,108,111, 97,116, 32,114,101,115,117,108,116, 41, 10,123, 10, 9,102,108,111, 97,116, 32,101,116, 97, 32, 61, + 32,109, 97,120, 40,105,111,114, 44, 32, 48, 46, 48, 48, 48, 48, 49, 41, 59, 10, 9,114,101,115,117,108,116, 32, 61, 32,102,114, +101,115,110,101,108, 95,100,105,101,108,101, 99,116,114,105, 99, 40, 73, 44, 32, 78, 44, 32,101,116, 97, 41, 59, 32, 47, 47, 98, + 97, 99,107,102, 97, 99,105,110,103, 40, 41, 63, 32, 49, 46, 48, 47,101,116, 97, 58, 32,101,116, 97, 41, 59, 10,125, 10, 10, 47, + 42, 32,103,101,111,109,101,116,114,121, 32, 42, 47, 10, 10,118,111,105,100, 32,110,111,100,101, 95,103,101,111,109,101,116,114, +121, 40,118,101, 99, 51, 32, 73, 44, 32,118,101, 99, 51, 32, 78, 44, 32,109, 97,116, 52, 32,116,111,119,111,114,108,100, 44, 10, + 9,111,117,116, 32,118,101, 99, 51, 32,112,111,115,105,116,105,111,110, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114, +109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,116, 97,110,103,101,110,116, 44, 10, 9,111,117,116, 32,118,101, 99, 51, + 32,116,114,117,101, 95,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,109,105,110,103, 44, + 32,111,117,116, 32,118,101, 99, 51, 32,112, 97,114, 97,109,101,116,114,105, 99, 44, 10, 9,111,117,116, 32,102,108,111, 97,116, + 32, 98, 97, 99,107,102, 97, 99,105,110,103, 41, 10,123, 10, 9,112,111,115,105,116,105,111,110, 32, 61, 32, 40,116,111,119,111, +114,108,100, 42,118,101, 99, 52, 40, 73, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9,110,111,114,109, 97,108, 32, 61, + 32, 78, 59, 10, 9,116, 97,110,103,101,110,116, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10, 9,116,114,117,101, 95, +110,111,114,109, 97,108, 32, 61, 32, 78, 59, 10, 9,105,110, 99,111,109,105,110,103, 32, 61, 32, 73, 59, 10, 9,112, 97,114, 97, +109,101,116,114,105, 99, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10, 9, 98, 97, 99,107,102, 97, 99,105,110,103, 32, + 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,100,101, 95,116,101,120, 95, 99,111,111,114,100, 40,118,101, + 99, 51, 32, 73, 44, 32,118,101, 99, 51, 32, 78, 44, 32,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,109, + 97,116, 52, 32,111, 98,105,110,118,109, 97,116, 44, 10, 9,118,101, 99, 51, 32, 97,116,116,114, 95,111,114, 99,111, 44, 32,118, +101, 99, 51, 32, 97,116,116,114, 95,117,118, 44, 10, 9,111,117,116, 32,118,101, 99, 51, 32,103,101,110,101,114, 97,116,101,100, + 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 44, 32, +111,117,116, 32,118,101, 99, 51, 32,111, 98,106,101, 99,116, 44, 10, 9,111,117,116, 32,118,101, 99, 51, 32, 99, 97,109,101,114, + 97, 44, 32,111,117,116, 32,118,101, 99, 51, 32,119,105,110,100,111,119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,114,101,102, +108,101, 99,116,105,111,110, 41, 10,123, 10, 9,103,101,110,101,114, 97,116,101,100, 32, 61, 32, 97,116,116,114, 95,111,114, 99, +111, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 40,111, 98,105,110,118,109, 97,116, + 42, 40,118,105,101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40, 78, 44, 32, 48, 46, 48, 41, 41, 41, 46,120,121,122, 41, 59, 10, 9,117,118, 32, 61, 32, 97,116,116,114, 95,117,118, 59, 10, 9,111, 98,106,101, 99,116, 32, 61, 32, 73, 59, 10, 9, 99, 97,109,101,114, 97, 32, 61, 32, 73, 59, 10, 9,119,105,110,100,111,119, 32, 61, 32,103,108, 95, 70,114, 97,103, 67,111,111,114, 100, 46,120,121,122, 59, 10, 9,114,101,102,108,101, 99,116,105,111,110, 32, 61, 32,114,101,102,108,101, 99,116, 40, 78, 44, 32, diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c index 8f67fb585c9..aa8b7070cab 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c @@ -33,6 +33,7 @@ static bNodeSocketTemplate sh_node_tex_coord_out[]= { { SOCK_VECTOR, 0, "Generated", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_VECTOR, 0, "UV", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_VECTOR, 0, "Object", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_VECTOR, 0, "Camera", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, @@ -48,7 +49,7 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *UNUSED(node), GPUN return GPU_stack_link(mat, "node_tex_coord", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL), - GPU_builtin(GPU_INVERSE_VIEW_MATRIX), orco, mtface); + GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), orco, mtface); } /* node type definition */ From 845cb7a6eed337c82f9167d3154734dce53218b9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 19 Apr 2012 09:03:43 +0000 Subject: [PATCH 009/360] Cycles: increase SVM stack size to allow more complex node setups, did not find any slowdowns with the increased size. --- intern/cycles/kernel/svm/svm_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 7ca852a24b6..fa7c211b5f9 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -24,7 +24,7 @@ CCL_NAMESPACE_BEGIN /* Stack */ /* SVM stack has a fixed size */ -#define SVM_STACK_SIZE 64 +#define SVM_STACK_SIZE 255 /* SVM stack offsets with this value indicate that it's not on the stack */ #define SVM_STACK_INVALID 255 From 90332f69a72f66a96b2b1d6f0c3b5e260db2a647 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 20 Apr 2012 12:55:44 +0000 Subject: [PATCH 010/360] Tomato branch: "persistent" parameter for addon_utils.enable(), so that we can enable addons from a startup script and keep them enabled after loading .blend files. --- release/scripts/modules/addon_utils.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 588c10eea54..695bb8cb6b6 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -212,10 +212,13 @@ def check(module_name): loaded_state = False + if mod and getattr(mod, "__addon_persistent__", False): + loaded_default = True + return loaded_default, loaded_state -def enable(module_name, default_set=True): +def enable(module_name, default_set=True, persistent=False): """ Enables an addon by name. @@ -283,6 +286,7 @@ def enable(module_name, default_set=True): ext.module = module_name mod.__addon_enabled__ = True + mod.__addon_persistent__ = persistent if _bpy.app.debug_python: print("\taddon_utils.enable", mod.__name__) @@ -305,6 +309,7 @@ def disable(module_name, default_set=True): # the addon in the user prefs. if mod: mod.__addon_enabled__ = False + mod.__addon_persistent = False try: mod.unregister() From ea4ce9e4ea88c7374e6633c6407812af0e2e6170 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Apr 2012 11:43:41 +0000 Subject: [PATCH 011/360] Cycles: centralized task scheduler for multithreading, which is basically the CPU device threading code wrapped into something reusable. Basic idea is that there is a single TaskScheduler that keeps a pool of threads, one for each core. Other places in the code can then create a TaskPool that they can drop Tasks in to be executed by the scheduler, and wait for them to complete or cancel them early. --- intern/cycles/device/device.cpp | 9 -- intern/cycles/device/device.h | 4 +- intern/cycles/device/device_cpu.cpp | 61 +++---- intern/cycles/device/device_multi.cpp | 7 +- intern/cycles/render/session.cpp | 5 + intern/cycles/util/CMakeLists.txt | 2 + intern/cycles/util/util_math.h | 105 +++++++++--- intern/cycles/util/util_task.cpp | 223 ++++++++++++++++++++++++++ intern/cycles/util/util_task.h | 122 ++++++++++++++ intern/cycles/util/util_thread.h | 127 --------------- intern/cycles/util/util_types.h | 170 ++++++++++++++++---- 11 files changed, 605 insertions(+), 230 deletions(-) create mode 100644 intern/cycles/util/util_task.cpp create mode 100644 intern/cycles/util/util_task.h diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index cceec8b8e5c..42dda1180c7 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -58,15 +58,6 @@ void DeviceTask::split_max_size(list& tasks, int max_size) split(tasks, num); } -void DeviceTask::split(ThreadQueue& queue, int num) -{ - list tasks; - split(tasks, num); - - foreach(DeviceTask& task, tasks) - queue.push(task); -} - void DeviceTask::split(list& tasks, int num) { if(type == SHADER) { diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index af2567498d9..87f255e54e7 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -25,6 +25,7 @@ #include "util_list.h" #include "util_string.h" +#include "util_task.h" #include "util_thread.h" #include "util_types.h" #include "util_vector.h" @@ -66,7 +67,7 @@ public: /* Device Task */ -class DeviceTask { +class DeviceTask : public Task { public: typedef enum { PATH_TRACE, TONEMAP, SHADER } Type; Type type; @@ -87,7 +88,6 @@ public: DeviceTask(Type type = PATH_TRACE); void split(list& tasks, int num); - void split(ThreadQueue& tasks, int num); void split_max_size(list& tasks, int max_size); }; diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index da977ed8472..ec84047c44f 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -40,35 +40,21 @@ CCL_NAMESPACE_BEGIN class CPUDevice : public Device { public: - vector threads; - ThreadQueue tasks; + TaskPool task_pool; KernelGlobals *kg; CPUDevice(int threads_num) + : task_pool(function_bind(&CPUDevice::thread_run, this, _1, _2)) { kg = kernel_globals_create(); /* do now to avoid thread issues */ system_cpu_support_optimized(); - - if(threads_num == 0) - threads_num = system_cpu_thread_count(); - - threads.resize(threads_num); - - for(size_t i = 0; i < threads.size(); i++) - threads[i] = new thread(function_bind(&CPUDevice::thread_run, this, i)); } ~CPUDevice() { - tasks.stop(); - - foreach(thread *t, threads) { - t->join(); - delete t; - } - + task_pool.stop(); kernel_globals_free(kg); } @@ -127,25 +113,21 @@ public: #endif } - void thread_run(int t) + void thread_run(Task *task_, int thread_id) { - DeviceTask task; + DeviceTask *task = (DeviceTask*)task_; - while(tasks.worker_wait_pop(task)) { - if(task.type == DeviceTask::PATH_TRACE) - thread_path_trace(task); - else if(task.type == DeviceTask::TONEMAP) - thread_tonemap(task); - else if(task.type == DeviceTask::SHADER) - thread_shader(task); - - tasks.worker_done(); - } + if(task->type == DeviceTask::PATH_TRACE) + thread_path_trace(*task); + else if(task->type == DeviceTask::TONEMAP) + thread_tonemap(*task); + else if(task->type == DeviceTask::SHADER) + thread_shader(*task); } void thread_path_trace(DeviceTask& task) { - if(tasks.worker_cancel()) + if(task_pool.cancelled()) return; #ifdef WITH_OSL @@ -160,7 +142,7 @@ public: kernel_cpu_optimized_path_trace(kg, (float*)task.buffer, (unsigned int*)task.rng_state, task.sample, x, y, task.offset, task.stride); - if(tasks.worker_cancel()) + if(task_pool.cancelled()) break; } } @@ -172,7 +154,7 @@ public: kernel_cpu_path_trace(kg, (float*)task.buffer, (unsigned int*)task.rng_state, task.sample, x, y, task.offset, task.stride); - if(tasks.worker_cancel()) + if(task_pool.cancelled()) break; } } @@ -214,7 +196,7 @@ public: for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { kernel_cpu_optimized_shader(kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x); - if(tasks.worker_cancel()) + if(task_pool.cancelled()) break; } } @@ -224,7 +206,7 @@ public: for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { kernel_cpu_shader(kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x); - if(tasks.worker_cancel()) + if(task_pool.cancelled()) break; } } @@ -239,17 +221,22 @@ public: { /* split task into smaller ones, more than number of threads for uneven workloads where some parts of the image render slower than others */ - task.split(tasks, threads.size()*10); + list tasks; + + task.split(tasks, TaskScheduler::num_threads()*10); + + foreach(DeviceTask& task, tasks) + task_pool.push(new DeviceTask(task)); } void task_wait() { - tasks.wait_done(); + task_pool.wait(); } void task_cancel() { - tasks.cancel(); + task_pool.cancel(); } }; diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp index 1f69f2c53fa..9f7d65e640b 100644 --- a/intern/cycles/device/device_multi.cpp +++ b/intern/cycles/device/device_multi.cpp @@ -257,13 +257,14 @@ public: void task_add(DeviceTask& task) { - ThreadQueue tasks; + list tasks; task.split(tasks, devices.size()); foreach(SubDevice& sub, devices) { - DeviceTask subtask; + if(!tasks.empty()) { + DeviceTask subtask = tasks.front(); + tasks.pop_front(); - if(tasks.worker_wait_pop(subtask)) { if(task.buffer) subtask.buffer = sub.ptr_map[task.buffer]; if(task.rng_state) subtask.rng_state = sub.ptr_map[task.rng_state]; if(task.rgba) subtask.rgba = sub.ptr_map[task.rgba]; diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 676f42be790..34a0c0ff877 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -27,6 +27,7 @@ #include "util_foreach.h" #include "util_function.h" +#include "util_task.h" #include "util_time.h" CCL_NAMESPACE_BEGIN @@ -37,6 +38,8 @@ Session::Session(const SessionParams& params_) { device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background); + TaskScheduler::init(params.threads); + device = Device::create(params.device, params.background, params.threads); buffers = new RenderBuffers(device); display = new DisplayBuffer(device); @@ -88,6 +91,8 @@ Session::~Session() delete display; delete scene; delete device; + + TaskScheduler::exit(); } void Session::start() diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt index 9182ee4cbe1..87bd84b4e0f 100644 --- a/intern/cycles/util/CMakeLists.txt +++ b/intern/cycles/util/CMakeLists.txt @@ -15,6 +15,7 @@ set(SRC util_path.cpp util_string.cpp util_system.cpp + util_task.cpp util_time.cpp util_transform.cpp ) @@ -50,6 +51,7 @@ set(SRC_HEADERS util_set.h util_string.h util_system.h + util_task.h util_thread.h util_time.h util_transform.h diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 019dede07fa..8768c798d16 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -578,51 +578,43 @@ __device_inline float average(const float4& a) __device_inline float4 operator-(const float4& a) { - float4 r = {-a.x, -a.y, -a.z, -a.w}; - return r; + return make_float4(-a.x, -a.y, -a.z, -a.w); } __device_inline float4 operator*(const float4& a, const float4& b) { - float4 r = {a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w}; - return r; + return make_float4(a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w); } __device_inline float4 operator*(const float4& a, float f) { - float4 r = {a.x*f, a.y*f, a.z*f, a.w*f}; - return r; + return make_float4(a.x*f, a.y*f, a.z*f, a.w*f); } __device_inline float4 operator*(float f, const float4& a) { - float4 r = {a.x*f, a.y*f, a.z*f, a.w*f}; - return r; + return make_float4(a.x*f, a.y*f, a.z*f, a.w*f); } __device_inline float4 operator/(const float4& a, float f) { float invf = 1.0f/f; - float4 r = {a.x*invf, a.y*invf, a.z*invf, a.w*invf}; - return r; + return make_float4(a.x*invf, a.y*invf, a.z*invf, a.w*invf); } __device_inline float4 operator/(const float4& a, const float4& b) { - float4 r = {a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w}; - return r; + return make_float4(a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w); } __device_inline float4 operator+(const float4& a, const float4& b) { - float4 r = {a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w}; - return r; + return make_float4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w); } __device_inline float4 operator-(const float4& a, const float4& b) { - float4 r = {a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w}; - return r; + return make_float4(a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w); } __device_inline float4 operator+=(float4& a, const float4& b) @@ -653,6 +645,21 @@ __device_inline float4 operator/=(float4& a, float f) return a; } +__device_inline int4 operator<(const float4& a, const float4& b) +{ + return make_int4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w); +} + +__device_inline int4 operator<=(const float4& a, const float4& b) +{ + return make_int4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w); +} + +__device_inline bool operator==(const float4 a, const float4 b) +{ + return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w); +} + __device_inline float dot(const float4& a, const float4& b) { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; @@ -660,8 +667,7 @@ __device_inline float dot(const float4& a, const float4& b) __device_inline float4 cross(const float4& a, const float4& b) { - float4 r = {a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x, 0.0f}; - return r; + return make_float4(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x, 0.0f); } __device_inline float4 min(float4 a, float4 b) @@ -674,6 +680,31 @@ __device_inline float4 max(float4 a, float4 b) return make_float4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w)); } +__device_inline float4 select(const int4& mask, const float4& a, const float4& b) +{ + return make_float4((mask.x)? a.x: b.x, (mask.y)? a.y: b.y, (mask.z)? a.z: b.z, (mask.w)? a.w: b.w); +} + +__device_inline float4 reduce_min(const float4& a) +{ + return make_float4(min(min(a.x, a.y), min(a.z, a.w))); +} + +__device_inline float4 reduce_max(const float4& a) +{ + return make_float4(max(max(a.x, a.y), max(a.z, a.w))); +} + +__device_inline float4 reduce_add(const float4& a) +{ + return make_float4((a.x + a.y) + (a.z + a.w)); +} + +__device_inline float3 rcp(const float3& a) +{ + return make_float3(1.0f/a.x, 1.0f/a.y, 1.0f/a.z); +} + #endif #ifndef __KERNEL_GPU__ @@ -691,20 +722,17 @@ __device_inline void print_float4(const char *label, const float4& a) __device_inline int3 max(int3 a, int3 b) { - int3 r = {max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)}; - return r; + return make_int3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)); } __device_inline int3 clamp(const int3& a, int mn, int mx) { - int3 r = {clamp(a.x, mn, mx), clamp(a.y, mn, mx), clamp(a.z, mn, mx)}; - return r; + return make_int3(clamp(a.x, mn, mx), clamp(a.y, mn, mx), clamp(a.z, mn, mx)); } __device_inline int3 clamp(const int3& a, int3& mn, int mx) { - int3 r = {clamp(a.x, mn.x, mx), clamp(a.y, mn.y, mx), clamp(a.z, mn.z, mx)}; - return r; + return make_int3(clamp(a.x, mn.x, mx), clamp(a.y, mn.y, mx), clamp(a.z, mn.z, mx)); } #endif @@ -731,6 +759,35 @@ __device_inline int4 operator>=(float4 a, float4 b) #ifndef __KERNEL_GPU__ +__device_inline int4 operator+(const int4& a, const int4& b) +{ + return make_int4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w); +} + +__device_inline int4 operator+=(int4& a, const int4& b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; + a.w += b.w; + return a; +} + +__device_inline int4 operator>>(const int4& a, int i) +{ + return make_int4(a.x >> i, a.y >> i, a.z >> i, a.w >> i); +} + +__device_inline int4 clamp(const int4& a, const int4& mn, const int4& mx) +{ + return make_int4(clamp(a.x, mn.x, mx.x), clamp(a.y, mn.y, mx.y), clamp(a.z, mn.z, mx.z), clamp(a.w, mn.w, mx.w)); +} + +__device_inline int4 select(const int4& mask, const int4& a, const int4& b) +{ + return make_int4((mask.x)? a.x: b.x, (mask.y)? a.y: b.y, (mask.z)? a.z: b.z, (mask.w)? a.w: b.w); +} + __device_inline void print_int4(const char *label, const int4& a) { printf("%s: %d %d %d %d\n", label, a.x, a.y, a.z, a.w); diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp new file mode 100644 index 00000000000..6da9a70ec0c --- /dev/null +++ b/intern/cycles/util/util_task.cpp @@ -0,0 +1,223 @@ +/* + * Copyright 2011, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "util_debug.h" +#include "util_foreach.h" +#include "util_system.h" +#include "util_task.h" + +CCL_NAMESPACE_BEGIN + +/* Task Pool */ + +TaskPool::TaskPool(const TaskRunFunction& run_) +{ + num = 0; + num_done = 0; + + do_cancel = false; + + run = run_; +} + +TaskPool::~TaskPool() +{ + stop(); +} + +void TaskPool::push(Task *task, bool front) +{ + TaskScheduler::Entry entry; + + entry.task = task; + entry.pool = this; + + TaskScheduler::push(entry, front); +} + +void TaskPool::wait() +{ + thread_scoped_lock lock(done_mutex); + + while(num_done != num) + done_cond.wait(lock); +} + +void TaskPool::cancel() +{ + TaskScheduler::clear(this); + + do_cancel = true; + wait(); + do_cancel = false; +} + +void TaskPool::stop() +{ + TaskScheduler::clear(this); + + assert(num_done == num); +} + +bool TaskPool::cancelled() +{ + return do_cancel; +} + +void TaskPool::done_increase(int done) +{ + done_mutex.lock(); + num_done += done; + done_mutex.unlock(); + + assert(num_done <= num); + done_cond.notify_all(); +} + +/* Task Scheduler */ + +thread_mutex TaskScheduler::mutex; +int TaskScheduler::users = 0; +vector TaskScheduler::threads; +volatile bool TaskScheduler::do_exit = false; + +list TaskScheduler::queue; +thread_mutex TaskScheduler::queue_mutex; +thread_condition_variable TaskScheduler::queue_cond; + +void TaskScheduler::init(int num_threads) +{ + thread_scoped_lock lock(mutex); + + /* multiple cycles instances can use this task scheduler, sharing the same + threads, so we keep track of the number of users. */ + if(users == 0) { + do_exit = false; + + /* launch threads that will be waiting for work */ + if(num_threads == 0) + num_threads = system_cpu_thread_count(); + + threads.resize(num_threads); + + for(size_t i = 0; i < threads.size(); i++) + threads[i] = new thread(function_bind(&TaskScheduler::thread_run, i)); + } + + users++; +} + +void TaskScheduler::exit() +{ + thread_scoped_lock lock(mutex); + + users--; + + if(users == 0) { + /* stop all waiting threads */ + do_exit = true; + TaskScheduler::queue_cond.notify_all(); + + /* delete threads */ + foreach(thread *t, threads) { + t->join(); + delete t; + } + + threads.clear(); + } +} + +bool TaskScheduler::thread_wait_pop(Entry& entry) +{ + thread_scoped_lock lock(queue_mutex); + + while(queue.empty() && !do_exit) + queue_cond.wait(lock); + + if(queue.empty()) { + assert(do_exit); + return false; + } + + entry = queue.front(); + queue.pop_front(); + + return true; +} + +void TaskScheduler::thread_run(int thread_id) +{ + Entry entry; + + /* todo: test affinity/denormal mask */ + + /* keep popping off tasks */ + while(thread_wait_pop(entry)) { + /* run task */ + entry.pool->run(entry.task, thread_id); + + /* delete task */ + delete entry.task; + + /* notify pool task was done */ + entry.pool->done_increase(1); + } +} + +void TaskScheduler::push(Entry& entry, bool front) +{ + /* add entry to queue */ + TaskScheduler::queue_mutex.lock(); + if(front) + TaskScheduler::queue.push_front(entry); + else + TaskScheduler::queue.push_back(entry); + entry.pool->num++; + TaskScheduler::queue_mutex.unlock(); + + TaskScheduler::queue_cond.notify_one(); +} + +void TaskScheduler::clear(TaskPool *pool) +{ + thread_scoped_lock lock(TaskScheduler::queue_mutex); + + /* erase all tasks from this pool from the queue */ + list::iterator it = TaskScheduler::queue.begin(); + int done = 0; + + while(it != TaskScheduler::queue.end()) { + TaskScheduler::Entry& entry = *it; + + if(entry.pool == pool) { + done++; + delete entry.task; + + it = TaskScheduler::queue.erase(it); + } + else + it++; + } + + /* notify done */ + pool->done_increase(done); +} + +CCL_NAMESPACE_END + diff --git a/intern/cycles/util/util_task.h b/intern/cycles/util/util_task.h new file mode 100644 index 00000000000..acdb2cb50a2 --- /dev/null +++ b/intern/cycles/util/util_task.h @@ -0,0 +1,122 @@ +/* + * Copyright 2011, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __UTIL_TASK_H__ +#define __UTIL_TASK_H__ + +#include "util_list.h" +#include "util_thread.h" +#include "util_vector.h" + +CCL_NAMESPACE_BEGIN + +class Task; +class TaskPool; +class TaskScheduler; + +typedef boost::function TaskRunFunction; + +/* Task + * + * Base class for tasks to be executed in threads. */ + +class Task +{ +public: + Task() {}; + virtual ~Task() {} +}; + +/* Task Pool + * + * Pool of tasks that will be executed by the central TaskScheduler.For each + * pool, we can wait for all tasks to be done, or cancel them before they are + * done. + * + * The run callback that actually executes the task may be create like this: + * function_bind(&MyClass::task_execute, this, _1, _2) */ + +class TaskPool +{ +public: + TaskPool(const TaskRunFunction& run); + ~TaskPool(); + + void push(Task *task, bool front = false); + + void wait(); /* wait until all tasks are done */ + void cancel(); /* cancel all tasks, keep worker threads running */ + void stop(); /* stop all worker threads */ + + bool cancelled(); /* for worker threads, test if cancelled */ + +protected: + friend class TaskScheduler; + + void done_increase(int done); + + TaskRunFunction run; + + thread_mutex done_mutex; + thread_condition_variable done_cond; + + volatile int num, num_done; + volatile bool do_cancel; +}; + +/* Task Scheduler + * + * Central scheduler that holds running threads ready to execute tasks. A singe + * queue holds the task from all pools. */ + +class TaskScheduler +{ +public: + static void init(int num_threads = 0); + static void exit(); + + static int num_threads() { return threads.size(); } + +protected: + friend class TaskPool; + + struct Entry { + Task *task; + TaskPool *pool; + }; + + static thread_mutex mutex; + static int users; + static vector threads; + static volatile bool do_exit; + + static list queue; + static thread_mutex queue_mutex; + static thread_condition_variable queue_cond; + + static void thread_run(int thread_id); + static bool thread_wait_pop(Entry& entry); + + static void push(Entry& entry, bool front); + static void clear(TaskPool *pool); +}; + +CCL_NAMESPACE_END + +#endif + diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h index 6836be203f5..3d15b342fe5 100644 --- a/intern/cycles/util/util_thread.h +++ b/intern/cycles/util/util_thread.h @@ -69,133 +69,6 @@ protected: bool joined; }; -/* Thread Safe Queue to pass tasks from one thread to another. Tasks should be - * pushed into the queue, while the worker thread waits to pop the next task - * off the queue. Once all tasks are into the queue, calling stop() will stop - * the worker threads from waiting for more tasks once all tasks are done. */ - -template class ThreadQueue -{ -public: - ThreadQueue() - { - tot = 0; - tot_done = 0; - do_stop = false; - do_cancel = false; - } - - /* Main thread functions */ - - /* push a task to be executed */ - void push(const T& value) - { - thread_scoped_lock lock(queue_mutex); - queue.push(value); - tot++; - lock.unlock(); - - queue_cond.notify_one(); - } - - /* wait until all tasks are done */ - void wait_done() - { - thread_scoped_lock lock(done_mutex); - - while(tot_done != tot) - done_cond.wait(lock); - } - - /* stop all worker threads */ - void stop() - { - clear(); - do_stop = true; - queue_cond.notify_all(); - } - - /* cancel all tasks, but keep worker threads running */ - void cancel() - { - clear(); - do_cancel = true; - wait_done(); - do_cancel = false; - } - - /* Worker thread functions - * - * while(queue.worker_wait_pop(task)) { - * for(..) { - * ... do work ... - * - * if(queue.worker_cancel()) - * break; - * } - * - * queue.worker_done(); - * } - */ - - bool worker_wait_pop(T& value) - { - thread_scoped_lock lock(queue_mutex); - - while(queue.empty() && !do_stop) - queue_cond.wait(lock); - - if(queue.empty()) - return false; - - value = queue.front(); - queue.pop(); - - return true; - } - - void worker_done() - { - thread_scoped_lock lock(done_mutex); - tot_done++; - lock.unlock(); - - assert(tot_done <= tot); - - done_cond.notify_all(); - } - - bool worker_cancel() - { - return do_cancel; - } - -protected: - void clear() - { - thread_scoped_lock lock(queue_mutex); - - while(!queue.empty()) { - thread_scoped_lock done_lock(done_mutex); - tot_done++; - done_lock.unlock(); - - queue.pop(); - } - - done_cond.notify_all(); - } - - std::queue queue; - thread_mutex queue_mutex; - thread_mutex done_mutex; - thread_condition_variable queue_cond; - thread_condition_variable done_cond; - volatile bool do_stop; - volatile bool do_cancel; - volatile int tot, tot_done; -}; - /* Thread Local Storage * * Boost implementation is a bit slow, and Mac OS X __thread is not supported diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h index efdda98571a..b6c57e3eb6e 100644 --- a/intern/cycles/util/util_types.h +++ b/intern/cycles/util/util_types.h @@ -36,23 +36,29 @@ #define __shared #define __constant -#ifdef __GNUC__ -#define __device_inline static inline __attribute__((always_inline)) -#else +#ifdef __WIN32__ #define __device_inline static __forceinline +#define __align(...) __declspec(align(__VA_ARGS__)) +#else +#define __device_inline static inline __attribute__((always_inline)) +#define __forceinline inline __attribute__((always_inline)) +#define __align(...) __attribute__((aligned(__VA_ARGS__))) #endif #endif /* SIMD Types */ -/* not needed yet, will be for qbvh -#ifndef __KERNEL_GPU__ +/* not enabled yet, just testing */ +#if 0 +#define __KERNEL_SSE__ +#ifdef __KERNEL_SSE__ #include #include -#endif*/ +#endif +#endif #ifndef _WIN32 #ifndef __KERNEL_GPU__ @@ -133,15 +139,31 @@ struct int2 { int& operator[](int i) { return *(&x + i); } }; +#ifdef __KERNEL_SSE__ +struct __align(16) int3 { + union { + __m128i m128; + struct { int x, y, z, w; }; + }; +#else struct int3 { - int x, y, z; + int x, y, z, w; +#endif int operator[](int i) const { return *(&x + i); } int& operator[](int i) { return *(&x + i); } }; +#ifdef __KERNEL_SSE__ +struct __align(16) int4 { + union { + __m128i m128; + struct { int x, y, z, w; }; + }; +#else struct int4 { int x, y, z, w; +#endif int operator[](int i) const { return *(&x + i); } int& operator[](int i) { return *(&x + i); } @@ -175,19 +197,31 @@ struct float2 { float& operator[](int i) { return *(&x + i); } }; +#ifdef __KERNEL_SSE__ +struct __align(16) float3 { + union { + __m128 m128; + struct { float x, y, z, w; }; + }; +#else struct float3 { - float x, y, z; - -#ifdef WITH_OPENCL - float w; + float x, y, z, w; #endif float operator[](int i) const { return *(&x + i); } float& operator[](int i) { return *(&x + i); } }; +#ifdef __KERNEL_SSE__ +struct __align(16) float4 { + union { + __m128 m128; + struct { float x, y, z, w; }; + }; +#else struct float4 { float x, y, z, w; +#endif float operator[](int i) const { return *(&x + i); } float& operator[](int i) { return *(&x + i); } @@ -201,87 +235,167 @@ struct float4 { * * OpenCL does not support C++ class, so we use these instead. */ -__device uchar2 make_uchar2(uchar x, uchar y) +__device_inline uchar2 make_uchar2(uchar x, uchar y) { uchar2 a = {x, y}; return a; } -__device uchar3 make_uchar3(uchar x, uchar y, uchar z) +__device_inline uchar3 make_uchar3(uchar x, uchar y, uchar z) { uchar3 a = {x, y, z}; return a; } -__device uchar4 make_uchar4(uchar x, uchar y, uchar z, uchar w) +__device_inline uchar4 make_uchar4(uchar x, uchar y, uchar z, uchar w) { uchar4 a = {x, y, z, w}; return a; } -__device int2 make_int2(int x, int y) +__device_inline int2 make_int2(int x, int y) { int2 a = {x, y}; return a; } -__device int3 make_int3(int x, int y, int z) +__device_inline int3 make_int3(int x, int y, int z) { - int3 a = {x, y, z}; +#ifdef __KERNEL_SSE__ + int3 a; + a.m128 = _mm_set_epi32(0, z, y, x); +#else + int3 a = {x, y, z, 0}; +#endif + return a; } -__device int4 make_int4(int x, int y, int z, int w) +__device_inline int4 make_int4(int x, int y, int z, int w) { +#ifdef __KERNEL_SSE__ + int4 a; + a.m128 = _mm_set_epi32(w, z, y, x); +#else int4 a = {x, y, z, w}; +#endif + return a; } -__device uint2 make_uint2(uint x, uint y) +__device_inline uint2 make_uint2(uint x, uint y) { uint2 a = {x, y}; return a; } -__device uint3 make_uint3(uint x, uint y, uint z) +__device_inline uint3 make_uint3(uint x, uint y, uint z) { uint3 a = {x, y, z}; return a; } -__device uint4 make_uint4(uint x, uint y, uint z, uint w) +__device_inline uint4 make_uint4(uint x, uint y, uint z, uint w) { uint4 a = {x, y, z, w}; return a; } -__device float2 make_float2(float x, float y) +__device_inline float2 make_float2(float x, float y) { float2 a = {x, y}; return a; } -__device float3 make_float3(float x, float y, float z) +__device_inline float3 make_float3(float x, float y, float z) { -#ifdef WITH_OPENCL - float3 a = {x, y, z, 0.0f}; +#ifdef __KERNEL_SSE__ + float3 a; + a.m128 = _mm_set_ps(0.0f, z, y, x); #else - float3 a = {x, y, z}; + float3 a = {x, y, z, 0.0f}; #endif + return a; } -__device float4 make_float4(float x, float y, float z, float w) +__device_inline float4 make_float4(float x, float y, float z, float w) { +#ifdef __KERNEL_SSE__ + float4 a; + a.m128 = _mm_set_ps(w, z, y, x); +#else float4 a = {x, y, z, w}; +#endif + return a; } -__device int align_up(int offset, int alignment) +__device_inline int align_up(int offset, int alignment) { return (offset + alignment - 1) & ~(alignment - 1); } +__device_inline int4 make_int4(int i) +{ +#ifdef __KERNEL_SSE__ + int4 a; + a.m128 = _mm_set1_epi32(i); +#else + int4 a = {i, i, i, i}; +#endif + + return a; +} + +__device_inline float3 make_float3(float f) +{ +#ifdef __KERNEL_SSE__ + float3 a; + a.m128 = _mm_set1_ps(f); +#else + float3 a = {f, f, f, f}; +#endif + + return a; +} + +__device_inline float4 make_float4(float f) +{ +#ifdef __KERNEL_SSE__ + float4 a; + a.m128 = _mm_set1_ps(f); +#else + float4 a = {f, f, f, f}; +#endif + + return a; +} + +__device_inline float4 make_float4(const int4& i) +{ +#ifdef __KERNEL_SSE__ + float4 a; + a.m128 = _mm_cvtepi32_ps(i.m128); +#else + float4 a = {(float)i.x, (float)i.y, (float)i.z, (float)i.w}; +#endif + + return a; +} + +__device_inline int4 make_int4(const float3& f) +{ +#ifdef __KERNEL_SSE__ + int4 a; + a.m128 = _mm_cvtps_epi32(f.m128); +#else + int4 a = {(int)f.x, (int)f.y, (int)f.z, (int)f.w}; +#endif + + return a; +} + #endif CCL_NAMESPACE_END From 764432ac930e0e62ca2e7ddd5228a2be4867e797 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Apr 2012 11:52:58 +0000 Subject: [PATCH 012/360] Cycles: BVH build time optimizations: * BVH building was multithreaded. Not all building is multithreaded, packing and the initial bounding/splitting is still single threaded, but recursive splitting is, which was the main bottleneck. * Object splitting now uses binning rather than sorting of all elements, using code from the Embree raytracer from Intel. http://software.intel.com/en-us/articles/embree-photo-realistic-ray-tracing-kernels/ * Other small changes to avoid allocations, pack memory more tightly, avoid some unnecessary operations, ... These optimizations do not work yet when Spatial Splits are enabled, for that more work is needed. There's also other optimizations still needed, in particular for the case of many low poly objects, the packing step and node memory allocation. BVH raytracing time should remain about the same, but BVH build time should be significantly reduced, test here show speedup of about 5x to 10x on a dual core and 5x to 25x on an 8-core machine, depending on the scene. --- intern/cycles/bvh/CMakeLists.txt | 4 + intern/cycles/bvh/bvh.cpp | 4 +- intern/cycles/bvh/bvh_binning.cpp | 219 ++++++++++ intern/cycles/bvh/bvh_binning.h | 86 ++++ intern/cycles/bvh/bvh_build.cpp | 648 +++++++++++++---------------- intern/cycles/bvh/bvh_build.h | 104 ++--- intern/cycles/bvh/bvh_node.cpp | 22 +- intern/cycles/bvh/bvh_node.h | 18 +- intern/cycles/bvh/bvh_params.h | 91 +++- intern/cycles/bvh/bvh_sort.cpp | 16 +- intern/cycles/bvh/bvh_sort.h | 2 +- intern/cycles/bvh/bvh_split.cpp | 293 +++++++++++++ intern/cycles/bvh/bvh_split.h | 110 +++++ intern/cycles/render/mesh.cpp | 7 +- intern/cycles/render/object.cpp | 1 + intern/cycles/subd/subd_patch.cpp | 12 +- intern/cycles/util/util_boundbox.h | 87 +++- 17 files changed, 1252 insertions(+), 472 deletions(-) create mode 100644 intern/cycles/bvh/bvh_binning.cpp create mode 100644 intern/cycles/bvh/bvh_binning.h create mode 100644 intern/cycles/bvh/bvh_split.cpp create mode 100644 intern/cycles/bvh/bvh_split.h diff --git a/intern/cycles/bvh/CMakeLists.txt b/intern/cycles/bvh/CMakeLists.txt index decc576fe51..131a7a1f750 100644 --- a/intern/cycles/bvh/CMakeLists.txt +++ b/intern/cycles/bvh/CMakeLists.txt @@ -10,17 +10,21 @@ set(INC set(SRC bvh.cpp + bvh_binning.cpp bvh_build.cpp bvh_node.cpp bvh_sort.cpp + bvh_split.cpp ) set(SRC_HEADERS bvh.h + bvh_binning.h bvh_build.h bvh_node.h bvh_params.h bvh_sort.h + bvh_split.h ) include_directories(${INC}) diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index c9bfa964332..15695dddf45 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -530,7 +530,7 @@ void RegularBVH::refit_nodes() { assert(!params.top_level); - BoundBox bbox; + BoundBox bbox = BoundBox::empty; uint visibility = 0; refit_node(0, (pack.is_leaf[0])? true: false, bbox, visibility); } @@ -572,7 +572,7 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility } else { /* refit inner node, set bbox from children */ - BoundBox bbox0, bbox1; + BoundBox bbox0 = BoundBox::empty, bbox1 = BoundBox::empty; uint visibility0 = 0, visibility1 = 0; refit_node((c0 < 0)? -c0-1: c0, (c0 < 0), bbox0, visibility0); diff --git a/intern/cycles/bvh/bvh_binning.cpp b/intern/cycles/bvh/bvh_binning.cpp new file mode 100644 index 00000000000..def5309e551 --- /dev/null +++ b/intern/cycles/bvh/bvh_binning.cpp @@ -0,0 +1,219 @@ +/* + * Adapted from code copyright 2009-2011 Intel Corporation + * Modifications Copyright 2012, Blender Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bvh_binning.h" + +#include "util_algorithm.h" +#include "util_boundbox.h" +#include "util_types.h" + +CCL_NAMESPACE_BEGIN + +/* SSE replacements */ + +__forceinline void prefetch_L1 (const void* ptr) { } +__forceinline void prefetch_L2 (const void* ptr) { } +__forceinline void prefetch_L3 (const void* ptr) { } +__forceinline void prefetch_NTA(const void* ptr) { } + +template __forceinline float extract(const int4& b) +{ return b[src]; } +template __forceinline const float4 insert(const float4& a, const float b) +{ float4 r = a; r[dst] = b; return r; } + +__forceinline int get_best_dimension(const float4& bestSAH) +{ + // return (int)__bsf(movemask(reduce_min(bestSAH) == bestSAH)); + + float minSAH = min(bestSAH.x, min(bestSAH.y, bestSAH.z)); + + if(bestSAH.x == minSAH) return 0; + else if(bestSAH.y == minSAH) return 1; + else return 2; +} + +/* BVH Object Binning */ + +BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims) +: BVHRange(job), splitSAH(FLT_MAX), dim(0), pos(0) +{ + /* compute number of bins to use and precompute scaling factor for binning */ + num_bins = min(size_t(MAX_BINS), size_t(4.0f + 0.05f*size())); + scale = rcp(cent_bounds().size()) * make_float3((float)num_bins); + + /* initialize binning counter and bounds */ + BoundBox bin_bounds[MAX_BINS][4]; /* bounds for every bin in every dimension */ + int4 bin_count[MAX_BINS]; /* number of primitives mapped to bin */ + + for(size_t i = 0; i < num_bins; i++) { + bin_count[i] = make_int4(0); + bin_bounds[i][0] = bin_bounds[i][1] = bin_bounds[i][2] = BoundBox::empty; + } + + /* map geometry to bins, unrolled once */ + { + ssize_t i; + + for(i = 0; i < ssize_t(size()) - 1; i += 2) { + prefetch_L2(&prims[start() + i + 8]); + + /* map even and odd primitive to bin */ + BVHReference prim0 = prims[start() + i + 0]; + BVHReference prim1 = prims[start() + i + 1]; + + int4 bin0 = get_bin(prim0.bounds()); + int4 bin1 = get_bin(prim1.bounds()); + + /* increase bounds for bins for even primitive */ + int b00 = extract<0>(bin0); bin_count[b00][0]++; bin_bounds[b00][0].grow(prim0.bounds()); + int b01 = extract<1>(bin0); bin_count[b01][1]++; bin_bounds[b01][1].grow(prim0.bounds()); + int b02 = extract<2>(bin0); bin_count[b02][2]++; bin_bounds[b02][2].grow(prim0.bounds()); + + /* increase bounds of bins for odd primitive */ + int b10 = extract<0>(bin1); bin_count[b10][0]++; bin_bounds[b10][0].grow(prim1.bounds()); + int b11 = extract<1>(bin1); bin_count[b11][1]++; bin_bounds[b11][1].grow(prim1.bounds()); + int b12 = extract<2>(bin1); bin_count[b12][2]++; bin_bounds[b12][2].grow(prim1.bounds()); + } + + /* for uneven number of primitives */ + if(i < ssize_t(size())) { + /* map primitive to bin */ + BVHReference prim0 = prims[start() + i]; + int4 bin0 = get_bin(prim0.bounds()); + + /* increase bounds of bins */ + int b00 = extract<0>(bin0); bin_count[b00][0]++; bin_bounds[b00][0].grow(prim0.bounds()); + int b01 = extract<1>(bin0); bin_count[b01][1]++; bin_bounds[b01][1].grow(prim0.bounds()); + int b02 = extract<2>(bin0); bin_count[b02][2]++; bin_bounds[b02][2].grow(prim0.bounds()); + } + } + + /* sweep from right to left and compute parallel prefix of merged bounds */ + float4 r_area[MAX_BINS]; /* area of bounds of primitives on the right */ + float4 r_count[MAX_BINS]; /* number of primitives on the right */ + int4 count = make_int4(0); + + BoundBox bx = BoundBox::empty; + BoundBox by = BoundBox::empty; + BoundBox bz = BoundBox::empty; + + for(size_t i = num_bins - 1; i > 0; i--) { + count = count + bin_count[i]; + r_count[i] = blocks(count); + + bx = merge(bx,bin_bounds[i][0]); r_area[i][0] = bx.half_area(); + by = merge(by,bin_bounds[i][1]); r_area[i][1] = by.half_area(); + bz = merge(bz,bin_bounds[i][2]); r_area[i][2] = bz.half_area(); + } + + /* sweep from left to right and compute SAH */ + int4 ii = make_int4(1); + float4 bestSAH = make_float4(FLT_MAX); + int4 bestSplit = make_int4(-1); + + count = make_int4(0); + + bx = BoundBox::empty; + by = BoundBox::empty; + bz = BoundBox::empty; + + for(size_t i = 1; i < num_bins; i++, ii += make_int4(1)) { + count = count + bin_count[i-1]; + + bx = merge(bx,bin_bounds[i-1][0]); float Ax = bx.half_area(); + by = merge(by,bin_bounds[i-1][1]); float Ay = by.half_area(); + bz = merge(bz,bin_bounds[i-1][2]); float Az = bz.half_area(); + + float4 lCount = blocks(count); + float4 lArea = make_float4(Ax,Ay,Az,Az); + float4 sah = lArea*lCount + r_area[i]*r_count[i]; + + bestSplit = select(sah < bestSAH,ii,bestSplit); + bestSAH = min(sah,bestSAH); + } + + int4 mask = float3_to_float4(cent_bounds().size()) <= make_float4(0.0f); + bestSAH = insert<3>(select(mask, make_float4(FLT_MAX), bestSAH), FLT_MAX); + + /* find best dimension */ + dim = get_best_dimension(bestSAH); + splitSAH = bestSAH[dim]; + pos = bestSplit[dim]; + leafSAH = bounds().half_area() * blocks(size()); +} + +void BVHObjectBinning::split(BVHReference* prims, BVHObjectBinning& left_o, BVHObjectBinning& right_o) const +{ + size_t N = size(); + + BoundBox lgeom_bounds = BoundBox::empty; + BoundBox rgeom_bounds = BoundBox::empty; + BoundBox lcent_bounds = BoundBox::empty; + BoundBox rcent_bounds = BoundBox::empty; + + ssize_t l = 0, r = N-1; + + while(l <= r) { + prefetch_L2(&prims[start() + l + 8]); + prefetch_L2(&prims[start() + r - 8]); + + BVHReference prim = prims[start() + l]; + float3 center = prim.bounds().center2(); + + if(get_bin(center)[dim] < pos) { + lgeom_bounds.grow(prim.bounds()); + lcent_bounds.grow(center); + l++; + } + else { + rgeom_bounds.grow(prim.bounds()); + rcent_bounds.grow(center); + swap(prims[start()+l],prims[start()+r]); + r--; + } + } + + /* finish */ + if(l != 0 && N-1-r != 0) { + right_o = BVHObjectBinning(BVHRange(rgeom_bounds, rcent_bounds, start() + l, N-1-r), prims); + left_o = BVHObjectBinning(BVHRange(lgeom_bounds, lcent_bounds, start(), l), prims); + return; + } + + /* object medium split if we did not make progress, can happen when all + primitives have same centroid */ + lgeom_bounds = BoundBox::empty; + rgeom_bounds = BoundBox::empty; + lcent_bounds = BoundBox::empty; + rcent_bounds = BoundBox::empty; + + for(size_t i = 0; i < N/2; i++) { + lgeom_bounds.grow(prims[start()+i].bounds()); + lcent_bounds.grow(prims[start()+i].bounds().center2()); + } + + for(size_t i = N/2; i < N; i++) { + rgeom_bounds.grow(prims[start()+i].bounds()); + rcent_bounds.grow(prims[start()+i].bounds().center2()); + } + + right_o = BVHObjectBinning(BVHRange(rgeom_bounds, rcent_bounds, start() + N/2, N/2 + N%2), prims); + left_o = BVHObjectBinning(BVHRange(lgeom_bounds, lcent_bounds, start(), N/2), prims); +} + +CCL_NAMESPACE_END + diff --git a/intern/cycles/bvh/bvh_binning.h b/intern/cycles/bvh/bvh_binning.h new file mode 100644 index 00000000000..60742157055 --- /dev/null +++ b/intern/cycles/bvh/bvh_binning.h @@ -0,0 +1,86 @@ +/* + * Adapted from code copyright 2009-2011 Intel Corporation + * Modifications Copyright 2012, Blender Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BVH_BINNING_H__ +#define __BVH_BINNING_H__ + +#include "bvh_params.h" + +#include "util_types.h" + +CCL_NAMESPACE_BEGIN + +/* Single threaded object binner. Finds the split with the best SAH heuristic + * by testing for each dimension multiple partitionings for regular spaced + * partition locations. A partitioning for a partition location is computed, + * by putting primitives whose centroid is on the left and right of the split + * location to different sets. The SAH is evaluated by computing the number of + * blocks occupied by the primitives in the partitions. */ + +class BVHObjectBinning : public BVHRange +{ +public: + __forceinline BVHObjectBinning() {} + BVHObjectBinning(const BVHRange& job, BVHReference *prims); + + void split(BVHReference *prims, BVHObjectBinning& left_o, BVHObjectBinning& right_o) const; + + float splitSAH; /* SAH cost of the best split */ + float leafSAH; /* SAH cost of creating a leaf */ + +protected: + int dim; /* best split dimension */ + int pos; /* best split position */ + size_t num_bins; /* actual number of bins to use */ + float3 scale; /* scaling factor to compute bin */ + + enum { MAX_BINS = 32 }; + enum { LOG_BLOCK_SIZE = 2 }; + + /* computes the bin numbers for each dimension for a box. */ + __forceinline int4 get_bin(const BoundBox& box) const + { + int4 a = make_int4((box.center2() - cent_bounds().min)*scale - make_float3(0.5f)); + int4 mn = make_int4(0); + int4 mx = make_int4((int)num_bins-1); + + return clamp(a, mn, mx); + } + + /* computes the bin numbers for each dimension for a point. */ + __forceinline int4 get_bin(const float3& c) const + { + return make_int4((c - cent_bounds().min)*scale - make_float3(0.5f)); + } + + /* compute the number of blocks occupied for each dimension. */ + __forceinline float4 blocks(const int4& a) const + { + return make_float4((a + make_int4((1 << LOG_BLOCK_SIZE)-1)) >> LOG_BLOCK_SIZE); + } + + /* compute the number of blocks occupied in one dimension. */ + __forceinline int blocks(size_t a) const + { + return (int)((a+((1LL << LOG_BLOCK_SIZE)-1)) >> LOG_BLOCK_SIZE); + } +}; + +CCL_NAMESPACE_END + +#endif + diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index 38674c2c561..c5b4f1d01ae 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -15,22 +15,36 @@ * limitations under the License. */ +#include "bvh_binning.h" #include "bvh_build.h" #include "bvh_node.h" #include "bvh_params.h" -#include "bvh_sort.h" +#include "bvh_split.h" #include "mesh.h" #include "object.h" #include "scene.h" -#include "util_algorithm.h" +#include "util_debug.h" #include "util_foreach.h" #include "util_progress.h" #include "util_time.h" CCL_NAMESPACE_BEGIN +/* BVH Build Task */ + +class BVHBuildTask : public Task { +public: + BVHBuildTask(InnerNode *node_, int child_, BVHObjectBinning& range_, int level_) + : node(node_), child(child_), level(level_), range(range_) {} + + InnerNode *node; + int child; + int level; + BVHObjectBinning range; +}; + /* Constructor / Destructor */ BVHBuild::BVHBuild(const vector& objects_, @@ -41,10 +55,10 @@ BVHBuild::BVHBuild(const vector& objects_, prim_object(prim_object_), params(params_), progress(progress_), - progress_start_time(0.0) + progress_start_time(0.0), + task_pool(function_bind(&BVHBuild::thread_build_node, this, _1, _2)) { spatial_min_overlap = 0.0f; - progress_num_duplicates = 0; } BVHBuild::~BVHBuild() @@ -53,57 +67,63 @@ BVHBuild::~BVHBuild() /* Adding References */ -void BVHBuild::add_reference_mesh(NodeSpec& root, Mesh *mesh, int i) +void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i) { for(uint j = 0; j < mesh->triangles.size(); j++) { Mesh::Triangle t = mesh->triangles[j]; - Reference ref; + BoundBox bounds = BoundBox::empty; for(int k = 0; k < 3; k++) { float3 pt = mesh->verts[t.v[k]]; - ref.bounds.grow(pt); + bounds.grow(pt); } - if(ref.bounds.valid()) { - ref.prim_index = j; - ref.prim_object = i; - - references.push_back(ref); - root.bounds.grow(ref.bounds); + if(bounds.valid()) { + references.push_back(BVHReference(bounds, j, i)); + root.grow(bounds); + center.grow(bounds.center2()); } } } -void BVHBuild::add_reference_object(NodeSpec& root, Object *ob, int i) +void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i) { - Reference ref; - - ref.prim_index = -1; - ref.prim_object = i; - ref.bounds = ob->bounds; - - references.push_back(ref); - root.bounds.grow(ref.bounds); + references.push_back(BVHReference(ob->bounds, -1, i)); + root.grow(ob->bounds); + center.grow(ob->bounds.center2()); } -void BVHBuild::add_references(NodeSpec& root) +void BVHBuild::add_references(BVHRange& root) { - /* init root spec */ - root.num = 0; - root.bounds = BoundBox(); + /* reserve space for references */ + size_t num_alloc_references = 0; - /* add objects */ + foreach(Object *ob, objects) { + if(params.top_level) { + if(ob->mesh->transform_applied) + num_alloc_references += ob->mesh->triangles.size(); + else + num_alloc_references++; + } + else + num_alloc_references += ob->mesh->triangles.size(); + } + + references.reserve(num_alloc_references); + + /* add references from objects */ + BoundBox bounds = BoundBox::empty, center = BoundBox::empty; int i = 0; foreach(Object *ob, objects) { if(params.top_level) { if(ob->mesh->transform_applied) - add_reference_mesh(root, ob->mesh, i); + add_reference_mesh(bounds, center, ob->mesh, i); else - add_reference_object(root, ob, i); + add_reference_object(bounds, center, ob, i); } else - add_reference_mesh(root, ob->mesh, i); + add_reference_mesh(bounds, center, ob->mesh, i); i++; @@ -111,129 +131,213 @@ void BVHBuild::add_references(NodeSpec& root) } /* happens mostly on empty meshes */ - if(!root.bounds.valid()) - root.bounds.grow(make_float3(0.0f, 0.0f, 0.0f)); + if(!bounds.valid()) + bounds.grow(make_float3(0.0f, 0.0f, 0.0f)); - root.num = references.size(); + root = BVHRange(bounds, center, 0, references.size()); } /* Build */ BVHNode* BVHBuild::run() { - NodeSpec root; + BVHRange root; /* add references */ add_references(root); - if(progress.get_cancel()) return NULL; + if(progress.get_cancel()) + return NULL; /* init spatial splits */ if(params.top_level) /* todo: get rid of this */ params.use_spatial_split = false; - spatial_min_overlap = root.bounds.area() * params.spatial_split_alpha; + spatial_min_overlap = root.bounds().safe_area() * params.spatial_split_alpha; spatial_right_bounds.clear(); - spatial_right_bounds.resize(max(root.num, (int)BVHParams::NUM_SPATIAL_BINS) - 1); + spatial_right_bounds.resize(max(root.size(), (int)BVHParams::NUM_SPATIAL_BINS) - 1); /* init progress updates */ - progress_num_duplicates = 0; progress_start_time = time_dt(); + progress_count = 0; + progress_total = references.size(); + progress_original_total = progress_total; + + prim_index.resize(references.size()); + prim_object.resize(references.size()); /* build recursively */ - return build_node(root, 0, 0.0f, 1.0f); + BVHNode *rootnode; + + if(params.use_spatial_split) { + /* singlethreaded spatial split build */ + rootnode = build_node(root, 0); + } + else { + /* multithreaded binning build */ + BVHObjectBinning rootbin(root, &references[0]); + rootnode = build_node(rootbin, 0); + task_pool.wait(); + } + + /* delete if we cancelled */ + if(rootnode) { + if(progress.get_cancel()) { + rootnode->deleteSubtree(); + rootnode = NULL; + } + else if(!params.use_spatial_split) { + /*rotate(rootnode, 4, 5);*/ + rootnode->update_visibility(); + } + } + + return rootnode; } -void BVHBuild::progress_update(float progress_start, float progress_end) +void BVHBuild::progress_update() { if(time_dt() - progress_start_time < 0.25f) return; + + double progress_start = (double)progress_count/(double)progress_total; + double duplicates = (double)(progress_total - progress_original_total)/(double)progress_total; - float duplicates = (float)progress_num_duplicates/(float)references.size(); string msg = string_printf("Building BVH %.0f%%, duplicates %.0f%%", progress_start*100.0f, duplicates*100.0f); progress.set_substatus(msg); - progress_start_time = time_dt(); + progress_start_time = time_dt(); } -BVHNode* BVHBuild::build_node(const NodeSpec& spec, int level, float progress_start, float progress_end) +void BVHBuild::thread_build_node(Task *task_, int thread_id) { - /* progress update */ - progress_update(progress_start, progress_end); - if(progress.get_cancel()) return NULL; + if(progress.get_cancel()) + return; - /* small enough or too deep => create leaf. */ - if(spec.num <= params.min_leaf_size || level >= BVHParams::MAX_DEPTH) - return create_leaf_node(spec); + /* build nodes */ + BVHBuildTask *task = (BVHBuildTask*)task_; + BVHNode *node = build_node(task->range, task->level); - /* find split candidates. */ - float area = spec.bounds.area(); - float leafSAH = area * params.triangle_cost(spec.num); - float nodeSAH = area * params.node_cost(2); - ObjectSplit object = find_object_split(spec, nodeSAH); - SpatialSplit spatial; + /* set child in inner node */ + task->node->children[task->child] = node; - if(params.use_spatial_split && level < BVHParams::MAX_SPATIAL_DEPTH) { - BoundBox overlap = object.left_bounds; - overlap.intersect(object.right_bounds); + /* update progress */ + if(task->range.size() < THREAD_TASK_SIZE) { + /*rotate(node, INT_MAX, 5);*/ - if(overlap.area() >= spatial_min_overlap) - spatial = find_spatial_split(spec, nodeSAH); + thread_scoped_lock lock(build_mutex); + + progress_count += task->range.size(); + progress_update(); } +} - /* leaf SAH is the lowest => create leaf. */ - float minSAH = min(min(leafSAH, object.sah), spatial.sah); +/* multithreaded binning builder */ +BVHNode* BVHBuild::build_node(const BVHObjectBinning& range, int level) +{ + size_t size = range.size(); + float leafSAH = params.sah_triangle_cost * range.leafSAH; + float splitSAH = params.sah_node_cost * range.bounds().half_area() + params.sah_triangle_cost * range.splitSAH; - if(minSAH == leafSAH && spec.num <= params.max_leaf_size) - return create_leaf_node(spec); + /* make leaf node when threshold reached or SAH tells us */ + if(params.small_enough_for_leaf(size, level) || (size <= params.max_leaf_size && leafSAH < splitSAH)) + return create_leaf_node(range); - /* perform split. */ - NodeSpec left, right; - - if(params.use_spatial_split && minSAH == spatial.sah) - do_spatial_split(left, right, spec, spatial); - if(!left.num || !right.num) - do_object_split(left, right, spec, object); + /* perform split */ + BVHObjectBinning left, right; + range.split(&references[0], left, right); /* create inner node. */ - progress_num_duplicates += left.num + right.num - spec.num; + InnerNode *inner; - float progress_mid = lerp(progress_start, progress_end, (float)right.num / (float)(left.num + right.num)); + if(range.size() < THREAD_TASK_SIZE) { + /* local build */ + BVHNode *leftnode = build_node(left, level + 1); + BVHNode *rightnode = build_node(right, level + 1); - BVHNode* rightNode = build_node(right, level + 1, progress_start, progress_mid); - if(progress.get_cancel()) { - if(rightNode) rightNode->deleteSubtree(); - return NULL; + inner = new InnerNode(range.bounds(), leftnode, rightnode); + } + else { + /* threaded build */ + inner = new InnerNode(range.bounds()); + + task_pool.push(new BVHBuildTask(inner, 0, left, level + 1), true); + task_pool.push(new BVHBuildTask(inner, 1, right, level + 1), true); } - BVHNode* leftNode = build_node(left, level + 1, progress_mid, progress_end); - if(progress.get_cancel()) { - if(leftNode) leftNode->deleteSubtree(); - return NULL; - } - - return new InnerNode(spec.bounds, leftNode, rightNode); + return inner; } -BVHNode *BVHBuild::create_object_leaf_nodes(const Reference *ref, int num) +/* single threaded spatial split builder */ +BVHNode* BVHBuild::build_node(const BVHRange& range, int level) +{ + /* progress update */ + progress_update(); + if(progress.get_cancel()) + return NULL; + + /* small enough or too deep => create leaf. */ + if(params.small_enough_for_leaf(range.size(), level)) { + progress_count += range.size(); + return create_leaf_node(range); + } + + /* splitting test */ + BVHMixedSplit split(this, range, level); + + if(split.no_split) { + progress_count += range.size(); + return create_leaf_node(range); + } + + /* do split */ + BVHRange left, right; + split.split(this, left, right, range); + + progress_total += left.size() + right.size() - range.size(); + size_t total = progress_total; + + /* leaft node */ + BVHNode *leftnode = build_node(left, level + 1); + + /* right node (modify start for splits) */ + right.set_start(right.start() + progress_total - total); + BVHNode *rightnode = build_node(right, level + 1); + + /* inner node */ + return new InnerNode(range.bounds(), leftnode, rightnode); +} + +/* Create Nodes */ + +BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start, int num) { if(num == 0) { - BoundBox bounds; + BoundBox bounds = BoundBox::empty; return new LeafNode(bounds, 0, 0, 0); } else if(num == 1) { - prim_index.push_back(ref[0].prim_index); - prim_object.push_back(ref[0].prim_object); - uint visibility = objects[ref[0].prim_object]->visibility; - return new LeafNode(ref[0].bounds, visibility, prim_index.size()-1, prim_index.size()); + if(start == prim_index.size()) { + assert(params.use_spatial_split); + + prim_index.push_back(ref->prim_index()); + prim_object.push_back(ref->prim_object()); + } + else { + prim_index[start] = ref->prim_index(); + prim_object[start] = ref->prim_object(); + } + + uint visibility = objects[ref->prim_object()]->visibility; + return new LeafNode(ref->bounds(), visibility, start, start+1); } else { int mid = num/2; - BVHNode *leaf0 = create_object_leaf_nodes(ref, mid); - BVHNode *leaf1 = create_object_leaf_nodes(ref+mid, num-mid); + BVHNode *leaf0 = create_object_leaf_nodes(ref, start, mid); + BVHNode *leaf1 = create_object_leaf_nodes(ref+mid, start+mid, num-mid); - BoundBox bounds; + BoundBox bounds = BoundBox::empty; bounds.grow(leaf0->m_bounds); bounds.grow(leaf1->m_bounds); @@ -241,310 +345,136 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const Reference *ref, int num) } } -BVHNode* BVHBuild::create_leaf_node(const NodeSpec& spec) +BVHNode* BVHBuild::create_leaf_node(const BVHRange& range) { vector& p_index = prim_index; vector& p_object = prim_object; - BoundBox bounds; - int num = 0; + BoundBox bounds = BoundBox::empty; + int num = 0, ob_num = 0; uint visibility = 0; - for(int i = 0; i < spec.num; i++) { - if(references.back().prim_index != -1) { - p_index.push_back(references.back().prim_index); - p_object.push_back(references.back().prim_object); - bounds.grow(references.back().bounds); - visibility |= objects[references.back().prim_object]->visibility; - references.pop_back(); + for(int i = 0; i < range.size(); i++) { + BVHReference& ref = references[range.start() + i]; + + if(ref.prim_index() != -1) { + if(range.start() + num == prim_index.size()) { + assert(params.use_spatial_split); + + p_index.push_back(ref.prim_index()); + p_object.push_back(ref.prim_object()); + } + else { + p_index[range.start() + num] = ref.prim_index(); + p_object[range.start() + num] = ref.prim_object(); + } + + bounds.grow(ref.bounds()); + visibility |= objects[ref.prim_object()]->visibility; num++; } + else { + if(ob_num < i) + references[range.start() + ob_num] = ref; + ob_num++; + } } BVHNode *leaf = NULL; if(num > 0) { - leaf = new LeafNode(bounds, visibility, p_index.size() - num, p_index.size()); + leaf = new LeafNode(bounds, visibility, range.start(), range.start() + num); - if(num == spec.num) + if(num == range.size()) return leaf; } /* while there may be multiple triangles in a leaf, for object primitives - * we want them to be the only one, so we */ - int ob_num = spec.num - num; - const Reference *ref = (ob_num)? &references.back() - (ob_num - 1): NULL; - BVHNode *oleaf = create_object_leaf_nodes(ref, ob_num); - for(int i = 0; i < ob_num; i++) - references.pop_back(); + * we want there to be the only one, so we keep splitting */ + const BVHReference *ref = (ob_num)? &references[range.start()]: NULL; + BVHNode *oleaf = create_object_leaf_nodes(ref, range.start() + num, ob_num); if(leaf) - return new InnerNode(spec.bounds, leaf, oleaf); + return new InnerNode(range.bounds(), leaf, oleaf); else return oleaf; } -/* Object Split */ +/* Tree Rotations */ -BVHBuild::ObjectSplit BVHBuild::find_object_split(const NodeSpec& spec, float nodeSAH) +void BVHBuild::rotate(BVHNode *node, int max_depth, int iterations) { - ObjectSplit split; - const Reference *ref_ptr = &references[references.size() - spec.num]; + /* in tested scenes, this resulted in slightly slower raytracing, so disabled + * it for now. could be implementation bug, or depend on the scene */ + if(node) + for(int i = 0; i < iterations; i++) + rotate(node, max_depth); +} - for(int dim = 0; dim < 3; dim++) { - /* sort references */ - bvh_reference_sort(references.size() - spec.num, references.size(), &references[0], dim); +void BVHBuild::rotate(BVHNode *node, int max_depth) +{ + /* nothing to rotate if we reached a leaf node. */ + if(node->is_leaf() || max_depth < 0) + return; + + InnerNode *parent = (InnerNode*)node; - /* sweep right to left and determine bounds. */ - BoundBox right_bounds; + /* rotate all children first */ + for(size_t c = 0; c < 2; c++) + rotate(parent->children[c], max_depth-1); - for(int i = spec.num - 1; i > 0; i--) { - right_bounds.grow(ref_ptr[i].bounds); - spatial_right_bounds[i - 1] = right_bounds; - } + /* compute current area of all children */ + BoundBox bounds0 = parent->children[0]->m_bounds; + BoundBox bounds1 = parent->children[1]->m_bounds; - /* sweep left to right and select lowest SAH. */ - BoundBox left_bounds; + float area0 = bounds0.half_area(); + float area1 = bounds1.half_area(); + float4 child_area = make_float4(area0, area1, 0.0f, 0.0f); - for(int i = 1; i < spec.num; i++) { - left_bounds.grow(ref_ptr[i - 1].bounds); - right_bounds = spatial_right_bounds[i - 1]; + /* find best rotation. we pick a target child of a first child, and swap + * this with an other child. we perform the best such swap. */ + float best_cost = FLT_MAX; + int best_child = -1, bets_target = -1, best_other = -1; - float sah = nodeSAH + - left_bounds.area() * params.triangle_cost(i) + - right_bounds.area() * params.triangle_cost(spec.num - i); + for(size_t c = 0; c < 2; c++) { + /* ignore leaf nodes as we cannot descent into */ + if(parent->children[c]->is_leaf()) + continue; - if(sah < split.sah) { - split.sah = sah; - split.dim = dim; - split.num_left = i; - split.left_bounds = left_bounds; - split.right_bounds = right_bounds; + InnerNode *child = (InnerNode*)parent->children[c]; + BoundBox& other = (c == 0)? bounds1: bounds0; + + /* transpose child bounds */ + BoundBox target0 = child->children[0]->m_bounds; + BoundBox target1 = child->children[1]->m_bounds; + + /* compute cost for both possible swaps */ + float cost0 = merge(other, target1).half_area() - child_area[c]; + float cost1 = merge(target0, other).half_area() - child_area[c]; + + if(min(cost0,cost1) < best_cost) { + best_child = (int)c; + best_other = (int)(1-c); + + if(cost0 < cost1) { + best_cost = cost0; + bets_target = 0; + } + else { + best_cost = cost0; + bets_target = 1; } } } - return split; -} + /* if we did not find a swap that improves the SAH then do nothing */ + if(best_cost >= 0) + return; -void BVHBuild::do_object_split(NodeSpec& left, NodeSpec& right, const NodeSpec& spec, const ObjectSplit& split) -{ - /* sort references according to split */ - int start = references.size() - spec.num; - int end = references.size(); /* todo: is this right? */ + /* perform the best found tree rotation */ + InnerNode *child = (InnerNode*)parent->children[best_child]; - bvh_reference_sort(start, end, &references[0], split.dim); - - /* split node specs */ - left.num = split.num_left; - left.bounds = split.left_bounds; - right.num = spec.num - split.num_left; - right.bounds = split.right_bounds; -} - -/* Spatial Split */ - -BVHBuild::SpatialSplit BVHBuild::find_spatial_split(const NodeSpec& spec, float nodeSAH) -{ - /* initialize bins. */ - float3 origin = spec.bounds.min; - float3 binSize = (spec.bounds.max - origin) * (1.0f / (float)BVHParams::NUM_SPATIAL_BINS); - float3 invBinSize = 1.0f / binSize; - - for(int dim = 0; dim < 3; dim++) { - for(int i = 0; i < BVHParams::NUM_SPATIAL_BINS; i++) { - SpatialBin& bin = spatial_bins[dim][i]; - - bin.bounds = BoundBox(); - bin.enter = 0; - bin.exit = 0; - } - } - - /* chop references into bins. */ - for(unsigned int refIdx = references.size() - spec.num; refIdx < references.size(); refIdx++) { - const Reference& ref = references[refIdx]; - float3 firstBinf = (ref.bounds.min - origin) * invBinSize; - float3 lastBinf = (ref.bounds.max - origin) * invBinSize; - int3 firstBin = make_int3((int)firstBinf.x, (int)firstBinf.y, (int)firstBinf.z); - int3 lastBin = make_int3((int)lastBinf.x, (int)lastBinf.y, (int)lastBinf.z); - - firstBin = clamp(firstBin, 0, BVHParams::NUM_SPATIAL_BINS - 1); - lastBin = clamp(lastBin, firstBin, BVHParams::NUM_SPATIAL_BINS - 1); - - for(int dim = 0; dim < 3; dim++) { - Reference currRef = ref; - - for(int i = firstBin[dim]; i < lastBin[dim]; i++) { - Reference leftRef, rightRef; - - split_reference(leftRef, rightRef, currRef, dim, origin[dim] + binSize[dim] * (float)(i + 1)); - spatial_bins[dim][i].bounds.grow(leftRef.bounds); - currRef = rightRef; - } - - spatial_bins[dim][lastBin[dim]].bounds.grow(currRef.bounds); - spatial_bins[dim][firstBin[dim]].enter++; - spatial_bins[dim][lastBin[dim]].exit++; - } - } - - /* select best split plane. */ - SpatialSplit split; - - for(int dim = 0; dim < 3; dim++) { - /* sweep right to left and determine bounds. */ - BoundBox right_bounds; - - for(int i = BVHParams::NUM_SPATIAL_BINS - 1; i > 0; i--) { - right_bounds.grow(spatial_bins[dim][i].bounds); - spatial_right_bounds[i - 1] = right_bounds; - } - - /* sweep left to right and select lowest SAH. */ - BoundBox left_bounds; - int leftNum = 0; - int rightNum = spec.num; - - for(int i = 1; i < BVHParams::NUM_SPATIAL_BINS; i++) { - left_bounds.grow(spatial_bins[dim][i - 1].bounds); - leftNum += spatial_bins[dim][i - 1].enter; - rightNum -= spatial_bins[dim][i - 1].exit; - - float sah = nodeSAH + - left_bounds.area() * params.triangle_cost(leftNum) + - spatial_right_bounds[i - 1].area() * params.triangle_cost(rightNum); - - if(sah < split.sah) { - split.sah = sah; - split.dim = dim; - split.pos = origin[dim] + binSize[dim] * (float)i; - } - } - } - - return split; -} - -void BVHBuild::do_spatial_split(NodeSpec& left, NodeSpec& right, const NodeSpec& spec, const SpatialSplit& split) -{ - /* Categorize references and compute bounds. - * - * Left-hand side: [left_start, left_end[ - * Uncategorized/split: [left_end, right_start[ - * Right-hand side: [right_start, refs.size()[ */ - - vector& refs = references; - int left_start = refs.size() - spec.num; - int left_end = left_start; - int right_start = refs.size(); - - left.bounds = right.bounds = BoundBox(); - - for(int i = left_end; i < right_start; i++) { - if(refs[i].bounds.max[split.dim] <= split.pos) { - /* entirely on the left-hand side */ - left.bounds.grow(refs[i].bounds); - swap(refs[i], refs[left_end++]); - } - else if(refs[i].bounds.min[split.dim] >= split.pos) { - /* entirely on the right-hand side */ - right.bounds.grow(refs[i].bounds); - swap(refs[i--], refs[--right_start]); - } - } - - /* duplicate or unsplit references intersecting both sides. */ - while(left_end < right_start) { - /* split reference. */ - Reference lref, rref; - - split_reference(lref, rref, refs[left_end], split.dim, split.pos); - - /* compute SAH for duplicate/unsplit candidates. */ - BoundBox lub = left.bounds; // Unsplit to left: new left-hand bounds. - BoundBox rub = right.bounds; // Unsplit to right: new right-hand bounds. - BoundBox ldb = left.bounds; // Duplicate: new left-hand bounds. - BoundBox rdb = right.bounds; // Duplicate: new right-hand bounds. - - lub.grow(refs[left_end].bounds); - rub.grow(refs[left_end].bounds); - ldb.grow(lref.bounds); - rdb.grow(rref.bounds); - - float lac = params.triangle_cost(left_end - left_start); - float rac = params.triangle_cost(refs.size() - right_start); - float lbc = params.triangle_cost(left_end - left_start + 1); - float rbc = params.triangle_cost(refs.size() - right_start + 1); - - float unsplitLeftSAH = lub.area() * lbc + right.bounds.area() * rac; - float unsplitRightSAH = left.bounds.area() * lac + rub.area() * rbc; - float duplicateSAH = ldb.area() * lbc + rdb.area() * rbc; - float minSAH = min(min(unsplitLeftSAH, unsplitRightSAH), duplicateSAH); - - if(minSAH == unsplitLeftSAH) { - /* unsplit to left */ - left.bounds = lub; - left_end++; - } - else if(minSAH == unsplitRightSAH) { - /* unsplit to right */ - right.bounds = rub; - swap(refs[left_end], refs[--right_start]); - } - else { - /* duplicate */ - left.bounds = ldb; - right.bounds = rdb; - refs[left_end++] = lref; - refs.push_back(rref); - } - } - - left.num = left_end - left_start; - right.num = refs.size() - right_start; -} - -void BVHBuild::split_reference(Reference& left, Reference& right, const Reference& ref, int dim, float pos) -{ - /* initialize references. */ - left.prim_index = right.prim_index = ref.prim_index; - left.prim_object = right.prim_object = ref.prim_object; - left.bounds = right.bounds = BoundBox(); - - /* loop over vertices/edges. */ - Object *ob = objects[ref.prim_object]; - const Mesh *mesh = ob->mesh; - const int *inds = mesh->triangles[ref.prim_index].v; - const float3 *verts = &mesh->verts[0]; - const float3* v1 = &verts[inds[2]]; - - for(int i = 0; i < 3; i++) { - const float3* v0 = v1; - int vindex = inds[i]; - v1 = &verts[vindex]; - float v0p = (*v0)[dim]; - float v1p = (*v1)[dim]; - - /* insert vertex to the boxes it belongs to. */ - if(v0p <= pos) - left.bounds.grow(*v0); - - if(v0p >= pos) - right.bounds.grow(*v0); - - /* edge intersects the plane => insert intersection to both boxes. */ - if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) { - float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); - left.bounds.grow(t); - right.bounds.grow(t); - } - } - - /* intersect with original bounds. */ - left.bounds.max[dim] = pos; - right.bounds.min[dim] = pos; - left.bounds.intersect(ref.bounds); - right.bounds.intersect(ref.bounds); + swap(parent->children[best_other], child->children[bets_target]); + child->m_bounds = merge(child->children[0]->m_bounds, child->children[1]->m_bounds); } CCL_NAMESPACE_END diff --git a/intern/cycles/bvh/bvh_build.h b/intern/cycles/bvh/bvh_build.h index 1fa1951d7f2..84e14632b4b 100644 --- a/intern/cycles/bvh/bvh_build.h +++ b/intern/cycles/bvh/bvh_build.h @@ -21,8 +21,10 @@ #include #include "bvh.h" +#include "bvh_binning.h" #include "util_boundbox.h" +#include "util_task.h" #include "util_vector.h" CCL_NAMESPACE_BEGIN @@ -37,28 +39,7 @@ class Progress; class BVHBuild { public: - struct Reference - { - int prim_index; - int prim_object; - BoundBox bounds; - - Reference() - { - } - }; - - struct NodeSpec - { - int num; - BoundBox bounds; - - NodeSpec() - { - num = 0; - } - }; - + /* Constructor/Destructor */ BVHBuild( const vector& objects, vector& prim_index, @@ -70,63 +51,37 @@ public: BVHNode *run(); protected: + friend class BVHMixedSplit; + friend class BVHObjectSplit; + friend class BVHSpatialSplit; + /* adding references */ - void add_reference_mesh(NodeSpec& root, Mesh *mesh, int i); - void add_reference_object(NodeSpec& root, Object *ob, int i); - void add_references(NodeSpec& root); + void add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i); + void add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i); + void add_references(BVHRange& root); /* building */ - BVHNode *build_node(const NodeSpec& spec, int level, float progress_start, float progress_end); - BVHNode *create_leaf_node(const NodeSpec& spec); - BVHNode *create_object_leaf_nodes(const Reference *ref, int num); + BVHNode *build_node(const BVHRange& range, int level); + BVHNode *build_node(const BVHObjectBinning& range, int level); + BVHNode *create_leaf_node(const BVHRange& range); + BVHNode *create_object_leaf_nodes(const BVHReference *ref, int start, int num); - void progress_update(float progress_start, float progress_end); + /* threads */ + enum { THREAD_TASK_SIZE = 4096 }; + void thread_build_node(Task *task_, int thread_id); + thread_mutex build_mutex; - /* object splits */ - struct ObjectSplit - { - float sah; - int dim; - int num_left; - BoundBox left_bounds; - BoundBox right_bounds; + /* progress */ + void progress_update(); - ObjectSplit() - : sah(FLT_MAX), dim(0), num_left(0) - { - } - }; - - ObjectSplit find_object_split(const NodeSpec& spec, float nodeSAH); - void do_object_split(NodeSpec& left, NodeSpec& right, const NodeSpec& spec, const ObjectSplit& split); - - /* spatial splits */ - struct SpatialSplit - { - float sah; - int dim; - float pos; - - SpatialSplit() - : sah(FLT_MAX), dim(0), pos(0.0f) - { - } - }; - - struct SpatialBin - { - BoundBox bounds; - int enter; - int exit; - }; - - SpatialSplit find_spatial_split(const NodeSpec& spec, float nodeSAH); - void do_spatial_split(NodeSpec& left, NodeSpec& right, const NodeSpec& spec, const SpatialSplit& split); - void split_reference(Reference& left, Reference& right, const Reference& ref, int dim, float pos); + /* tree rotations */ + void rotate(BVHNode *node, int max_depth); + void rotate(BVHNode *node, int max_depth, int iterations); /* objects and primitive references */ vector objects; - vector references; + vector references; + int num_original_references; /* output primitive indexes and objects */ vector& prim_index; @@ -138,12 +93,17 @@ protected: /* progress reporting */ Progress& progress; double progress_start_time; - int progress_num_duplicates; + size_t progress_count; + size_t progress_total; + size_t progress_original_total; /* spatial splitting */ float spatial_min_overlap; vector spatial_right_bounds; - SpatialBin spatial_bins[3][BVHParams::NUM_SPATIAL_BINS]; + BVHSpatialBin spatial_bins[3][BVHParams::NUM_SPATIAL_BINS]; + + /* threads */ + TaskPool task_pool; }; CCL_NAMESPACE_END diff --git a/intern/cycles/bvh/bvh_node.cpp b/intern/cycles/bvh/bvh_node.cpp index 63683bae4a3..4edfb4b70a4 100644 --- a/intern/cycles/bvh/bvh_node.cpp +++ b/intern/cycles/bvh/bvh_node.cpp @@ -24,6 +24,8 @@ CCL_NAMESPACE_BEGIN +/* BVH Node */ + int BVHNode::getSubtreeSize(BVH_STAT stat) const { int cnt = 0; @@ -59,7 +61,8 @@ int BVHNode::getSubtreeSize(BVH_STAT stat) const void BVHNode::deleteSubtree() { for(int i=0;ideleteSubtree(); + if(get_child(i)) + get_child(i)->deleteSubtree(); delete this; } @@ -70,12 +73,27 @@ float BVHNode::computeSubtreeSAHCost(const BVHParams& p, float probability) cons for(int i=0;icomputeSubtreeSAHCost(p, probability * child->m_bounds.area()/m_bounds.area()); + SAH += child->computeSubtreeSAHCost(p, probability * child->m_bounds.safe_area()/m_bounds.safe_area()); } return SAH; } +uint BVHNode::update_visibility() +{ + if(!is_leaf() && m_visibility == 0) { + InnerNode *inner = (InnerNode*)this; + BVHNode *child0 = inner->children[0]; + BVHNode *child1 = inner->children[1]; + + m_visibility = child0->update_visibility()|child1->update_visibility(); + } + + return m_visibility; +} + +/* Inner Node */ + void InnerNode::print(int depth) const { for(int i = 0; i < depth; i++) diff --git a/intern/cycles/bvh/bvh_node.h b/intern/cycles/bvh/bvh_node.h index 5e0a17a1193..5c00f7b7a38 100644 --- a/intern/cycles/bvh/bvh_node.h +++ b/intern/cycles/bvh/bvh_node.h @@ -49,8 +49,6 @@ public: virtual int num_triangles() const { return 0; } virtual void print(int depth = 0) const = 0; - float getArea() const { return m_bounds.area(); } - BoundBox m_bounds; uint m_visibility; @@ -58,6 +56,8 @@ public: int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const; float computeSubtreeSAHCost(const BVHParams& p, float probability = 1.0f) const; void deleteSubtree(); + + uint update_visibility(); }; class InnerNode : public BVHNode @@ -66,9 +66,21 @@ public: InnerNode(const BoundBox& bounds, BVHNode* child0, BVHNode* child1) { m_bounds = bounds; - m_visibility = child0->m_visibility|child1->m_visibility; children[0] = child0; children[1] = child1; + + if(child0 && child1) + m_visibility = child0->m_visibility|child1->m_visibility; + else + m_visibility = 0; /* happens on build cancel */ + } + + InnerNode(const BoundBox& bounds) + { + m_bounds = bounds; + m_visibility = 0; + children[0] = NULL; + children[1] = NULL; } bool is_leaf() const { return false; } diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h index 38093438500..0cf5e905fea 100644 --- a/intern/cycles/bvh/bvh_params.h +++ b/intern/cycles/bvh/bvh_params.h @@ -18,6 +18,8 @@ #ifndef __BVH_PARAMS_H__ #define __BVH_PARAMS_H__ +#include "util_boundbox.h" + CCL_NAMESPACE_BEGIN /* BVH Parameters */ @@ -73,14 +75,97 @@ public: } /* SAH costs */ - float cost(int num_nodes, int num_tris) const + __forceinline float cost(int num_nodes, int num_tris) const { return node_cost(num_nodes) + triangle_cost(num_tris); } - float triangle_cost(int n) const + __forceinline float triangle_cost(int n) const { return n*sah_triangle_cost; } - float node_cost(int n) const + __forceinline float node_cost(int n) const { return n*sah_node_cost; } + + __forceinline bool small_enough_for_leaf(int size, int level) + { return (size <= min_leaf_size || level >= MAX_DEPTH); } +}; + +/* BVH Reference + * + * Reference to a primitive. Primitive index and object are sneakily packed + * into BoundBox to reduce memory usage and align nicely */ + +class BVHReference +{ +public: + __forceinline BVHReference() {} + + __forceinline BVHReference(const BoundBox& bounds_, int prim_index, int prim_object) + : rbounds(bounds_) + { + rbounds.min.w = __int_as_float(prim_index); + rbounds.max.w = __int_as_float(prim_object); + } + + __forceinline const BoundBox& bounds() const { return rbounds; } + __forceinline int prim_index() const { return __float_as_int(rbounds.min.w); } + __forceinline int prim_object() const { return __float_as_int(rbounds.max.w); } + +protected: + BoundBox rbounds; +}; + +/* BVH Range + * + * Build range used during construction, to indicate the bounds and place in + * the reference array of a subset of pirmitives Again uses trickery to pack + * integers into BoundBox for alignment purposes. */ + +class BVHRange +{ +public: + __forceinline BVHRange() + { + rbounds.min.w = __int_as_float(0); + rbounds.max.w = __int_as_float(0); + } + + __forceinline BVHRange(const BoundBox& bounds_, int start_, int size_) + : rbounds(bounds_) + { + rbounds.min.w = __int_as_float(start_); + rbounds.max.w = __int_as_float(size_); + } + + __forceinline BVHRange(const BoundBox& bounds_, const BoundBox& cbounds_, int start_, int size_) + : rbounds(bounds_), cbounds(cbounds_) + { + rbounds.min.w = __int_as_float(start_); + rbounds.max.w = __int_as_float(size_); + } + + __forceinline void set_start(int start_) { rbounds.min.w = __int_as_float(start_); } + + __forceinline const BoundBox& bounds() const { return rbounds; } + __forceinline const BoundBox& cent_bounds() const { return cbounds; } + __forceinline int start() const { return __float_as_int(rbounds.min.w); } + __forceinline int size() const { return __float_as_int(rbounds.max.w); } + __forceinline int end() const { return start() + size(); } + +protected: + BoundBox rbounds; + BoundBox cbounds; +}; + +/* BVH Spatial Bin */ + +struct BVHSpatialBin +{ + BoundBox bounds; + int enter; + int exit; + + __forceinline BVHSpatialBin() + { + } }; CCL_NAMESPACE_END diff --git a/intern/cycles/bvh/bvh_sort.cpp b/intern/cycles/bvh/bvh_sort.cpp index ee4531a4843..bef384be592 100644 --- a/intern/cycles/bvh/bvh_sort.cpp +++ b/intern/cycles/bvh/bvh_sort.cpp @@ -32,23 +32,23 @@ public: dim = dim_; } - bool operator()(const BVHBuild::Reference& ra, const BVHBuild::Reference& rb) + bool operator()(const BVHReference& ra, const BVHReference& rb) { - float ca = ra.bounds.min[dim] + ra.bounds.max[dim]; - float cb = rb.bounds.min[dim] + rb.bounds.max[dim]; + float ca = ra.bounds().min[dim] + ra.bounds().max[dim]; + float cb = rb.bounds().min[dim] + rb.bounds().max[dim]; if(ca < cb) return true; else if(ca > cb) return false; - else if(ra.prim_object < rb.prim_object) return true; - else if(ra.prim_object > rb.prim_object) return false; - else if(ra.prim_index < rb.prim_index) return true; - else if(ra.prim_index > rb.prim_index) return false; + else if(ra.prim_object() < rb.prim_object()) return true; + else if(ra.prim_object() > rb.prim_object()) return false; + else if(ra.prim_index() < rb.prim_index()) return true; + else if(ra.prim_index() > rb.prim_index()) return false; return false; } }; -void bvh_reference_sort(int start, int end, BVHBuild::Reference *data, int dim) +void bvh_reference_sort(int start, int end, BVHReference *data, int dim) { sort(data+start, data+end, BVHReferenceCompare(dim)); } diff --git a/intern/cycles/bvh/bvh_sort.h b/intern/cycles/bvh/bvh_sort.h index f0676948146..ba35ba3fae7 100644 --- a/intern/cycles/bvh/bvh_sort.h +++ b/intern/cycles/bvh/bvh_sort.h @@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN -void bvh_reference_sort(int start, int end, BVHBuild::Reference *data, int dim); +void bvh_reference_sort(int start, int end, BVHReference *data, int dim); CCL_NAMESPACE_END diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp new file mode 100644 index 00000000000..263c5834428 --- /dev/null +++ b/intern/cycles/bvh/bvh_split.cpp @@ -0,0 +1,293 @@ +/* + * Adapted from code copyright 2009-2010 NVIDIA Corporation + * Modifications Copyright 2011, Blender Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bvh_build.h" +#include "bvh_split.h" +#include "bvh_sort.h" + +#include "mesh.h" +#include "object.h" + +#include "util_algorithm.h" + +CCL_NAMESPACE_BEGIN + +/* Object Split */ + +BVHObjectSplit::BVHObjectSplit(BVHBuild *builder, const BVHRange& range, float nodeSAH) +: sah(FLT_MAX), dim(0), num_left(0), left_bounds(BoundBox::empty), right_bounds(BoundBox::empty) +{ + const BVHReference *ref_ptr = &builder->references[range.start()]; + float min_sah = FLT_MAX; + + for(int dim = 0; dim < 3; dim++) { + /* sort references */ + bvh_reference_sort(range.start(), range.end(), &builder->references[0], dim); + + /* sweep right to left and determine bounds. */ + BoundBox right_bounds = BoundBox::empty; + + for(int i = range.size() - 1; i > 0; i--) { + right_bounds.grow(ref_ptr[i].bounds()); + builder->spatial_right_bounds[i - 1] = right_bounds; + } + + /* sweep left to right and select lowest SAH. */ + BoundBox left_bounds = BoundBox::empty; + + for(int i = 1; i < range.size(); i++) { + left_bounds.grow(ref_ptr[i - 1].bounds()); + right_bounds = builder->spatial_right_bounds[i - 1]; + + float sah = nodeSAH + + left_bounds.safe_area() * builder->params.triangle_cost(i) + + right_bounds.safe_area() * builder->params.triangle_cost(range.size() - i); + + if(sah < min_sah) { + min_sah = sah; + + this->sah = sah; + this->dim = dim; + this->num_left = i; + this->left_bounds = left_bounds; + this->right_bounds = right_bounds; + } + } + } +} + +void BVHObjectSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right, const BVHRange& range) +{ + /* sort references according to split */ + bvh_reference_sort(range.start(), range.end(), &builder->references[0], this->dim); + + /* split node ranges */ + left = BVHRange(this->left_bounds, range.start(), this->num_left); + right = BVHRange(this->right_bounds, left.end(), range.size() - this->num_left); + +} + +/* Spatial Split */ + +BVHSpatialSplit::BVHSpatialSplit(BVHBuild *builder, const BVHRange& range, float nodeSAH) +: sah(FLT_MAX), dim(0), pos(0.0f) +{ + /* initialize bins. */ + float3 origin = range.bounds().min; + float3 binSize = (range.bounds().max - origin) * (1.0f / (float)BVHParams::NUM_SPATIAL_BINS); + float3 invBinSize = 1.0f / binSize; + + for(int dim = 0; dim < 3; dim++) { + for(int i = 0; i < BVHParams::NUM_SPATIAL_BINS; i++) { + BVHSpatialBin& bin = builder->spatial_bins[dim][i]; + + bin.bounds = BoundBox::empty; + bin.enter = 0; + bin.exit = 0; + } + } + + /* chop references into bins. */ + for(unsigned int refIdx = range.start(); refIdx < range.end(); refIdx++) { + const BVHReference& ref = builder->references[refIdx]; + float3 firstBinf = (ref.bounds().min - origin) * invBinSize; + float3 lastBinf = (ref.bounds().max - origin) * invBinSize; + int3 firstBin = make_int3((int)firstBinf.x, (int)firstBinf.y, (int)firstBinf.z); + int3 lastBin = make_int3((int)lastBinf.x, (int)lastBinf.y, (int)lastBinf.z); + + firstBin = clamp(firstBin, 0, BVHParams::NUM_SPATIAL_BINS - 1); + lastBin = clamp(lastBin, firstBin, BVHParams::NUM_SPATIAL_BINS - 1); + + for(int dim = 0; dim < 3; dim++) { + BVHReference currRef = ref; + + for(int i = firstBin[dim]; i < lastBin[dim]; i++) { + BVHReference leftRef, rightRef; + + split_reference(builder, leftRef, rightRef, currRef, dim, origin[dim] + binSize[dim] * (float)(i + 1)); + builder->spatial_bins[dim][i].bounds.grow(leftRef.bounds()); + currRef = rightRef; + } + + builder->spatial_bins[dim][lastBin[dim]].bounds.grow(currRef.bounds()); + builder->spatial_bins[dim][firstBin[dim]].enter++; + builder->spatial_bins[dim][lastBin[dim]].exit++; + } + } + + /* select best split plane. */ + for(int dim = 0; dim < 3; dim++) { + /* sweep right to left and determine bounds. */ + BoundBox right_bounds = BoundBox::empty; + + for(int i = BVHParams::NUM_SPATIAL_BINS - 1; i > 0; i--) { + right_bounds.grow(builder->spatial_bins[dim][i].bounds); + builder->spatial_right_bounds[i - 1] = right_bounds; + } + + /* sweep left to right and select lowest SAH. */ + BoundBox left_bounds = BoundBox::empty; + int leftNum = 0; + int rightNum = range.size(); + + for(int i = 1; i < BVHParams::NUM_SPATIAL_BINS; i++) { + left_bounds.grow(builder->spatial_bins[dim][i - 1].bounds); + leftNum += builder->spatial_bins[dim][i - 1].enter; + rightNum -= builder->spatial_bins[dim][i - 1].exit; + + float sah = nodeSAH + + left_bounds.safe_area() * builder->params.triangle_cost(leftNum) + + builder->spatial_right_bounds[i - 1].safe_area() * builder->params.triangle_cost(rightNum); + + if(sah < this->sah) { + this->sah = sah; + this->dim = dim; + this->pos = origin[dim] + binSize[dim] * (float)i; + } + } + } +} + +void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right, const BVHRange& range) +{ + /* Categorize references and compute bounds. + * + * Left-hand side: [left_start, left_end[ + * Uncategorized/split: [left_end, right_start[ + * Right-hand side: [right_start, refs.size()[ */ + + vector& refs = builder->references; + int left_start = range.start(); + int left_end = left_start; + int right_start = range.end(); + int right_end = range.end(); + BoundBox left_bounds = BoundBox::empty; + BoundBox right_bounds = BoundBox::empty; + + for(int i = left_end; i < right_start; i++) { + if(refs[i].bounds().max[this->dim] <= this->pos) { + /* entirely on the left-hand side */ + left_bounds.grow(refs[i].bounds()); + swap(refs[i], refs[left_end++]); + } + else if(refs[i].bounds().min[this->dim] >= this->pos) { + /* entirely on the right-hand side */ + right_bounds.grow(refs[i].bounds()); + swap(refs[i--], refs[--right_start]); + } + } + + /* duplicate or unsplit references intersecting both sides. */ + while(left_end < right_start) { + /* split reference. */ + BVHReference lref, rref; + + split_reference(builder, lref, rref, refs[left_end], this->dim, this->pos); + + /* compute SAH for duplicate/unsplit candidates. */ + BoundBox lub = left_bounds; // Unsplit to left: new left-hand bounds. + BoundBox rub = right_bounds; // Unsplit to right: new right-hand bounds. + BoundBox ldb = left_bounds; // Duplicate: new left-hand bounds. + BoundBox rdb = right_bounds; // Duplicate: new right-hand bounds. + + lub.grow(refs[left_end].bounds()); + rub.grow(refs[left_end].bounds()); + ldb.grow(lref.bounds()); + rdb.grow(rref.bounds()); + + float lac = builder->params.triangle_cost(left_end - left_start); + float rac = builder->params.triangle_cost(right_end - right_start); + float lbc = builder->params.triangle_cost(left_end - left_start + 1); + float rbc = builder->params.triangle_cost(right_end - right_start + 1); + + float unsplitLeftSAH = lub.safe_area() * lbc + right_bounds.safe_area() * rac; + float unsplitRightSAH = left_bounds.safe_area() * lac + rub.safe_area() * rbc; + float duplicateSAH = ldb.safe_area() * lbc + rdb.safe_area() * rbc; + float minSAH = min(min(unsplitLeftSAH, unsplitRightSAH), duplicateSAH); + + if(minSAH == unsplitLeftSAH) { + /* unsplit to left */ + left_bounds = lub; + left_end++; + } + else if(minSAH == unsplitRightSAH) { + /* unsplit to right */ + right_bounds = rub; + swap(refs[left_end], refs[--right_start]); + } + else { + /* duplicate */ + left_bounds = ldb; + right_bounds = rdb; + refs[left_end++] = lref; + refs.insert(refs.begin() + right_end, rref); + right_end++; + } + } + + left = BVHRange(left_bounds, left_start, left_end - left_start); + right = BVHRange(right_bounds, right_start, right_end - right_start); +} + +void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos) +{ + /* initialize boundboxes */ + BoundBox left_bounds = BoundBox::empty; + BoundBox right_bounds = BoundBox::empty; + + /* loop over vertices/edges. */ + Object *ob = builder->objects[ref.prim_object()]; + const Mesh *mesh = ob->mesh; + const int *inds = mesh->triangles[ref.prim_index()].v; + const float3 *verts = &mesh->verts[0]; + const float3* v1 = &verts[inds[2]]; + + for(int i = 0; i < 3; i++) { + const float3* v0 = v1; + int vindex = inds[i]; + v1 = &verts[vindex]; + float v0p = (*v0)[dim]; + float v1p = (*v1)[dim]; + + /* insert vertex to the boxes it belongs to. */ + if(v0p <= pos) + left_bounds.grow(*v0); + + if(v0p >= pos) + right_bounds.grow(*v0); + + /* edge intersects the plane => insert intersection to both boxes. */ + if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) { + float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); + left_bounds.grow(t); + right_bounds.grow(t); + } + } + + /* intersect with original bounds. */ + left_bounds.max[dim] = pos; + right_bounds.min[dim] = pos; + left_bounds.intersect(ref.bounds()); + right_bounds.intersect(ref.bounds()); + + /* set referecnes */ + left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object()); + right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object()); +} + +CCL_NAMESPACE_END + diff --git a/intern/cycles/bvh/bvh_split.h b/intern/cycles/bvh/bvh_split.h new file mode 100644 index 00000000000..1f4befbe8e2 --- /dev/null +++ b/intern/cycles/bvh/bvh_split.h @@ -0,0 +1,110 @@ +/* + * Adapted from code copyright 2009-2010 NVIDIA Corporation + * Modifications Copyright 2011, Blender Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BVH_SPLIT_H__ +#define __BVH_SPLIT_H__ + +#include "bvh_build.h" +#include "bvh_params.h" + +CCL_NAMESPACE_BEGIN + +class BVHBuild; + +/* Object Split */ + +class BVHObjectSplit +{ +public: + float sah; + int dim; + int num_left; + BoundBox left_bounds; + BoundBox right_bounds; + + BVHObjectSplit() {} + BVHObjectSplit(BVHBuild *builder, const BVHRange& range, float nodeSAH); + + void split(BVHBuild *builder, BVHRange& left, BVHRange& right, const BVHRange& range); +}; + +/* Spatial Split */ + +class BVHSpatialSplit +{ +public: + float sah; + int dim; + float pos; + + BVHSpatialSplit() : sah(FLT_MAX), dim(0), pos(0.0f) {} + BVHSpatialSplit(BVHBuild *builder, const BVHRange& range, float nodeSAH); + + void split(BVHBuild *builder, BVHRange& left, BVHRange& right, const BVHRange& range); + void split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos); +}; + +/* Mixed Object-Spatial Split */ + +class BVHMixedSplit +{ +public: + BVHObjectSplit object; + BVHSpatialSplit spatial; + + float leafSAH; + float nodeSAH; + float minSAH; + + bool no_split; + + __forceinline BVHMixedSplit(BVHBuild *builder, const BVHRange& range, int level) + { + /* find split candidates. */ + float area = range.bounds().safe_area(); + + leafSAH = area * builder->params.triangle_cost(range.size()); + nodeSAH = area * builder->params.node_cost(2); + + object = BVHObjectSplit(builder, range, nodeSAH); + + if(builder->params.use_spatial_split && level < BVHParams::MAX_SPATIAL_DEPTH) { + BoundBox overlap = object.left_bounds; + overlap.intersect(object.right_bounds); + + if(overlap.safe_area() >= builder->spatial_min_overlap) + spatial = BVHSpatialSplit(builder, range, nodeSAH); + } + + /* leaf SAH is the lowest => create leaf. */ + minSAH = min(min(leafSAH, object.sah), spatial.sah); + no_split = (minSAH == leafSAH && range.size() <= builder->params.max_leaf_size); + } + + __forceinline void split(BVHBuild *builder, BVHRange& left, BVHRange& right, const BVHRange& range) + { + if(builder->params.use_spatial_split && minSAH == spatial.sah) + spatial.split(builder, left, right, range); + if(!left.size() || !right.size()) + object.split(builder, left, right, range); + } +}; + +CCL_NAMESPACE_END + +#endif /* __BVH_SPLIT_H__ */ + diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index a7eb365f983..0ce16e65621 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -43,6 +43,7 @@ Mesh::Mesh() transform_applied = false; transform_negative_scaled = false; displacement_method = DISPLACE_BUMP; + bounds = BoundBox::empty; bvh = NULL; @@ -96,7 +97,7 @@ void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_) void Mesh::compute_bounds() { - BoundBox bnds; + BoundBox bnds = BoundBox::empty; size_t verts_size = verts.size(); for(size_t i = 0; i < verts_size; i++) @@ -697,6 +698,8 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen progress.set_status(msg, "Building BVH"); mesh->compute_bvh(&scene->params, progress); + + i++; } if(progress.get_cancel()) return; @@ -704,8 +707,6 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen mesh->need_update = false; mesh->need_update_rebuild = false; } - - i++; } foreach(Shader *shader, scene->shaders) diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 5f7a5810c09..28645d856a8 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -37,6 +37,7 @@ Object::Object() tfm = transform_identity(); visibility = ~0; pass_id = 0; + bounds = BoundBox::empty; } Object::~Object() diff --git a/intern/cycles/subd/subd_patch.cpp b/intern/cycles/subd/subd_patch.cpp index ff477296c7e..f6acc358959 100644 --- a/intern/cycles/subd/subd_patch.cpp +++ b/intern/cycles/subd/subd_patch.cpp @@ -93,7 +93,7 @@ void LinearQuadPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float BoundBox LinearQuadPatch::bound() { - BoundBox bbox; + BoundBox bbox = BoundBox::empty; for(int i = 0; i < 4; i++) bbox.grow(hull[i]); @@ -115,7 +115,7 @@ void LinearTrianglePatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, f BoundBox LinearTrianglePatch::bound() { - BoundBox bbox; + BoundBox bbox = BoundBox::empty; for(int i = 0; i < 3; i++) bbox.grow(hull[i]); @@ -132,7 +132,7 @@ void BicubicPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v) BoundBox BicubicPatch::bound() { - BoundBox bbox; + BoundBox bbox = BoundBox::empty; for(int i = 0; i < 16; i++) bbox.grow(hull[i]); @@ -152,7 +152,7 @@ void BicubicTangentPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, f BoundBox BicubicTangentPatch::bound() { - BoundBox bbox; + BoundBox bbox = BoundBox::empty; for(int i = 0; i < 16; i++) bbox.grow(hull[i]); @@ -205,7 +205,7 @@ void GregoryQuadPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, floa BoundBox GregoryQuadPatch::bound() { - BoundBox bbox; + BoundBox bbox = BoundBox::empty; for(int i = 0; i < 20; i++) bbox.grow(hull[i]); @@ -276,7 +276,7 @@ void GregoryTrianglePatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, BoundBox GregoryTrianglePatch::bound() { - BoundBox bbox; + BoundBox bbox = BoundBox::empty; for(int i = 0; i < 20; i++) bbox.grow(hull[i]); diff --git a/intern/cycles/util/util_boundbox.h b/intern/cycles/util/util_boundbox.h index bb1df0b220f..2c0f38c44a6 100644 --- a/intern/cycles/util/util_boundbox.h +++ b/intern/cycles/util/util_boundbox.h @@ -35,45 +35,81 @@ class BoundBox public: float3 min, max; - BoundBox(void) + __forceinline BoundBox() { - min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX); - max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); } - BoundBox(const float3& min_, const float3& max_) + __forceinline BoundBox(const float3& pt) + : min(pt), max(pt) + { + } + + __forceinline BoundBox(const float3& min_, const float3& max_) : min(min_), max(max_) { } - void grow(const float3& pt) + static struct empty_t {} empty; + + __forceinline BoundBox(empty_t) + : min(make_float3(FLT_MAX, FLT_MAX, FLT_MAX)), max(make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX)) + { + } + + __forceinline void grow(const float3& pt) { min = ccl::min(min, pt); max = ccl::max(max, pt); } - void grow(const BoundBox& bbox) + __forceinline void grow(const BoundBox& bbox) { grow(bbox.min); grow(bbox.max); } - void intersect(const BoundBox& bbox) + __forceinline void intersect(const BoundBox& bbox) { min = ccl::max(min, bbox.min); max = ccl::min(max, bbox.max); } - float area(void) const + /* todo: avoid using this */ + __forceinline float safe_area() const { - if(!valid()) + if(!((min.x <= max.x) && (min.y <= max.y) && (min.z <= max.z))) return 0.0f; - float3 d = max - min; - return dot(d, d)*2.0f; + return area(); } - bool valid(void) const + __forceinline float area() const + { + return half_area()*2.0f; + } + + __forceinline float half_area() const + { + float3 d = max - min; + return (d.x*d.z + d.y*d.z + d.x*d.y); + } + + __forceinline float3 center() const + { + return 0.5f*(min + max); + } + + __forceinline float3 center2() const + { + return min + max; + } + + __forceinline float3 size() const + { + return max - min; + } + + __forceinline bool valid() const { return (min.x <= max.x) && (min.y <= max.y) && (min.z <= max.z) && (isfinite(min.x) && isfinite(min.y) && isfinite(min.z)) && @@ -82,7 +118,7 @@ public: BoundBox transformed(const Transform *tfm) { - BoundBox result; + BoundBox result = BoundBox::empty; for(int i = 0; i < 8; i++) { float3 p; @@ -98,6 +134,31 @@ public: } }; +__forceinline BoundBox merge(const BoundBox& bbox, const float3& pt) +{ + return BoundBox(min(bbox.min, pt), max(bbox.max, pt)); +} + +__forceinline BoundBox merge(const BoundBox& a, const BoundBox& b) +{ + return BoundBox(min(a.min, b.min), max(a.max, b.max)); +} + +__forceinline BoundBox merge(const BoundBox& a, const BoundBox& b, const BoundBox& c, const BoundBox& d) +{ + return merge(merge(a, b), merge(c, d)); +} + +__forceinline BoundBox intersect(const BoundBox& a, const BoundBox& b) +{ + return BoundBox(max(a.min, b.min), min(a.max, b.max)); +} + +__forceinline BoundBox intersect(const BoundBox& a, const BoundBox& b, const BoundBox& c) +{ + return intersect(a, intersect(b, c)); +} + CCL_NAMESPACE_END #endif /* __UTIL_BOUNDBOX_H__ */ From 9be1c5c009c51a304dc11a98df628782e4cdabd0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Apr 2012 12:01:24 +0000 Subject: [PATCH 013/360] Cycles: cuda build fix. --- intern/cycles/util/util_math.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 8768c798d16..d9e4d4fbac9 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -680,6 +680,10 @@ __device_inline float4 max(float4 a, float4 b) return make_float4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w)); } +#endif + +#ifndef __KERNEL_GPU__ + __device_inline float4 select(const int4& mask, const float4& a, const float4& b) { return make_float4((mask.x)? a.x: b.x, (mask.y)? a.y: b.y, (mask.z)? a.z: b.z, (mask.w)? a.w: b.w); @@ -705,10 +709,6 @@ __device_inline float3 rcp(const float3& a) return make_float3(1.0f/a.x, 1.0f/a.y, 1.0f/a.z); } -#endif - -#ifndef __KERNEL_GPU__ - __device_inline void print_float4(const char *label, const float4& a) { printf("%s: %.8f %.8f %.8f %.8f\n", label, a.x, a.y, a.z, a.w); From 40e58dbca98898c8dd7db16eb6cfce17137a02fa Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 24 Apr 2012 14:59:08 +0000 Subject: [PATCH 014/360] Cycles: * Fixing wrong windows define, causing compile errors. --- intern/cycles/util/util_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h index b6c57e3eb6e..da9e68300a6 100644 --- a/intern/cycles/util/util_types.h +++ b/intern/cycles/util/util_types.h @@ -36,7 +36,7 @@ #define __shared #define __constant -#ifdef __WIN32__ +#ifdef _WIN32 #define __device_inline static __forceinline #define __align(...) __declspec(align(__VA_ARGS__)) #else From effc0d352e08e579dbab3d7d880951be8a683351 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Apr 2012 17:56:27 +0000 Subject: [PATCH 015/360] Cycles: attempted BVH binning build fix for windows. --- intern/cycles/bvh/bvh_binning.cpp | 2 ++ intern/cycles/util/util_boundbox.h | 1 + 2 files changed, 3 insertions(+) diff --git a/intern/cycles/bvh/bvh_binning.cpp b/intern/cycles/bvh/bvh_binning.cpp index def5309e551..8286e15b5c6 100644 --- a/intern/cycles/bvh/bvh_binning.cpp +++ b/intern/cycles/bvh/bvh_binning.cpp @@ -15,6 +15,8 @@ * limitations under the License. */ +#include + #include "bvh_binning.h" #include "util_algorithm.h" diff --git a/intern/cycles/util/util_boundbox.h b/intern/cycles/util/util_boundbox.h index 2c0f38c44a6..9511b48e103 100644 --- a/intern/cycles/util/util_boundbox.h +++ b/intern/cycles/util/util_boundbox.h @@ -23,6 +23,7 @@ #include #include "util_math.h" +#include "util_string.h" #include "util_transform.h" #include "util_types.h" From 713de1b1f4639895a8edcb71d9bb3d8e16f0a15f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Apr 2012 17:59:57 +0000 Subject: [PATCH 016/360] Point Cache: allow baking external smoke caches. This needs to be cleaned up a bit, I couldn't fully understand how the External setting is supposed to work to make further changes, but this should make it work at least. --- .../bl_ui/properties_physics_common.py | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index f623d9a37eb..4db056e77a2 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -94,18 +94,25 @@ def point_cache_ui(self, context, cache, enabled, cachetype): if cachetype in {'PSYS', 'HAIR', 'SMOKE'}: row.prop(cache, "use_external") + if cachetype == 'SMOKE': + row.prop(cache, "use_library_path", "Use Lib Path") + if cache.use_external: - split = layout.split(percentage=0.80) - split.prop(cache, "name", text="File Name") - split.prop(cache, "index", text="") + split = layout.split(percentage=0.35) + col = split.column() + col.label(text="File Name:") + if cache.use_external: + col.label(text="File Path:") - row = layout.row() - row.label(text="File Path:") - row.prop(cache, "use_library_path", "Use Lib Path") + col = split.column() + sub = col.split(percentage=0.70, align=True) + sub.prop(cache, "name", text="") + sub.prop(cache, "index", text="") + col.prop(cache, "filepath", text="") - layout.prop(cache, "filepath", text="") - - layout.label(text=cache.info) + cache_info = cache.info + if cache_info: + layout.label(text=cache_info) else: if cachetype in {'SMOKE', 'DYNAMIC_PAINT'}: if not bpy.data.is_saved: @@ -117,6 +124,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype): else: layout.prop(cache, "name", text="Cache Name") + if not cache.use_external or cachetype == 'SMOKE': row = layout.row(align=True) if cachetype not in {'PSYS', 'DYNAMIC_PAINT'}: From d40da2c9023c1bdd8f5e33e8fbe7ad6c1e2e9295 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Apr 2012 19:08:26 +0000 Subject: [PATCH 017/360] Cycles: more attempts to fix windows build for BVH binning. --- intern/cycles/util/util_types.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h index da9e68300a6..3c61d1f468b 100644 --- a/intern/cycles/util/util_types.h +++ b/intern/cycles/util/util_types.h @@ -47,6 +47,12 @@ #endif +/* Bitness */ + +#if defined(__ppc64__) || defined(__PPC64__) || defined(__x86_64__) || defined(__ia64__) || defined(_M_X64) +#define __KERNEL_64_BIT__ +#endif + /* SIMD Types */ /* not enabled yet, just testing */ @@ -103,6 +109,12 @@ typedef unsigned int uint32_t; typedef long long int64_t; typedef unsigned long long uint64_t; +#ifdef __KERNEL_64_BIT__ +typedef int64_t ssize_t; +#else +typedef int32_t ssize_t; +#endif + #endif /* Generic Memory Pointer */ From a49a64b7108e1016d84c2063d7ea93b3e5a8cc54 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 28 Apr 2012 14:40:37 +0000 Subject: [PATCH 018/360] Camera tracking: small improvements to tripod solver" - Disable camera refirement due to it's not only refines camera intrinsics but also adjusts camera position which isn't necessary here - Detect rigid transformation between initial frame and current instead of detecting it between two neighbour frames. This prevents accumulation of error and seems to be working better in footages i've tested. --- extern/libmv/libmv-capi.cpp | 7 +------ extern/libmv/libmv-capi.h | 2 +- extern/libmv/libmv/simple_pipeline/modal_solver.cc | 10 +++------- release/scripts/startup/bl_ui/space_clip.py | 2 +- source/blender/blenkernel/intern/tracking.c | 1 - 5 files changed, 6 insertions(+), 16 deletions(-) diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index 3f697d487b6..6c20d76eeac 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -460,7 +460,7 @@ libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *tracks, int keyfra return (libmv_Reconstruction *)libmv_reconstruction; } -struct libmv_Reconstruction *libmv_solveModal(struct libmv_Tracks *tracks, int refine_intrinsics, double focal_length, +struct libmv_Reconstruction *libmv_solveModal(struct libmv_Tracks *tracks, double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, reconstruct_progress_update_cb progress_update_callback, void *callback_customdata) { @@ -488,11 +488,6 @@ struct libmv_Reconstruction *libmv_solveModal(struct libmv_Tracks *tracks, int r libmv::ModalSolver(normalized_tracks, reconstruction, &update_callback); - if (refine_intrinsics) { - libmv_solveRefineIntrinsics((libmv::Tracks *)tracks, intrinsics, reconstruction, - refine_intrinsics, progress_update_callback, callback_customdata); - } - progress_update_callback(callback_customdata, 1.0, "Finishing solution"); libmv_reconstruction->tracks = *(libmv::Tracks *)tracks; libmv_reconstruction->error = libmv::EuclideanReprojectionError(*(libmv::Tracks *)tracks, *reconstruction, *intrinsics); diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index f72a72d494b..bccc4706832 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -68,7 +68,7 @@ int libmv_refineParametersAreValid(int parameters); struct libmv_Reconstruction *libmv_solveReconstruction(struct libmv_Tracks *tracks, int keyframe1, int keyframe2, int refine_intrinsics, double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, reconstruct_progress_update_cb progress_update_callback, void *callback_customdata); -struct libmv_Reconstruction *libmv_solveModal(struct libmv_Tracks *tracks, int refine_intrinsics, double focal_length, +struct libmv_Reconstruction *libmv_solveModal(struct libmv_Tracks *tracks, double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, reconstruct_progress_update_cb progress_update_callback, void *callback_customdata); int libmv_reporojectionPointForTrack(struct libmv_Reconstruction *libmv_reconstruction, int track, double pos[3]); diff --git a/extern/libmv/libmv/simple_pipeline/modal_solver.cc b/extern/libmv/libmv/simple_pipeline/modal_solver.cc index ede0071dc64..bb49b30dbce 100644 --- a/extern/libmv/libmv/simple_pipeline/modal_solver.cc +++ b/extern/libmv/libmv/simple_pipeline/modal_solver.cc @@ -91,19 +91,15 @@ void ModalSolver(Tracks &tracks, ProjectMarkerOnSphere(marker, X); - points.push_back(R * point->X); + points.push_back(point->X); reference_points.push_back(X); } } } if (points.size()) { - Mat3 dR = Mat3::Identity(); - - // Find rigid delta transformation from previous image to current image - RigidRegistration(reference_points, points, dR); - - R *= dR; + // Find rigid delta transformation to current image + RigidRegistration(reference_points, points, R); } reconstruction->InsertCamera(image, R, Vec3::Zero()); diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index fb84fa29cbc..e4f608e2660 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -256,7 +256,7 @@ class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel): col.prop(settings, "keyframe_b") col = layout.column(align=True) - col.active = tracking_object.is_camera + col.active = tracking_object.is_camera and not settings.use_tripod_solver col.label(text="Refine:") col.prop(settings, "refine_intrinsics", text="") diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 9e3bc2648a5..e511cd362de 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1902,7 +1902,6 @@ void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short * if (context->motion_flag & TRACKING_MOTION_MODAL) { context->reconstruction = libmv_solveModal(context->tracks, - context->refine_flags, context->focal_length, context->principal_point[0], context->principal_point[1], context->k1, context->k2, context->k3, From 1e73bf60f9c20e54158756e021cf98fb9368a2f7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 29 Apr 2012 11:16:40 +0000 Subject: [PATCH 019/360] - Synchronize with changes in trunk - Reverted parts of recent trunk merge related on changes for preview image save skip needed for startup.blend generation --- source/blender/blenloader/intern/writefile.c | 4 ++-- source/blender/editors/space_clip/space_clip.c | 2 +- source/blender/windowmanager/intern/wm_files.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 5f8e4841d2d..42736b6b787 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1867,7 +1867,7 @@ static void write_previews(WriteData *wd, PreviewImage *prv) short h = prv->h[1]; unsigned int *rect = prv->rect[1]; /* don't write out large previews if not requested */ - if (!(U.flag & USER_SAVE_PREVIEWS) || TRUE) { + if (!(U.flag & USER_SAVE_PREVIEWS)) { prv->w[1] = 0; prv->h[1] = 0; prv->rect[1] = NULL; @@ -1877,7 +1877,7 @@ static void write_previews(WriteData *wd, PreviewImage *prv) if (prv->rect[1]) writedata(wd, DATA, prv->w[1]*prv->h[1]*sizeof(unsigned int), prv->rect[1]); /* restore preview, we still want to keep it in memory even if not saved to file */ - if (!(U.flag & USER_SAVE_PREVIEWS) || TRUE) { + if (!(U.flag & USER_SAVE_PREVIEWS) ) { prv->w[1] = w; prv->h[1] = h; prv->rect[1] = rect; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 8339bc14cdd..9a5a7120a3d 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -315,7 +315,7 @@ static SpaceLink *clip_duplicate(SpaceLink *sl) /* clear or remove stuff from old */ scn->scopes.track_preview = NULL; - scn->scopes.ok = 0; + scn->scopes.ok = FALSE; scn->draw_context = NULL; return (SpaceLink *)scn; diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 7f5271e5ffa..e50fbaa624e 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -787,7 +787,7 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re /* blend file thumbnail */ /* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */ - if ((U.flag & USER_SAVE_PREVIEWS) && 0) { + if (U.flag & USER_SAVE_PREVIEWS) { ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb); } From f8e134db13d9cf7e0e1ef00802f87bbed46c208c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 29 Apr 2012 15:30:54 +0000 Subject: [PATCH 020/360] Tomato branch: correction to dopesheet background color versioning check --- source/blender/editors/interface/resources.c | 2 +- source/blender/editors/space_clip/clip_dopesheet_draw.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 26b0d13e10b..b2aff51006e 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1778,7 +1778,7 @@ void init_userdef_do_versions(void) } } - if (bmain->versionfile < 262 || (bmain->versionfile == 262 && bmain->subversionfile < 5)) { + { bTheme *btheme; for (btheme = U.themes.first; btheme; btheme = btheme->next) { if (btheme->tclip.strip[0] == 0) { diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index 3da5ec10582..c64ead91589 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -194,7 +194,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) track_channel_color(track, default_color, color); glColor4fv(color); - glRectf(v2d->cur.xmin, (float)y - CHANNEL_HEIGHT_HALF, + glRectf(v2d->cur.xmin, (float) y - CHANNEL_HEIGHT_HALF, v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF); } @@ -228,7 +228,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) else glColor4fv(strip); - glRectf(start_marker->framenr, (float)y - STRIP_HEIGHT_HALF, + glRectf(start_marker->framenr, (float) y - STRIP_HEIGHT_HALF, start_marker->framenr + len, (float) y + STRIP_HEIGHT_HALF); draw_keyframe_shape(start_marker->framenr, y, xscale, yscale, sel, alpha); @@ -318,7 +318,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) track_channel_color(track, NULL, color); glColor3fv(color); - glRectf(v2d->cur.xmin, (float)y - CHANNEL_HEIGHT_HALF, + glRectf(v2d->cur.xmin, (float) y - CHANNEL_HEIGHT_HALF, v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF); if (sel) From ebbc038e4f044be9f2c5f495bce685fb267d99cf Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 29 Apr 2012 16:56:56 +0000 Subject: [PATCH 021/360] Tomato: fixed opengl issue with intel cards Issue was caused by some mixes of glRect called to draw zero-width rectangles and glCalllist. Resolved by not using glRect if rectangle is "degenerated". --- .../editors/space_clip/clip_dopesheet_draw.c | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index c64ead91589..758a2ac3d99 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -108,7 +108,7 @@ static void draw_keyframe_shape(float x, float y, float xscale, float yscale, sh if (displist2 == 0) { displist2 = glGenLists(1); glNewList(displist2, GL_COMPILE); - + glBegin(GL_QUADS); glVertex2fv(_unit_diamond_shape[0]); glVertex2fv(_unit_diamond_shape[1]); @@ -180,8 +180,8 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) continue; /* check if visible */ - if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) + if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { float alpha; int i, sel = track->flag & TRACK_DOPE_SEL; @@ -228,11 +228,15 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) else glColor4fv(strip); - glRectf(start_marker->framenr, (float) y - STRIP_HEIGHT_HALF, - start_marker->framenr + len, (float) y + STRIP_HEIGHT_HALF); - - draw_keyframe_shape(start_marker->framenr, y, xscale, yscale, sel, alpha); - draw_keyframe_shape(start_marker->framenr + len, y, xscale, yscale, sel, alpha); + if (len) { + glRectf(start_marker->framenr, (float) y - STRIP_HEIGHT_HALF, + start_marker->framenr + len, (float) y + STRIP_HEIGHT_HALF); + draw_keyframe_shape(start_marker->framenr, y, xscale, yscale, sel, alpha); + draw_keyframe_shape(start_marker->framenr + len, y, xscale, yscale, sel, alpha); + } + else { + draw_keyframe_shape(start_marker->framenr, y, xscale, yscale, sel, alpha); + } } i++; @@ -309,8 +313,8 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) continue; /* check if visible */ - if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) + if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { float font_height, color[3]; int sel = track->flag & TRACK_DOPE_SEL; @@ -349,8 +353,8 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) continue; /* check if visible */ - if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) + if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { uiBut *but; PointerRNA ptr; From ebe4ffa8de3c0a2d471e6f859e96921fe95b475b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 29 Apr 2012 20:04:12 +0000 Subject: [PATCH 022/360] Tomato: refactoring of dopesheet to allow different sort orders in list of channels Store list of channels displaying in dopesheet separately from list of tracks. This allows to re-sort channels in dopesheet independently from list of all tracks (currently only alphabetic sorting is implemented). This also allows to cache assorted information (like tracked segments of track) but currently such a things are not bottlenecks and could be done after merge dopesheet view into trunk. TODO: - Still have some deadlocks when drawing selected channels. Skipping channel background or keyframe drawing helps here but this need to be resolved. - Bump sub-version and wrote code needed to convert pre-dopesheet interface with opened curve view displaying properly. - Probably it'll worth caching tracked segments. --- source/blender/blenkernel/BKE_tracking.h | 3 + source/blender/blenkernel/intern/movieclip.c | 2 +- source/blender/blenkernel/intern/tracking.c | 60 +++++++++++++++++++ source/blender/blenloader/intern/readfile.c | 16 +++++ source/blender/blenloader/intern/writefile.c | 14 +++++ source/blender/editors/include/ED_clip.h | 2 + .../editors/space_clip/clip_dopesheet_draw.c | 33 ++++------ .../editors/space_clip/clip_dopesheet_ops.c | 30 +++------- .../blender/editors/space_clip/clip_editor.c | 8 +++ .../editors/space_clip/clip_graph_ops.c | 5 -- .../blender/editors/space_clip/tracking_ops.c | 17 ++++++ source/blender/makesdna/DNA_tracking_types.h | 13 ++++ 12 files changed, 156 insertions(+), 47 deletions(-) diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 2bb8fc691f0..3b1a5dbfc8a 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -164,6 +164,9 @@ struct MovieTrackingObject *BKE_tracking_named_object(struct MovieTracking *trac void BKE_tracking_select_track(struct ListBase *tracksbase, struct MovieTrackingTrack *track, int area, int extend); void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area); +/* Dopesheet */ +void BKE_tracking_update_dopesheet(struct MovieTracking *tracking); + #define TRACK_SELECTED(track) ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT) #define TRACK_AREA_SELECTED(track, area) ((area)==TRACK_AREA_POINT ? (track)->flag&SELECT : \ diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index d548d7589bb..0fd3a9eb753 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -453,7 +453,7 @@ static MovieClip *movieclip_alloc(const char *name) MovieClip *BKE_movieclip_file_add(const char *name) { MovieClip *clip; - MovieClipUser user; + MovieClipUser user = {0}; int file, len, width, height; const char *libname; char str[FILE_MAX], strtest[FILE_MAX]; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index e511cd362de..316cb4b6159 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -632,6 +632,12 @@ static void tracking_objects_free(ListBase *objects) BLI_freelistN(objects); } +static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet) +{ + BLI_freelistN(&dopesheet->channels); + dopesheet->tot_channel = 0; +} + void BKE_tracking_free(MovieTracking *tracking) { tracking_tracks_free(&tracking->tracks); @@ -643,6 +649,8 @@ void BKE_tracking_free(MovieTracking *tracking) if (tracking->camera.intrinsics) BKE_tracking_distortion_destroy(tracking->camera.intrinsics); + + tracking_dopesheet_free(&tracking->dopesheet); } static MovieTrackingTrack *duplicate_track(MovieTrackingTrack *track) @@ -1352,6 +1360,8 @@ void BKE_tracking_sync(MovieTrackingContext *context) newframe = context->user.framenr - 1; context->sync_frame = newframe; + + BKE_tracking_update_dopesheet(tracking); } void BKE_tracking_sync_user(MovieClipUser *user, MovieTrackingContext *context) @@ -3033,3 +3043,53 @@ MovieTrackingObject *BKE_tracking_named_object(MovieTracking *tracking, const ch return NULL; } + +/*********************** dopesheet functions *************************/ + +static int channels_alpha_sort(void *a, void *b) +{ + MovieTrackingDopesheetChannel *channel_a = a; + MovieTrackingDopesheetChannel *channel_b = b; + + if (BLI_strcasecmp(channel_a->track->name, channel_b->track->name) > 0) + return 1; + else + return 0; +} + +void BKE_tracking_update_dopesheet(MovieTracking *tracking) +{ + MovieTrackingObject *object = BKE_tracking_active_object(tracking); + MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; + MovieTrackingTrack *track; + ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + ListBase old_channels; + + old_channels = dopesheet->channels; + dopesheet->channels.first = dopesheet->channels.last = NULL; + dopesheet->tot_channel = 0; + + for (track = tracksbase->first; track; track = track->next) { + if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) { + MovieTrackingDopesheetChannel *channel, *old_channel; + + channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), "tracking dopesheet channel"); + channel->track = track; + + /* copy flags from current dopsheet information to new one */ + for (old_channel = old_channels.first; old_channel; old_channel = old_channel->next) { + if (old_channel->track == track) { + channel->flag = old_channel->flag; + break; + } + } + + BLI_addtail(&dopesheet->channels, channel); + dopesheet->tot_channel++; + } + } + + BLI_sortlist(&dopesheet->channels, channels_alpha_sort); + + BLI_freelistN(&old_channels); +} diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c54daed8139..f13b6ebecdc 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6167,6 +6167,20 @@ static void direct_link_movieTracks(FileData *fd, ListBase *tracksbase) } } +static void direct_link_movieDopesheet(FileData *fd, MovieTrackingDopesheet *dopesheet) +{ + MovieTrackingDopesheetChannel *channel; + + link_list(fd, &dopesheet->channels); + + channel = dopesheet->channels.first; + while (channel) { + channel->track = newdataadr(fd, channel->track); + + channel = channel->next; + } +} + static void direct_link_movieclip(FileData *fd, MovieClip *clip) { MovieTracking *tracking= &clip->tracking; @@ -6202,6 +6216,8 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip) object= object->next; } + + direct_link_movieDopesheet(fd, &clip->tracking.dopesheet); } static void lib_link_movieclip(FileData *fd, Main *main) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 42736b6b787..e74498a59aa 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2677,6 +2677,18 @@ static void write_movieTracks(WriteData *wd, ListBase *tracks) } } +static void write_movieDopesheet(WriteData *wd, MovieTrackingDopesheet *dopesheet) +{ + MovieTrackingDopesheetChannel *channel; + + channel = dopesheet->channels.first; + while (channel) { + writestruct(wd, DATA, "MovieTrackingDopesheetChannel", 1, channel); + + channel = channel->next; + } +} + static void write_movieReconstruction(WriteData *wd, MovieTrackingReconstruction *reconstruction) { if (reconstruction->camnr) @@ -2709,6 +2721,8 @@ static void write_movieclips(WriteData *wd, ListBase *idbase) object= object->next; } + + write_movieDopesheet(wd, &tracking->dopesheet); } clip= clip->id.next; diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 24d9fd3a297..db6d9bbd013 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -69,6 +69,8 @@ void ED_space_clip_free_texture_buffer(struct SpaceClip *sc); int ED_space_clip_show_trackedit(struct SpaceClip *sc); +void ED_space_clip_update_dopesheet(struct SpaceClip *sc); + /* clip_ops.c */ void ED_operatormacros_clip(void); diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index 758a2ac3d99..d1733cf322b 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -154,8 +154,8 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) if (clip) { MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *track; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; + MovieTrackingDopesheetChannel *channel; float y, xscale, yscale; float strip[4], selected_strip[4]; @@ -172,17 +172,15 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) glEnable(GL_BLEND); - for (track = tracksbase->first; track; track = track->next) { + for (channel = dopesheet->channels.first; channel; channel = channel->next) { float yminc = (float) (y - CHANNEL_HEIGHT_HALF); float ymaxc = (float) (y + CHANNEL_HEIGHT_HALF); - if (!TRACK_VIEW_SELECTED(sc, track)) - continue; - /* check if visible */ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + MovieTrackingTrack *track = channel->track; float alpha; int i, sel = track->flag & TRACK_DOPE_SEL; @@ -272,21 +270,20 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) View2D *v2d = &ar->v2d; MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking; - MovieTrackingTrack *track; - ListBase *tracksbase; + MovieTrackingDopesheet *dopesheet; + MovieTrackingDopesheetChannel *channel; uiStyle *style = UI_GetStyle(); uiBlock *block; int fontid = style->widget.uifont_id; - int items, height; + int height; float y; if (!clip) return; tracking = &clip->tracking; - tracksbase = BKE_tracking_get_tracks(tracking); - items = BLI_countlist(tracksbase); - height = (items * CHANNEL_STEP) + (CHANNEL_HEIGHT * 2); + dopesheet = &tracking->dopesheet; + height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT * 2); if (height > (v2d->mask.ymax - v2d->mask.ymin)) { /* don't use totrect set, as the width stays the same @@ -305,17 +302,15 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) BLF_size(fontid, 11.0f, U.dpi); - for (track = tracksbase->first; track; track = track->next) { + for (channel = dopesheet->channels.first; channel; channel = channel->next) { float yminc = (float) (y - CHANNEL_HEIGHT_HALF); float ymaxc = (float) (y + CHANNEL_HEIGHT_HALF); - if (!TRACK_VIEW_SELECTED(sc, track)) - continue; - /* check if visible */ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + MovieTrackingTrack *track = channel->track; float font_height, color[3]; int sel = track->flag & TRACK_DOPE_SEL; @@ -345,17 +340,15 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) y = (float) CHANNEL_FIRST; glEnable(GL_BLEND); - for (track = tracksbase->first; track; track = track->next) { + for (channel = dopesheet->channels.first; channel; channel = channel->next) { float yminc = (float)(y - CHANNEL_HEIGHT_HALF); float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF); - if (!TRACK_VIEW_SELECTED(sc, track)) - continue; - /* check if visible */ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + MovieTrackingTrack *track = channel->track; uiBut *but; PointerRNA ptr; int icon; diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c index 2225f01afe3..bec030f5e21 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_ops.c +++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c @@ -91,40 +91,28 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); - MovieTrackingTrack *track; + MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; + MovieTrackingDopesheetChannel *channel; float location[2]; - int extend = RNA_boolean_get(op->ptr, "extend"), channel, channel_index; + int extend = RNA_boolean_get(op->ptr, "extend"); + int current_channel_index = 0, channel_index; RNA_float_get_array(op->ptr, "location", location); - channel = -(location[1] - (CHANNEL_FIRST + CHANNEL_HEIGHT_HALF)) / CHANNEL_STEP; + channel_index = -(location[1] - (CHANNEL_FIRST + CHANNEL_HEIGHT_HALF)) / CHANNEL_STEP; - for (track = tracksbase->first, channel_index = 0; track; track = track->next) { - if (!TRACK_VIEW_SELECTED(sc, track)) - continue; + for (channel = dopesheet->channels.first; channel; channel = channel->next) { + MovieTrackingTrack *track = channel->track; - if (channel_index == channel) { + if (current_channel_index == channel_index) { if (extend) track->flag ^= TRACK_DOPE_SEL; else track->flag |= TRACK_DOPE_SEL; - - if (track->flag & TRACK_DOPE_SEL) { - MovieTrackingMarker *marker; - - /* make last selected in dopesheet track active in clip editor */ - tracking->act_track = track; - - /* make active track be centered to screen */ - /* XXX: doesn't work in other opened spaces */ - marker = BKE_tracking_get_marker(track, sc->user.framenr); - clip_view_center_to_point(sc, marker->pos[0], marker->pos[1]); - } } else if (!extend) track->flag &= ~TRACK_DOPE_SEL; - channel_index++; + current_channel_index++; } WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 69a8b0f4c92..e61580295fc 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -565,3 +565,11 @@ int ED_space_clip_show_trackedit(SpaceClip *sc) return FALSE; } + +void ED_space_clip_update_dopesheet(SpaceClip *sc) +{ + MovieClip *clip = sc->clip; + MovieTracking *tracking = &clip->tracking; + + BKE_tracking_update_dopesheet(tracking); +} diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index 7ab41078e16..0414c969705 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -234,11 +234,6 @@ static int mouse_select_curve(bContext *C, float co[2], int extend) tracking->act_track = userdata.track; - /* make active track be centered to screen */ - /* XXX: doesn't work in other opened spaces */ - marker = BKE_tracking_get_marker(userdata.track, sc->user.framenr); - clip_view_center_to_point(sc, marker->pos[0], marker->pos[1]); - /* deselect all knots on newly selected curve */ clip_graph_tracking_iterate(sc, &selectdata, toggle_selection_cb); } diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index b3bb7464761..2c9b61ed1ef 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -95,6 +95,8 @@ static void add_marker(SpaceClip *sc, float x, float y) BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, 0); clip->tracking.act_track = track; + + ED_space_clip_update_dopesheet(sc); } static int add_marker_exec(bContext *C, wmOperator *op) @@ -174,6 +176,8 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op)) /* nothing selected now, unlock view so it can be scrolled nice again */ sc->flag &= ~SC_LOCK_SELECTION; + ED_space_clip_update_dopesheet(sc); + return OPERATOR_FINISHED; } @@ -225,6 +229,8 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) sc->flag &= ~SC_LOCK_SELECTION; } + ED_space_clip_update_dopesheet(sc); + return OPERATOR_FINISHED; } @@ -790,6 +796,7 @@ static int mouse_select(bContext *C, float co[2], int extend) } WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); + ED_space_clip_update_dopesheet(sc); return OPERATOR_FINISHED; } @@ -901,6 +908,8 @@ static int border_select_exec(bContext *C, wmOperator *op) } if (change) { + ED_space_clip_update_dopesheet(sc); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); return OPERATOR_FINISHED; @@ -985,6 +994,8 @@ static int circle_select_exec(bContext *C, wmOperator *op) } if (change) { + ED_space_clip_update_dopesheet(sc); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); return OPERATOR_FINISHED; @@ -1081,6 +1092,8 @@ static int select_all_exec(bContext *C, wmOperator *op) if (!has_selection) sc->flag &= ~SC_LOCK_SELECTION; + ED_space_clip_update_dopesheet(sc); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); return OPERATOR_FINISHED; @@ -1161,6 +1174,8 @@ static int select_groped_exec(bContext *C, wmOperator *op) track = track->next; } + ED_space_clip_update_dopesheet(sc); + WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip); return OPERATOR_FINISHED; @@ -2730,6 +2745,8 @@ static int hide_tracks_exec(bContext *C, wmOperator *op) sc->flag &= ~SC_LOCK_SELECTION; } + BKE_tracking_update_dopesheet(tracking); + WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, NULL); return OPERATOR_FINISHED; diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 84d4215401b..e8abee36716 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -193,6 +193,17 @@ typedef struct MovieTrackingStats { char message[256]; } MovieTrackingStats; +typedef struct MovieTrackingDopesheetChannel { + struct MovieTrackingDopesheetChannel *next, *prev; + MovieTrackingTrack *track; + int flag, pad; +} MovieTrackingDopesheetChannel; + +typedef struct MovieTrackingDopesheet { + ListBase channels; + int tot_channel, pad; +} MovieTrackingDopesheet; + typedef struct MovieTracking { MovieTrackingSettings settings; /* different tracking-related settings */ MovieTrackingCamera camera; /* camera intrinsics */ @@ -205,6 +216,8 @@ typedef struct MovieTracking { int objectnr, tot_object; /* index of active object and total number of objects */ MovieTrackingStats *stats; /* statistics displaying in clip editor */ + + MovieTrackingDopesheet dopesheet; /* dopesheet data */ } MovieTracking; /* MovieTrackingCamera->units */ From 9151d46d7dbab7c978604656c146245aaf8f4ce3 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 30 Apr 2012 07:43:21 +0000 Subject: [PATCH 023/360] Tomato: initial commit of mask editing tools into SVN - Added new dtaablock called Mask which might be re-used in any area. Currently editing of masks happens in clip editor and they might be used in compositor nodes only. - Added new mode to clip clip editor to interact with masks. Implemented basic tools to create shapes, splines and points. Also implemented idea of UW points for feather which means feather points are have got U coordinate along spline (which is measured from 0 to 1) and W is it's weight meaning distance from main spline. - Spline points might be parented to movie tracks. Interface for this isn't best yet. - Rasterisaztion of masks happens in compositor node (Input -> Mask) Input image of this ode is used as reference for mask resolution. Currently all splines of all shapes are rasterizing independently which means shapes with holes are not supported. Also feather rasterization is not implemented. Rasterized was implemented by Pete Larbell, thanks! Do not consider this is something finished, there's still lots of things to be done (especially from interface and usability points of view). --- intern/CMakeLists.txt | 1 + intern/SConscript | 3 +- intern/raskter/CMakeLists.txt | 40 + intern/raskter/SConscript | 10 + intern/raskter/raskter.c | 367 ++++ intern/raskter/raskter.h | 55 + .../modules/bpy_extras/keyconfig_utils.py | 1 + release/scripts/startup/bl_ui/space_clip.py | 121 +- source/blender/CMakeLists.txt | 1 + source/blender/blenkernel/BKE_context.h | 1 + source/blender/blenkernel/BKE_library.h | 2 +- source/blender/blenkernel/BKE_main.h | 1 + source/blender/blenkernel/BKE_mask.h | 95 + source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/CMakeLists.txt | 2 + source/blender/blenkernel/intern/context.c | 5 + source/blender/blenkernel/intern/depsgraph.c | 12 + source/blender/blenkernel/intern/idcode.c | 1 + source/blender/blenkernel/intern/library.c | 11 + source/blender/blenkernel/intern/mask.c | 890 +++++++++ source/blender/blenkernel/intern/node.c | 1 + source/blender/blenkernel/intern/scene.c | 6 + source/blender/blenloader/intern/readfile.c | 91 + source/blender/blenloader/intern/writefile.c | 50 + source/blender/editors/CMakeLists.txt | 1 + source/blender/editors/SConscript | 1 + source/blender/editors/include/ED_clip.h | 9 + source/blender/editors/include/ED_mask.h | 44 + source/blender/editors/include/ED_screen.h | 1 + source/blender/editors/include/ED_transform.h | 1 + .../editors/interface/interface_templates.c | 6 +- source/blender/editors/mask/CMakeLists.txt | 47 + source/blender/editors/mask/SConscript | 9 + source/blender/editors/mask/mask_draw.c | 270 +++ source/blender/editors/mask/mask_editor.c | 218 +++ source/blender/editors/mask/mask_intern.h | 69 + source/blender/editors/mask/mask_ops.c | 1653 +++++++++++++++++ source/blender/editors/screen/screen_ops.c | 8 + source/blender/editors/space_api/spacetypes.c | 4 + .../blender/editors/space_clip/clip_editor.c | 91 + .../blender/editors/space_clip/space_clip.c | 53 +- source/blender/editors/space_node/drawnode.c | 8 + .../blender/editors/space_node/space_node.c | 7 + source/blender/editors/transform/transform.c | 61 +- source/blender/editors/transform/transform.h | 1 + .../editors/transform/transform_conversions.c | 207 +++ .../editors/transform/transform_generics.c | 50 +- .../blender/editors/transform/transform_ops.c | 1 + source/blender/makesdna/DNA_ID.h | 1 + source/blender/makesdna/DNA_mask_types.h | 108 ++ source/blender/makesdna/DNA_space_types.h | 5 + source/blender/makesdna/intern/makesdna.c | 2 + source/blender/makesrna/RNA_access.h | 2 + source/blender/makesrna/intern/CMakeLists.txt | 1 + source/blender/makesrna/intern/makesrna.c | 1 + source/blender/makesrna/intern/rna_ID.c | 2 + source/blender/makesrna/intern/rna_internal.h | 2 + source/blender/makesrna/intern/rna_main.c | 7 + source/blender/makesrna/intern/rna_main_api.c | 51 + source/blender/makesrna/intern/rna_mask.c | 600 ++++++ source/blender/makesrna/intern/rna_nodetree.c | 12 + .../makesrna/intern/rna_nodetree_types.h | 1 + source/blender/makesrna/intern/rna_space.c | 16 + source/blender/nodes/CMakeLists.txt | 2 + source/blender/nodes/NOD_composite.h | 2 + .../nodes/composite/node_composite_tree.c | 4 + .../composite/nodes/node_composite_mask.c | 124 ++ source/blender/windowmanager/WM_types.h | 1 + source/blenderplayer/CMakeLists.txt | 1 + .../bad_level_call_stubs/stubs.c | 1 + source/creator/CMakeLists.txt | 2 + 71 files changed, 5496 insertions(+), 40 deletions(-) create mode 100644 intern/raskter/CMakeLists.txt create mode 100644 intern/raskter/SConscript create mode 100644 intern/raskter/raskter.c create mode 100644 intern/raskter/raskter.h create mode 100644 source/blender/blenkernel/BKE_mask.h create mode 100644 source/blender/blenkernel/intern/mask.c create mode 100644 source/blender/editors/include/ED_mask.h create mode 100644 source/blender/editors/mask/CMakeLists.txt create mode 100644 source/blender/editors/mask/SConscript create mode 100644 source/blender/editors/mask/mask_draw.c create mode 100644 source/blender/editors/mask/mask_editor.c create mode 100644 source/blender/editors/mask/mask_intern.h create mode 100644 source/blender/editors/mask/mask_ops.c create mode 100644 source/blender/makesdna/DNA_mask_types.h create mode 100644 source/blender/makesrna/intern/rna_mask.c create mode 100644 source/blender/nodes/composite/nodes/node_composite_mask.c diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt index c85f0fddc34..71d2ef5e410 100644 --- a/intern/CMakeLists.txt +++ b/intern/CMakeLists.txt @@ -31,6 +31,7 @@ add_subdirectory(memutil) add_subdirectory(iksolver) add_subdirectory(opennl) add_subdirectory(mikktspace) +add_subdirectory(raskter) if(WITH_AUDASPACE) add_subdirectory(audaspace) diff --git a/intern/SConscript b/intern/SConscript index b6305f7dbab..6f08c696317 100644 --- a/intern/SConscript +++ b/intern/SConscript @@ -14,7 +14,8 @@ SConscript(['audaspace/SConscript', 'boolop/SConscript', 'opennl/SConscript', 'mikktspace/SConscript', - 'smoke/SConscript']) + 'smoke/SConscript', + 'raskter/SConscript']) # NEW_CSG was intended for intern/csg, but # getting it to compile is difficult diff --git a/intern/raskter/CMakeLists.txt b/intern/raskter/CMakeLists.txt new file mode 100644 index 00000000000..3e1368d8eb0 --- /dev/null +++ b/intern/raskter/CMakeLists.txt @@ -0,0 +1,40 @@ +# ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2012, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Peter Larabell +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + . +) + +set(INC_SYS + +) + +set(SRC + raskter.c + + raskter.h +) + +blender_add_lib(bf_intern_raskter "${SRC}" "${INC}" "${INC_SYS}") diff --git a/intern/raskter/SConscript b/intern/raskter/SConscript new file mode 100644 index 00000000000..7ad505d70e4 --- /dev/null +++ b/intern/raskter/SConscript @@ -0,0 +1,10 @@ +#!/usr/bin/python + +Import ('env') + +sources = ['raskter.c'] + +incs = '' +defs = '' + +env.BlenderLib ('bf_intern_raskter', sources, Split(incs), Split(defs), libtype=['intern'], priority=[100] ) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c new file mode 100644 index 00000000000..d5890f1741a --- /dev/null +++ b/intern/raskter/raskter.c @@ -0,0 +1,367 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Peter Larabell. + * + * ***** END GPL LICENSE BLOCK ***** + */ +/** \file raskter.c + * \ingroup RASKTER + */ + +#include +#include "raskter.h" + +#define R_XCHG(a,b) t=a;a=b;b=t; + +struct e_status { + int x; + int ybeg; + int xshift; + int xdir; + int drift; + int drift_inc; + int drift_dec; + int num; + struct e_status *e_next; +}; + +struct r_buffer_stats { + float *buf; + int sizex; + int sizey; +}; + +static struct e_status *all_edges, *possible_edges; +static struct r_buffer_stats rb; +/* + * Sort all the edges of the input polygon by Y, then by X, of the "first" vertex encountered. + * This will ensure we can scan convert the entire poly in one pass. + * + * Really the poly should be clipped to the frame buffer's dimensions here for speed of drawing + * just the poly. Since the DEM code could end up being coupled with this, we'll keep it separate + * for now. + */ +static void preprocess_all_edges(struct poly_vert * verts, int num_verts, struct e_status * open_edge) { + int i; + int xbeg; + int ybeg; + int xend; + int yend; + int dx; + int dy; + int t; + int xdist; + struct e_status *e_new; + struct e_status *next_edge; + struct e_status **next_edge_ref; + struct poly_vert *v; + // set up pointers + v = verts; + all_edges = NULL; + // loop all verts + for(i = 0; i < num_verts; i++) { + xbeg = v[i].x; + ybeg = v[i].y; + // determine starts and ends of edges, linking last vertex to first vertex + if(i == 0) { + xend = v[num_verts-1].x; + yend = v[num_verts-1].y; + } else { + xend = v[i-1].x; + yend = v[i-1].y; + } + // make sure our edges are facing the correct direction + if(ybeg > yend) { + R_XCHG(xbeg, xend); + R_XCHG(ybeg, yend); + } + // create the edge and determine it's slope (for incremental line drawing) + if((dy = yend - ybeg) != 0) { + e_new = open_edge++; + e_new->xdir = ((dx = xend - xbeg) > 0) ? 1 : -1; + xdist = (dx > 0) ? dx : -dx; + e_new->x = xbeg; + e_new->ybeg = ybeg; + e_new->num = dy; + e_new->drift_dec = dy; + if(dx >= 0) { + e_new->drift = 0; + } else { + e_new->drift = -dy + 1; + } + // calculate deltas for drawing + if(dy >= xdist) { + e_new->drift_inc = xdist; + e_new->xshift = 0; + } else { + e_new->drift_inc = xdist % dy; + e_new->xshift = (xdist / dy) * e_new->xdir; + } + next_edge_ref = &all_edges; + // link in all the edges, in sorted order + for(;;) { + next_edge = *next_edge_ref; + if((next_edge == NULL) || (next_edge->ybeg > ybeg) || ((next_edge->ybeg == ybeg) && (next_edge->x >= xbeg))) { + e_new->e_next = next_edge; + *next_edge_ref = e_new; + break; + } + next_edge_ref = &next_edge->e_next; + } + } + } +} + +/* + * This function clips drawing to the frame buffer. That clipping will likely be moved into the preprocessor + * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need + * if it ends up being coupled with this function. + */ +int rast_scan_fill(struct poly_vert * verts, int num_verts) { + int x_curr; // current pixel position in X + int y_curr; // current scan line being drawn + int yp; // y-pixel's position in frame buffer + int swixd = 0; // whether or not edges switched position in X + float *cpxl; // pixel pointers... + float *mpxl; + float *spxl; + struct e_status *e_curr; // edge pointers... + struct e_status *e_temp; + struct e_status *edgbuf; + struct e_status **edgec; + + + /* + If the number of verts specified to render as a polygon is less than 3, + return immediately. Obviously we cant render a poly with sides < 3. The + return for this we set to 1, simply so it can be distinguished from the + next place we could return, which is a failure to allocate memory. + */ + if(num_verts < 3) { + return(1); + } + + /* + Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data + multiplied by the number of edges, which is always equal to the number of verts in + a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for + the preceeding error, which was a rasterization request on a 2D poly with less than + 3 sides. + */ + if((edgbuf = (struct e_status *)(malloc(sizeof(struct e_status) * num_verts))) == NULL) { + return(0); + } + + /* + Do some preprocessing on all edges. This constructs a table structure in memory of all + the edge properties and can "flip" some edges so sorting works correctly. + */ + preprocess_all_edges(verts, num_verts, edgbuf); + + /* + Set the pointer for tracking the edges currently in processing to NULL to make sure + we don't get some crazy value after initialization. + */ + possible_edges = NULL; + + /* + Loop through all scan lines to be drawn. Since we sorted by Y values during + preprocess_all_edges(), we can already exact values for the lowest and + highest Y values we could possibly need by induction. The preprocessing sorted + out edges by Y position, we can cycle the current edge being processed once + it runs out of Y pixels. When we have no more edges, meaning the current edge + is NULL after setting the "current" edge to be the previous current edge's + "next" edge in the Y sorted edge connection chain, we can stop looping Y values, + since we can't possibly have more scan lines if we ran out of edges. :) + + TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here. + Will get changed once DEM code gets in. + */ + for(y_curr = (all_edges->ybeg > 0 ? all_edges->ybeg : 0); ((all_edges != NULL) || (possible_edges != NULL)) && (y_curr < rb.sizey); y_curr++) { + + /* + Link any edges that start on the current scan line into the list of + edges currently needed to draw at least this, if not several, scan lines. + */ + + /* + Set the current edge to the beginning of the list of edges to be rasterized + into this scan line. + + We could have lots of edge here, so iterate over all the edges needed. The + preprocess_all_edges() function sorted edges by X within each chunk of Y sorting + so we safely cycle edges to thier own "next" edges in order. + + At each iteration, make sure we still have a non-NULL edge. + */ + for(edgec = &possible_edges; (all_edges != NULL) && (all_edges->ybeg == y_curr);) { + x_curr = all_edges->x; // Set current X position. + for(;;) { // Start looping edges. Will break when edges run out. + e_curr = *edgec; // Set up a current edge pointer. + if((e_curr == NULL) || (e_curr->x >= x_curr)) { // If we have an no edge, or we need to skip some X-span, + e_temp = all_edges->e_next; // set a temp "next" edge to test. + *edgec = all_edges; // Add this edge to the list to be scanned. + all_edges->e_next = e_curr; // Set up the next edge. + edgec = &all_edges->e_next; // Set our list to the next edge's location in memory. + all_edges = e_temp; // Skip the NULL or bad X edge, set pointer to next edge. + break; // Stop looping edges (since we ran out or hit empty X span. + } else { + edgec = &e_curr->e_next; // Set the pointer to the edge list the "next" edge. + } + } + } + + /* + Determine the current scan line's offset in the pixel buffer based on its Y position. + Basically we just multiply the current scan line's Y value by the number of pixels in each line. + */ + yp = y_curr * rb.sizex; + /* + Set a "scan line pointer" in memory. The location of the buffer plus the row offset. + */ + spxl = rb.buf + (yp); + /* + Set up the current edge to the first (in X) edge. The edges which could possibly be in this + list were determined in the preceeding edge loop above. They were already sorted in X by the + initial processing function. + + At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge + we will eventually hit a NULL when the list runs out. + */ + for(e_curr = possible_edges; e_curr != NULL; e_curr = e_curr->e_next) { + /* + Calculate a span of pixels to fill on the current scan line. + + Set the current pixel pointer by adding the X offset to the scan line's start offset. + Cycle the current edge the next edge. + Set the max X value to draw to be one less than the next edge's first pixel. This way we are + sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than + one time because it's on a vertex connecting two edges) + + Then blast through all the pixels in the span, advancing the pointer and setting the color to white. + + TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor, + but for now it is done here until the DEM code comes in. + */ + cpxl = spxl + (e_curr->x > 0 ? e_curr->x : 0); + e_curr = e_curr->e_next; + mpxl = spxl + (e_curr->x < rb.sizex ? e_curr->x : rb.sizex) - 1; + for(; cpxl <= mpxl; *cpxl++ = 1.0f); + } + + /* + Loop through all edges of polygon that could be hit by this scan line, + and figure out their x-intersections with the next scan line. + + Either A.) we wont have any more edges to test, or B.) we just add on the + slope delta computed in preprocessing step. Since this draws non-antialiased + polygons, we dont have fractional positions, so we only move in x-direction + when needed to get all the way to the next pixel over... + */ + for(edgec = &possible_edges; (e_curr = *edgec) != NULL;) { + if((--(e_curr->num)) == 0) { + *edgec = e_curr->e_next; + } else { + e_curr->x += e_curr->xshift; + if((e_curr->drift += e_curr->drift_inc) > 0) { + e_curr->x += e_curr->xdir; + e_curr->drift -= e_curr->drift_dec; + } + edgec = &e_curr->e_next; + } + } + /* + It's possible that some edges may have crossed during the last step, so we'll be sure + that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges + sorted by x-intersection coordinate. We'll always scan through at least once to see if + edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial + pass, then we know we need to sort by x, so then cycle through edges again and perform + the sort.- + */ + if(possible_edges != NULL) { + for(edgec = &possible_edges; (e_curr = *edgec)->e_next != NULL;) { + if(e_curr->x > e_curr->e_next->x) { + e_temp = e_curr->e_next->e_next; + *edgec = e_curr->e_next; + e_curr->e_next->e_next = e_curr; + e_curr->e_next = e_temp; + swixd = 1; + } + edgec = &(*edgec)->e_next; + } + for(; swixd;) { + swixd = 0; + for(edgec = &possible_edges; (e_curr = *edgec)->e_next != NULL;) { + if(e_curr->x > e_curr->e_next->x) { + e_temp = e_curr->e_next->e_next; + *edgec = e_curr->e_next; + e_curr->e_next->e_next = e_curr; + e_curr->e_next = e_temp; + swixd = 1; + } + edgec = &(*edgec)->e_next; + } + } + } + } + + free(edgbuf); + return 1; +} + +int PLX_raskterize(float * verts, int num, float * buf, int buf_x, int buf_y) { + int i; // i: Loop counter. + struct poly_vert *ply; // ply: Pointer to a list of integer buffer-space vertex coordinates. + + /* + * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert + * data structure multiplied by the number of verts. + * + * In the event of a failure to allocate the memory, return 0, so this error can + * be distinguished as a memory allocation error. + */ + if((ply = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num))) == NULL) { + return(0); + } + + /* + * Loop over all verts passed in to be rasterized. Each vertex's X and Y coordinates are + * then converted from normalized screen space (0.0 <= POS <= 1.0) to integer coordinates + * in the buffer-space coordinates passed in inside buf_x and buf_y. + * + * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel + * drawn will be 1.0f in value, there is no anti-aliasing. + */ + for(i = 0; i < num; i++) { // Loop over all verts. + ply[i].x = (verts[i<<1] * buf_x) + 0.5f; // Range expand normalized X to integer buffer-space X. + ply[i].y = (verts[(i<<1)+1] * buf_y) + 0.5f; // Range expand normalized Y to integer buffer-space Y. + } + + rb.buf = buf; // Set the output buffer pointer. + rb.sizex = buf_x; // Set the output buffer size in X. (width) + rb.sizey = buf_y; // Set the output buffer size in Y. (height) + + i = rast_scan_fill(ply, num); // Call our rasterizer, passing in the integer coords for each vert. + free(ply); // Free the memory allocated for the integer coordinate table. + return(i); // Return the value returned by the rasterizer. +} diff --git a/intern/raskter/raskter.h b/intern/raskter/raskter.h new file mode 100644 index 00000000000..0b3cf365ff4 --- /dev/null +++ b/intern/raskter/raskter.h @@ -0,0 +1,55 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Peter Larabell. + * + * ***** END GPL LICENSE BLOCK ***** + */ +/** \file raskter.h + * \ingroup RASKTER + */ + +struct poly_vert{ + int x; + int y; +}; + +struct scan_line{ + int xstart; + int xend; +}; + +struct scan_line_batch{ + int num; + int ystart; + struct scan_line * slines; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int PLX_raskterize(float * verts, int num, float * buf, int buf_x, int buf_y); + +#ifdef __cplusplus +} +#endif diff --git a/release/scripts/modules/bpy_extras/keyconfig_utils.py b/release/scripts/modules/bpy_extras/keyconfig_utils.py index 20b0669e531..306371ea6f5 100644 --- a/release/scripts/modules/bpy_extras/keyconfig_utils.py +++ b/release/scripts/modules/bpy_extras/keyconfig_utils.py @@ -95,6 +95,7 @@ KM_HIERARCHY = [ ('Clip', 'CLIP_EDITOR', 'WINDOW', [ ('Clip Editor', 'CLIP_EDITOR', 'WINDOW', []), ('Clip Graph Editor', 'CLIP_EDITOR', 'WINDOW', []), + ('Mask Editor', 'EMPTY', 'WINDOW', []), # image (reverse order, UVEdit before Image ]), ('View3D Gesture Circle', 'EMPTY', 'WINDOW', []), diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index e4f608e2660..e72778e3776 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -44,11 +44,12 @@ class CLIP_HT_header(Header): sub.menu("CLIP_MT_clip") - if clip: + if clip and sc.mode != 'MASKEDITING': sub.menu("CLIP_MT_track") sub.menu("CLIP_MT_reconstruction") - layout.prop(sc, "view", text="", expand=True) + if sc.mode != 'MASKEDITING': + layout.prop(sc, "view", text="", expand=True) if clip: if sc.view == 'CLIP': @@ -72,6 +73,10 @@ class CLIP_HT_header(Header): row = layout.row() row.template_ID(sc, "clip", open='clip.open') + if sc.mode == 'MASKEDITING': + row = layout.row() + row.template_ID(sc, "mask", new="mask.new") + if clip: tracking = clip.tracking active = tracking.objects.active @@ -545,6 +550,112 @@ class CLIP_PT_tracking_camera(Panel): col.prop(clip.tracking.camera, "k3") +class CLIP_PT_shapes(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Shapes" + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.mask and sc.mode == 'MASKEDITING' + + def draw(self, context): + layout = self.layout + + sc = context.space_data + mask = sc.mask + + row = layout.row() + row.template_list(mask, "shapes", + mask, "active_shape_index", rows=3) + + sub = row.column(align=True) + + sub.operator("mask.shape_new", icon='ZOOMIN', text="") + sub.operator("mask.shape_remove", icon='ZOOMOUT', text="") + + active = mask.shapes.active + if active: + layout.prop(active, "name") + + +class CLIP_PT_active_mask_spline(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Active Spline" + + @classmethod + def poll(cls, context): + sc = context.space_data + mask = sc.mask + + if mask and sc.mode == 'MASKEDITING': + return mask.shapes.active and mask.shapes.active.splines.active + + return False + + def draw(self, context): + layout = self.layout + + sc = context.space_data + mask = sc.mask + spline = mask.shapes.active.splines.active + + col = layout.column() + col.prop(spline, "weight_interpolation") + col.prop(spline, "use_cyclic") + + +class CLIP_PT_active_mask_point(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Active Point" + + @classmethod + def poll(cls, context): + sc = context.space_data + mask = sc.mask + + if mask and sc.mode == 'MASKEDITING': + return mask.shapes.active and mask.shapes.active.splines.active_point + + return False + + def draw(self, context): + layout = self.layout + + sc = context.space_data + mask = sc.mask + point = mask.shapes.active.splines.active_point + parent = point.parent + + col = layout.column() + col.prop(point, "handle_type") + + col = layout.column() + col.prop(parent, "use_parent", text="Parent") + if parent.use_parent: + # Currently only parenting yo movie clip is allowed, so do not + # ver-oplicate things for now and use single template_ID + #col.template_any_ID(parent, "id", "id_type", text="") + + col.template_ID(parent, "id") + + if parent.id_type == 'MOVIECLIP' and parent.id: + clip = parent.id + tracking = clip.tracking + + col.prop_search(parent, "parent", tracking, "objects", icon='OBJECT_DATA', text="Object:") + + if parent.parent and parent.parent in tracking.objects: + object = clip.tracking.objects[parent.parent] + col.prop_search(parent, "sub_parent", object, "tracks", icon='ANIM_DATA', text="Track:") + else: + col.prop_search(parent, "sub_parent", clip.tracking, "tracks", icon='ANIM_DATA', text="Track:") + + class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' @@ -595,6 +706,12 @@ class CLIP_PT_marker_display(CLIP_PT_clip_view_panel, Panel): bl_region_type = 'UI' bl_label = "Marker Display" + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.mode != 'MASKEDITING' + def draw(self, context): layout = self.layout sc = context.space_data diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index cb17a87fd76..dc7e7948088 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -86,6 +86,7 @@ set(SRC_DNA_INC ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_world_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_movieclip_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_tracking_types.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_mask_types.h ) add_subdirectory(editors) diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index b2bd840a09a..c170cbb5694 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -260,6 +260,7 @@ struct Image *CTX_data_edit_image(const bContext *C); struct Text *CTX_data_edit_text(const bContext *C); struct MovieClip *CTX_data_edit_movieclip(const bContext *C); +struct Mask *CTX_data_edit_mask(const bContext *C); int CTX_data_selected_nodes(const bContext *C, ListBase *list); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index be21996428a..d97e035a547 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -65,7 +65,7 @@ void id_clear_lib_data(struct Main *bmain, struct ID *id); struct ListBase *which_libbase(struct Main *mainlib, short type); -#define MAX_LIBARRAY 40 +#define MAX_LIBARRAY 41 int set_listbasepointers(struct Main *main, struct ListBase **lb); void free_libblock(struct ListBase *lb, void *idv); diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index ffcbb6e40bc..382ce7c1274 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -86,6 +86,7 @@ typedef struct Main { ListBase wm; ListBase gpencil; ListBase movieclip; + ListBase mask; char id_tag_update[256]; } Main; diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h new file mode 100644 index 00000000000..268b7df0247 --- /dev/null +++ b/source/blender/blenkernel/BKE_mask.h @@ -0,0 +1,95 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BKE_MASK_H__ +#define __BKE_MASK_H__ + +struct Main; +struct Mask; +struct MaskParent; +struct MaskShape; +struct MaskSpline; +struct MaskSplinePoint; +struct MaskSplinePointUW; +struct Scene; + +/* shapes */ +struct MaskShape *BKE_mask_shape_new(struct Mask *mask, const char *name); +struct MaskShape *BKE_mask_shape_active(struct Mask *mask); +void BKE_mask_shape_active_set(struct Mask *mask, struct MaskShape *shape); +void BKE_mask_shape_remove(struct Mask *mask, struct MaskShape *shape); + +void BKE_mask_shape_free(struct MaskShape *shape); +void BKE_mask_spline_free(struct MaskSpline *spline); +void BKE_mask_point_free(struct MaskSplinePoint *point); + +void BKE_mask_shape_unique_name(struct Mask *mask, struct MaskShape *shape); + +/* splines */ +struct MaskSpline *BKE_mask_spline_add(struct MaskShape *shape); +int BKE_mask_spline_resolution(struct MaskSpline *spline); +float *BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point); +float *BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, float aspx, + float aspy, int *tot_feather_point); +float *BKE_mask_spline_feather_points(struct MaskSpline *spline, float aspx, float aspy, int *tot_feather_point); + +/* point */ +int BKE_mask_point_has_handle(struct MaskSplinePoint *point); +void BKE_mask_point_handle(struct MaskSplinePoint *point, float aspx, float aspy, float handle[2]); +void BKE_mask_point_set_handle(struct MaskSplinePoint *point, float loc[2], int keep_direction, float aspx, float aspy, float orig_handle[2], float orig_vec[3][3]); +float *BKE_mask_point_segment_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, int *tot_diff_point); +float *BKE_mask_point_segment_feather_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, + float aspx, float aspy, int *tot_feather_point); +void BKE_mask_point_segment_co(struct MaskSpline *spline, struct MaskSplinePoint *point, float u, float co[2]); +void BKE_mask_point_normal(struct MaskSpline *spline, struct MaskSplinePoint *point, float aspx, float aspy, float u, float n[2]); +float BKE_mask_point_weight(struct MaskSpline *spline, struct MaskSplinePoint *point, float u); +struct MaskSplinePointUW * BKE_mask_point_sort_uw(struct MaskSplinePoint *point, struct MaskSplinePointUW *uw); +void BKE_mask_point_add_uw(struct MaskSplinePoint *point, float u, float w); + +/* general */ +struct Mask *BKE_mask_new(const char *name); + +void BKE_mask_free(struct Mask *mask); +void BKE_mask_unlink(struct Main *bmain, struct Mask *mask); + +/* parenting */ + +void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime); +void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene); +void BKE_mask_parent_init(struct MaskParent *parent); + +#define MASKPOINT_ISSEL(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT ) +#define MASKPOINT_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } +#define MASKPOINT_DESEL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } +#define MASKPOINT_INVSEL(p) { (p)->bezt.f1 ^= SELECT; (p)->bezt.f2 ^= SELECT; (p)->bezt.f3 ^= SELECT; } + +#define MASKPOINT_CV_ISSEL(p) ( (p)->bezt.f2 & SELECT ) + +#define MASKPOINT_HANDLE_ONLY_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT ) && (((p)->bezt.f2 & SELECT) == 0) ) +#define MASKPOINT_HANDLE_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT ) ) +#define MASKPOINT_HANDLE_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f3 |= SELECT; } + +#endif diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index a4eddd0b590..4f3a6d4e174 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -638,6 +638,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); #define CMP_NODE_MOVIEDISTORTION 265 #define CMP_NODE_DOUBLEEDGEMASK 266 #define CMP_NODE_OUTPUT_MULTI_FILE__DEPRECATED 267 /* DEPRECATED multi file node has been merged into regular CMP_NODE_OUTPUT_FILE */ +#define CMP_NODE_MASK 268 #define CMP_NODE_GLARE 301 #define CMP_NODE_TONEMAP 302 diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index c2a83b5c048..61461044fa7 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -100,6 +100,7 @@ set(SRC intern/lamp.c intern/lattice.c intern/library.c + intern/mask.c intern/material.c intern/mball.c intern/mesh.c @@ -186,6 +187,7 @@ set(SRC BKE_lamp.h BKE_lattice.h BKE_library.h + BKE_mask.h BKE_main.h BKE_material.h BKE_mball.h diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 7a5b4ef9b24..639af36e15f 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -925,6 +925,11 @@ struct MovieClip *CTX_data_edit_movieclip(const bContext *C) return ctx_data_pointer_get(C, "edit_movieclip"); } +struct Mask *CTX_data_edit_mask(const bContext *C) +{ + return ctx_data_pointer_get(C, "edit_mask"); +} + struct EditBone *CTX_data_active_bone(const bContext *C) { return ctx_data_pointer_get(C, "active_bone"); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index d8cdd728c16..95ee3b34644 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2604,6 +2604,18 @@ static void dag_id_flush_update(Scene *sce, ID *id) } } + if (idtype == ID_MSK) { + if (sce->nodetree) { + bNode *node; + + for (node = sce->nodetree->nodes.first; node; node = node->next) { + if (node->id == id) { + nodeUpdate(sce->nodetree, node); + } + } + } + } + /* camera's matrix is used to orient reconstructed stuff, * so it should happen tracking-related constraints recalculation * when camera is changing (sergey) */ diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c index cd246681f3c..1f4d9d01fe1 100644 --- a/source/blender/blenkernel/intern/idcode.c +++ b/source/blender/blenkernel/intern/idcode.c @@ -79,6 +79,7 @@ static IDType idtypes[]= { { ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE}, { ID_WM, "WindowManager", "window_managers", 0}, { ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE}, + { ID_MSK, "Mask", "masks", IDTYPE_FLAGS_ISLINKABLE}, }; static int nidtypes= sizeof(idtypes)/sizeof(idtypes[0]); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 2924ea457a8..bd147db34d7 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -66,6 +66,7 @@ #include "DNA_world_types.h" #include "DNA_gpencil_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "BLI_blenlib.h" #include "BLI_dynstr.h" @@ -108,6 +109,7 @@ #include "BKE_speaker.h" #include "BKE_utildefines.h" #include "BKE_movieclip.h" +#include "BKE_mask.h" #include "RNA_access.h" @@ -486,6 +488,8 @@ ListBase *which_libbase(Main *mainlib, short type) return &(mainlib->gpencil); case ID_MC: return &(mainlib->movieclip); + case ID_MSK: + return &(mainlib->mask); } return NULL; } @@ -569,6 +573,7 @@ int set_listbasepointers(Main *main, ListBase **lb) lb[a++]= &(main->library); lb[a++]= &(main->wm); lb[a++]= &(main->movieclip); + lb[a++]= &(main->mask); lb[a]= NULL; @@ -680,6 +685,9 @@ static ID *alloc_libblock_notest(short type) case ID_MC: id = MEM_callocN(sizeof(MovieClip), "Movie Clip"); break; + case ID_MSK: + id = MEM_callocN(sizeof(Mask), "Mask"); + break; } return id; } @@ -888,6 +896,9 @@ void free_libblock(ListBase *lb, void *idv) case ID_MC: BKE_movieclip_free((MovieClip *)id); break; + case ID_MSK: + BKE_mask_free((Mask *)id); + break; } if (id->properties) { diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c new file mode 100644 index 00000000000..ad0baa9d63c --- /dev/null +++ b/source/blender/blenkernel/intern/mask.c @@ -0,0 +1,890 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/mask.c + * \ingroup bke + */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "DNA_mask_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_movieclip_types.h" +#include "DNA_tracking_types.h" + +#include "BKE_curve.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_mask.h" +#include "BKE_tracking.h" +#include "BKE_utildefines.h" + +/* shapes */ + +MaskShape *BKE_mask_shape_new(Mask *mask, const char *name) +{ + MaskShape *shape = MEM_callocN(sizeof(MaskShape), "new mask shape"); + + if (name && name[0]) + BLI_strncpy(shape->name, name, sizeof(shape->name)); + else + strcpy(shape->name, "Shape"); + + BLI_addtail(&mask->shapes, shape); + + BKE_mask_shape_unique_name(mask, shape); + + mask->tot_shape++; + + return shape; +} + +MaskShape *BKE_mask_shape_active(Mask *mask) +{ + return BLI_findlink(&mask->shapes, mask->shapenr); +} + +void BKE_mask_shape_active_set(Mask *mask, MaskShape *shape) +{ + int index = BLI_findindex(&mask->shapes, shape); + + if (index >= 0) + mask->shapenr = index; + else + mask->shapenr = 0; +} + +void BKE_mask_shape_remove(Mask *mask, MaskShape *shape) +{ + BLI_remlink(&mask->shapes, shape); + BKE_mask_shape_free(shape); + + mask->tot_shape--; + + if (mask->shapenr >= mask->tot_shape) + mask->shapenr = mask->tot_shape - 1; +} + +void BKE_mask_shape_unique_name(Mask *mask, MaskShape *shape) +{ + BLI_uniquename(&mask->shapes, shape, "Shape", '.', offsetof(MaskShape, name), sizeof(shape->name)); +} + +/* splines */ + +MaskSpline *BKE_mask_spline_add(MaskShape *shape) +{ + MaskSpline *spline; + + spline = MEM_callocN(sizeof(MaskSpline), "new shape spline"); + BLI_addtail(&shape->splines, spline); + + /* spline shall have one point at least */ + spline->points = MEM_callocN(sizeof(MaskSplinePoint), "new shape spline point"); + spline->tot_point = 1; + + /* cyclic shapes are more usually used */ + spline->flag |= MASK_SPLINE_CYCLIC; + + spline->weight_interp = MASK_SPLINE_INTERP_LINEAR; + + BKE_mask_parent_init(&spline->parent); + + return spline; +} + +int BKE_mask_spline_resolution(MaskSpline *spline) +{ + const float max_segment = 0.01; + int i, resol = 1; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *next_point; + BezTriple *bezt, *next_bezt; + float a, b, c, len; + int cur_resol; + + if (i == spline->tot_point - 1) { + if (spline->flag & MASK_SPLINE_CYCLIC) + next_point = &spline->points[0]; + else + break; + } + else + next_point = &spline->points[i + 1]; + + bezt = &point->bezt; + next_bezt = &next_point->bezt; + + a = len_v3v3(bezt->vec[1], bezt->vec[2]); + b = len_v3v3(bezt->vec[2], next_bezt->vec[0]); + c = len_v3v3(next_bezt->vec[0], next_bezt->vec[1]); + + len = a + b + c; + cur_resol = len / max_segment; + + resol = MAX2(resol, cur_resol); + } + + return resol; +} + +int BKE_mask_spline_feather_resolution(MaskSpline *spline) +{ + const float max_segment = 0.005; + int resol = BKE_mask_spline_resolution(spline); + float max_jump = 0.0f; + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + float prev_u, prev_w; + int j; + + prev_u = 0.0f; + prev_w = point->bezt.weight; + + for (j = 0; j < point->tot_uw; j++) { + float jump = fabsf((point->uw[j].w - prev_w) / (point->uw[j].u - prev_u)); + + max_jump = MAX2(max_jump, jump); + + prev_u = point->uw[j].u; + prev_w = point->uw[j].w; + } + } + + resol += max_jump / max_segment; + + return resol; +} + +float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) +{ + MaskSplinePoint *point, *prev; + float *diff_points, *fp; + int a, len, resol = BKE_mask_spline_resolution(spline); + + if (spline->tot_point <= 1) { + /* nothing to differentiate */ + *tot_diff_point = 0; + return NULL; + } + + /* count */ + len = (spline->tot_point - 1) * resol; + + if (spline->flag & MASK_SPLINE_CYCLIC) + len += resol; + else + len++; + + /* len+1 because of 'forward_diff_bezier' function */ + *tot_diff_point = len; + diff_points = fp = MEM_callocN((len + 1)*2*sizeof(float), "mask spline vets"); + + a = spline->tot_point - 1; + if (spline->flag & MASK_SPLINE_CYCLIC) + a++; + + prev = spline->points; + point = prev + 1; + + while (a--) { + BezTriple *prevbezt; + BezTriple *bezt; + int j; + + if (a==0 && (spline->flag & MASK_SPLINE_CYCLIC)) + point = spline->points; + + prevbezt = &prev->bezt; + bezt = &point->bezt; + + for (j = 0; j < 2; j++) { + BKE_curve_forward_diff_bezier(prevbezt->vec[1][j], prevbezt->vec[2][j], + bezt->vec[0][j], bezt->vec[1][j], + fp + j, resol, 2 * sizeof(float)); + } + + fp += 2 * resol; + + if (a==0 && (spline->flag & MASK_SPLINE_CYCLIC)==0) { + copy_v2_v2(fp, bezt->vec[1]); + } + + prev = point; + point++; + } + + return diff_points; +} + +float *BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, float aspx, float aspy, + int *tot_feather_point) +{ + float *feather, *fp; + int i, j, tot, resol = BKE_mask_spline_feather_resolution(spline); + + tot = resol * spline->tot_point; + feather = fp = MEM_callocN(2 * tot * sizeof(float), "mask spline feather diff points"); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + for (j = 0; j < resol; j++, fp += 2) { + float u = (float) j / resol, weight; + float co[2], n[2]; + + BKE_mask_point_segment_co(spline, point, u, co); + BKE_mask_point_normal(spline, point, aspx, aspy, u, n); + weight = BKE_mask_point_weight(spline, point, u); + + fp[0] = co[0] + n[0] * weight; + fp[1] = co[1] + n[1] * weight; + } + } + + *tot_feather_point = tot; + + return feather; +} + +float *BKE_mask_spline_feather_points(MaskSpline *spline, float aspx, float aspy, int *tot_feather_point) +{ + int i, tot = 0; + float *feather, *fp; + + /* count */ + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + tot += point->tot_uw + 1; + } + + /* create data */ + feather = fp = MEM_callocN(2 * tot * sizeof(float), "mask spline feather points"); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + BezTriple *bezt = &point->bezt; + float weight, n[2]; + int j; + + BKE_mask_point_normal(spline, point, aspx, aspy, 0.0f, n); + weight = BKE_mask_point_weight(spline, point, 0.0f); + + fp[0] = bezt->vec[1][0] + n[0] * weight; + fp[1] = bezt->vec[1][1] + n[1] * weight; + fp += 2; + + for (j = 0; j < point->tot_uw; j++) { + float u = point->uw[j].u; + float co[2]; + + BKE_mask_point_segment_co(spline, point, u, co); + BKE_mask_point_normal(spline, point, aspx, aspy, u, n); + weight = BKE_mask_point_weight(spline, point, u); + + fp[0] = co[0] + n[0] * weight; + fp[1] = co[1] + n[1] * weight; + + fp += 2; + } + } + + *tot_feather_point = tot; + + return feather; +} + +/* point */ + +int BKE_mask_point_has_handle(MaskSplinePoint *point) +{ + BezTriple *bezt = &point->bezt; + + return bezt->h1 == HD_ALIGN; +} + +void BKE_mask_point_handle(MaskSplinePoint *point, float aspx, float aspy, float handle[2]) +{ + float vec[2]; + + sub_v2_v2v2(vec, point->bezt.vec[0], point->bezt.vec[1]); + + vec[0] *= aspx; + vec[1] *= aspy; + + handle[0] = (point->bezt.vec[1][0]*aspx + vec[1]) / aspx; + handle[1] = (point->bezt.vec[1][1]*aspy - vec[0]) / aspy; +} + +void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_direction, float aspx, float aspy, + float orig_handle[2], float orig_vec[3][3]) +{ + BezTriple *bezt = &point->bezt; + float v1[2], v2[2], vec[2]; + + if (keep_direction) { + sub_v2_v2v2(v1, loc, orig_vec[1]); + sub_v2_v2v2(v2, orig_handle, orig_vec[1]); + + v1[0] *= aspx; + v1[1] *= aspy; + v2[0] *= aspx; + v2[1] *= aspx; + + project_v2_v2v2(vec, v1, v2); + + if (dot_v2v2(v2, vec) > 0) { + float len = len_v2(vec); + + sub_v2_v2v2(v1, orig_vec[0], orig_vec[1]); + + v1[0] *= aspx; + v1[1] *= aspy; + + mul_v2_fl(v1, len / len_v2(v1)); + + v1[0] /= aspx; + v1[1] /= aspy; + + add_v2_v2v2(bezt->vec[0], bezt->vec[1], v1); + sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v1); + } + else { + copy_v3_v3(bezt->vec[0], bezt->vec[1]); + copy_v3_v3(bezt->vec[2], bezt->vec[1]); + } + } else { + sub_v2_v2v2(v1, loc, bezt->vec[1]); + + v2[0] = -v1[1] * aspy / aspx; + v2[1] = v1[0] * aspx / aspy; + + add_v2_v2v2(bezt->vec[0], bezt->vec[1], v2); + sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v2); + } +} + +float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, float aspx, float aspy, + int *tot_feather_point) +{ + float *feather, *fp; + int i, resol = BKE_mask_spline_feather_resolution(spline); + + feather = fp = MEM_callocN(2 * resol * sizeof(float), "mask point spline feather diff points"); + + for (i = 0; i < resol; i++, fp += 2) { + float u = (float)(i % resol) / resol, weight; + float co[2], n[2]; + + BKE_mask_point_segment_co(spline, point, u, co); + BKE_mask_point_normal(spline, point, aspx, aspy, u, n); + weight = BKE_mask_point_weight(spline, point, u); + + fp[0] = co[0] + n[0] * weight; + fp[1] = co[1] + n[1] * weight; + } + + *tot_feather_point = resol; + + return feather; +} + +float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_diff_point) +{ + BezTriple *bezt, *next; + float *diff_points, *fp; + int j, resol = BKE_mask_spline_resolution(spline); + + bezt = &point->bezt; + + if (point == &spline->points[spline->tot_point - 1]) { + if (spline->flag & MASK_SPLINE_CYCLIC) + next = &(spline->points[0].bezt); + else + next = NULL; + } + else next = &((point + 1))->bezt; + + if (!next) + return NULL; + + /* resol+1 because of 'forward_diff_bezier' function */ + *tot_diff_point = resol + 1; + diff_points = fp = MEM_callocN((resol + 1)*2*sizeof(float), "mask segment vets"); + + for (j = 0; j < 2; j++) { + BKE_curve_forward_diff_bezier(bezt->vec[1][j], bezt->vec[2][j], + next->vec[0][j], next->vec[1][j], + fp + j, resol, 2 * sizeof(float)); + } + + copy_v2_v2(fp + 2 * resol, next->vec[1]); + + return diff_points; +} + +void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float u, float co[2]) +{ + BezTriple *bezt = &point->bezt, *next; + float q0[2], q1[2], q2[2], r0[2], r1[2]; + + if (point == &spline->points[spline->tot_point - 1]) { + if (spline->flag & MASK_SPLINE_CYCLIC) + next = &(spline->points[0].bezt); + else + next = NULL; + } + else next = &((point + 1))->bezt; + + if (!next) { + copy_v2_v2(co, bezt->vec[1]); + return; + } + + interp_v2_v2v2(q0, bezt->vec[1], bezt->vec[2], u); + interp_v2_v2v2(q1, bezt->vec[2], next->vec[0], u); + interp_v2_v2v2(q2, next->vec[0], next->vec[1], u); + + interp_v2_v2v2(r0, q0, q1, u); + interp_v2_v2v2(r1, q1, q2, u); + + interp_v2_v2v2(co, r0, r1, u); +} + +void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float aspx, float aspy, float u, float n[2]) +{ + BezTriple *bezt = &point->bezt, *next; + float q0[2], q1[2], q2[2], r0[2], r1[2], vec[2]; + + if (point == &spline->points[spline->tot_point - 1]) { + if (spline->flag & MASK_SPLINE_CYCLIC) + next = &(spline->points[0].bezt); + else + next = NULL; + } + else next = &((point + 1))->bezt; + + if (!next) { + BKE_mask_point_handle(point, aspx, aspy, vec); + + sub_v2_v2v2(n, vec, bezt->vec[1]); + + n[0] *= aspx; + n[1] *= aspy; + + normalize_v2(n); + + n[0] /= aspx; + n[1] /= aspy; + + return; + } + + interp_v2_v2v2(q0, bezt->vec[1], bezt->vec[2], u); + interp_v2_v2v2(q1, bezt->vec[2], next->vec[0], u); + interp_v2_v2v2(q2, next->vec[0], next->vec[1], u); + + interp_v2_v2v2(r0, q0, q1, u); + interp_v2_v2v2(r1, q1, q2, u); + + sub_v2_v2v2(vec, r1, r0); + + n[0] = -vec[1] * aspy; + n[1] = vec[0] * aspx; + + normalize_v2(n); + + n[0] /= aspx; + n[1] /= aspy; +} + +float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, float u) +{ + BezTriple *bezt = &point->bezt, *next; + float cur_u, cur_w, next_u, next_w, fac; + int i; + + if (point == &spline->points[spline->tot_point - 1]) { + if (spline->flag & MASK_SPLINE_CYCLIC) + next = &(spline->points[0].bezt); + else + next = NULL; + } + else next = &((point + 1))->bezt; + + if (!next) + return bezt->weight; + + for (i = 0; i < point->tot_uw + 1; i++) { + + if (i == 0) { + cur_u = 0.0f; + cur_w = bezt->weight; + } + else { + cur_u = point->uw[i - 1].u; + cur_w = point->uw[i - 1].w; + } + + if (i == point->tot_uw) { + next_u = 1.0f; + next_w = next->weight; + } + else { + next_u = point->uw[i].u; + next_w = point->uw[i].w; + } + + if (u >= cur_u && u <= next_u) { + break; + } + } + + fac = (u - cur_u) / (next_u - cur_u); + + if (spline->weight_interp == MASK_SPLINE_INTERP_EASE) + return cur_w + (next_w - cur_w) * (3.0f * fac * fac - 2.0f * fac * fac * fac); + else + return (1.0f - fac) * cur_w + fac * next_w; +} + +MaskSplinePointUW *BKE_mask_point_sort_uw(MaskSplinePoint *point, MaskSplinePointUW *uw) +{ + if (point->tot_uw > 1) { + int idx = uw - point->uw; + + if (idx > 0 && point->uw[idx - 1].u > uw->u) { + while (idx > 0 && point->uw[idx - 1].u > point->uw[idx].u) { + SWAP(MaskSplinePointUW, point->uw[idx - 1], point->uw[idx]); + idx--; + } + } + + if (idx < point->tot_uw - 1 && point->uw[idx + 1].u < uw->u) { + while (idx < point->tot_uw - 1 && point->uw[idx + 1].u < point->uw[idx].u) { + SWAP(MaskSplinePointUW, point->uw[idx + 1], point->uw[idx]); + idx++; + } + } + + return &point->uw[idx]; + } + + return uw; +} + +void BKE_mask_point_add_uw(MaskSplinePoint *point, float u, float w) +{ + if (!point->uw) + point->uw = MEM_callocN(sizeof(*point->uw), "mask point uw"); + else + point->uw = MEM_reallocN(point->uw, (point->tot_uw + 1) * sizeof(*point->uw)); + + point->uw[point->tot_uw].u = u; + point->uw[point->tot_uw].w = w; + + point->tot_uw++; + + BKE_mask_point_sort_uw(point, &point->uw[point->tot_uw - 1]); +} + +/* only mask block itself */ +static Mask *mask_alloc(const char *name) +{ + Mask *mask; + + mask = alloc_libblock(&G.main->mask, ID_MSK, name); + + return mask; +} + +Mask *BKE_mask_new(const char *name) +{ + Mask *mask; + char mask_name[MAX_ID_NAME - 2]; + + if (name && name[0]) + BLI_strncpy(mask_name, name, sizeof(mask_name)); + else + strcpy(mask_name, "Mask"); + + mask = mask_alloc(mask_name); + + return mask; +} + +void BKE_mask_point_free(MaskSplinePoint *point) +{ + if (point->uw) + MEM_freeN(point->uw); +} + +void BKE_mask_spline_free(MaskSpline *spline) +{ + int i = 0; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + BKE_mask_point_free(point); + } + + MEM_freeN(spline->points); + + MEM_freeN(spline); +} + +void BKE_mask_shape_free(MaskShape *shape) +{ + MaskSpline *spline = shape->splines.first; + + while (spline) { + MaskSpline *next_spline = spline->next; + + BLI_remlink(&shape->splines, spline); + BKE_mask_spline_free(spline); + + spline = next_spline; + } + + MEM_freeN(shape); +} + +void BKE_mask_free(Mask *mask) +{ + MaskShape *shape = mask->shapes.first; + + while (shape) { + MaskShape *next_shape = shape->next; + + BLI_remlink(&mask->shapes, shape); + BKE_mask_shape_free(shape); + + shape = next_shape; + } +} + +void BKE_mask_unlink(Main *bmain, Mask *mask) +{ + bScreen *scr; + ScrArea *area; + SpaceLink *sl; + + for (scr = bmain->screen.first; scr; scr = scr->id.next) { + for (area = scr->areabase.first; area; area = area->next) { + for(sl = area->spacedata.first; sl; sl = sl->next) { + if(sl->spacetype == SPACE_CLIP) { + SpaceClip *sc = (SpaceClip *) sl; + + if(sc->mask == mask) + sc->mask = NULL; + } + } + } + } + + mask->id.us= 0; +} + +static void evaluate_mask_parent(MaskParent *parent, float ctime, float co[2]) +{ + if (!parent) + return; + + if ((parent->flag & MASK_PARENT_ACTIVE) == 0) + return; + + if (parent->id_type == ID_MC) { + if (parent->id) { + MovieClip *clip = (MovieClip *) parent->id; + MovieTracking *tracking = (MovieTracking *) &clip->tracking; + MovieTrackingObject *ob = BKE_tracking_named_object(tracking, parent->parent); + + if (ob) { + MovieTrackingTrack *track = BKE_tracking_named_track(tracking, ob, parent->sub_parent); + + if (track) { + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, ctime); + + copy_v2_v2(co, marker->pos); + } + } + } + } +} + +static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *prev_point, MaskSplinePoint *next_point) +{ + BezTriple *bezt = &point->bezt; + BezTriple *prev_bezt = NULL, *next_bezt = NULL; + int handle_type = bezt->h1; + + if (prev_point) + prev_bezt = &prev_point->bezt; + + if (next_point) + next_bezt = &next_point->bezt; + + if (handle_type == HD_VECT) { + BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0); + } + else if (handle_type == HD_AUTO) { + BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0); + } + else if (handle_type == HD_ALIGN) { + float v1[3], v2[3]; + float vec[3], h[3]; + + sub_v3_v3v3(v1, bezt->vec[0], bezt->vec[1]); + sub_v3_v3v3(v2, bezt->vec[2], bezt->vec[1]); + add_v3_v3v3(vec, v1, v2); + + if (len_v3(vec) > 1e-3) { + h[0] = vec[1]; + h[1] = -vec[0]; + h[2] = 0.0f; + } + else { + copy_v3_v3(h, v1); + } + + add_v3_v3v3(bezt->vec[0], bezt->vec[1], h); + sub_v3_v3v3(bezt->vec[2], bezt->vec[1], h); + } +} + +void BKE_mask_calc_handles(Mask *mask) +{ + MaskShape *shape = mask->shapes.first; + + while (shape) { + MaskSpline *spline = shape->splines.first; + int i; + + while (spline) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *prev_point, *next_point; + + if (i == 0) { + if (spline->flag & MASK_SPLINE_CYCLIC) + prev_point = &spline->points[spline->tot_point - 1]; + else + prev_point = NULL; + } + else prev_point = point - 1; + + if (i == spline->tot_point - 1) { + if (spline->flag & MASK_SPLINE_CYCLIC) + next_point = &spline->points[0]; + else + next_point = NULL; + } + else next_point = point + 1; + + mask_calc_point_handle(point, prev_point, next_point); + } + + spline = spline->next; + } + + shape = shape->next; + } +} + +void BKE_mask_evaluate(Mask *mask, float ctime) +{ + MaskShape *shape = mask->shapes.first; + + while (shape) { + MaskSpline *spline = shape->splines.first; + int i; + + while (spline) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + BezTriple *bezt = &point->bezt; + float co[2], delta[2]; + + copy_v2_v2(co, bezt->vec[1]); + evaluate_mask_parent(&point->parent, ctime, co); + sub_v2_v2v2(delta, co, bezt->vec[1]); + + add_v2_v2(bezt->vec[0], delta); + add_v2_v2(bezt->vec[1], delta); + add_v2_v2(bezt->vec[2], delta); + } + + spline = spline->next; + } + + shape = shape->next; + } + + BKE_mask_calc_handles(mask); +} + +void BKE_mask_evaluate_all_masks(Main *bmain, float ctime) +{ + Mask *mask; + + for (mask = bmain->mask.first; mask; mask = mask->id.next) { + BKE_mask_evaluate(mask, ctime); + } +} + +void BKE_mask_update_scene(Main *bmain, Scene *scene) +{ + Mask *mask; + + for (mask = bmain->mask.first; mask; mask = mask->id.next) { + if (mask->id.flag & LIB_ID_RECALC) { + BKE_mask_evaluate_all_masks(bmain, CFRA); + } + } +} + +void BKE_mask_parent_init(MaskParent *parent) +{ + parent->id_type = ID_MC; +} diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index b2a85ad0629..19713f60ec8 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1930,6 +1930,7 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_cmp_transform(ttype); register_node_type_cmp_stabilize2d(ttype); register_node_type_cmp_moviedistortion(ttype); + register_node_type_cmp_mask(ttype); } static void registerShaderNodes(bNodeTreeType *ttype) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 864260833a6..2a311a871f0 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -63,6 +63,7 @@ #include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_mask.h" #include "BKE_node.h" #include "BKE_object.h" #include "BKE_paint.h" @@ -1003,6 +1004,9 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen /* update sound system animation */ sound_update_scene(scene); + + /* update masking curves */ + BKE_mask_update_scene(bmain, scene); } /* this is called in main loop, doing tagged updates before redraw */ @@ -1073,6 +1077,8 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) * so don't call within 'scene_update_tagged_recursive' */ DAG_scene_update_flags(bmain, sce, lay, TRUE); // only stuff that moves or needs display still + BKE_mask_evaluate_all_masks(bmain, ctime); + /* All 'standard' (i.e. without any dependencies) animation is handled here, * with an 'local' to 'macro' order of evaluation. This should ensure that * settings stored nestled within a hierarchy (i.e. settings in a Texture block diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 993426545ee..753cd93b89a 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -94,6 +94,7 @@ #include "DNA_vfont_types.h" #include "DNA_world_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" @@ -5387,6 +5388,7 @@ static void lib_link_screen(FileData *fd, Main *main) SpaceClip *sclip= (SpaceClip *)sl; sclip->clip= newlibadr_us(fd, sc->id.lib, sclip->clip); + sclip->mask= newlibadr_us(fd, sc->id.lib, sclip->mask); sclip->scopes.track_preview = NULL; sclip->draw_context = NULL; @@ -5654,6 +5656,7 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) SpaceClip *sclip= (SpaceClip *)sl; sclip->clip= restore_pointer_by_name(newmain, (ID *)sclip->clip, 1); + sclip->mask= restore_pointer_by_name(newmain, (ID *)sclip->mask, 1); sclip->scopes.ok = 0; } @@ -6238,6 +6241,90 @@ static void lib_link_movieclip(FileData *fd, Main *main) } } +/* ***************** READ MOVIECLIP *************** */ + +static void direct_link_mask(FileData *fd, Mask *mask) +{ + MaskShape *shape; + + mask->adt = newdataadr(fd, mask->adt); + + link_list(fd, &mask->shapes); + + shape = mask->shapes.first; + while (shape) { + MaskSpline *spline; + + link_list(fd, &shape->splines); + + spline = shape->splines.first; + while (spline) { + int i; + + spline->points = newdataadr(fd, spline->points); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (point->tot_uw) + point->uw = newdataadr(fd, point->uw); + } + + spline = spline->next; + } + + shape->act_spline = newdataadr(fd, shape->act_spline); + shape->act_point = newdataadr(fd, shape->act_point); + + shape = shape->next; + } +} + +static void lib_link_mask_parent(FileData *fd, Mask *mask, MaskParent *parent) +{ + parent->id = newlibadr_us(fd, mask->id.lib, parent->id); +} + +static void lib_link_mask(FileData *fd, Main *main) +{ + Mask *mask; + + mask = main->mask.first; + while (mask) { + if(mask->id.flag & LIB_NEEDLINK) { + MaskShape *shape; + + if (mask->adt) + lib_link_animdata(fd, &mask->id, mask->adt); + + shape = mask->shapes.first; + while (shape) { + MaskSpline *spline; + + spline = shape->splines.first; + while (spline) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + lib_link_mask_parent(fd, mask, &point->parent); + } + + lib_link_mask_parent(fd, mask, &spline->parent); + + spline = spline->next; + } + + shape = shape->next; + } + + mask->id.flag -= LIB_NEEDLINK; + } + mask = mask->id.next; + } +} + /* ************** GENERAL & MAIN ******************** */ @@ -6444,6 +6531,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID case ID_MC: direct_link_movieclip(fd, (MovieClip *)id); break; + case ID_MSK: + direct_link_mask(fd, (Mask *)id); + break; } /*link direct data of ID properties*/ @@ -13344,6 +13434,7 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_brush(fd, main); lib_link_particlesettings(fd, main); lib_link_movieclip(fd, main); + lib_link_mask(fd, main); lib_link_mesh(fd, main); /* as last: tpage images with users at zero */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 5580c9efc9b..e11e0274b28 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -133,6 +133,7 @@ Any case: direct data is ALWAYS after the lib block #include "DNA_world_types.h" #include "DNA_windowmanager_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" // MEM_freeN #include "BLI_bitmap.h" @@ -2732,6 +2733,54 @@ static void write_movieclips(WriteData *wd, ListBase *idbase) mywrite(wd, MYWRITE_FLUSH, 0); } +static void write_masks(WriteData *wd, ListBase *idbase) +{ + Mask *mask; + + mask = idbase->first; + while (mask) { + if (mask->id.us > 0 || wd->current) { + MaskShape *shape; + + writestruct(wd, ID_MSK, "Mask", 1, mask); + + if (mask->adt) + write_animdata(wd, mask->adt); + + shape = mask->shapes.first; + while (shape) { + MaskSpline *spline; + + writestruct(wd, DATA, "MaskShape", 1, shape); + + spline = shape->splines.first; + while (spline) { + int i; + + writestruct(wd, DATA, "MaskSpline", 1, spline); + writestruct(wd, DATA, "MaskSplinePoint", spline->tot_point, spline->points); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (point->tot_uw) + writestruct(wd, DATA, "MaskSplinePointUW", point->tot_uw, point->uw); + } + + spline = spline->next; + } + + shape = shape->next; + } + } + + mask = mask->id.next; + } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); +} + /* context is usually defined by WM, two cases where no WM is available: * - for forward compatibility, curscreen has to be saved * - for undofile, curscene needs to be saved */ @@ -2816,6 +2865,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil write_screens (wd, &mainvar->screen); } write_movieclips (wd, &mainvar->movieclip); + write_masks (wd, &mainvar->mask); write_scenes (wd, &mainvar->scene); write_curves (wd, &mainvar->curve); write_mballs (wd, &mainvar->mball); diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index 088376b20ef..67ed77bcc4b 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -24,6 +24,7 @@ if(WITH_BLENDER) add_subdirectory(curve) add_subdirectory(gpencil) add_subdirectory(interface) + add_subdirectory(mask) add_subdirectory(mesh) add_subdirectory(metaball) add_subdirectory(object) diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript index ed66a76a324..d08b496f0ef 100644 --- a/source/blender/editors/SConscript +++ b/source/blender/editors/SConscript @@ -8,6 +8,7 @@ SConscript(['datafiles/SConscript', 'interface/SConscript', 'animation/SConscript', 'armature/SConscript', + 'mask/SConscript', 'mesh/SConscript', 'metaball/SConscript', 'object/SConscript', diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index db6d9bbd013..285f1487a71 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -36,6 +36,7 @@ struct bContext; struct bScreen; struct ImBuf; struct Main; +struct Mask; struct MovieClip; struct SpaceClip; struct wmEvent; @@ -45,13 +46,19 @@ int ED_space_clip_poll(struct bContext *C); int ED_space_clip_tracking_poll(struct bContext *C); int ED_space_clip_tracking_size_poll(struct bContext *C); int ED_space_clip_tracking_frame_poll(struct bContext *C); +int ED_space_clip_maskediting_poll(struct bContext *C); +int ED_space_clip_maskediting_mask_poll(bContext *C); void ED_space_clip_set(struct bContext *C, struct bScreen *screen, struct SpaceClip *sc, struct MovieClip *clip); struct MovieClip *ED_space_clip(struct SpaceClip *sc); +struct Mask *ED_space_clip_mask(struct SpaceClip *sc); void ED_space_clip_size(struct SpaceClip *sc, int *width, int *height); void ED_space_clip_zoom(struct SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy); void ED_space_clip_aspect(struct SpaceClip *sc, float *aspx, float *aspy); +void ED_space_clip_mask_size(struct SpaceClip *sc, int *width, int *height); +void ED_space_clip_mask_aspect(struct SpaceClip *sc, float *aspx, float *aspy); + struct ImBuf *ED_space_clip_get_buffer(struct SpaceClip *sc); struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale, float *angle); @@ -68,6 +75,8 @@ void ED_space_clip_unload_movieclip_buffer(struct SpaceClip *sc); void ED_space_clip_free_texture_buffer(struct SpaceClip *sc); int ED_space_clip_show_trackedit(struct SpaceClip *sc); +int ED_space_clip_show_maskedit(struct SpaceClip *sc); +void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask); void ED_space_clip_update_dopesheet(struct SpaceClip *sc); diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h new file mode 100644 index 00000000000..5df91b4032a --- /dev/null +++ b/source/blender/editors/include/ED_mask.h @@ -0,0 +1,44 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file ED_mask.h + * \ingroup editors + */ + +#ifndef __ED_MASK_H__ +#define __ED_MASK_H__ + +struct wmKeyConfig; + +/* mask_editor.c */ +void ED_operatortypes_mask(void); +void ED_keymap_mask(struct wmKeyConfig *keyconf); +void ED_operatormacros_mask(void); + +/* mask_draw.c */ +void ED_mask_draw(bContext *C, int width, int height, float zoomx, float zoomy); + +#endif /* ED_TEXT_H */ diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index f62befdaa31..44a66d436db 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -169,6 +169,7 @@ int ED_operator_editmball(struct bContext *C); int ED_operator_uvedit(struct bContext *C); int ED_operator_uvmap(struct bContext *C); int ED_operator_posemode(struct bContext *C); +int ED_operator_mask(struct bContext *C); /* default keymaps, bitflags */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index f6dee351c29..2d6379ad8a6 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -95,6 +95,7 @@ enum { #define CTX_BMESH 64 #define CTX_NDOF 128 #define CTX_MOVIECLIP 256 +#define CTX_MASK 512 /* Standalone call to get the transformation center corresponding to the current situation * returns 1 if successful, 0 otherwise (usually means there's no selection) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index bafd85e9451..c6bc975d981 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -576,8 +576,10 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co row = uiLayoutRow(layout, 1); /* Label - either use the provided text, or will become "ID-Block:" */ - if (text) - uiItemL(row, text, ICON_NONE); + if (text) { + if (text[0]) + uiItemL(row, text, ICON_NONE); + } else uiItemL(row, "ID-Block:", ICON_NONE); diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt new file mode 100644 index 00000000000..fc1d2f4be6b --- /dev/null +++ b/source/blender/editors/mask/CMakeLists.txt @@ -0,0 +1,47 @@ +# ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2012 Blender Foundation. +# +# Contributor(s): Blender Foundation, +# Sergey Sharybin +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + ../include + ../../blenkernel + ../../blenloader + ../../blenlib + ../../makesdna + ../../makesrna + ../../windowmanager + ../../../../intern/guardedalloc + ${GLEW_INCLUDE_PATH} +) + +set(INC_SYS +) + +set(SRC + mask_draw.c + mask_editor.c + mask_ops.c + + mask_intern.h +) + +blender_add_lib(bf_editor_mask "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/mask/SConscript b/source/blender/editors/mask/SConscript new file mode 100644 index 00000000000..4af000d038d --- /dev/null +++ b/source/blender/editors/mask/SConscript @@ -0,0 +1,9 @@ +#!/usr/bin/python +Import ('env') + +sources = env.Glob('*.c') +defs = [] +incs = '../include ../../blenkernel ../../blenloader ../../blenlib ../../windowmanager ../../makesdna' +incs += ' ../../makesrna #/extern/glew/include #/intern/guardedalloc' + +env.BlenderLib ( 'bf_editors_mask', sources, Split(incs), defs, libtype=['core'], priority=[100] ) diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c new file mode 100644 index 00000000000..d898a1c5232 --- /dev/null +++ b/source/blender/editors/mask/mask_draw.c @@ -0,0 +1,270 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_draw.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_mask.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "ED_mask.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "UI_resources.h" + +#include "mask_intern.h" // own include + +typedef struct PixelSpaceContext { + int width, height; + float zoomx, zoomy; + float aspx, aspy; +} PixelSpaceContext; + +static void set_spline_color(MaskShape *shape, MaskSpline *spline) +{ + if (spline->flag & SELECT) { + if (shape->act_spline == spline) + glColor3f(1.0f, 1.0f, 1.0f); + else + glColor3f(1.0f, 0.0f, 0.0f); + } + else { + glColor3f(0.5f, 0.0f, 0.0f); + } +} + +/* return non-zero if spline is selected */ +static void draw_spline_points(MaskShape *shape, MaskSpline *spline, PixelSpaceContext *pixelspace) +{ + int i, hsize, tot_feather_point; + float *feather_points, *fp; + + if (!spline->tot_point) + return; + + hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); + + glPointSize(hsize); + + /* feather points */ + feather_points = fp = BKE_mask_spline_feather_points(spline, pixelspace->aspx, pixelspace->aspy, &tot_feather_point); + for (i = 0; i < spline->tot_point; i++) { + int j; + MaskSplinePoint *point = &spline->points[i]; + + for (j = 0; j < point->tot_uw + 1; j++) { + int sel = FALSE; + + if (j == 0) { + sel = MASKPOINT_ISSEL(point); + } + else { + sel = point->uw[j - 1].flag & SELECT; + } + + if (sel) { + if (point == shape->act_point) + glColor3f(1.0f, 1.0f, 1.0f); + else + glColor3f(1.0f, 1.0f, 0.0f); + } else + glColor3f(0.5f, 0.5f, 0.0f); + + glBegin(GL_POINTS); + glVertex2fv(fp); + glEnd(); + + fp += 2; + } + } + MEM_freeN(feather_points); + + /* control points */ + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + BezTriple *bezt = &point->bezt; + float vert[2], handle[2]; + int has_handle = BKE_mask_point_has_handle(point);; + + copy_v2_v2(vert, bezt->vec[1]); + BKE_mask_point_handle(point, pixelspace->aspx, pixelspace->aspy, handle); + + /* draw handle segment */ + if (has_handle) { + set_spline_color(shape, spline); + + glBegin(GL_LINES); + glVertex3fv(vert); + glVertex3fv(handle); + glEnd(); + } + + /* draw CV point */ + if (MASKPOINT_CV_ISSEL(point)) { + if (point == shape->act_point) + glColor3f(1.0f, 1.0f, 1.0f); + else + glColor3f(1.0f, 1.0f, 0.0f); + } else + glColor3f(0.5f, 0.5f, 0.0f); + + glBegin(GL_POINTS); + glVertex3fv(vert); + glEnd(); + + /* draw handle points */ + if (has_handle) { + if (MASKPOINT_HANDLE_ISSEL(point)) { + if (point == shape->act_point) + glColor3f(1.0f, 1.0f, 1.0f); + else + glColor3f(1.0f, 1.0f, 0.0f); + } else + glColor3f(0.5f, 0.5f, 0.0f); + + glBegin(GL_POINTS); + glVertex3fv(handle); + glEnd(); + } + } + + glPointSize(1.0f); +} + +static void draw_spline_curve_lines(float *points, int tot_point, int closed) +{ + int i; + float *fp = points; + + if (closed) + glBegin(GL_LINE_LOOP); + else + glBegin(GL_LINE_STRIP); + + for (i = 0; i < tot_point; i++, fp+=2) { + glVertex3fv(fp); + } + glEnd(); +} + +static void draw_dashed_curve(MaskSpline *spline, float *points, int tot_point) +{ + glEnable(GL_COLOR_LOGIC_OP); + glLogicOp(GL_OR); + + draw_spline_curve_lines(points, tot_point, spline->flag & MASK_SPLINE_CYCLIC); + + glDisable(GL_COLOR_LOGIC_OP); + glLineStipple(3, 0xaaaa); + glEnable(GL_LINE_STIPPLE); + + glColor3f(0.0f, 0.0f, 0.0f); + draw_spline_curve_lines(points, tot_point, spline->flag & MASK_SPLINE_CYCLIC); + + glDisable(GL_LINE_STIPPLE); +} + +static void draw_spline_curve(MaskShape *shape, MaskSpline *spline, PixelSpaceContext *pixelspace) +{ + float *diff_points, *feather_points; + int tot_diff_point, tot_feather_point; + + diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); + + if (!diff_points) + return; + + feather_points = BKE_mask_spline_feather_differentiated_points(spline, pixelspace->aspx, pixelspace->aspy, + &tot_feather_point); + + /* draw feather */ + if (spline->flag & SELECT) + glColor3f(0.0f, 1.0f, 0.0f); + else + glColor3f(0.0f, 0.5f, 0.0f); + draw_dashed_curve(spline, feather_points, tot_feather_point); + + /* draw main curve */ + set_spline_color(shape, spline); + draw_dashed_curve(spline, diff_points, tot_diff_point); + + MEM_freeN(diff_points); + MEM_freeN(feather_points); +} + +static void draw_shapes(Mask *mask, PixelSpaceContext *pixelspace) +{ + MaskShape *shape = mask->shapes.first; + + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + /* draw curve itself first... */ + draw_spline_curve(shape, spline, pixelspace); + + /* ...and then handles over the curve so they're nicely visible */ + draw_spline_points(shape, spline, pixelspace); + + spline = spline->next; + } + + shape = shape->next; + } +} + +void ED_mask_draw(bContext *C, int width, int height, float zoomx, float zoomy) +{ + Mask *mask = CTX_data_edit_mask(C); + PixelSpaceContext pixelspace; + float aspx, aspy; + + if (!mask) + return; + + ED_mask_aspect(C, &aspx, &aspy); + + pixelspace.width = width; + pixelspace.height = height; + pixelspace.zoomx = zoomx; + pixelspace.zoomy = zoomy; + pixelspace.aspx = aspx; + pixelspace.aspy = aspy; + + draw_shapes(mask, &pixelspace); +} diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c new file mode 100644 index 00000000000..fcdf66ed69d --- /dev/null +++ b/source/blender/editors/mask/mask_editor.c @@ -0,0 +1,218 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_ops.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_mask.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" +#include "ED_clip.h" +#include "ED_transform.h" + +#include "RNA_access.h" + +#include "mask_intern.h" // own include + +/********************** generic poll functions *********************/ + +int ED_maskediting_poll(bContext *C) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + return ED_space_clip_maskediting_poll(C); + } + + return FALSE; +} + +int ED_maskediting_mask_poll(bContext *C) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + return ED_space_clip_maskediting_mask_poll(C); + } + + return FALSE; +} + +/********************** registration *********************/ + +void ED_mask_mouse_pos(bContext *C, wmEvent *event, float co[2]) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + ED_clip_mouse_pos(C, event, co); + } + else { + /* possible other spaces from which mask editing is available */ + zero_v2(co); + } +} + +void ED_mask_size(bContext *C, int *width, int *height) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + ED_space_clip_mask_size(sc, width, height); + } + else { + /* possible other spaces from which mask editing is available */ + *width = 0; + *height = 0; + } +} + +void ED_mask_aspect(bContext *C, float *aspx, float *aspy) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + ED_space_clip_mask_aspect(sc, aspx, aspy); + } + else { + /* possible other spaces from which mask editing is available */ + *aspx = 1.0f; + *aspy = 1.0f; + } +} + +void ED_mask_pixelspace_factor(bContext *C, float *scalex, float *scaley) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + ARegion *ar = CTX_wm_region(C); + int width, height; + float zoomx, zoomy, aspx, aspy; + + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + ED_space_clip_aspect(sc, &aspx, &aspy); + + *scalex = ((float)width * aspx) * zoomx; + *scaley = ((float)height * aspy) * zoomy; + } + else { + /* possible other spaces from which mask editing is available */ + *scalex = 1.0f; + *scaley = 1.0f; + } +} + +/********************** registration *********************/ + +void ED_operatortypes_mask(void) +{ + WM_operatortype_append(MASK_OT_new); + + /* shapes */ + WM_operatortype_append(MASK_OT_shape_new); + WM_operatortype_append(MASK_OT_shape_remove); + + /* geometry */ + WM_operatortype_append(MASK_OT_add_vertex); + WM_operatortype_append(MASK_OT_add_feather_vertex); + WM_operatortype_append(MASK_OT_delete); + + /* select */ + WM_operatortype_append(MASK_OT_select); + WM_operatortype_append(MASK_OT_select_all); + + /* shape */ + WM_operatortype_append(MASK_OT_slide_point); + WM_operatortype_append(MASK_OT_cyclic_toggle); + WM_operatortype_append(MASK_OT_handle_type_set); +} + +void ED_keymap_mask(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap; + wmKeyMapItem *kmi; + + keymap = WM_keymap_find(keyconf, "Mask Editor", 0, 0); + keymap->poll = ED_maskediting_poll; + + WM_keymap_add_item(keymap, "MASK_OT_new", NKEY, KM_PRESS, KM_ALT, 0); + + /* geometry */ + WM_keymap_add_item(keymap, "MASK_OT_add_vertex_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "MASK_OT_add_feather_vertex_slide", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "MASK_OT_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_delete", DELKEY, KM_PRESS, 0, 0); + + /* select */ + WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + + /* shape */ + WM_keymap_add_item(keymap, "MASK_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "MASK_OT_slide_point", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_handle_type_set", VKEY, KM_PRESS, 0, 0); + + transform_keymap_for_space(keyconf, keymap, SPACE_CLIP); +} + +void ED_operatormacros_mask(void) +{ + /* XXX: just for sample */ + wmOperatorType *ot; + wmOperatorTypeMacro *otmacro; + + ot= WM_operatortype_append_macro("MASK_OT_add_vertex_slide", "Add Vertex and Slide", OPTYPE_UNDO|OPTYPE_REGISTER); + ot->description = "Add new vertex and slide it"; + WM_operatortype_macro_define(ot, "MASK_OT_add_vertex"); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE); + + ot= WM_operatortype_append_macro("MASK_OT_add_feather_vertex_slide", "Add Feather Vertex and Slide", OPTYPE_UNDO|OPTYPE_REGISTER); + ot->description = "Add new feather vertex and slide it"; + WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex"); + otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point"); + RNA_boolean_set(otmacro->ptr, "slide_feather", TRUE); +} diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h new file mode 100644 index 00000000000..073eba3efc9 --- /dev/null +++ b/source/blender/editors/mask/mask_intern.h @@ -0,0 +1,69 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_intern.h + * \ingroup spclip + */ + +#ifndef __MASK_INTERN_H__ +#define __MASK_INTERN_H__ + +struct bContext; +struct wmEvent; +struct wmOperatorType; + +/* internal exports only */ + +/* mask_ops.c */ +void MASK_OT_new(struct wmOperatorType *ot); +void MASK_OT_shape_new(struct wmOperatorType *ot); +void MASK_OT_shape_remove(struct wmOperatorType *ot); + +void MASK_OT_add_vertex(struct wmOperatorType *ot); +void MASK_OT_add_feather_vertex(struct wmOperatorType *ot); +void MASK_OT_cyclic_toggle(struct wmOperatorType *ot); + +void MASK_OT_select(struct wmOperatorType *ot); +void MASK_OT_select_all(struct wmOperatorType *ot); + +void MASK_OT_slide_point(struct wmOperatorType *ot); + +void MASK_OT_delete(struct wmOperatorType *ot); + +void MASK_OT_handle_type_set(struct wmOperatorType *ot); + +/* mask_editor.c */ +int ED_maskediting_poll(struct bContext *C); +int ED_maskediting_mask_poll(struct bContext *C); + +void ED_mask_size(struct bContext *C, int *width, int *height); +void ED_mask_aspect(struct bContext *C, float *aspx, float *aspy); + +void ED_mask_pixelspace_factor(struct bContext *C, float *scalex, float *scaley); +void ED_mask_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]); + +#endif /* __MASK_INTERN_H__ */ diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c new file mode 100644 index 00000000000..0fedc2b34dc --- /dev/null +++ b/source/blender/editors/mask/mask_ops.c @@ -0,0 +1,1653 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_ops.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" +#include "ED_clip.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "mask_intern.h" // own include + +/******************** utility functions *********************/ + +static void spline_point_select(MaskSplinePoint *point, int action) +{ + int i; + + switch (action) { + case SEL_SELECT: + MASKPOINT_SEL(point); + break; + case SEL_DESELECT: + MASKPOINT_DESEL(point); + break; + case SEL_INVERT: + MASKPOINT_INVSEL(point); + break; + } + + for (i = 0; i < point->tot_uw; i++) { + switch (action) { + case SEL_SELECT: + point->uw[i].flag |= SELECT; + break; + case SEL_DESELECT: + point->uw[i].flag &= ~SELECT; + break; + case SEL_INVERT: + point->uw[i].flag ^= SELECT; + break; + } + } +} + +static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, float aspx, float aspy, float start_u, float co[2]) +{ + const int N = 1000; + float u = -1.0f, du = 1.0f / N, u1 = start_u, u2 = start_u; + float ang = -1.0f; + + while (u1 > 0.0f || u2 < 1.0d) { + float n1[2], n2[2], co1[2], co2[2]; + float v1[2], v2[2]; + float ang1, ang2; + + if (u1 >= 0.0f) { + BKE_mask_point_segment_co(spline, point, u1, co1); + BKE_mask_point_normal(spline, point, aspx, aspy, u1, n1); + sub_v2_v2v2(v1, co, co1); + + if (len_v2(v1) > 1e-3) { + ang1 = angle_v2v2(v1, n1); + if (ang1 > M_PI / 2.0f) + ang1 = M_PI - ang1; + + if (ang < 0.0f || ang1 < ang) { + ang = ang1; + u = u1; + } + } + else { + u = u1; + break; + } + } + + if (u2 <= 1.0f) { + BKE_mask_point_segment_co(spline, point, u2, co2); + BKE_mask_point_normal(spline, point, aspx, aspy, u2, n2); + sub_v2_v2v2(v2, co, co2); + + if (len_v2(v2) > 1e-3) { + ang2 = angle_v2v2(v2, n2); + if (ang2 > M_PI / 2.0f) + ang2 = M_PI - ang2; + + if (ang2 < ang) { + ang = ang2; + u = u2; + } + } + else { + u = u2; + break; + } + } + + u1 -= du; + u2 += du; + } + + return u; +} + +static int points_has_selection(MaskSplinePoint *points, int tot_point) +{ + int i; + + for (i = 0; i < tot_point; i++) { + MaskSplinePoint *point = &points[i]; + + if (MASKPOINT_ISSEL(point)) + return TRUE; + } + + return FALSE; +} + +static int mask_has_selection(Mask *mask) +{ + MaskShape *shape = mask->shapes.first; + + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + if (points_has_selection(spline->points, spline->tot_point)) + return TRUE; + + spline = spline->next; + } + + shape = shape->next; + } + + return FALSE; +} + +static void toggle_selection_all(Mask *mask, int action) +{ + MaskShape *shape = mask->shapes.first; + + if (action == SEL_TOGGLE) { + if (mask_has_selection(mask)) + action = SEL_DESELECT; + else + action = SEL_SELECT; + } + + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + spline_point_select(point, action); + } + + spline = spline->next; + } + + shape = shape->next; + } +} + +static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal_co[2], int threshold, + MaskShape **shape_r, MaskSpline **spline_r, int *is_handle_r, + float *score) +{ + MaskShape *shape; + MaskShape *point_shape = NULL; + MaskSpline *point_spline = NULL; + MaskSplinePoint *point = NULL; + float co[2], aspx, aspy; + float len = FLT_MAX, scalex, scaley; + int is_handle = FALSE, width, height; + + ED_mask_size(C, &width, &height); + ED_mask_aspect(C, &aspx, &aspy); + ED_mask_pixelspace_factor(C, &scalex, &scaley); + + co[0] = normal_co[0] * scalex; + co[1] = normal_co[1] * scaley; + + shape = mask->shapes.first; + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *cur_point = &spline->points[i]; + float cur_len, vec[2], handle[2]; + + vec[0] = cur_point->bezt.vec[1][0] * scalex; + vec[1] = cur_point->bezt.vec[1][1] * scaley; + + if (BKE_mask_point_has_handle(cur_point)) { + BKE_mask_point_handle(cur_point, aspx, aspy, handle); + handle[0] *= scalex; + handle[1] *= scaley; + + cur_len = len_v2v2(co, handle); + + if (cur_len < len) { + point_shape = shape; + point_spline = spline; + point = cur_point; + len = cur_len; + is_handle = TRUE; + } + } + + cur_len = len_v2v2(co, vec); + + if (cur_len < len) { + point_spline = spline; + point_shape = shape; + point = cur_point; + len = cur_len; + is_handle = FALSE; + } + } + + spline = spline->next; + } + + shape = shape->next; + } + + if (len < threshold) { + if (shape_r) + *shape_r = point_shape; + + if (spline_r) + *spline_r = point_spline; + + if (is_handle_r) + *is_handle_r = is_handle; + + if (score) + *score = len; + + return point; + } + + if (shape_r) + *shape_r = NULL; + + if (spline_r) + *spline_r = NULL; + + if (is_handle_r) + *is_handle_r = FALSE; + + return NULL; +} + +static int find_nearest_feather(bContext *C, Mask *mask, float normal_co[2], int threshold, + MaskShape **shape_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + MaskSplinePointUW **uw_r, float *score) +{ + MaskShape *shape, *point_shape = NULL; + MaskSpline *point_spline = NULL; + MaskSplinePoint *point = NULL; + MaskSplinePointUW *uw = NULL; + float len = FLT_MAX, co[2]; + float scalex, scaley, aspx, aspy; + int width, height; + + ED_mask_size(C, &width, &height); + ED_mask_aspect(C, &aspx, &aspy); + ED_mask_pixelspace_factor(C, &scalex, &scaley); + + co[0] = normal_co[0] * scalex; + co[1] = normal_co[1] * scaley; + + shape = mask->shapes.first; + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + int i, tot_feather_point; + float *feather_points, *fp; + + feather_points = fp = BKE_mask_spline_feather_points(spline, aspx, aspy, &tot_feather_point); + + for (i = 0; i < spline->tot_point; i++) { + int j; + MaskSplinePoint *cur_point = &spline->points[i]; + + for (j = 0; j < cur_point->tot_uw + 1; j++) { + float cur_len, vec[2]; + + vec[0] = fp[0] * scalex; + vec[1] = fp[1] * scaley; + + cur_len = len_v2v2(vec, co); + + if (point == NULL || cur_len < len) { + if (j == 0) + uw = NULL; + else + uw = &cur_point->uw[j - 1]; + + point_shape = shape; + point_spline = spline; + point = cur_point; + len = cur_len; + } + + fp += 2; + } + } + + MEM_freeN(feather_points); + + spline = spline->next; + } + + shape = shape->next; + } + + if (len < threshold) { + if (shape_r) + *shape_r = point_shape; + + if (spline_r) + *spline_r = point_spline; + + if (point_r) + *point_r = point; + + if (uw_r) + *uw_r = uw; + + if (score) + *score = len; + + return TRUE; + } + + if (shape_r) + *shape_r = NULL; + + if (spline_r) + *spline_r = NULL; + + if (point_r) + *point_r = NULL; + + return FALSE; +} + +static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], int threshold, int feather, + MaskShape **shape_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + float *u_r, float tangent[2]) +{ + MaskShape *shape, *point_shape; + MaskSpline *point_spline; + MaskSplinePoint *point = NULL; + float dist, co[2]; + int width, height; + float u; + float scalex, scaley, aspx, aspy; + + ED_mask_size(C, &width, &height); + ED_mask_aspect(C, &aspx, &aspy); + ED_mask_pixelspace_factor(C, &scalex, &scaley); + + co[0] = normal_co[0] * scalex; + co[1] = normal_co[1] * scaley; + + shape = mask->shapes.first; + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *cur_point = &spline->points[i]; + float *diff_points; + int tot_diff_point; + + diff_points = BKE_mask_point_segment_diff(spline, cur_point, &tot_diff_point); + + if (diff_points) { + int i, tot_feather_point, tot_point; + float *feather_points = NULL, *points; + + if (feather) { + feather_points = BKE_mask_point_segment_feather_diff(spline, cur_point, + aspx, aspy, &tot_feather_point); + + points = feather_points; + tot_point = tot_feather_point; + } + else { + points = diff_points; + tot_point = tot_diff_point; + } + + for (i = 0; i < tot_point - 1; i++) { + float cur_dist, a[2], b[2]; + + a[0] = points[2 * i] * scalex; + a[1] = points[2 * i + 1] * scaley; + + b[0] = points[2 * i + 2] * scalex; + b[1] = points[2 * i + 3] * scaley; + + cur_dist = dist_to_line_segment_v2(co, a, b); + + if (point == NULL || cur_dist < dist) { + if (tangent) + sub_v2_v2v2(tangent, &diff_points[2 * i + 2], &diff_points[2 * i]); + + point_shape = shape; + point_spline = spline; + point = cur_point; + dist = cur_dist; + u = (float)i / tot_point; + + } + } + + if (feather_points) + MEM_freeN(feather_points); + } + + MEM_freeN(diff_points); + } + + spline = spline->next; + } + + shape = shape->next; + } + + if (point && dist < threshold) { + if (shape_r) + *shape_r = point_shape; + + if (spline_r) + *spline_r = point_spline; + + if (point_r) + *point_r = point; + + if (u_r) { + u = projection_on_spline(point_spline, point, aspx, aspy, u, normal_co); + + *u_r = u; + } + + return TRUE; + } + + if (shape_r) + *shape_r = NULL; + + if (spline_r) + *spline_r = NULL; + + if (point_r) + *point_r = NULL; + + return FALSE; +} + +static void mask_flush_selection(Mask *mask) +{ + MaskShape *shape; + + shape = mask->shapes.first; + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + int i; + + spline->flag &= ~SELECT; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *cur_point = &spline->points[i]; + + if (MASKPOINT_ISSEL(cur_point)) { + spline->flag |= SELECT; + } + else { + int j; + + for (j = 0; j < cur_point->tot_uw; j++) { + if (cur_point->uw[j].flag & SELECT) { + spline->flag |= SELECT; + break; + } + } + } + } + + spline = spline->next; + } + + shape = shape->next; + } +} + +/******************** create new mask *********************/ + +static int mask_new_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + Mask *mask; + char name[MAX_ID_NAME-2]; + + RNA_string_get(op->ptr, "name", name); + + mask = BKE_mask_new(name); + + if (sc) + ED_space_clip_set_mask(C, sc, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_new(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "New Mask"; + ot->description = "Create new mask"; + ot->idname = "MASK_OT_new"; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec = mask_new_exec; + ot->poll = ED_operator_mask; + + /* properties */ + RNA_def_string(ot->srna, "name", "", MAX_ID_NAME-2, "Name", "Name of new mask"); +} + +/******************** create new shape *********************/ + +static int shape_new_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + char name[MAX_ID_NAME-2]; + + RNA_string_get(op->ptr, "name", name); + + BKE_mask_shape_new(mask, name); + mask->shapenr = mask->tot_shape - 1; + + WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_shape_new(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Shape"; + ot->description = "Add new shape for masking"; + ot->idname = "MASK_OT_shape_new"; + + /* api callbacks */ + ot->exec = shape_new_exec; + ot->poll = ED_maskediting_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_string(ot->srna, "name", "", MAX_ID_NAME-2, "Name", "Name of new shape"); +} + +/******************** remove shape *********************/ + +static int shape_remove_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskShape *shape = BKE_mask_shape_active(mask); + + if (shape) { + BKE_mask_shape_remove(mask, shape); + + WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + } + + return OPERATOR_FINISHED; +} + +void MASK_OT_shape_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Shape"; + ot->description = "Remove shape used for masking"; + ot->idname = "MASK_OT_shape_remove"; + + /* api callbacks */ + ot->exec = shape_remove_exec; + ot->poll = ED_maskediting_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/******************** slide *********************/ + +#define SLIDE_ACTION_NONE 0 +#define SLIDE_ACTION_POINT 1 +#define SLIDE_ACTION_HANDLE 2 +#define SLIDE_ACTION_FEATHER 3 + +typedef struct SlidePointData { + int action; + + float co[2]; + float vec[3][3]; + + Mask *mask; + MaskShape *shape; + MaskSpline *spline; + MaskSplinePoint *point; + MaskSplinePointUW *uw; + float handle[2], no[2], feather[2]; + float aspx, aspy; + int width, height; + float weight; + + short curvature_only, accurate; +} SlidePointData; + +static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) +{ + Mask *mask = CTX_data_edit_mask(C); + SlidePointData *customdata = NULL; + MaskShape *shape, *cv_shape, *feather_shape; + MaskSpline *spline, *cv_spline, *feather_spline; + MaskSplinePoint *point, *cv_point, *feather_point; + MaskSplinePointUW *uw = NULL; + int is_handle = FALSE, width, height, action = SLIDE_ACTION_NONE; + int slide_feather = RNA_boolean_get(op->ptr, "slide_feather"); + float co[2], cv_score, feather_score; + const float threshold = 19; + + ED_mask_mouse_pos(C, event, co); + ED_mask_size(C, &width, &height); + + cv_point = find_nearest_point(C, mask, co, threshold, &cv_shape, &cv_spline, &is_handle, &cv_score); + + if (find_nearest_feather(C, mask, co, threshold, &feather_shape, &feather_spline, &feather_point, &uw, &feather_score)) { + if (slide_feather || !cv_point || feather_score < cv_score) { + action = SLIDE_ACTION_FEATHER; + + shape = feather_shape; + spline = feather_spline; + point = feather_point; + } + } + + if (cv_point && action == SLIDE_ACTION_NONE) { + if (is_handle) + action = SLIDE_ACTION_HANDLE; + else + action = SLIDE_ACTION_POINT; + + shape = cv_shape; + spline = cv_spline; + point = cv_point; + } + + if (action != SLIDE_ACTION_NONE) { + customdata = MEM_callocN(sizeof(SlidePointData), "mask slide point data"); + + customdata->mask = mask; + customdata->shape = shape; + customdata->spline = spline; + customdata->point = point; + customdata->width = width; + customdata->height = height; + customdata->action = action; + customdata->uw = uw; + + ED_mask_aspect(C, &customdata->aspx, &customdata->aspy); + + if (uw) { + float co[2]; + + customdata->weight = point->bezt.weight; + + customdata->weight = uw->w; + BKE_mask_point_segment_co(spline, point, uw->u, co); + BKE_mask_point_normal(spline, point, customdata->aspx, customdata->aspy, uw->u, customdata->no); + + customdata->feather[0] = co[0] + customdata->no[0] * uw->w; + customdata->feather[1] = co[1] + customdata->no[1] * uw->w; + } + else { + BezTriple *bezt = &point->bezt; + BKE_mask_point_normal(spline, point, customdata->aspx, customdata->aspy, 0.0f, customdata->no); + + customdata->feather[0] = bezt->vec[1][0] + customdata->no[0] * bezt->weight; + customdata->feather[1] = bezt->vec[1][1] + customdata->no[1] * bezt->weight; + } + + copy_m3_m3(customdata->vec, point->bezt.vec); + if (BKE_mask_point_has_handle(point)) + BKE_mask_point_handle(point, customdata->aspx, customdata->aspy, customdata->handle); + ED_mask_mouse_pos(C, event, customdata->co); + } + + return customdata; +} + +static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + SlidePointData *slidedata = slide_point_customdata(C, op, event); + + if (slidedata) { + Mask *mask = CTX_data_edit_mask(C); + + op->customdata = slidedata; + + WM_event_add_modal_handler(C, op); + + if (slidedata->uw) { + if ((slidedata->uw->flag & SELECT) == 0) { + toggle_selection_all(mask, SEL_DESELECT); + + slidedata->uw->flag |= SELECT; + + mask_flush_selection(mask); + } + } + else if (!MASKPOINT_ISSEL(slidedata->point)) { + toggle_selection_all(mask, SEL_DESELECT); + + spline_point_select(slidedata->point, SEL_SELECT); + + mask_flush_selection(mask); + } + + slidedata->shape->act_spline = slidedata->spline; + slidedata->shape->act_point = slidedata->point; + + WM_event_add_notifier(C, NC_MASK|ND_SELECT, mask); + + return OPERATOR_RUNNING_MODAL; + } + + return OPERATOR_PASS_THROUGH; +} + +static void cancel_slide_point(SlidePointData *data) +{ + /* cancel sliding */ + if (data->action == SLIDE_ACTION_FEATHER) { + if (data->uw) + data->uw->w = data->weight; + else + data->point->bezt.weight = data->weight; + } + else { + copy_m3_m3(data->point->bezt.vec, data->vec); + } +} + +static void free_slide_point_data(SlidePointData *data) +{ + MEM_freeN(data); +} + +static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + SlidePointData *data = (SlidePointData *)op->customdata; + BezTriple *bezt = &data->point->bezt; + float co[2], dco[2]; + + switch(event->type) { + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) + data->curvature_only = event->val==KM_PRESS; + + if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) + data->accurate = event->val==KM_PRESS; + + /* no break! update CV position */ + + case MOUSEMOVE: + ED_mask_mouse_pos(C, event, co); + sub_v2_v2v2(dco, co, data->co); + + if (data->action == SLIDE_ACTION_HANDLE) { + float delta[2], offco[2]; + + sub_v2_v2v2(delta, data->handle, data->co); + + sub_v2_v2v2(offco, co, data->co); + if (data->accurate) + mul_v2_fl(offco, 0.2f); + add_v2_v2(offco, data->co); + add_v2_v2(offco, delta); + + BKE_mask_point_set_handle(data->point, offco, data->curvature_only, data->aspx, data->aspy, data->handle, data->vec); + } + else if (data->action == SLIDE_ACTION_POINT) { + float delta[2]; + + copy_v2_v2(delta, dco); + if (data->accurate) + mul_v2_fl(delta, 0.2f); + + add_v2_v2v2(bezt->vec[0], data->vec[0], delta); + add_v2_v2v2(bezt->vec[1], data->vec[1], delta); + add_v2_v2v2(bezt->vec[2], data->vec[2], delta); + } + else if (data->action == SLIDE_ACTION_FEATHER) { + float vec[2], no[2], p[2], c[2], w, offco[2]; + float *weight; + + add_v2_v2v2(offco, data->feather, dco); + + if (data->uw) { + float u = projection_on_spline(data->spline, data->point, data->aspx, data->aspy, data->uw->u, offco); + + if (u > 0.0f && u < 1.0f) + data->uw->u = u; + + data->uw = BKE_mask_point_sort_uw(data->point, data->uw); + weight = &data->uw->w; + BKE_mask_point_normal(data->spline, data->point, data->aspx, data->aspy, data->uw->u, no); + BKE_mask_point_segment_co(data->spline, data->point, data->uw->u, p); + } + else { + weight = &bezt->weight; + copy_v2_v2(no, data->no); + copy_v2_v2(p, bezt->vec[1]); + } + + sub_v2_v2v2(c, offco, p); + project_v2_v2v2(vec, c, no); + + vec[0] *= data->aspx; + vec[1] *= data->aspy; + + w = len_v2(vec); + + if (dot_v2v2(no, vec) > 0.0f) + *weight = w; + else + *weight = 0; + } + + WM_event_add_notifier(C, NC_MASK|NA_EDITED, data->mask); + DAG_id_tag_update(&data->mask->id, 0); + + break; + + case LEFTMOUSE: + if(event->val==KM_RELEASE) { + free_slide_point_data(op->customdata); + + WM_event_add_notifier(C, NC_MASK|NA_EDITED, data->mask); + DAG_id_tag_update(&data->mask->id, 0); + + return OPERATOR_FINISHED; + } + + break; + + case ESCKEY: + cancel_slide_point(op->customdata); + + free_slide_point_data(op->customdata); + + WM_event_add_notifier(C, NC_MASK|NA_EDITED, data->mask); + DAG_id_tag_update(&data->mask->id, 0); + + return OPERATOR_CANCELLED; + } + + return OPERATOR_RUNNING_MODAL; +} + +void MASK_OT_slide_point(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Slide Point"; + ot->description = "Slide control points"; + ot->idname = "MASK_OT_slide_point"; + + /* api callbacks */ + ot->invoke = slide_point_invoke; + ot->modal = slide_point_modal; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "slide_feather", 0, "Slide Feather", "First try to slide slide feather instead of vertex"); +} + +/******************** toggle selection *********************/ + +static int select_all_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + int action = RNA_enum_get(op->ptr, "action"); + + toggle_selection_all(mask, action); + mask_flush_selection(mask); + + WM_event_add_notifier(C, NC_MASK|ND_SELECT, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_select_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select or Deselect All"; + ot->description = "Change selection of all curve points"; + ot->idname = "MASK_OT_select_all"; + + /* api callbacks */ + ot->exec = select_all_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_select_all(ot); +} + +/******************** select *********************/ + +static int select_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskShape *shape; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + float co[2]; + int extend = RNA_boolean_get(op->ptr, "extend"); + int is_handle = 0; + const float threshold = 19; + + RNA_float_get_array(op->ptr, "location", co); + + point = find_nearest_point(C, mask, co, threshold, &shape, &spline, &is_handle, NULL); + + if (point) { + if (!extend) + toggle_selection_all(mask, SEL_DESELECT); + + if (is_handle) { + MASKPOINT_HANDLE_SEL(point); + } + else { + spline_point_select(point, SEL_SELECT); + } + + shape->act_spline = spline; + shape->act_point = point; + + mask_flush_selection(mask); + + WM_event_add_notifier(C, NC_MASK|ND_SELECT, mask); + } + else { + MaskSplinePointUW *uw; + + if (find_nearest_feather(C, mask, co, threshold, &shape, &spline, &point, &uw, NULL)) { + if (!extend) + toggle_selection_all(mask, SEL_DESELECT); + + uw->flag |= SELECT; + + shape->act_spline = spline; + shape->act_point = point; + + mask_flush_selection(mask); + + WM_event_add_notifier(C, NC_MASK|ND_SELECT, mask); + } + } + + return OPERATOR_PASS_THROUGH; +} + +static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return select_exec(C, op); +} + +void MASK_OT_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select"; + ot->description = "Select spline points"; + ot->idname = "MASK_OT_select"; + + /* api callbacks */ + ot->exec = select_exec; + ot->invoke = select_invoke; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "extend", 0, + "Extend", "Extend selection rather than clearing the existing selection"); + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} + +/******************** add vertex *********************/ + +static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point, + float point_co[2], float tangent[2]) +{ + BezTriple *bezt; + int width, height; + float co[3]; + const float len = 20.0; /* default length of handle in pixel space */ + + copy_v2_v2(co, point_co); + co[2] = 0.0f; + + ED_mask_size(C, &width, &height); + + /* point coordinate */ + bezt = &new_point->bezt; + + bezt->h1 = bezt->h2 = HD_ALIGN; + + copy_v3_v3(bezt->vec[0], co); + copy_v3_v3(bezt->vec[1], co); + copy_v3_v3(bezt->vec[2], co); + + /* initial offset for handles */ + if (spline->tot_point == 1) { + /* first point of splien is aligned horizontally */ + bezt->vec[0][0] -= len / width; + bezt->vec[2][0] += len / width; + } + else if (tangent) { + float vec[2]; + + copy_v2_v2(vec, tangent); + + vec[0] *= width; + vec[1] *= height; + + mul_v2_fl(vec, len / len_v2(vec)); + + vec[0] /= width; + vec[1] /= height; + + sub_v2_v2(bezt->vec[0], vec); + add_v2_v2(bezt->vec[2], vec); + } else { + /* next points are aligning in the direction of previous/next point */ + MaskSplinePoint *point; + float v1[2], v2[2], vec[2]; + float dir = 1.0f; + + if (new_point == spline->points) { + point = new_point + 1; + dir = -1.0f; + } else + point = new_point - 1; + + if (spline->tot_point < 3) { + v1[0] = point->bezt.vec[1][0] * width; + v1[1] = point->bezt.vec[1][1] * height; + + v2[0] = new_point->bezt.vec[1][0] * width; + v2[1] = new_point->bezt.vec[1][1] * height; + } + else { + if (new_point == spline->points) { + v1[0] = spline->points[1].bezt.vec[1][0] * width; + v1[1] = spline->points[1].bezt.vec[1][1] * height; + + v2[0] = spline->points[spline->tot_point - 1].bezt.vec[1][0] * width; + v2[1] = spline->points[spline->tot_point - 1].bezt.vec[1][1] * height; + } + else { + v1[0] = spline->points[0].bezt.vec[1][0] * width; + v1[1] = spline->points[0].bezt.vec[1][1] * height; + + v2[0] = spline->points[spline->tot_point - 2].bezt.vec[1][0] * width; + v2[1] = spline->points[spline->tot_point - 2].bezt.vec[1][1] * height; + } + } + + sub_v2_v2v2(vec, v1, v2); + mul_v2_fl(vec, len * dir / len_v2(vec)); + + vec[0] /= width; + vec[1] /= height; + + add_v2_v2(bezt->vec[0], vec); + sub_v2_v2(bezt->vec[2], vec); + } + + BKE_mask_parent_init(&new_point->parent); + + /* select new point */ + MASKPOINT_SEL(new_point); + mask_flush_selection(mask); +} + +/* **** add subdivide vertex **** */ + +static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) +{ + MaskShape *shape; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + const float threshold = 9; + float tangent[2]; + + if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &shape, &spline, &point, NULL, tangent)) { + MaskSplinePoint *new_point_array, *new_point; + int point_index = point - spline->points; + + toggle_selection_all(mask, SEL_DESELECT); + + new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); + + memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1)); + memcpy(new_point_array + point_index + 2, spline->points + point_index + 1, + sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1)); + + MEM_freeN(spline->points); + spline->points = new_point_array; + spline->tot_point++; + + new_point = &new_point_array[point_index + 1]; + + setup_vertex_point(C, mask, spline, new_point, co, tangent); + + shape->act_point = new_point; + + WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + + return TRUE; + } + + return FALSE; +} + +/* **** add extrude vertex **** */ + +static void finSelectedSplinePoint(MaskShape *shape, MaskSpline **spline, MaskSplinePoint **point) +{ + MaskSpline *cur_spline = shape->splines.first; + + *spline = NULL; + *point = NULL; + + while (cur_spline) { + int i; + + for (i = 0; i < cur_spline->tot_point; i++) { + MaskSplinePoint *cur_point = &cur_spline->points[i]; + + if (MASKPOINT_ISSEL(cur_point)) { + if (*spline != NULL && *spline != cur_spline) { + *spline = NULL; + *point = NULL; + return; + } + else if (*point) { + *point = NULL; + } + else { + *spline = cur_spline; + *point = cur_point; + } + } + } + + cur_spline = cur_spline->next; + } +} + +static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) +{ + MaskShape *shape; + MaskSpline *spline; + MaskSplinePoint *point, *new_point = NULL; + + shape = BKE_mask_shape_active(mask); + + if (!shape) { + /* if there's no shape currently operationg on, create new one */ + shape = BKE_mask_shape_new(mask, ""); + mask->shapenr = mask->tot_shape - 1; + spline = NULL; + point = NULL; + } + else { + finSelectedSplinePoint(shape, &spline, &point); + } + + if (!spline) { + /* no selected splines in actuve shape, create new spline */ + spline = BKE_mask_spline_add(shape); + shape->act_spline = spline; + new_point = spline->points; + } + + if (!new_point) { + MaskSplinePoint *new_point_array; + + if (point == &spline->points[spline->tot_point - 1]) { + MASKPOINT_DESEL(point); + new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); + memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * spline->tot_point); + MEM_freeN(spline->points); + spline->points = new_point_array; + spline->tot_point++; + + new_point = &spline->points[spline->tot_point - 1]; + } + else if (point == &spline->points[0]) { + MASKPOINT_DESEL(point); + new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); + memcpy(new_point_array + 1, spline->points, sizeof(MaskSplinePoint) * spline->tot_point); + MEM_freeN(spline->points); + spline->points = new_point_array; + spline->tot_point++; + + new_point = &spline->points[0]; + } + else { + spline = BKE_mask_spline_add(shape); + shape->act_spline = spline; + new_point = spline->points; + } + } + + shape->act_point = new_point; + + setup_vertex_point(C, mask, spline, new_point, co, NULL); + WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + + return TRUE; +} + +static int add_vertex_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + float co[2]; + + RNA_float_get_array(op->ptr, "location", co); + + if (!add_vertex_subdivide(C, mask, co)) { + if (!add_vertex_extrude(C, mask, co)) + return OPERATOR_CANCELLED; + } + + return OPERATOR_FINISHED; +} + +static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return add_vertex_exec(C, op); +} + +void MASK_OT_add_vertex(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Vertex"; + ot->description = "Add vertex to active spline"; + ot->idname = "MASK_OT_add_vertex"; + + /* api callbacks */ + ot->exec = add_vertex_exec; + ot->invoke = add_vertex_invoke; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} + +/******************** add feather vertex *********************/ + +static int add_feather_vertex_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskShape *shape; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + const float threshold = 9; + float co[2], u; + + RNA_float_get_array(op->ptr, "location", co); + + point = find_nearest_point(C, mask, co, threshold, NULL, NULL, NULL, NULL); + if (point) + return OPERATOR_FINISHED; + + if (find_nearest_diff_point(C, mask, co, threshold, TRUE, &shape, &spline, &point, &u, NULL)) { + float w = BKE_mask_point_weight(spline, point, u); + + BKE_mask_point_add_uw(point, u, w); + + WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +static int add_feather_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return add_feather_vertex_exec(C, op); +} + +void MASK_OT_add_feather_vertex(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add feather Vertex"; + ot->description = "Add vertex to feather"; + ot->idname = "MASK_OT_add_feather_vertex"; + + /* api callbacks */ + ot->exec = add_feather_vertex_exec; + ot->invoke = add_feather_vertex_invoke; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} + +/******************** toggle cyclic *********************/ + +static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskShape *shape = mask->shapes.first; + + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + if (points_has_selection(spline->points, spline->tot_point)) + spline->flag ^= MASK_SPLINE_CYCLIC; + + spline = spline->next; + } + + shape = shape->next; + } + + WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_cyclic_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Toggle Cyclic"; + ot->description = "Toggle cyclic for selected splines"; + ot->idname = "MASK_OT_cyclic_toggle"; + + /* api callbacks */ + ot->exec = cyclic_toggle_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/******************** delete *********************/ + +static void delete_feather_points(MaskSplinePoint *point) +{ + int i, count = 0; + + if (!point->tot_uw) + return; + + for (i = 0; i < point->tot_uw; i++) { + if ((point->uw[i].flag & SELECT) == 0) + count++; + } + + if (count == 0) { + MEM_freeN(point->uw); + point->uw = NULL; + point->tot_uw = 0; + } + else { + MaskSplinePointUW *new_uw; + int j = 0; + + new_uw = MEM_callocN(count * sizeof(MaskSplinePointUW), "new mask uw points"); + + for (i = 0; i < point->tot_uw; i++) { + if ((point->uw[i].flag & SELECT) == 0) { + new_uw[j++] = point->uw[i]; + } + } + + MEM_freeN(point->uw); + + point->uw = new_uw; + point->tot_uw = count; + } +} + +static int delete_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskShape *shape = mask->shapes.first; + + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + int i, count = 0; + MaskSpline *next_spline = spline->next; + + /* count unselected points */ + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (!MASKPOINT_ISSEL(point)) + count++; + } + + if (count == 0) { + /* delete the whole spline */ + BLI_remlink(&shape->splines, spline); + BKE_mask_spline_free(spline); + + if (spline == shape->act_spline) { + shape->act_spline = NULL; + shape->act_point = NULL; + } + } + else { + MaskSplinePoint *new_points; + int j; + + new_points = MEM_callocN(count*sizeof(MaskSplinePoint), "deleteMaskPoints"); + + for (i = 0, j = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (!MASKPOINT_ISSEL(point)) { + if (point == shape->act_point) + shape->act_point = &new_points[j]; + + delete_feather_points(point); + + new_points[j] = *point; + j++; + } + else { + if (point == shape->act_point) + shape->act_point = NULL; + + BKE_mask_point_free(point); + } + } + + MEM_freeN(spline->points); + spline->points = new_points; + spline->tot_point = j; + + mask_flush_selection(mask); + } + + spline = next_spline; + } + + shape = shape->next; + } + + WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_delete(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Delete"; + ot->description = "Delete selected control points or splines"; + ot->idname = "MASK_OT_delete"; + + /* api callbacks */ + ot->invoke = WM_operator_confirm; + ot->exec = delete_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/******************** set handle type *********************/ + +static int set_handle_type_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskShape *shape = mask->shapes.first; + int handle_type = RNA_enum_get(op->ptr, "type"); + + while (shape) { + MaskSpline *spline = shape->splines.first; + int i; + + while (spline) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL(point)) { + BezTriple *bezt = &point->bezt; + + bezt->h1 = bezt->h2 = handle_type; + } + } + + spline = spline->next; + } + + shape = shape->next; + } + + WM_event_add_notifier(C, NC_MASK|ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; +} + +void MASK_OT_handle_type_set(wmOperatorType *ot) +{ + static EnumPropertyItem editcurve_handle_type_items[]= { + {HD_AUTO, "AUTO", 0, "Auto", ""}, + {HD_VECT, "VECTOR", 0, "Vector", ""}, + {HD_ALIGN, "ALIGNED", 0, "Aligned", ""}, + {0, NULL, 0, NULL, NULL}}; + + /* identifiers */ + ot->name = "Set Handle Type"; + ot->description = "Set type of handles for selected control points"; + ot->idname = "MASK_OT_handle_type_set"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = set_handle_type_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", editcurve_handle_type_items, 1, "Type", "Spline type"); +} diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 49672b77d43..e6fa4d43851 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -69,6 +69,7 @@ #include "ED_screen_types.h" #include "ED_keyframes_draw.h" #include "ED_view3d.h" +#include "ED_clip.h" #include "RNA_access.h" #include "RNA_define.h" @@ -449,6 +450,13 @@ int ED_operator_editmball(bContext *C) return 0; } +int ED_operator_mask(bContext *C) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + + return ED_space_clip_show_maskedit(sc); +} + /* *************************** action zone operator ************************** */ /* operator state vars used: diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 31243184961..6733d95ad71 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -62,6 +62,7 @@ #include "ED_mball.h" #include "ED_logic.h" #include "ED_clip.h" +#include "ED_mask.h" /* only call once on startup, storage is global in BKE kernel listbase */ void ED_spacetypes_init(void) @@ -111,6 +112,7 @@ void ED_spacetypes_init(void) ED_operatortypes_sound(); ED_operatortypes_render(); ED_operatortypes_logic(); + ED_operatortypes_mask(); UI_view2d_operatortypes(); UI_buttons_operatortypes(); @@ -133,6 +135,7 @@ void ED_spacetypes_init(void) ED_operatormacros_action(); ED_operatormacros_clip(); ED_operatormacros_curve(); + ED_operatormacros_mask(); /* register dropboxes (can use macros) */ spacetypes = BKE_spacetypes_list(); @@ -164,6 +167,7 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf) ED_keymap_physics(keyconf); ED_keymap_metaball(keyconf); ED_keymap_paint(keyconf); + ED_keymap_mask(keyconf); ED_marker_keymap(keyconf); UI_view2d_keymap(keyconf); diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index e61580295fc..2e7de318299 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -34,10 +34,12 @@ #include "MEM_guardedalloc.h" #include "BKE_main.h" +#include "BKE_mask.h" #include "BKE_movieclip.h" #include "BKE_context.h" #include "BKE_tracking.h" +#include "DNA_mask_types.h" #include "DNA_object_types.h" /* SELECT */ #include "BLI_utildefines.h" @@ -116,6 +118,32 @@ int ED_space_clip_tracking_frame_poll(bContext *C) return FALSE; } +int ED_space_clip_maskediting_poll(bContext *C) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc && sc->clip) { + return ED_space_clip_show_maskedit(sc); + } + + return FALSE; +} + +int ED_space_clip_maskediting_mask_poll(bContext *C) +{ + if (ED_space_clip_maskediting_poll(C)) { + MovieClip *clip = CTX_data_edit_movieclip(C); + + if (clip) { + SpaceClip *sc= CTX_wm_space_clip(C); + + return sc->mask != NULL; + } + } + + return FALSE; +} + /* ******** editing functions ******** */ void ED_space_clip_set(bContext *C, bScreen *screen, SpaceClip *sc, MovieClip *clip) @@ -159,6 +187,11 @@ MovieClip *ED_space_clip(SpaceClip *sc) return sc->clip; } +Mask *ED_space_clip_mask(SpaceClip *sc) +{ + return sc->mask; +} + ImBuf *ED_space_clip_get_buffer(SpaceClip *sc) { if (sc->clip) { @@ -203,6 +236,42 @@ void ED_space_clip_size(SpaceClip *sc, int *width, int *height) } } +void ED_space_clip_mask_size(SpaceClip *sc, int *width, int *height) +{ + if(!sc->mask) { + *width= 0; + *height= 0; + } else { + float aspx, aspy; + + ED_space_clip_size(sc, width, height); + ED_space_clip_aspect(sc, &aspx, &aspy); + + *width *= aspx; + *height *= aspy; + } +} + +void ED_space_clip_mask_aspect(SpaceClip *sc, float *aspx, float *aspy) +{ + int w, h; + + ED_space_clip_aspect(sc, aspx, aspy); + ED_space_clip_size(sc, &w, &h); + + *aspx *= (float)w; + *aspy *= (float)h; + + if(*aspx < *aspy) { + *aspy= *aspy / *aspx; + *aspx= 1.0f; + } + else { + *aspx= *aspx / *aspy; + *aspy= 1.0f; + } +} + void ED_space_clip_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy) { int width, height; @@ -557,6 +626,8 @@ void ED_space_clip_free_texture_buffer(SpaceClip *sc) } } +/* ******** masking editing related functions ******** */ + int ED_space_clip_show_trackedit(SpaceClip *sc) { if (sc) { @@ -573,3 +644,23 @@ void ED_space_clip_update_dopesheet(SpaceClip *sc) BKE_tracking_update_dopesheet(tracking); } + +int ED_space_clip_show_maskedit(SpaceClip *sc) +{ + if (sc) { + return sc->mode == SC_MODE_MASKEDITING; + } + + return FALSE; +} + +void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask) +{ + sc->mask = mask; + + if(sc->mask && sc->mask->id.us==0) + sc->clip->id.us = 1; + + if(C) + WM_event_add_notifier(C, NC_MASK|NA_SELECTED, mask); +} diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 80db32303cb..04b1c92cf8e 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -33,6 +33,7 @@ #include #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "DNA_movieclip_types.h" #include "MEM_guardedalloc.h" @@ -49,6 +50,7 @@ #include "IMB_imbuf_types.h" +#include "ED_mask.h" #include "ED_screen.h" #include "ED_clip.h" #include "ED_transform.h" @@ -357,6 +359,23 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) break; } break; + case NC_MASK: + switch(wmn->data) { + case ND_SELECT: + case ND_DATA: + ED_area_tag_redraw(sa); + break; + } + switch(wmn->action) { + case NA_SELECTED: + clip_scopes_tag_refresh(sa); + ED_area_tag_redraw(sa); + break; + case NA_EDITED: + ED_area_tag_redraw(sa); + break; + } + break; case NC_GEOM: switch (wmn->data) { case ND_SELECT: @@ -710,7 +729,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */ } -const char *clip_context_dir[]= {"edit_movieclip", NULL}; +const char *clip_context_dir[]= {"edit_movieclip", "edit_mask", NULL}; static int clip_context(const bContext *C, const char *member, bContextDataResult *result) { @@ -724,7 +743,11 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul else if (CTX_data_equals(member, "edit_movieclip")) { if (sc->clip) CTX_data_id_pointer_set(result, &sc->clip->id); - + return TRUE; + } + else if (CTX_data_equals(member, "edit_mask")) { + if (sc->mask) + CTX_data_id_pointer_set(result, &sc->mask->id); return TRUE; } @@ -996,6 +1019,9 @@ static void clip_main_area_init(wmWindowManager *wm, ARegion *ar) keymap = WM_keymap_find(wm->defaultconf, "Clip Editor", SPACE_CLIP, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + + keymap= WM_keymap_find(wm->defaultconf, "Mask Editor", 0, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } static void clip_main_area_draw(const bContext *C, ARegion *ar) @@ -1038,6 +1064,29 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) /* Grease Pencil */ clip_draw_grease_pencil((bContext *)C, 1); + if(sc->mode == SC_MODE_MASKEDITING) { + int x, y; + int width, height; + float zoomx, zoomy, aspx, aspy; + + /* find window pixel coordinates of origin */ + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); + + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + ED_space_clip_aspect(sc, &aspx, &aspy); + + /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ + glPushMatrix(); + glTranslatef(x, y, 0); + glScalef(width*zoomx, height*zoomy, 0); + glMultMatrixf(sc->stabmat); + + ED_mask_draw((bContext *)C, width*aspx, height*aspy, zoomx, zoomy); + + glPopMatrix(); + } + /* reset view matrix */ UI_view2d_view_restore(C); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index bd17c821567..883eb962c0c 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1942,6 +1942,11 @@ static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, Po uiItemR(layout, ptr, "distortion_type", 0, "", 0); } +static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL); +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -2108,6 +2113,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_MOVIEDISTORTION: ntype->uifunc= node_composit_buts_moviedistortion; break; + case CMP_NODE_MASK: + ntype->uifunc= node_composit_buts_mask; + break; default: ntype->uifunc= NULL; } diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 3540c20e515..119b350052e 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -250,6 +250,13 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn) break; } break; + case NC_MASK: + if (wmn->action == NA_EDITED) { + if (type==NTREE_COMPOSIT) { + ED_area_tag_refresh(sa); + } + } + break; case NC_IMAGE: if (wmn->action == NA_EDITED) { diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 6d72ca99678..5fe8444fe65 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -49,6 +49,7 @@ #include "DNA_constraint_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_mask_types.h" #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" /* PET modes */ @@ -169,6 +170,13 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) r_vec[0] = (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx; r_vec[1] = (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy; r_vec[2] = 0.0f; + + if (t->options & CTX_MASK) { + float aspx, aspy; + ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy); + r_vec[0] *= aspx; + r_vec[1] *= aspy; + } } else { printf("%s: called in an invalid context\n", __func__); @@ -229,6 +237,19 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) copy_v2_v2(v, vec); + if (t->options & CTX_MASK) { + float aspx, aspy; + ED_space_clip_aspect(t->sa->spacedata.first, &aspx, &aspy); + v[0] /= aspx; + v[1] /= aspy; + } + else if (t->options & CTX_MASK) { + float aspx, aspy; + ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy); + v[0] /= aspx; + v[1] /= aspy; + } + UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr+1); } } @@ -279,13 +300,15 @@ void applyAspectRatio(TransInfo *t, float *vec) vec[1] /= aspy; } else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) { - if (t->options & CTX_MOVIECLIP) { + if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { SpaceClip *sc = t->sa->spacedata.first; float aspx, aspy; int width, height; - ED_space_clip_size(sc, &width, &height); - ED_space_clip_aspect(sc, &aspx, &aspy); + if (t->options & CTX_MOVIECLIP) + ED_space_clip_size(sc, &width, &height); + else if (t->options & CTX_MASK) + ED_space_clip_aspect(sc, &aspx, &aspy); vec[0] *= width / aspx; vec[1] *= height / aspy; @@ -312,13 +335,15 @@ void removeAspectRatio(TransInfo *t, float *vec) vec[1] *= aspy; } else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) { - if (t->options & CTX_MOVIECLIP) { + if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { SpaceClip *sc = t->sa->spacedata.first; float aspx, aspy; int width, height; - ED_space_clip_size(sc, &width, &height); - ED_space_clip_aspect(sc, &aspx, &aspy); + if (t->options & CTX_MOVIECLIP) + ED_space_clip_size(sc, &width, &height); + else if (t->options & CTX_MASK) + ED_space_clip_aspect(sc, &aspx, &aspy); vec[0] *= aspx / width; vec[1] *= aspy / height; @@ -367,12 +392,20 @@ static void viewRedrawForce(const bContext *C, TransInfo *t) } else if (t->spacetype==SPACE_CLIP) { SpaceClip *sc = (SpaceClip*)t->sa->spacedata.first; - MovieClip *clip = ED_space_clip(sc); - /* objects could be parented to tracking data, so send this for viewport refresh */ - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + if (ED_space_clip_show_trackedit(sc)) { + MovieClip *clip = ED_space_clip(sc); - WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + /* objects could be parented to tracking data, so send this for viewport refresh */ + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + } + else if (ED_space_clip_show_maskedit(sc)) { + Mask *mask = ED_space_clip_mask(sc); + + WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + } } } @@ -654,7 +687,7 @@ int transformEvent(TransInfo *t, wmEvent *event) t->redraw |= TREDRAW_HARD; } else if (t->mode == TFM_TRANSLATION) { - if(t->options & CTX_MOVIECLIP) { + if(t->options & (CTX_MOVIECLIP | CTX_MASK)) { restoreTransObjects(t); t->flag ^= T_ALT_TRANSFORM; @@ -1591,9 +1624,13 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), helpline_poll, drawHelpline, t); } else if (t->spacetype == SPACE_CLIP) { + SpaceClip *sc = CTX_wm_space_clip(C); unit_m3(t->spacemtx); t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); - t->options |= CTX_MOVIECLIP; + if (ED_space_clip_show_trackedit(sc)) + t->options |= CTX_MOVIECLIP; + else if (ED_space_clip_show_maskedit(sc)) + t->options |= CTX_MASK; } else unit_m3(t->spacemtx); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 69af8cf2489..3fb86acf697 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -546,6 +546,7 @@ int clipUVTransform(TransInfo *t, float *vec, int resize); void flushTransNodes(TransInfo *t); void flushTransSeq(TransInfo *t); void flushTransTracking(TransInfo *t); +void flushTransMasking(TransInfo *t); /*********************** exported from transform_manipulator.c ********** */ int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index ecd69f0d10c..85e970a0441 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -53,6 +53,7 @@ #include "DNA_meshdata_types.h" #include "DNA_gpencil_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" @@ -87,6 +88,7 @@ #include "BKE_sequencer.h" #include "BKE_tessmesh.h" #include "BKE_tracking.h" +#include "BKE_mask.h" #include "ED_anim_api.h" @@ -102,6 +104,7 @@ #include "ED_types.h" #include "ED_uvedit.h" #include "ED_clip.h" +#include "ED_mask.h" #include "ED_util.h" /* for crazyspace correction */ #include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */ @@ -4848,6 +4851,17 @@ void special_aftertrans_update(bContext *C, TransInfo *t) WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); } } + else if (t->options & CTX_MASK) { + SpaceClip *sc = t->sa->spacedata.first; + Mask *mask = ED_space_clip_mask(sc); + + if (t->scene->nodetree) { + /* tracks can be used for stabilization nodes, + * flush update for such nodes */ + nodeUpdateID(t->scene->nodetree, &mask->id); + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + } + } } else if (t->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; @@ -5773,6 +5787,197 @@ void flushTransTracking(TransInfo *t) } } +/* * masking * */ + +typedef struct TransDataMasking{ + float is_handle; + + float handle[2], orig_handle[2]; + float vec[3][3]; + MaskSplinePoint *point; +} TransDataMasking; + +static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, TransData *td, TransData2D *td2d, TransDataMasking *tdm) +{ + BezTriple *bezt = &point->bezt; + float aspx, aspy; + + tdm->point = point; + copy_m3_m3(tdm->vec, bezt->vec); + + ED_space_clip_mask_aspect(sc, &aspx, &aspy); + + if (MASKPOINT_CV_ISSEL(point)) { + int i; + for (i = 0; i < 3; i++) { + /* CV coords are scaled by aspects. this is needed for rotations and + * proportional editing to be consistent with the stretched CV coords + * that are displayed. this also means that for display and numinput, + * and when the the CV coords are flushed, these are converted each time */ + td2d->loc[0] = bezt->vec[i][0]*aspx; + td2d->loc[1] = bezt->vec[i][1]*aspy; + td2d->loc[2] = 0.0f; + td2d->loc2d = bezt->vec[i]; + + td->flag = 0; + td->loc = td2d->loc; + copy_v3_v3(td->center, td->loc); + copy_v3_v3(td->iloc, td->loc); + + memset(td->axismtx, 0, sizeof(td->axismtx)); + td->axismtx[2][2] = 1.0f; + + td->ext= NULL; + td->val= NULL; + + td->flag |= TD_SELECTED; + td->dist= 0.0; + + unit_m3(td->mtx); + unit_m3(td->smtx); + + td++; + td2d++; + } + } + else { + int width, height; + + tdm->is_handle = TRUE; + + ED_space_clip_mask_size(sc, &width, &height); + BKE_mask_point_handle(point, width, height, tdm->handle); + + copy_v2_v2(tdm->orig_handle, tdm->handle); + + td2d->loc[0] = tdm->handle[0]*aspx; + td2d->loc[1] = tdm->handle[1]*aspy; + td2d->loc[2] = 0.0f; + td2d->loc2d = tdm->handle; + + td->flag = 0; + td->loc = td2d->loc; + copy_v3_v3(td->center, td->loc); + copy_v3_v3(td->iloc, td->loc); + + memset(td->axismtx, 0, sizeof(td->axismtx)); + td->axismtx[2][2] = 1.0f; + + td->ext= NULL; + td->val= NULL; + + td->flag |= TD_SELECTED; + td->dist= 0.0; + + unit_m3(td->mtx); + unit_m3(td->smtx); + + td++; + td2d++; + } +} + +static void createTransMaskingData(bContext *C, TransInfo *t) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + Mask *mask = CTX_data_edit_mask(C); + MaskShape *shape; + TransData *td = NULL; + TransData2D *td2d = NULL; + TransDataMasking *tdm = NULL; + + /* count */ + shape = mask->shapes.first; + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL(point)) { + if (MASKPOINT_CV_ISSEL(point)) + t->total += 3; + else + t->total += 1; + } + } + + spline = spline->next; + } + + shape = shape->next; + } + + if (t->total == 0) + return; + + td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransObData(Mask Editing)"); + /* for each 2d uv coord a 3d vector is allocated, so that they can be + * treated just as if they were 3d verts */ + td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(Mask Editing)"); + tdm = t->customData = MEM_callocN(t->total*sizeof(TransDataMasking), "TransDataMasking(Mask Editing)"); + + t->flag |= T_FREE_CUSTOMDATA; + + /* create data */ + shape = mask->shapes.first; + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL(point)) { + MaskPointToTransData(sc, point, td, td2d, tdm); + + if (MASKPOINT_CV_ISSEL(point)) { + td += 3; + td2d += 3; + tdm += 3; + } + else { + td++; + td2d++; + tdm++; + } + } + } + + spline = spline->next; + } + + shape = shape->next; + } +} + +void flushTransMasking(TransInfo *t) +{ + SpaceClip *sc = t->sa->spacedata.first; + TransData2D *td; + TransDataMasking *tdm; + int a; + float aspx, aspy, invx, invy; + + ED_space_clip_mask_aspect(sc, &aspx, &aspy); + invx = 1.0f/aspx; + invy = 1.0f/aspy; + + /* flush to 2d vector from internally used 3d vector */ + for(a=0, td = t->data2d, tdm = t->customData; atotal; a++, td++, tdm++) { + td->loc2d[0]= td->loc[0]*invx; + td->loc2d[1]= td->loc[1]*invy; + + if (tdm->is_handle) + BKE_mask_point_set_handle(tdm->point, td->loc2d, t->flag & T_ALT_TRANSFORM, aspx, aspy, tdm->orig_handle, tdm->vec); + } +} + void createTransData(bContext *C, TransInfo *t) { Scene *scene = t->scene; @@ -5842,6 +6047,8 @@ void createTransData(bContext *C, TransInfo *t) t->flag |= T_POINTS|T_2D_EDIT; if (t->options & CTX_MOVIECLIP) createTransTrackingData(C, t); + else if (t->options & CTX_MASK) + createTransMaskingData(C, t); } else if (t->obedit) { t->ext = NULL; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 0bf02d1a2bf..7f6cc9ca336 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -49,6 +49,7 @@ #include "DNA_view3d_types.h" #include "DNA_modifier_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -637,33 +638,42 @@ static void recalcData_spaceclip(TransInfo *t) { SpaceClip *sc = t->sa->spacedata.first; - MovieClip *clip = ED_space_clip(sc); - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); - MovieTrackingTrack *track; + if (ED_space_clip_show_trackedit(sc)) { + MovieClip *clip = ED_space_clip(sc); + ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + MovieTrackingTrack *track; - flushTransTracking(t); + flushTransTracking(t); - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { - if (t->mode == TFM_TRANSLATION) { - if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_track(track, CLAMP_PAT_POS); - if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) - BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS); - } - else if (t->mode == TFM_RESIZE) { - if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_track(track, CLAMP_PAT_DIM); - if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) - BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); + track = tracksbase->first; + while (track) { + if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + if (t->mode == TFM_TRANSLATION) { + if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) + BKE_tracking_clamp_track(track, CLAMP_PAT_POS); + if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) + BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS); + } + else if (t->mode == TFM_RESIZE) { + if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) + BKE_tracking_clamp_track(track, CLAMP_PAT_DIM); + if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) + BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); + } } + + track = track->next; } - track = track->next; + DAG_id_tag_update(&clip->id, 0); } + else if (ED_space_clip_show_maskedit(sc)) { + Mask *mask = ED_space_clip_mask(sc); - DAG_id_tag_update(&clip->id, 0); + flushTransMasking(t); + + DAG_id_tag_update(&mask->id, 0); + } } /* helper for recalcData() - for 3d-view transforms */ diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 83d4a5dfa6e..06355d623eb 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -967,6 +967,7 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0); WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0); break; default: break; diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 1737f3b79e6..2c664a7de21 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -207,6 +207,7 @@ typedef struct PreviewImage { #define ID_GD MAKE_ID2('G', 'D') /* GreasePencil */ #define ID_WM MAKE_ID2('W', 'M') /* WindowManager */ #define ID_MC MAKE_ID2('M', 'C') /* MovieClip */ +#define ID_MSK MAKE_ID2('M', 'S') /* Mask */ /* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */ #define ID_SEQ MAKE_ID2('S', 'Q') diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h new file mode 100644 index 00000000000..7597a21fd03 --- /dev/null +++ b/source/blender/makesdna/DNA_mask_types.h @@ -0,0 +1,108 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file DNA_mask_types.h + * \ingroup DNA + * \since march-2012 + * \author Sergey Sharybin + */ + +#ifndef __DNA_MASK_TYPES_H__ +#define __DNA_MASK_TYPES_H__ + +#include "DNA_defs.h" +#include "DNA_ID.h" +#include "DNA_listBase.h" +#include "DNA_curve_types.h" + +typedef struct Mask { + ID id; + struct AnimData *adt; + ListBase shapes; /* shapes which defines this mask */ + int shapenr; /* index of active shape */ + int tot_shape; /* total number of shapes */ +} Mask; + +typedef struct MaskParent { + int flag; /* parenting flags */ + int id_type; /* type of parenting */ + ID *id; /* ID block of entity to which mask/spline is parented to + * in case of parenting to movie tracking data set to MovieClip datablock */ + char parent[64]; /* entity of parent to which parenting happened + * in case of parenting to movie tracking data contains name of object */ + char sub_parent[64]; /* sub-entity of parent to which parenting happened + * in case of parenting to movie tracking data contains name of track */ + float offset[2]; /* offset from parent position, so object/control point can be parented to a + * motion track and also be animated (see ZanQdo's request below) */ +} MaskParent; + +typedef struct MaskSplinePointUW { + float u, w; /* u coordinate along spline segment and weight of this point */ + int flag; /* different flags of this point */ +} MaskSplinePointUW; + +typedef struct MaskSplinePoint { + BezTriple bezt; /* actual point coordinates and it's handles */ + int pad; + int tot_uw; /* number of uv feather values */ + MaskSplinePointUW *uw; /* feather UV values */ + MaskParent parent; /* parenting information of particular spline point */ +} MaskSplinePoint; + +typedef struct MaskSpline { + struct MaskSpline *next, *prev; + + int flag; /* defferent spline flag (closed, ...) */ + int tot_point; /* total number of points */ + MaskSplinePoint *points; /* points which defines spline itself */ + MaskParent parent; /* parenting information of the whole spline */ + + int weight_interp, pad; /* weight interpolation */ +} MaskSpline; + +typedef struct MaskShape { + struct MaskShape *next, *prev; + + char name[64]; /* name of the shape (64 = MAD_ID_NAME - 2) */ + + ListBase splines; /* list of splines which defines this shape */ + struct MaskSpline *act_spline; /* active spline */ + struct MaskSplinePoint *act_point; /* active point */ +} MaskShape; + +/* MaskParent->flag */ +#define MASK_PARENT_ACTIVE (1<<0) + +/* MaskSpline->flag */ +#define MASK_SPLINE_CYCLIC (1<<1) + +/* MaskSpline->weight_interp */ +#define MASK_SPLINE_INTERP_LINEAR 1 +#define MASK_SPLINE_INTERP_EASE 2 + +#endif // __DNA_MASK_TYPES_H__ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index c2fbc611bc3..ad13f5047d5 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -67,6 +67,7 @@ struct wmOperator; struct wmTimer; struct MovieClip; struct MovieClipScopes; +struct Mask; /** * The base structure all the other spaces @@ -523,6 +524,9 @@ typedef struct SpaceClip { int postproc_flag, pad2; void *draw_context; + + /* **** mask editing **** */ + struct Mask *mask; } SpaceClip; /* view3d Now in DNA_view3d_types.h */ @@ -910,6 +914,7 @@ enum { #define SC_MODE_TRACKING 0 #define SC_MODE_RECONSTRUCTION 1 #define SC_MODE_DISTORTION 2 +#define SC_MODE_MASKEDITING 3 /* SpaceClip->view */ #define SC_VIEW_CLIP 0 diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index adcdf5df106..d66682b8e0a 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -132,6 +132,7 @@ static const char *includefiles[] = { "DNA_movieclip_types.h", "DNA_tracking_types.h", "DNA_dynamicpaint_types.h", + "DNA_mask_types.h", // empty string to indicate end of includefiles "" @@ -1239,4 +1240,5 @@ int main(int argc, char ** argv) #include "DNA_movieclip_types.h" #include "DNA_tracking_types.h" #include "DNA_dynamicpaint_types.h" +#include "DNA_mask_types.h" /* end of list */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 316ea46d159..de2edbea845 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -145,6 +145,7 @@ extern StructRNA RNA_CompositorNodeLumaMatte; extern StructRNA RNA_CompositorNodeMapUV; extern StructRNA RNA_CompositorNodeMapValue; extern StructRNA RNA_CompositorNodeMath; +extern StructRNA RNA_CompositorNodeMask; extern StructRNA RNA_CompositorNodeMixRGB; extern StructRNA RNA_CompositorNodeNormal; extern StructRNA RNA_CompositorNodeNormalize; @@ -304,6 +305,7 @@ extern StructRNA RNA_MaterialStrand; extern StructRNA RNA_MaterialSubsurfaceScattering; extern StructRNA RNA_MaterialTextureSlot; extern StructRNA RNA_MaterialVolume; +extern StructRNA RNA_Mask; extern StructRNA RNA_Menu; extern StructRNA RNA_Mesh; extern StructRNA RNA_MeshColor; diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 6f8e7656a83..71c03858d00 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -56,6 +56,7 @@ set(DEFSRC rna_lamp.c rna_lattice.c rna_main.c + rna_mask.c rna_material.c rna_mesh.c rna_meta.c diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 62957ac5de8..1a4e8b3d5a7 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -2679,6 +2679,7 @@ static RNAProcessItem PROCESS_ITEMS[] = { {"rna_world.c", NULL, RNA_def_world}, {"rna_movieclip.c", NULL, RNA_def_movieclip}, {"rna_tracking.c", NULL, RNA_def_tracking}, + {"rna_mask.c", NULL, RNA_def_mask}, {NULL, NULL}}; static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const char *api_filename) diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 6992d992cca..0be95645a07 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -144,6 +144,7 @@ short RNA_type_to_ID_code(StructRNA *type) if (RNA_struct_is_a(type, &RNA_World)) return ID_WO; if (RNA_struct_is_a(type, &RNA_WindowManager)) return ID_WM; if (RNA_struct_is_a(type, &RNA_MovieClip)) return ID_MC; + if (RNA_struct_is_a(type, &RNA_Mask)) return ID_MSK; return 0; } @@ -179,6 +180,7 @@ StructRNA *ID_code_to_RNA_type(short idcode) case ID_WO: return &RNA_World; case ID_WM: return &RNA_WindowManager; case ID_MC: return &RNA_MovieClip; + case ID_MSK: return &RNA_Mask; default: return &RNA_ID; } } diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 155c9c67e4a..b52465fce57 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -179,6 +179,7 @@ void RNA_def_wm(struct BlenderRNA *brna); void RNA_def_world(struct BlenderRNA *brna); void RNA_def_movieclip(struct BlenderRNA *brna); void RNA_def_tracking(struct BlenderRNA *brna); +void RNA_def_mask(struct BlenderRNA *brna); /* Common Define functions */ @@ -296,6 +297,7 @@ void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop); +void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop); /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 1a039295924..a6d7f7d484e 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -253,6 +253,12 @@ static void rna_Main_movieclips_begin(CollectionPropertyIterator *iter, PointerR rna_iterator_listbase_begin(iter, &bmain->movieclip, NULL); } +static void rna_Main_masks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Main *bmain= (Main*)ptr->data; + rna_iterator_listbase_begin(iter, &bmain->mask, NULL); +} + #ifdef UNIT_TEST static PointerRNA rna_Test_test_get(PointerRNA *ptr) @@ -322,6 +328,7 @@ void RNA_def_main(BlenderRNA *brna) RNA_def_main_gpencil}, {"movieclips", "MovieClip", "rna_Main_movieclips_begin", "Movie Clips", "Movie Clip datablocks", RNA_def_main_movieclips}, + {"masks", "Mask", "rna_Main_masks_begin", "Masks", "Masks datablocks", RNA_def_main_masks}, {NULL, NULL, NULL, NULL, NULL, NULL}}; int i; diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 63006af7c72..8f4d1aa97b5 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -33,6 +33,8 @@ #include #include +#include "DNA_ID.h" + #include "RNA_define.h" #include "RNA_access.h" #include "RNA_enum_types.h" @@ -67,6 +69,7 @@ #include "BKE_depsgraph.h" #include "BKE_speaker.h" #include "BKE_movieclip.h" +#include "BKE_mask.h" #include "DNA_armature_types.h" #include "DNA_camera_types.h" @@ -87,6 +90,7 @@ #include "DNA_vfont_types.h" #include "DNA_node_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "ED_screen.h" @@ -539,6 +543,22 @@ void rna_Main_movieclips_remove(Main *bmain, MovieClip *clip) /* XXX python now has invalid pointer? */ } +Mask *rna_Main_mask_new(Main *UNUSED(bmain), const char *name) +{ + Mask *mask; + + mask = BKE_mask_new("Mask"); + + return mask; +} + +void rna_Main_masks_remove(Main *bmain, Mask *mask) +{ + BKE_mask_unlink(bmain, mask); + free_libblock(&bmain->mask, mask); + /* XXX python now has invalid pointer? */ +} + /* tag functions, all the same */ void rna_Main_cameras_tag(Main *bmain, int value) { tag_main_lb(&bmain->camera, value); } void rna_Main_scenes_tag(Main *bmain, int value) { tag_main_lb(&bmain->scene, value); } @@ -569,6 +589,7 @@ void rna_Main_actions_tag(Main *bmain, int value) { tag_main_lb(&bmain->action, void rna_Main_particles_tag(Main *bmain, int value) { tag_main_lb(&bmain->particle, value); } void rna_Main_gpencil_tag(Main *bmain, int value) { tag_main_lb(&bmain->gpencil, value); } void rna_Main_movieclips_tag(Main *bmain, int value) { tag_main_lb(&bmain->movieclip, value); } +void rna_Main_masks_tag(Main *bmain, int value) { tag_main_lb(&bmain->mask, value); } static int rna_Main_cameras_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CA); } static int rna_Main_scenes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SCE); } @@ -1519,4 +1540,34 @@ void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_return(func, parm); } +void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "BlendDataMasks"); + srna= RNA_def_struct(brna, "BlendDataMasks", NULL); + RNA_def_struct_sdna(srna, "Main"); + RNA_def_struct_ui_text(srna, "Main Masks", "Collection of masks"); + + func= RNA_def_function(srna, "tag", "rna_Main_masks_tag"); + parm= RNA_def_boolean(func, "value", 0, "Value", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + + /* new func */ + func = RNA_def_function(srna, "new", "rna_Main_mask_new"); + RNA_def_function_ui_description(func, "Add a new mask with a given name to the main database"); + parm = RNA_def_string_file_path(func, "name", "", MAX_ID_NAME - 2, "Mask", "Name of new mask datablock"); + /* return type */ + parm = RNA_def_pointer(func, "mask", "Mask", "", "New mask datablock"); + RNA_def_function_return(func, parm); + + /* remove func */ + func= RNA_def_function(srna, "remove", "rna_Main_masks_remove"); + RNA_def_function_ui_description(func, "Remove a masks from the current blendfile."); + parm= RNA_def_pointer(func, "mask", "Mask", "", "Mask to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL); +} + #endif diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c new file mode 100644 index 00000000000..3d4a5a39dc2 --- /dev/null +++ b/source/blender/makesrna/intern/rna_mask.c @@ -0,0 +1,600 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/makesrna/intern/rna_mask.c + * \ingroup RNA + */ + + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BKE_movieclip.h" +#include "BKE_tracking.h" + +#include "RNA_define.h" + +#include "rna_internal.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ +#include "DNA_scene_types.h" + +#include "WM_types.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#ifdef RNA_RUNTIME + +#include "DNA_mask_types.h" + +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "RNA_access.h" + +#include "WM_api.h" + +static void rna_Mask_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + Mask *mask = ptr->id.data; + + WM_main_add_notifier(NC_MASK|ND_DATA, mask); + DAG_id_tag_update( &mask->id, 0); +} + +/* note: this function exists only to avoid id refcounting */ +static void rna_MaskParent_id_set(PointerRNA *ptr, PointerRNA value) +{ + MaskParent *mpar = (MaskParent*) ptr->data; + + mpar->id = value.data; +} + +static StructRNA *rna_MaskParent_id_typef(PointerRNA *ptr) +{ + MaskParent *mpar = (MaskParent*) ptr->data; + + return ID_code_to_RNA_type(mpar->id_type); +} + +static void rna_MaskParent_id_type_set(PointerRNA *ptr, int value) +{ + MaskParent *mpar = (MaskParent*) ptr->data; + + /* change ID-type to the new type */ + mpar->id_type = value; + + /* clear the id-block if the type is invalid */ + if ((mpar->id) && (GS(mpar->id->name) != mpar->id_type)) + mpar->id = NULL; +} + +static void rna_Mask_shapes_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Mask *mask = (Mask *)ptr->id.data; + + rna_iterator_listbase_begin(iter, &mask->shapes, NULL); +} + +static int rna_Mask_active_shape_index_get(PointerRNA *ptr) +{ + Mask *mask = (Mask *)ptr->id.data; + + return mask->shapenr; +} + +static void rna_Mask_active_shape_index_set(PointerRNA *ptr, int value) +{ + Mask *mask = (Mask *)ptr->id.data; + + mask->shapenr = value; +} + +static void rna_Mask_active_shape_index_range(PointerRNA *ptr, int *min, int *max) +{ + Mask *mask = (Mask *)ptr->id.data; + + *min = 0; + *max = mask->tot_shape - 1; + *max = MAX2(0, *max); +} + +static PointerRNA rna_Mask_active_shape_get(PointerRNA *ptr) +{ + Mask *mask = (Mask *)ptr->id.data; + MaskShape *shape = BKE_mask_shape_active(mask); + + return rna_pointer_inherit_refine(ptr, &RNA_MaskShape, shape); +} + +static void rna_Mask_active_shape_set(PointerRNA *ptr, PointerRNA value) +{ + Mask *mask = (Mask *)ptr->id.data; + MaskShape *shape = (MaskShape *)value.data; + + BKE_mask_shape_active_set(mask, shape); +} + +static void rna_MaskShape_splines_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + MaskShape *shape = (MaskShape *)ptr->data; + + rna_iterator_listbase_begin(iter, &shape->splines, NULL); +} + +void rna_MaskShape_name_set(PointerRNA *ptr, const char *value) +{ + Mask *mask = (Mask *)ptr->id.data; + MaskShape *shape = (MaskShape *)ptr->data; + + BLI_strncpy(shape->name, value, sizeof(shape->name)); + + BKE_mask_shape_unique_name(mask, shape); +} + +static PointerRNA rna_MaskShape_active_spline_get(PointerRNA *ptr) +{ + MaskShape *shape = (MaskShape *)ptr->data; + + return rna_pointer_inherit_refine(ptr, &RNA_MaskSpline, shape->act_spline); +} + +static void rna_MaskShape_active_spline_set(PointerRNA *ptr, PointerRNA value) +{ + MaskShape *shape = (MaskShape *)ptr->data; + MaskSpline *spline = (MaskSpline *)value.data; + int index = BLI_findindex(&shape->splines, spline); + + if (index >= 0) + shape->act_spline = spline; + else + shape->act_spline = NULL; +} + +static PointerRNA rna_MaskShape_active_spline_point_get(PointerRNA *ptr) +{ + MaskShape *shape = (MaskShape *)ptr->data; + + return rna_pointer_inherit_refine(ptr, &RNA_MaskSplinePoint, shape->act_point); +} + +static void rna_MaskShape_active_spline_point_set(PointerRNA *ptr, PointerRNA value) +{ + MaskShape *shape = (MaskShape *)ptr->data; + MaskSpline *spline = shape->splines.first; + MaskSplinePoint *point = (MaskSplinePoint *)value.data; + + shape->act_point = NULL; + + while (spline) { + if (point >= spline->points && point < spline->points + spline->tot_point) { + shape->act_point = point; + + break; + } + + spline = spline->next; + } +} + +static void rna_MaskSplinePoint_handle1_get(PointerRNA *ptr, float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + values[0] = bezt->vec[0][0]; + values[1] = bezt->vec[0][1]; + values[2] = bezt->vec[0][2]; +} + +static void rna_MaskSplinePoint_handle1_set(PointerRNA *ptr, const float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + bezt->vec[0][0] = values[0]; + bezt->vec[0][1] = values[1]; + bezt->vec[0][2] = values[2]; +} + +static void rna_MaskSplinePoint_handle2_get(PointerRNA *ptr, float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + values[0] = bezt->vec[2][0]; + values[1] = bezt->vec[2][1]; + values[2] = bezt->vec[2][2]; +} + +static void rna_MaskSplinePoint_handle2_set(PointerRNA *ptr, const float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + bezt->vec[2][0] = values[0]; + bezt->vec[2][1] = values[1]; + bezt->vec[2][2] = values[2]; +} + +static void rna_MaskSplinePoint_ctrlpoint_get(PointerRNA *ptr, float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + values[0] = bezt->vec[1][0]; + values[1] = bezt->vec[1][1]; + values[2] = bezt->vec[1][2]; +} + +static void rna_MaskSplinePoint_ctrlpoint_set(PointerRNA *ptr, const float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + bezt->vec[1][0] = values[0]; + bezt->vec[1][1] = values[1]; + bezt->vec[1][2] = values[2]; +} + +static int rna_MaskSplinePoint_handle_type_get(PointerRNA *ptr) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + return bezt->h1; +} + +static void rna_MaskSplinePoint_handle_type_set(PointerRNA *ptr, int value) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + bezt->h1 = bezt->h2 = value; +} + +/* ** API ** */ + +static MaskShape *rna_Mask_shape_new(Mask *mask, const char *name) +{ + MaskShape *shape = BKE_mask_shape_new(mask, name); + + WM_main_add_notifier(NC_MASK|NA_EDITED, mask); + + return shape; +} + +void rna_Mask_shape_remove(Mask *mask, MaskShape *shape) +{ + BKE_mask_shape_remove(mask, shape); + + WM_main_add_notifier(NC_MASK|NA_EDITED, mask); +} + +static void rna_MaskShape_spline_add(ID *id, MaskShape *shape, int number) +{ + Mask *mask = (Mask*) id; + int i; + + for (i = 0; i < number; i++) + BKE_mask_spline_add(shape); + + WM_main_add_notifier(NC_MASK|NA_EDITED, mask); +} + +#else + +static void rna_def_maskParent(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem mask_id_type_items[] = { + {ID_MC, "MOVIECLIP", ICON_SEQUENCE, "Movie Clip", ""}, + {0, NULL, 0, NULL, NULL}}; + + srna = RNA_def_struct(brna, "MaskParent", NULL); + RNA_def_struct_ui_text(srna, "Mask Parent", "Parenting settings for maskign element"); + + /* use_parent */ + prop = RNA_def_property(srna, "use_parent", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_PARENT_ACTIVE); + RNA_def_property_ui_text(prop, "Use Parent", "Use parenting for this object"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* Target Properties - ID-block to Drive */ + prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "ID"); + RNA_def_property_flag(prop, PROP_EDITABLE); + // RNA_def_property_editable_func(prop, "rna_maskSpline_id_editable"); + /* note: custom set function is ONLY to avoid rna setting a user for this. */ + RNA_def_property_pointer_funcs(prop, NULL, "rna_MaskParent_id_set", "rna_MaskParent_id_typef", NULL); + RNA_def_property_ui_text(prop, "ID", "ID-block to which masking element would be parented to or to it's property"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + prop = RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "id_type"); + RNA_def_property_enum_items(prop, mask_id_type_items); + RNA_def_property_enum_default(prop, ID_MC); + RNA_def_property_enum_funcs(prop, NULL, "rna_MaskParent_id_type_set", NULL); + //RNA_def_property_editable_func(prop, "rna_MaskParent_id_type_editable"); + RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* parent */ + prop = RNA_def_property(srna, "parent", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Parent", "Name of parent object in specified data block to which parenting happens"); + RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* sub_parent */ + prop = RNA_def_property(srna, "sub_parent", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Sub Parent", "Name of parent sub-object in specified data block to which parenting happens"); + RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); +} + +static void rna_def_maskSplinePointUW(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "MaskSplinePointUW", NULL); + RNA_def_struct_ui_text(srna, "Mask Spline UW Point", "Single point in spline segment defining feather"); + + /* u */ + prop = RNA_def_property(srna, "u", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "u"); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_text(prop, "U", "U coordinate of point along spline segment"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* weight */ + prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "w"); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_text(prop, "Weight", "Weight of feather point"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* select */ + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT); + RNA_def_property_ui_text(prop, "Select", "Selection status"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); +} + +static void rna_def_maskSplinePoint(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem handle_type_items[] = { + {HD_AUTO, "AUTO", 0, "Auto", ""}, + {HD_VECT, "VECTOR", 0, "Vector", ""}, + {HD_ALIGN, "ALIGNED", 0, "Aligned", ""}, + {0, NULL, 0, NULL, NULL}}; + + rna_def_maskSplinePointUW(brna); + + srna = RNA_def_struct(brna, "MaskSplinePoint", NULL); + RNA_def_struct_ui_text(srna, "Mask Spline Point", "Single point in spline used for defining mash shape"); + + /* Vector values */ + prop = RNA_def_property(srna, "handle_left", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 3); + RNA_def_property_float_funcs(prop, "rna_MaskSplinePoint_handle1_get", "rna_MaskSplinePoint_handle1_set", NULL); + RNA_def_property_ui_text(prop, "Handle 1", "Coordinates of the first handle"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 3); + RNA_def_property_float_funcs(prop, "rna_MaskSplinePoint_ctrlpoint_get", "rna_MaskSplinePoint_ctrlpoint_set", NULL); + RNA_def_property_ui_text(prop, "Control Point", "Coordinates of the control point"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + prop = RNA_def_property(srna, "handle_right", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 3); + RNA_def_property_float_funcs(prop, "rna_MaskSplinePoint_handle2_get", "rna_MaskSplinePoint_handle2_set", NULL); + RNA_def_property_ui_text(prop, "Handle 2", "Coordinates of the second handle"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* handle_type */ + prop = RNA_def_property(srna, "handle_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_funcs(prop, "rna_MaskSplinePoint_handle_type_get", "rna_MaskSplinePoint_handle_type_set", NULL); + RNA_def_property_enum_items(prop, handle_type_items); + RNA_def_property_ui_text(prop, "Handle Type", "Handle type"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* select */ + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "bezt.f1", SELECT); + RNA_def_property_ui_text(prop, "Select", "Selection status"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* parent */ + prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MaskParent"); + + /* feather points */ + prop = RNA_def_property(srna, "feather_points", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "MaskSplinePointUW"); + RNA_def_property_collection_sdna(prop, NULL, "uw", "tot_uw"); + RNA_def_property_ui_text(prop, "Feather Points", "Points defining feather"); +} + +static void rna_def_maskSplines(BlenderRNA *brna) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "MaskSplines", NULL); + RNA_def_struct_sdna(srna, "MaskShape"); + RNA_def_struct_ui_text(srna, "Mask Splines", "Collection of masking splines"); + + func = RNA_def_function(srna, "add", "rna_MaskShape_spline_add"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_ui_description(func, "Add a number of splines to mask shape"); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of splines to add to the shape", 0, INT_MAX); + + /* active spline */ + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MaskSpline"); + RNA_def_property_pointer_funcs(prop, "rna_MaskShape_active_spline_get", "rna_MaskShape_active_spline_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking shape"); + + /* active point */ + prop = RNA_def_property(srna, "active_point", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MaskSplinePoint"); + RNA_def_property_pointer_funcs(prop, "rna_MaskShape_active_spline_point_get", "rna_MaskShape_active_spline_point_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking shape"); +} + +static void rna_def_maskSpline(BlenderRNA *brna) +{ + static EnumPropertyItem spline_interpolation_items[] = { + {MASK_SPLINE_INTERP_LINEAR, "LINEAR", 0, "Linear", ""}, + {MASK_SPLINE_INTERP_EASE, "EASE", 0, "Ease", ""}, + {0, NULL, 0, NULL, NULL}}; + + StructRNA *srna; + PropertyRNA *prop; + + rna_def_maskSplinePoint(brna); + + srna = RNA_def_struct(brna, "MaskSpline", NULL); + RNA_def_struct_ui_text(srna, "Mask spline", "Single spline used for defining mash shape"); + + /* weight interpolation */ + prop = RNA_def_property(srna, "weight_interpolation", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "weight_interp"); + RNA_def_property_enum_items(prop, spline_interpolation_items); + RNA_def_property_ui_text(prop, "Weight Interpolation", "The type of weight interpolation for spline"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* cyclic */ + prop = RNA_def_property(srna, "use_cyclic", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_SPLINE_CYCLIC); + RNA_def_property_ui_text(prop, "Cyclic", "Make this spline a closed loop"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); +} + +static void rna_def_maskShape(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + rna_def_maskSpline(brna); + rna_def_maskSplines(brna); + + srna = RNA_def_struct(brna, "MaskShape", NULL); + RNA_def_struct_ui_text(srna, "Mask shape", "Single shape used for masking stuff"); + + /* name */ + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Name", "Unique name of shape"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MaskShape_name_set"); + RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + RNA_def_struct_name_property(srna, prop); + + /* splines */ + prop = RNA_def_property(srna, "splines", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_MaskShape_splines_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_struct_type(prop, "MaskSpline"); + RNA_def_property_ui_text(prop, "Splines", "Collection of splines which defines this shape"); + RNA_def_property_srna(prop, "MaskSplines"); +} + +static void rna_def_maskShapes(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + PropertyRNA *prop; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "MaskShapes"); + srna = RNA_def_struct(brna, "MaskShapes", NULL); + RNA_def_struct_sdna(srna, "Mask"); + RNA_def_struct_ui_text(srna, "Mask Shapes", "Collection of shapes used by mask"); + + func = RNA_def_function(srna, "new", "rna_Mask_shape_new"); + RNA_def_function_ui_description(func, "Add shape to this mask"); + RNA_def_string(func, "name", "", 0, "Name", "Name of new shape"); + parm = RNA_def_pointer(func, "shape", "MaskShape", "", "New mask shape"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_Mask_shape_remove"); + RNA_def_function_ui_description(func, "Remove shape from this mask"); + RNA_def_pointer(func, "shape", "MaskShape", "", "Shape to be removed"); + + /* active object */ + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MaskShape"); + RNA_def_property_pointer_funcs(prop, "rna_Mask_active_shape_get", "rna_Mask_active_shape_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "Active Shape", "Active shape in this mask"); +} + +static void rna_def_mask(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + rna_def_maskShape(brna); + + srna = RNA_def_struct(brna, "Mask", "ID"); + RNA_def_struct_ui_text(srna, "Mask", "Mask datablock defining mask for compositing"); + RNA_def_struct_ui_icon(srna, ICON_MOD_MASK); + + /* shapes */ + prop = RNA_def_property(srna, "shapes", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_Mask_shapes_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_struct_type(prop, "MaskShape"); + RNA_def_property_ui_text(prop, "Shapes", "Collection of shapes which defines this mask"); + rna_def_maskShapes(brna, prop); + + /* active shape index */ + prop = RNA_def_property(srna, "active_shape_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "shapenr"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_funcs(prop, "rna_Mask_active_shape_index_get", "rna_Mask_active_shape_index_set", "rna_Mask_active_shape_index_range"); + RNA_def_property_ui_text(prop, "Active Shape Index", "Index of active shape in list of all mask's shapes"); +} + +void RNA_def_mask(BlenderRNA *brna) +{ + rna_def_maskParent(brna); + rna_def_mask(brna); +} + +#endif diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 58fd936819b..a6c3c664ce6 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2875,6 +2875,18 @@ static void def_cmp_moviedistortion(StructRNA *srna) RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); } +static void def_cmp_mask(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "Mask"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Mask", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); +} + static void dev_cmd_transform(StructRNA *srna) { PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index 5352bbd0e0f..e536314e145 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -158,6 +158,7 @@ DefNode( CompositorNode, CMP_NODE_MOVIECLIP, def_cmp_movieclip, "MOVIE DefNode( CompositorNode, CMP_NODE_TRANSFORM, dev_cmd_transform, "TRANSFORM", Transform, "Transform", "" ) DefNode( CompositorNode, CMP_NODE_STABILIZE2D, def_cmp_stabilize2d, "STABILIZE2D", Stabilize, "Stabilize 2D", "" ) DefNode( CompositorNode, CMP_NODE_MOVIEDISTORTION,def_cmp_moviedistortion,"MOVIEDISTORTION",MovieDistortion, "Movie Distortion", "" ) +DefNode( CompositorNode, CMP_NODE_MASK, def_cmp_mask, "MASK", Mask, "Mask", "" ) DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" ) DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" ) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 47bad8f31e5..532690eff64 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -115,6 +115,7 @@ EnumPropertyItem viewport_shade_items[] = { #ifdef RNA_RUNTIME #include "DNA_anim_types.h" +#include "DNA_mask_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -1029,6 +1030,13 @@ static void rna_SpaceClipEditor_clip_set(PointerRNA *ptr, PointerRNA value) ED_space_clip_set(NULL, screen, sc, (MovieClip*)value.data); } +static void rna_SpaceClipEditor_mask_set(PointerRNA *ptr, PointerRNA value) +{ + SpaceClip *sc= (SpaceClip*)(ptr->data); + + ED_space_clip_set_mask(NULL, sc, (Mask*)value.data); +} + static void rna_SpaceClipEditor_clip_mode_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { SpaceClip *sc = (SpaceClip*)(ptr->data); @@ -2926,6 +2934,7 @@ static void rna_def_space_clip(BlenderRNA *brna) {SC_MODE_RECONSTRUCTION, "RECONSTRUCTION", ICON_SNAP_FACE, "Reconstruction", "Show tracking/reconstruction tools"}, {SC_MODE_DISTORTION, "DISTORTION", ICON_GRID, "Distortion", "Show distortion tools"}, + {SC_MODE_MASKEDITING, "MASKEDITING", ICON_MOD_MASK, "Mask editing", "Show mask editing tools"}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem view_items[] = { @@ -2954,6 +2963,13 @@ static void rna_def_space_clip(BlenderRNA *brna) "Parameters defining which frame of the movie clip is displayed"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + /* mask */ + prop= RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Mask", "Mask displayed and edited in this space"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceClipEditor_mask_set", NULL, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + /* mode */ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "mode"); diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 9bcbc91265c..5320d9f65cc 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -35,6 +35,7 @@ set(INC ../makesrna ../render/extern/include ../../../intern/guardedalloc + ../../../intern/raskter ) set(INC_SYS @@ -81,6 +82,7 @@ set(SRC composite/nodes/node_composite_mapUV.c composite/nodes/node_composite_mapValue.c composite/nodes/node_composite_math.c + composite/nodes/node_composite_mask.c composite/nodes/node_composite_mixrgb.c composite/nodes/node_composite_movieclip.c composite/nodes/node_composite_moviedistortion.c diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index 284b89bc095..4378c6a1d36 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -50,6 +50,7 @@ void register_node_type_cmp_value(struct bNodeTreeType *ttype); void register_node_type_cmp_rgb(struct bNodeTreeType *ttype); void register_node_type_cmp_curve_time(struct bNodeTreeType *ttype); void register_node_type_cmp_movieclip(struct bNodeTreeType *ttype); +void register_node_type_cmp_usermask(struct bNodeTreeType *ttype); void register_node_type_cmp_composite(struct bNodeTreeType *ttype); void register_node_type_cmp_viewer(struct bNodeTreeType *ttype); @@ -115,6 +116,7 @@ void register_node_type_cmp_mapuv(struct bNodeTreeType *ttype); void register_node_type_cmp_transform(struct bNodeTreeType *ttype); void register_node_type_cmp_stabilize2d(struct bNodeTreeType *ttype); void register_node_type_cmp_moviedistortion(struct bNodeTreeType *ttype); +void register_node_type_cmp_mask(struct bNodeTreeType *ttype); void register_node_type_cmp_glare(struct bNodeTreeType *ttype); void register_node_type_cmp_tonemap(struct bNodeTreeType *ttype); diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 049b5dd8178..ca8922eaf64 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -872,6 +872,10 @@ int ntreeCompositTagAnimated(bNodeTree *ntree) nodeUpdate(ntree, node); tagged= 1; } + else if (node->type==CMP_NODE_MASK) { + nodeUpdate(ntree, node); + tagged= 1; + } } return tagged; diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c new file mode 100644 index 00000000000..2c49be48f7d --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -0,0 +1,124 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_mask.c + * \ingroup cmpnodes + */ + +#include "BLF_translation.h" + +#include "DNA_mask_types.h" + +#include "BKE_mask.h" + +// XXX: ... +#include "../../../../intern/raskter/raskter.h" +#include "node_composite_util.h" + +/* **************** Translate ******************** */ + +static bNodeSocketTemplate cmp_node_mask_in[] = { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate cmp_node_mask_out[] = { + { SOCK_RGBA, 0, "Image"}, + { -1, 0, "" } +}; + +static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + if (node->id) { + Mask *mask = (Mask *)node->id; + CompBuf *stackbuf; + RenderData *rd = data; + MaskShape *shape = mask->shapes.first; + float *res; + int sx, sy; + + if (!out[0]->hasoutput) { + /* the node's output socket is not connected to anything... + * do not execute any further, just exit the node immediately + */ + return; + } + + if (in[0]->hasinput && in[0]->data) { + CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA); + + sx = cbuf->x; + sy = cbuf->y; + } + else { + sx = (rd->size * rd->xsch) / 100; + sy = (rd->size * rd->ysch) / 100; + } + + /* allocate the output buffer */ + stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE); + res = stackbuf->rect; + + shape = mask->shapes.first; + while (shape) { + MaskSpline *spline = shape->splines.first; + + while (spline) { + float *diff_points; + int tot_diff_point; + + diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); + + if (tot_diff_point) { + PLX_raskterize(diff_points, tot_diff_point, res, sx, sy); + + MEM_freeN(diff_points); + } + + spline = spline->next; + } + + shape = shape->next; + } + + /* pass on output and free */ + out[0]->data = stackbuf; + } +} + +void register_node_type_cmp_mask(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, CMP_NODE_MASK, "Mask", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_mask_in, cmp_node_mask_out); + node_type_size(&ntype, 140, 100, 320); + node_type_exec(&ntype, exec); + + nodeRegisterType(ttype, &ntype); +} diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 7cbeab6a02e..25abc171057 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -167,6 +167,7 @@ typedef struct wmNotifier { #define NC_ID (18<<24) #define NC_LOGIC (19<<24) #define NC_MOVIECLIP (20<<24) +#define NC_MASK (21<<24) /* data type, 256 entries is enough, it can overlap */ #define NOTE_DATA 0x00FF0000 diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index 7edf5314821..70354c0a2ec 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -154,6 +154,7 @@ endif() bf_blenkernel # duplicate for linking bf_intern_mikktspace extern_recastnavigation + bf_intern_raskter ) if(WITH_MOD_CLOTH_ELTOPO) diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index a036e8a8212..ad9bd924e9f 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -236,6 +236,7 @@ void ED_space_image_uv_sculpt_update(struct wmWindowManager *wm, struct ToolSett void ED_screen_set_scene(struct bContext *C, struct Scene *scene){} void ED_space_clip_set(struct bContext *C, struct SpaceClip *sc, struct MovieClip *clip){} +void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask){} void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype){} void ED_render_engine_changed(struct Main *bmain) {} diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 0168c06b7da..f81d6320c23 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -807,6 +807,7 @@ endif() bf_editor_sound bf_editor_animation bf_editor_datafiles + bf_editor_mask bf_render bf_intern_opennl @@ -877,6 +878,7 @@ endif() cycles_kernel cycles_util cycles_subd + bf_intern_raskter ) if(WITH_LIBMV) From 288a734b6ff0ece0264e1f623130368eb1e6f3b3 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 30 Apr 2012 10:04:20 +0000 Subject: [PATCH 024/360] Tomato: disable texture buffers for intel cards due to they're constantly blinking with black frames Also remove unused code. --- .../blender/editors/space_clip/clip_editor.c | 36 ++++--------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 2e7de318299..cd3d04279ac 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -486,7 +486,12 @@ int ED_space_clip_texture_buffer_supported(SpaceClip *sc) if (!context->support_checked) { context->support_checked = TRUE; - context->buffers_supported = GPU_non_power_of_two_support(); + if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) { + context->buffers_supported = FALSE; + } + else { + context->buffers_supported = GPU_non_power_of_two_support(); + } } return context->buffers_supported; @@ -526,35 +531,6 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) context->texture_allocated = 0; } -#if 0 - /* disabled for now because current tracking users have got NPOT textures - * working smoothly on their computers and forcing re-scaling during playback - * slows down playback a lot */ - - /* if videocard doesn't support NPOT textures, need to do rescaling */ - if (!GPU_non_power_of_two_support()) { - if (!is_power_of_2_i(width) || !is_power_of_2_i(height)) { - width = power_of_2_max_i(width); - height = power_of_2_max_i(height); - - if (ibuf->x != width || ibuf->y != height) { - if (frect) { - fscalerect= MEM_mallocN(width*width*sizeof(*fscalerect)*4, "fscalerect"); - gluScaleImage(GL_RGBA, ibuf->x, ibuf->y, GL_FLOAT, ibuf->rect_float, width, height, GL_FLOAT, fscalerect); - - frect = fscalerect; - } - else { - scalerect= MEM_mallocN(width*height*sizeof(*scalerect), "scalerect"); - gluScaleImage(GL_RGBA, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect, width, height, GL_UNSIGNED_BYTE, scalerect); - - rect = scalerect; - } - } - } - } -#endif - if (need_recreate || !context->texture_allocated) { /* texture doesn't exist yet or need to be re-allocated because of changed dimensions */ int filter = GL_LINEAR; From 0974368b322ac06b41c90c1dfd87a2df91f324b9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 30 Apr 2012 11:31:22 +0000 Subject: [PATCH 025/360] Tomato: versioning patch for current files which have got curves view open --- source/blender/blenloader/intern/readfile.c | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 753cd93b89a..a46d05fc97c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -13389,6 +13389,40 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + { + bScreen *sc; + + for (sc = main->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_CLIP) { + SpaceClip *sclip = (SpaceClip *)sl; + ARegion *ar; + int hide = FALSE; + + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_PREVIEW) { + if (ar->alignment != RGN_ALIGN_NONE) { + ar->flag |= RGN_FLAG_HIDDEN; + ar->v2d.flag &= ~V2D_IS_INITIALISED; + ar->alignment = RGN_ALIGN_NONE; + + hide = TRUE; + } + } + } + + if (hide) { + sclip->view = SC_VIEW_CLIP; + } + } + } + } + } + } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ From 398884d1866fc3d9aa95892c534498a27cef9491 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 3 May 2012 07:32:26 +0000 Subject: [PATCH 026/360] Tomato: update raskter library to newer version from Pete Larbell --- intern/raskter/raskter.c | 109 ++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 35 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index d5890f1741a..0839e8a09c2 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -31,7 +31,10 @@ #include #include "raskter.h" -#define R_XCHG(a,b) t=a;a=b;b=t; +// from BLI_utildefines.h +#define MIN2(x,y) ( (x)<(y) ? (x) : (y) ) +#define MAX2(x,y) ( (x)>(y) ? (x) : (y) ) + struct e_status { int x; @@ -69,7 +72,7 @@ static void preprocess_all_edges(struct poly_vert * verts, int num_verts, struct int yend; int dx; int dy; - int t; + int temp_pos; int xdist; struct e_status *e_new; struct e_status *next_edge; @@ -80,36 +83,58 @@ static void preprocess_all_edges(struct poly_vert * verts, int num_verts, struct all_edges = NULL; // loop all verts for(i = 0; i < num_verts; i++) { + // determine beginnings and endings of edges, linking last vertex to first vertex xbeg = v[i].x; ybeg = v[i].y; - // determine starts and ends of edges, linking last vertex to first vertex - if(i == 0) { - xend = v[num_verts-1].x; - yend = v[num_verts-1].y; - } else { + if(i) { + // we're not at the last vert, so end of the edge is the previous vertex xend = v[i-1].x; yend = v[i-1].y; + } else { + // we're at the first vertex, so the "end" of this edge is the last vertex + xend = v[num_verts-1].x; + yend = v[num_verts-1].y; } // make sure our edges are facing the correct direction if(ybeg > yend) { - R_XCHG(xbeg, xend); - R_XCHG(ybeg, yend); + // flip the Xs + temp_pos = xbeg; + xbeg = xend; + xend = temp_pos; + // flip the Ys + temp_pos = ybeg; + ybeg = yend; + yend = temp_pos; } - // create the edge and determine it's slope (for incremental line drawing) - if((dy = yend - ybeg) != 0) { + + // calculate y delta + dy = yend - ybeg; + // dont draw horizontal lines directly, they are scanned as part of the edges they connect, so skip em. :) + if(dy) { + // create the edge and determine it's slope (for incremental line drawing) e_new = open_edge++; - e_new->xdir = ((dx = xend - xbeg) > 0) ? 1 : -1; - xdist = (dx > 0) ? dx : -dx; + + // calculate x delta + dx = xend - xbeg; + if(dx > 0){ + e_new->xdir = 1; + xdist = dx; + }else{ + e_new->xdir = -1; + xdist = -dx; + } + e_new->x = xbeg; e_new->ybeg = ybeg; e_new->num = dy; e_new->drift_dec = dy; + + // calculate deltas for incremental drawing if(dx >= 0) { e_new->drift = 0; } else { e_new->drift = -dy + 1; } - // calculate deltas for drawing if(dy >= xdist) { e_new->drift_inc = xdist; e_new->xshift = 0; @@ -121,7 +146,7 @@ static void preprocess_all_edges(struct poly_vert * verts, int num_verts, struct // link in all the edges, in sorted order for(;;) { next_edge = *next_edge_ref; - if((next_edge == NULL) || (next_edge->ybeg > ybeg) || ((next_edge->ybeg == ybeg) && (next_edge->x >= xbeg))) { + if(!next_edge || (next_edge->ybeg > ybeg) || ((next_edge->ybeg == ybeg) && (next_edge->x >= xbeg))) { e_new->e_next = next_edge; *next_edge_ref = e_new; break; @@ -197,7 +222,7 @@ int rast_scan_fill(struct poly_vert * verts, int num_verts) { TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here. Will get changed once DEM code gets in. */ - for(y_curr = (all_edges->ybeg > 0 ? all_edges->ybeg : 0); ((all_edges != NULL) || (possible_edges != NULL)) && (y_curr < rb.sizey); y_curr++) { + for(y_curr = MAX2(all_edges->ybeg,0); (all_edges || possible_edges) && (y_curr < rb.sizey); y_curr++) { /* Link any edges that start on the current scan line into the list of @@ -214,19 +239,19 @@ int rast_scan_fill(struct poly_vert * verts, int num_verts) { At each iteration, make sure we still have a non-NULL edge. */ - for(edgec = &possible_edges; (all_edges != NULL) && (all_edges->ybeg == y_curr);) { + for(edgec = &possible_edges; all_edges && (all_edges->ybeg == y_curr);) { x_curr = all_edges->x; // Set current X position. - for(;;) { // Start looping edges. Will break when edges run out. - e_curr = *edgec; // Set up a current edge pointer. - if((e_curr == NULL) || (e_curr->x >= x_curr)) { // If we have an no edge, or we need to skip some X-span, + for(;;) { // Start looping edges. Will break when edges run out. + e_curr = *edgec; // Set up a current edge pointer. + if(!e_curr || (e_curr->x >= x_curr)) { // If we have an no edge, or we need to skip some X-span, e_temp = all_edges->e_next; // set a temp "next" edge to test. *edgec = all_edges; // Add this edge to the list to be scanned. all_edges->e_next = e_curr; // Set up the next edge. edgec = &all_edges->e_next; // Set our list to the next edge's location in memory. all_edges = e_temp; // Skip the NULL or bad X edge, set pointer to next edge. - break; // Stop looping edges (since we ran out or hit empty X span. + break; // Stop looping edges (since we ran out or hit empty X span. } else { - edgec = &e_curr->e_next; // Set the pointer to the edge list the "next" edge. + edgec = &e_curr->e_next; // Set the pointer to the edge list the "next" edge. } } } @@ -248,7 +273,7 @@ int rast_scan_fill(struct poly_vert * verts, int num_verts) { At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge we will eventually hit a NULL when the list runs out. */ - for(e_curr = possible_edges; e_curr != NULL; e_curr = e_curr->e_next) { + for(e_curr = possible_edges; e_curr; e_curr = e_curr->e_next) { /* Calculate a span of pixels to fill on the current scan line. @@ -263,9 +288,12 @@ int rast_scan_fill(struct poly_vert * verts, int num_verts) { TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor, but for now it is done here until the DEM code comes in. */ - cpxl = spxl + (e_curr->x > 0 ? e_curr->x : 0); + // set up xmin and xmax bounds on this scan line + cpxl = spxl + MAX2(e_curr->x,0); e_curr = e_curr->e_next; - mpxl = spxl + (e_curr->x < rb.sizex ? e_curr->x : rb.sizex) - 1; + mpxl = spxl + MIN2(e_curr->x,rb.sizex) - 1; + + // draw the pixels. for(; cpxl <= mpxl; *cpxl++ = 1.0f); } @@ -278,8 +306,8 @@ int rast_scan_fill(struct poly_vert * verts, int num_verts) { polygons, we dont have fractional positions, so we only move in x-direction when needed to get all the way to the next pixel over... */ - for(edgec = &possible_edges; (e_curr = *edgec) != NULL;) { - if((--(e_curr->num)) == 0) { + for(edgec = &possible_edges; (e_curr = *edgec);) { + if(!(--(e_curr->num))) { *edgec = e_curr->e_next; } else { e_curr->x += e_curr->xshift; @@ -298,28 +326,38 @@ int rast_scan_fill(struct poly_vert * verts, int num_verts) { pass, then we know we need to sort by x, so then cycle through edges again and perform the sort.- */ - if(possible_edges != NULL) { - for(edgec = &possible_edges; (e_curr = *edgec)->e_next != NULL;) { + if(possible_edges) { + for(edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + // if the current edge hits scan line at greater X than the next edge, we need to exchange the edges if(e_curr->x > e_curr->e_next->x) { - e_temp = e_curr->e_next->e_next; *edgec = e_curr->e_next; + // exchange the pointers + e_temp = e_curr->e_next->e_next; e_curr->e_next->e_next = e_curr; e_curr->e_next = e_temp; + // set flag that we had at least one switch swixd = 1; } - edgec = &(*edgec)->e_next; } - for(; swixd;) { + // if we did have a switch, look for more (there will more if there was one) + for(;;) { + // reset exchange flag so it's only set if we encounter another one swixd = 0; - for(edgec = &possible_edges; (e_curr = *edgec)->e_next != NULL;) { + for(edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + // again, if current edge hits scan line at higher X than next edge, exchange the edges and set flag if(e_curr->x > e_curr->e_next->x) { - e_temp = e_curr->e_next->e_next; *edgec = e_curr->e_next; + // exchange the pointers + e_temp = e_curr->e_next->e_next; e_curr->e_next->e_next = e_curr; e_curr->e_next = e_temp; + // flip the exchanged flag swixd = 1; } - edgec = &(*edgec)->e_next; + } + // if we had no exchanges, we're done reshuffling the pointers + if(!swixd) { + break; } } } @@ -365,3 +403,4 @@ int PLX_raskterize(float * verts, int num, float * buf, int buf_x, int buf_y) { free(ply); // Free the memory allocated for the integer coordinate table. return(i); // Return the value returned by the rasterizer. } + From 5b7cad343e7e5cd09a9dbc6fb973d04c9d11ba3e Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 9 May 2012 15:39:54 +0000 Subject: [PATCH 027/360] Initial Ceres integration into Blender Currently only put sources of Ceres library into extern/libmv/third_party and setup CMake and SCons building systems. Integration details: - Even CMake build files are not re-used from Ceres's trunk: they're using some automatic stuff detection like glog, pthreads, protobuf and so and it's not so clear how to re-use that files without modifications. And IMO it's easier if build files are getting re-generated automatically to match Blender-specific setup rather than keeping changes made locally in Blender in sync when re-bundling Ceres library. Especially in case when it's alerady needed to support SCons build system. - Integrated only actual sources, all tests were stripped. Probably it'll be nice to have them, but they'll need clear integration with current module test stuff in Blender. Hopefully integration went smooth. - Suitesparse was disabled. It'll help a lot having it, but there are some difficulties making cholmod working fine on windows. Would be added in future - collections_port.cc was also stripped. It's not used by Ceres's upstream and it gives compilation error (undefined uint32 -- looks like namespace issue). - Currently all schur eliminators are included. Not sure if it makes sense, also not sure if it makes sense having them switchable on and off -- IMO better to have single configuration which works and does not require special tweaks after everything was set up. - Personally i'd say if some of Ceres modules are not used better to drop it away -- all symbols would be stripped anyway, but it'll be waste of compilation time which is annoying in cases when one doing, say, binary search of revision at which some regression was introduced. Especially when it's easy to add modules which should be used by Blender. But as long as it stays in Tomato i'm not worrying much about this. To bundle updated version of Ceres: - You'll need to use GIT-SVN checkout, Re-bundling Ceres using SVN is still NOT supported! - Go to extern/libmv/third_party/ceres folder - Run ./bundle.sh This will checkout fresh Ceres snapshot of Windows branch (which is currently most interesting from integration into Blender POV), apply all patches listed in patches/series and copy needed files into Blender's working copy. This will also re-generate CMake/SCons build rules. If you'll need extra files from Ceres repository which are not present in Blender, you'll need to copy them manually and then run ./mkfiles.sh from extern/libmv/third_party/ceres folder which will update list of files used by Blender. Thanks all Ceres developers for this library and thanks to Keir Mierle with help integrating Ceres into Blender! --- extern/libmv/CMakeLists.txt | 3 + extern/libmv/ChangeLog | 81 +- extern/libmv/SConscript | 4 +- extern/libmv/bundle.sh | 15 +- extern/libmv/libmv/image/convolve.cc | 14 + extern/libmv/libmv/image/convolve.h | 10 + extern/libmv/mkfiles.sh | 2 +- extern/libmv/third_party/CMakeLists.txt | 2 + extern/libmv/third_party/SConscript | 3 + extern/libmv/third_party/ceres/CMakeLists.txt | 218 ++++++ extern/libmv/third_party/ceres/ChangeLog | 227 ++++++ extern/libmv/third_party/ceres/LICENSE | 27 + extern/libmv/third_party/ceres/README | 3 + extern/libmv/third_party/ceres/SConscript | 34 + extern/libmv/third_party/ceres/bundle.sh | 183 +++++ extern/libmv/third_party/ceres/files.txt | 150 ++++ .../include/ceres/autodiff_cost_function.h | 170 +++++ .../third_party/ceres/include/ceres/ceres.h | 48 ++ .../include/ceres/conditioned_cost_function.h | 97 +++ .../ceres/include/ceres/cost_function.h | 127 ++++ .../ceres/include/ceres/internal/autodiff.h | 374 ++++++++++ .../ceres/include/ceres/internal/eigen.h | 80 ++ .../include/ceres/internal/fixed_array.h | 193 +++++ .../ceres/include/ceres/internal/macros.h | 154 ++++ .../ceres/internal/manual_constructor.h | 214 ++++++ .../ceres/include/ceres/internal/port.h | 44 ++ .../ceres/include/ceres/internal/scoped_ptr.h | 311 ++++++++ .../ceres/include/ceres/iteration_callback.h | 159 ++++ .../third_party/ceres/include/ceres/jet.h | 671 +++++++++++++++++ .../include/ceres/local_parameterization.h | 189 +++++ .../ceres/include/ceres/loss_function.h | 322 ++++++++ .../ceres/include/ceres/normal_prior.h | 75 ++ .../ceres/numeric_diff_cost_function.h | 283 +++++++ .../third_party/ceres/include/ceres/problem.h | 265 +++++++ .../ceres/include/ceres/rotation.h | 526 +++++++++++++ .../ceres/include/ceres/sized_cost_function.h | 82 ++ .../third_party/ceres/include/ceres/solver.h | 379 ++++++++++ .../third_party/ceres/include/ceres/types.h | 224 ++++++ .../internal/ceres/block_evaluate_preparer.cc | 73 ++ .../internal/ceres/block_evaluate_preparer.h | 67 ++ .../ceres/block_jacobi_preconditioner.cc | 136 ++++ .../ceres/block_jacobi_preconditioner.h | 84 +++ .../internal/ceres/block_jacobian_writer.cc | 209 ++++++ .../internal/ceres/block_jacobian_writer.h | 127 ++++ .../ceres/block_random_access_dense_matrix.cc | 83 +++ .../ceres/block_random_access_dense_matrix.h | 98 +++ .../ceres/block_random_access_matrix.cc | 40 + .../ceres/block_random_access_matrix.h | 132 ++++ .../block_random_access_sparse_matrix.cc | 158 ++++ .../ceres/block_random_access_sparse_matrix.h | 109 +++ .../internal/ceres/block_sparse_matrix.cc | 263 +++++++ .../internal/ceres/block_sparse_matrix.h | 142 ++++ .../ceres/internal/ceres/block_structure.cc | 92 +++ .../ceres/internal/ceres/block_structure.h | 105 +++ .../ceres/canonical_views_clustering.cc | 238 ++++++ .../ceres/canonical_views_clustering.h | 133 ++++ .../third_party/ceres/internal/ceres/casts.h | 108 +++ .../internal/ceres/cgnr_linear_operator.h | 120 +++ .../ceres/internal/ceres/cgnr_solver.cc | 80 ++ .../ceres/internal/ceres/cgnr_solver.h | 66 ++ .../ceres/internal/ceres/collections_port.h | 141 ++++ .../ceres/compressed_row_jacobian_writer.cc | 201 +++++ .../ceres/compressed_row_jacobian_writer.h | 75 ++ .../ceres/compressed_row_sparse_matrix.cc | 325 ++++++++ .../ceres/compressed_row_sparse_matrix.h | 129 ++++ .../ceres/conditioned_cost_function.cc | 130 ++++ .../ceres/conjugate_gradients_solver.cc | 233 ++++++ .../ceres/conjugate_gradients_solver.h | 74 ++ .../ceres/internal/ceres/corrector.cc | 125 ++++ .../ceres/internal/ceres/corrector.h | 88 +++ .../internal/ceres/dense_jacobian_writer.h | 110 +++ .../ceres/internal/ceres/dense_qr_solver.cc | 93 +++ .../ceres/internal/ceres/dense_qr_solver.h | 99 +++ .../internal/ceres/dense_sparse_matrix.cc | 184 +++++ .../internal/ceres/dense_sparse_matrix.h | 115 +++ .../ceres/internal/ceres/detect_structure.cc | 114 +++ .../ceres/internal/ceres/detect_structure.h | 63 ++ .../ceres/internal/ceres/evaluator.cc | 71 ++ .../ceres/internal/ceres/evaluator.h | 129 ++++ .../third_party/ceres/internal/ceres/file.cc | 93 +++ .../third_party/ceres/internal/ceres/file.h | 52 ++ .../ceres/generated/schur_eliminator_2_2_2.cc | 53 ++ .../ceres/generated/schur_eliminator_2_2_3.cc | 53 ++ .../ceres/generated/schur_eliminator_2_2_4.cc | 53 ++ .../ceres/generated/schur_eliminator_2_2_d.cc | 53 ++ .../ceres/generated/schur_eliminator_2_3_3.cc | 53 ++ .../ceres/generated/schur_eliminator_2_3_4.cc | 53 ++ .../ceres/generated/schur_eliminator_2_3_9.cc | 53 ++ .../ceres/generated/schur_eliminator_2_3_d.cc | 53 ++ .../ceres/generated/schur_eliminator_2_4_3.cc | 53 ++ .../ceres/generated/schur_eliminator_2_4_4.cc | 53 ++ .../ceres/generated/schur_eliminator_2_4_d.cc | 53 ++ .../ceres/generated/schur_eliminator_4_4_2.cc | 53 ++ .../ceres/generated/schur_eliminator_4_4_3.cc | 53 ++ .../ceres/generated/schur_eliminator_4_4_4.cc | 53 ++ .../ceres/generated/schur_eliminator_4_4_d.cc | 53 ++ .../ceres/generated/schur_eliminator_d_d_d.cc | 53 ++ .../ceres/gradient_checking_cost_function.cc | 308 ++++++++ .../ceres/gradient_checking_cost_function.h | 85 +++ .../third_party/ceres/internal/ceres/graph.h | 138 ++++ .../ceres/internal/ceres/graph_algorithms.h | 270 +++++++ .../ceres/implicit_schur_complement.cc | 237 ++++++ .../ceres/implicit_schur_complement.h | 176 +++++ .../ceres/internal/ceres/integral_types.h | 92 +++ .../iterative_schur_complement_solver.cc | 150 ++++ .../ceres/iterative_schur_complement_solver.h | 94 +++ .../internal/ceres/levenberg_marquardt.cc | 620 ++++++++++++++++ .../internal/ceres/levenberg_marquardt.h | 65 ++ .../ceres/linear_least_squares_problems.cc | 574 ++++++++++++++ .../ceres/linear_least_squares_problems.h | 77 ++ .../ceres/internal/ceres/linear_operator.cc | 40 + .../ceres/internal/ceres/linear_operator.h | 59 ++ .../ceres/internal/ceres/linear_solver.cc | 87 +++ .../ceres/internal/ceres/linear_solver.h | 291 ++++++++ .../internal/ceres/local_parameterization.cc | 140 ++++ .../ceres/internal/ceres/loss_function.cc | 93 +++ .../ceres/internal/ceres/map_util.h | 129 ++++ .../ceres/internal/ceres/matrix_proto.h | 40 + .../ceres/internal/ceres/minimizer.h | 102 +++ .../third_party/ceres/internal/ceres/mutex.h | 312 ++++++++ .../ceres/internal/ceres/normal_prior.cc | 67 ++ .../ceres/internal/ceres/parameter_block.h | 256 +++++++ .../internal/ceres/partitioned_matrix_view.cc | 315 ++++++++ .../internal/ceres/partitioned_matrix_view.h | 121 +++ .../ceres/internal/ceres/problem.cc | 149 ++++ .../ceres/internal/ceres/problem_impl.cc | 359 +++++++++ .../ceres/internal/ceres/problem_impl.h | 127 ++++ .../ceres/internal/ceres/program.cc | 233 ++++++ .../ceres/internal/ceres/program.h | 128 ++++ .../ceres/internal/ceres/program_evaluator.h | 279 +++++++ .../third_party/ceres/internal/ceres/random.h | 47 ++ .../ceres/internal/ceres/residual_block.cc | 212 ++++++ .../ceres/internal/ceres/residual_block.h | 124 ++++ .../internal/ceres/residual_block_utils.cc | 185 +++++ .../internal/ceres/residual_block_utils.h | 89 +++ .../runtime_numeric_diff_cost_function.cc | 218 ++++++ .../runtime_numeric_diff_cost_function.h | 87 +++ .../internal/ceres/schur_complement_solver.cc | 285 +++++++ .../internal/ceres/schur_complement_solver.h | 182 +++++ .../ceres/internal/ceres/schur_eliminator.cc | 141 ++++ .../ceres/internal/ceres/schur_eliminator.h | 339 +++++++++ .../internal/ceres/schur_eliminator_impl.h | 702 ++++++++++++++++++ .../ceres/internal/ceres/schur_ordering.cc | 113 +++ .../ceres/internal/ceres/schur_ordering.h | 74 ++ .../ceres/scratch_evaluate_preparer.cc | 78 ++ .../ceres/scratch_evaluate_preparer.h | 69 ++ .../ceres/internal/ceres/solver.cc | 230 ++++++ .../ceres/internal/ceres/solver_impl.cc | 693 +++++++++++++++++ .../ceres/internal/ceres/solver_impl.h | 111 +++ .../ceres/internal/ceres/sparse_matrix.cc | 40 + .../ceres/internal/ceres/sparse_matrix.h | 108 +++ .../ceres/sparse_normal_cholesky_solver.cc | 129 ++++ .../ceres/sparse_normal_cholesky_solver.h | 77 ++ .../third_party/ceres/internal/ceres/split.cc | 115 +++ .../ceres/internal/ceres/stl_util.h | 75 ++ .../ceres/internal/ceres/stringprintf.cc | 126 ++++ .../ceres/internal/ceres/stringprintf.h | 89 +++ .../ceres/internal/ceres/suitesparse.cc | 193 +++++ .../ceres/internal/ceres/suitesparse.h | 159 ++++ .../internal/ceres/triplet_sparse_matrix.cc | 299 ++++++++ .../internal/ceres/triplet_sparse_matrix.h | 136 ++++ .../third_party/ceres/internal/ceres/types.cc | 98 +++ .../ceres/internal/ceres/visibility.cc | 150 ++++ .../ceres/internal/ceres/visibility.h | 77 ++ .../ceres/visibility_based_preconditioner.cc | 611 +++++++++++++++ .../ceres/visibility_based_preconditioner.h | 273 +++++++ extern/libmv/third_party/ceres/mkfiles.sh | 4 + extern/libmv/third_party/ceres/patches/series | 1 + source/blenderplayer/CMakeLists.txt | 1 + source/creator/CMakeLists.txt | 1 + 170 files changed, 25035 insertions(+), 37 deletions(-) create mode 100644 extern/libmv/third_party/CMakeLists.txt create mode 100644 extern/libmv/third_party/SConscript create mode 100644 extern/libmv/third_party/ceres/CMakeLists.txt create mode 100644 extern/libmv/third_party/ceres/ChangeLog create mode 100644 extern/libmv/third_party/ceres/LICENSE create mode 100644 extern/libmv/third_party/ceres/README create mode 100644 extern/libmv/third_party/ceres/SConscript create mode 100755 extern/libmv/third_party/ceres/bundle.sh create mode 100644 extern/libmv/third_party/ceres/files.txt create mode 100644 extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/ceres.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/cost_function.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/internal/eigen.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/internal/macros.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/internal/port.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/iteration_callback.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/jet.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/local_parameterization.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/loss_function.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/normal_prior.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/problem.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/rotation.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/solver.h create mode 100644 extern/libmv/third_party/ceres/include/ceres/types.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_evaluate_preparer.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_evaluate_preparer.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_jacobian_writer.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_jacobian_writer.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_random_access_matrix.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_random_access_matrix.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_structure.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/block_structure.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/casts.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/cgnr_linear_operator.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/collections_port.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/conditioned_cost_function.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/corrector.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/corrector.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/dense_jacobian_writer.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/detect_structure.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/detect_structure.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/evaluator.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/evaluator.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/file.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/file.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_2.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_3.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_4.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_d.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_3.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_4.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_9.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_d.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_3.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_4.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_d.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_2.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_3.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_4.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_d.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_d_d_d.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/graph.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/implicit_schur_complement.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/implicit_schur_complement.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/integral_types.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/linear_operator.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/linear_operator.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/linear_solver.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/linear_solver.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/local_parameterization.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/loss_function.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/map_util.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/matrix_proto.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/minimizer.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/mutex.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/normal_prior.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/parameter_block.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/problem.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/problem_impl.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/program.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/program.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/random.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/residual_block.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/residual_block.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/runtime_numeric_diff_cost_function.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/runtime_numeric_diff_cost_function.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/schur_ordering.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/schur_ordering.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/scratch_evaluate_preparer.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/scratch_evaluate_preparer.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/solver.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/solver_impl.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/split.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/stl_util.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/stringprintf.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/stringprintf.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/suitesparse.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/types.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/visibility.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/visibility.h create mode 100644 extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc create mode 100644 extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h create mode 100755 extern/libmv/third_party/ceres/mkfiles.sh create mode 100644 extern/libmv/third_party/ceres/patches/series diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt index 6be813883ec..cf0ad1102e0 100644 --- a/extern/libmv/CMakeLists.txt +++ b/extern/libmv/CMakeLists.txt @@ -32,6 +32,7 @@ set(INC third_party/ssba third_party/ldl/Include ../colamd/Include + third_party/ceres/include ) set(INC_SYS @@ -250,3 +251,5 @@ add_definitions( ) blender_add_lib(extern_libmv "${SRC}" "${INC}" "${INC_SYS}") + +add_subdirectory(third_party) diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog index 7248e4c9cd9..02b79c93ec2 100644 --- a/extern/libmv/ChangeLog +++ b/extern/libmv/ChangeLog @@ -1,3 +1,54 @@ +commit b813dbe3f46bbbc7e73ac791d4665622e4fc7ba5 +Author: Sergey Sharybin +Date: Wed May 9 19:01:10 2012 +0600 + + Modal solver: Detect rigid transformation between initial frame and current + instead of detecting it between two neighbour frames. + + This prevents accumulation of error and seems to be working better in footages i've tested. + +commit 9254621c76daaf239ec1f535e197ca792eea97b6 +Author: Sergey Sharybin +Date: Wed May 9 18:57:00 2012 +0600 + + Backport changes made by Keir in Blender: + + - Enhance logging in libmv's trackers. + - Cleanups in brute_region_tracker.cc. + +commit d9c56b9d3c63f886d83129ca0ebed1e76d9c93d7 +Author: Sergey Sharybin +Date: Fri Apr 27 16:20:41 2012 +0600 + + Fixes for MinGW64 support by Caleb Joseph with slight modifications by Antony Riakiotakis + + - Functions snprintf and sincos shouldn't be redefined for MinGW64 + - Type pid_t shouldn't be re-defined for MinGW64 + +commit e1902b6938676011607ac99986b8b140bdbf090e +Author: Sergey Sharybin +Date: Fri Apr 27 16:04:19 2012 +0600 + + Fixes for Qt calibration tool + + - Passing directory with images via command line argument now isn't + required -- it there's no such directory specified standard open + dialog might be used for this (before application used to abort + due to accessing to non-existing list element). + - Conversion of source images to grayscale now happens correct. + It was needed to build grayscale palette for 8bit indexed buffer. + +commit 05f1a0a78ad8ff6646d1e8da97e6f7575b891536 +Author: Sergey Sharybin +Date: Sat Apr 14 17:21:29 2012 +0600 + + Make QtTracker compilable again porting it to recent API change and code cleanup: + + - It was using SAD tracker with own API, now it's using standard RegionTracker API + which should make it easier to switch between different trackers. + - Restored LaplaceFilter from old SAD module which convolves images with the + discrete laplacian operator. + commit a44312a7beb2963b8e3bf8015c516d2eff40cc3d Author: Sergey Sharybin Date: Thu Apr 12 13:56:02 2012 +0600 @@ -503,33 +554,3 @@ Author: Matthias Fauconneau Date: Fri Aug 19 18:37:48 2011 +0200 Fix CMake build. - -commit 2ac7281ff6b9545b425dd84fb03bf9c5c98b4de2 -Author: Matthias Fauconneau -Date: Fri Aug 19 17:34:45 2011 +0200 - - Avoid symbol shadowing. - -commit 2a7c3de4acc60e0433b4952f69e30528dbafe0d2 -Author: Matthias Fauconneau -Date: Fri Aug 19 17:22:47 2011 +0200 - - Better dragging behavior when hitting borders. - -commit a14eb3953c9521b2e08ff9ddd45b33ff1f8aeafb -Author: Matthias Fauconneau -Date: Fri Aug 19 17:12:12 2011 +0200 - - Update marker preview to new affine tracking. - -commit 5299ea67043459eda147950e589c2d327a8fbced -Author: Matthias Fauconneau -Date: Fri Aug 19 16:05:54 2011 +0200 - - sqrt takes double precision. - -commit 9f9221ce151d788c49b48f6f293ab2e2f8813978 -Author: Matthias Fauconneau -Date: Fri Aug 19 16:04:37 2011 +0200 - - MSVC compatibility: heap allocate pattern, explicit float cast. diff --git a/extern/libmv/SConscript b/extern/libmv/SConscript index fbb6ee36f85..b47086f3e91 100644 --- a/extern/libmv/SConscript +++ b/extern/libmv/SConscript @@ -30,7 +30,7 @@ src += env.Glob('third_party/ldl/Source/*.c') src += env.Glob('third_party/ssba/Geometry/*.cpp') src += env.Glob('third_party/ssba/Math/*.cpp') -incs = '. ../Eigen3' +incs = '. ../Eigen3 third_party/ceres/include' incs += ' ' + env['BF_PNG_INC'] incs += ' ' + env['BF_ZLIB_INC'] @@ -65,3 +65,5 @@ else: incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include' env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv ) + +SConscript(['third_party/SConscript']) diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh index 30d08cd680a..9baad88a7e2 100755 --- a/extern/libmv/bundle.sh +++ b/extern/libmv/bundle.sh @@ -23,7 +23,7 @@ for p in `cat ./patches/series`; do done rm -rf libmv -rm -rf third_party +rm -rf `find third_party/ -mindepth 1 -maxdepth 1 | grep -v ceres | grep -v CMake | grep -c SCons` cat "files.txt" | while read f; do mkdir -p `dirname $f` @@ -37,14 +37,14 @@ chmod 664 ./third_party/glog/src/windows/*.cc ./third_party/glog/src/windows/*.h sources=`find ./libmv -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | sort -d` headers=`find ./libmv -type f -iname '*.h' | sed -r 's/^\.\//\t/' | sort -d` -third_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep -v glog | sed -r 's/^\.\//\t/' | sort -d` -third_headers=`find ./third_party -type f -iname '*.h' | grep -v glog | sed -r 's/^\.\//\t/' | sort -d` +third_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep -v glog | grep -v ceres | sed -r 's/^\.\//\t/' | sort -d` +third_headers=`find ./third_party -type f -iname '*.h' | grep -v glog | grep -v ceres | sed -r 's/^\.\//\t/' | sort -d` third_glog_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/' | sort -d` third_glog_headers=`find ./third_party -type f -iname '*.h' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/' | sort -d` src_dir=`find ./libmv -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort -d | uniq` -src_third_dir=`find ./third_party -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort -d | uniq` +src_third_dir=`find ./third_party -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | grep -v ceres | sed -r 's/^\.\//\t/' | sort -d | uniq` src="" win_src="" for x in $src_dir $src_third_dir; do @@ -124,6 +124,7 @@ set(INC third_party/ssba third_party/ldl/Include ../colamd/Include + third_party/ceres/include ) set(INC_SYS @@ -218,6 +219,8 @@ add_definitions( ) blender_add_lib(extern_libmv "\${SRC}" "\${INC}" "\${INC_SYS}") + +add_subdirectory(third_party) EOF cat > SConscript << EOF @@ -244,7 +247,7 @@ defs.append('GOOGLE_GLOG_DLL_DECL=') src = env.Glob("*.cpp") $src -incs = '. ../Eigen3' +incs = '. ../Eigen3 third_party/ceres/include' incs += ' ' + env['BF_PNG_INC'] incs += ' ' + env['BF_ZLIB_INC'] @@ -279,4 +282,6 @@ else: incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include' env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv ) + +SConscript(['third_party/SConscript']) EOF diff --git a/extern/libmv/libmv/image/convolve.cc b/extern/libmv/libmv/image/convolve.cc index be73a1a3263..63ff7d6d8ff 100644 --- a/extern/libmv/libmv/image/convolve.cc +++ b/extern/libmv/libmv/image/convolve.cc @@ -302,4 +302,18 @@ void BoxFilter(const Array3Df &in, BoxFilterVertical(tmp, box_width, out); } +void LaplaceFilter(unsigned char* src, unsigned char* dst, int width, int height, int strength) { + for(int y=1; y 255) d=255; + dst[y*width+x] = d; + } +} + } // namespace libmv diff --git a/extern/libmv/libmv/image/convolve.h b/extern/libmv/libmv/image/convolve.h index c6c995fd674..a005dc31f10 100644 --- a/extern/libmv/libmv/image/convolve.h +++ b/extern/libmv/libmv/image/convolve.h @@ -87,6 +87,16 @@ void BoxFilter(const FloatImage &in, int box_width, FloatImage *out); +/*! + Convolve \a src into \a dst with the discrete laplacian operator. + + \a src and \a dst should be \a width x \a height images. + \a strength is an interpolation coefficient (0-256) between original image and the laplacian. + + \note Make sure the search region is filtered with the same strength as the pattern. +*/ +void LaplaceFilter(unsigned char* src, unsigned char* dst, int width, int height, int strength); + } // namespace libmv #endif // LIBMV_IMAGE_CONVOLVE_H_ diff --git a/extern/libmv/mkfiles.sh b/extern/libmv/mkfiles.sh index fe84c357de4..c7c8c33f725 100755 --- a/extern/libmv/mkfiles.sh +++ b/extern/libmv/mkfiles.sh @@ -1,4 +1,4 @@ #!/bin/sh find ./libmv/ -type f | sed -r 's/^\.\///' | sort > files.txt -find ./third_party/ -type f | sed -r 's/^\.\///' | sort >> files.txt +find ./third_party/ -mindepth 2 -type f | grep -v third_party/ceres | sed -r 's/^\.\///' | sort >> files.txt diff --git a/extern/libmv/third_party/CMakeLists.txt b/extern/libmv/third_party/CMakeLists.txt new file mode 100644 index 00000000000..6212fe480b1 --- /dev/null +++ b/extern/libmv/third_party/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_subdirectory(ceres) diff --git a/extern/libmv/third_party/SConscript b/extern/libmv/third_party/SConscript new file mode 100644 index 00000000000..b05692e385f --- /dev/null +++ b/extern/libmv/third_party/SConscript @@ -0,0 +1,3 @@ +#!/usr/bin/python + +SConscript(['ceres/SConscript']) diff --git a/extern/libmv/third_party/ceres/CMakeLists.txt b/extern/libmv/third_party/ceres/CMakeLists.txt new file mode 100644 index 00000000000..19158dcfebb --- /dev/null +++ b/extern/libmv/third_party/ceres/CMakeLists.txt @@ -0,0 +1,218 @@ +# ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2012, Blender Foundation +# All rights reserved. +# +# Contributor(s): Blender Foundation, +# Sergey Sharybin +# +# ***** END GPL LICENSE BLOCK ***** + +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + +set(INC + . + ../../../Eigen3 + include + internal + ../gflags +) + +set(INC_SYS +) + +set(SRC + internal/ceres/block_evaluate_preparer.cc + internal/ceres/block_jacobian_writer.cc + internal/ceres/block_jacobi_preconditioner.cc + internal/ceres/block_random_access_dense_matrix.cc + internal/ceres/block_random_access_matrix.cc + internal/ceres/block_random_access_sparse_matrix.cc + internal/ceres/block_sparse_matrix.cc + internal/ceres/block_structure.cc + internal/ceres/canonical_views_clustering.cc + internal/ceres/cgnr_solver.cc + internal/ceres/compressed_row_jacobian_writer.cc + internal/ceres/compressed_row_sparse_matrix.cc + internal/ceres/conditioned_cost_function.cc + internal/ceres/conjugate_gradients_solver.cc + internal/ceres/corrector.cc + internal/ceres/dense_qr_solver.cc + internal/ceres/dense_sparse_matrix.cc + internal/ceres/detect_structure.cc + internal/ceres/evaluator.cc + internal/ceres/file.cc + internal/ceres/generated/schur_eliminator_2_2_2.cc + internal/ceres/generated/schur_eliminator_2_2_3.cc + internal/ceres/generated/schur_eliminator_2_2_4.cc + internal/ceres/generated/schur_eliminator_2_2_d.cc + internal/ceres/generated/schur_eliminator_2_3_3.cc + internal/ceres/generated/schur_eliminator_2_3_4.cc + internal/ceres/generated/schur_eliminator_2_3_9.cc + internal/ceres/generated/schur_eliminator_2_3_d.cc + internal/ceres/generated/schur_eliminator_2_4_3.cc + internal/ceres/generated/schur_eliminator_2_4_4.cc + internal/ceres/generated/schur_eliminator_2_4_d.cc + internal/ceres/generated/schur_eliminator_4_4_2.cc + internal/ceres/generated/schur_eliminator_4_4_3.cc + internal/ceres/generated/schur_eliminator_4_4_4.cc + internal/ceres/generated/schur_eliminator_4_4_d.cc + internal/ceres/generated/schur_eliminator_d_d_d.cc + internal/ceres/gradient_checking_cost_function.cc + internal/ceres/implicit_schur_complement.cc + internal/ceres/iterative_schur_complement_solver.cc + internal/ceres/levenberg_marquardt.cc + internal/ceres/linear_least_squares_problems.cc + internal/ceres/linear_operator.cc + internal/ceres/linear_solver.cc + internal/ceres/local_parameterization.cc + internal/ceres/loss_function.cc + internal/ceres/normal_prior.cc + internal/ceres/partitioned_matrix_view.cc + internal/ceres/problem.cc + internal/ceres/problem_impl.cc + internal/ceres/program.cc + internal/ceres/residual_block.cc + internal/ceres/residual_block_utils.cc + internal/ceres/runtime_numeric_diff_cost_function.cc + internal/ceres/schur_complement_solver.cc + internal/ceres/schur_eliminator.cc + internal/ceres/schur_ordering.cc + internal/ceres/scratch_evaluate_preparer.cc + internal/ceres/solver.cc + internal/ceres/solver_impl.cc + internal/ceres/sparse_matrix.cc + internal/ceres/sparse_normal_cholesky_solver.cc + internal/ceres/split.cc + internal/ceres/stringprintf.cc + internal/ceres/suitesparse.cc + internal/ceres/triplet_sparse_matrix.cc + internal/ceres/types.cc + internal/ceres/visibility_based_preconditioner.cc + internal/ceres/visibility.cc + + include/ceres/autodiff_cost_function.h + include/ceres/ceres.h + include/ceres/conditioned_cost_function.h + include/ceres/cost_function.h + include/ceres/internal/autodiff.h + include/ceres/internal/eigen.h + include/ceres/internal/fixed_array.h + include/ceres/internal/macros.h + include/ceres/internal/manual_constructor.h + include/ceres/internal/port.h + include/ceres/internal/scoped_ptr.h + include/ceres/iteration_callback.h + include/ceres/jet.h + include/ceres/local_parameterization.h + include/ceres/loss_function.h + include/ceres/normal_prior.h + include/ceres/numeric_diff_cost_function.h + include/ceres/problem.h + include/ceres/rotation.h + include/ceres/sized_cost_function.h + include/ceres/solver.h + include/ceres/types.h + internal/ceres/block_evaluate_preparer.h + internal/ceres/block_jacobian_writer.h + internal/ceres/block_jacobi_preconditioner.h + internal/ceres/block_random_access_dense_matrix.h + internal/ceres/block_random_access_matrix.h + internal/ceres/block_random_access_sparse_matrix.h + internal/ceres/block_sparse_matrix.h + internal/ceres/block_structure.h + internal/ceres/canonical_views_clustering.h + internal/ceres/casts.h + internal/ceres/cgnr_linear_operator.h + internal/ceres/cgnr_solver.h + internal/ceres/collections_port.h + internal/ceres/compressed_row_jacobian_writer.h + internal/ceres/compressed_row_sparse_matrix.h + internal/ceres/conjugate_gradients_solver.h + internal/ceres/corrector.h + internal/ceres/dense_jacobian_writer.h + internal/ceres/dense_qr_solver.h + internal/ceres/dense_sparse_matrix.h + internal/ceres/detect_structure.h + internal/ceres/evaluator.h + internal/ceres/file.h + internal/ceres/gradient_checking_cost_function.h + internal/ceres/graph_algorithms.h + internal/ceres/graph.h + internal/ceres/implicit_schur_complement.h + internal/ceres/integral_types.h + internal/ceres/iterative_schur_complement_solver.h + internal/ceres/levenberg_marquardt.h + internal/ceres/linear_least_squares_problems.h + internal/ceres/linear_operator.h + internal/ceres/linear_solver.h + internal/ceres/map_util.h + internal/ceres/matrix_proto.h + internal/ceres/minimizer.h + internal/ceres/mutex.h + internal/ceres/parameter_block.h + internal/ceres/partitioned_matrix_view.h + internal/ceres/problem_impl.h + internal/ceres/program_evaluator.h + internal/ceres/program.h + internal/ceres/random.h + internal/ceres/residual_block.h + internal/ceres/residual_block_utils.h + internal/ceres/runtime_numeric_diff_cost_function.h + internal/ceres/schur_complement_solver.h + internal/ceres/schur_eliminator.h + internal/ceres/schur_eliminator_impl.h + internal/ceres/schur_ordering.h + internal/ceres/scratch_evaluate_preparer.h + internal/ceres/solver_impl.h + internal/ceres/sparse_matrix.h + internal/ceres/sparse_normal_cholesky_solver.h + internal/ceres/stl_util.h + internal/ceres/stringprintf.h + internal/ceres/suitesparse.h + internal/ceres/triplet_sparse_matrix.h + internal/ceres/visibility_based_preconditioner.h + internal/ceres/visibility.h +) + +if(WIN32) + list(APPEND INC + ../glog/src/windows + ) + + if(NOT MINGW) + list(APPEND INC + third_party/msinttypes + ) + endif() +else() + list(APPEND INC + ../glog/src + ) +endif() + +add_definitions( + -DCERES_HAVE_PTHREAD + -D"CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {" + -D"CERES_HASH_NAMESPACE_END=}}" + -DCERES_NO_SUITESPARSE + -DCERES_DONT_HAVE_PROTOCOL_BUFFERS +) + +blender_add_lib(extern_ceres "${SRC}" "${INC}" "${INC_SYS}") diff --git a/extern/libmv/third_party/ceres/ChangeLog b/extern/libmv/third_party/ceres/ChangeLog new file mode 100644 index 00000000000..c652a73c0c1 --- /dev/null +++ b/extern/libmv/third_party/ceres/ChangeLog @@ -0,0 +1,227 @@ +commit d297f8d3d3f5025c24752f0f4c1ec2469a769f99 +Merge: 7e74d81 f8bd7fa +Author: Keir Mierle +Date: Tue May 8 05:39:56 2012 -0700 + + Merge branch 'master' into windows + +commit f8bd7fa9aa9dbf64b6165606630287cf8cf21194 +Author: Keir Mierle +Date: Tue May 8 05:39:32 2012 -0700 + + Small tweaks to the block jacobi preconditioner. + +commit 7e74d81ad57a159f14110eb5348b3bc7990b8bd4 +Merge: ecd7c8d e2a6cdc +Author: Keir Mierle +Date: Mon May 7 07:02:49 2012 -0700 + + Merge branch 'master' into windows + +commit e2a6cdc0816af9d0c77933f5017f137da3d52a35 +Author: Keir Mierle +Date: Mon May 7 06:39:56 2012 -0700 + + Address some of the comments on CGNR patch + + - Rename BlockDiagonalPreconditioner to BlockJacobiPreconditioner + - Include the diagonal in the block jacobi preconditioner. + - Better flag help for eta. + - Enable test for CGNR + - Rename CONJUGATE_GRADIENTS to CGNR. + - etc. + +commit 1b95dc580aa5d89be021c0915e26df83f18013bb +Merge: 211812a 7646039 +Author: Keir Mierle +Date: Mon May 7 04:34:10 2012 -0700 + + Merge branch 'master' of https://code.google.com/p/ceres-solver + +commit 211812a57360d2011cbcfd115cd55e0eb73600db +Author: Keir Mierle +Date: Mon May 7 04:33:50 2012 -0700 + + Better error handling in bundle_adjuster.cc + +commit 7646039ad9672b267495f5b31925473ad3022ac8 +Author: Sameer Agarwal +Date: Sun May 6 22:02:19 2012 -0700 + + Kashif's corrections to the docs + +commit 0d2d34148d10c5c7e924b3ca82ad2b237573ef64 +Author: Sameer Agarwal +Date: Sun May 6 21:16:03 2012 -0700 + + glog minimum version requirements + + Building Ceres requires version 0.3.1 or better of glog. + Fedora 16 ships with a busted version 0.3. + + issue 15 contains the gory details. + + Added a note to the build documentation to this effect. + +commit 39efc5ec4b64b8f5a2c5a3dbacdbc45421221547 +Author: Keir Mierle +Date: Sun May 6 16:09:52 2012 -0700 + + Fix tests broken by the CGNR change. + +commit 3faa08b7f7c4ac73661c6a15a6824c12080dfcb1 +Author: Sameer Agarwal +Date: Sun May 6 16:08:22 2012 -0700 + + Formatting fixed based on Keir's comments and extended the tests + +commit 4f21c68409bc478c431a9b6aedf9e5cfdf11d2f3 +Author: Sameer Agarwal +Date: Sun May 6 15:33:47 2012 -0700 + + Fix the struct weak ordering used by independent set ordering, tests for it + +commit 887b156b917ccd4c172484452b059d33ea45f4f0 +Author: Sameer Agarwal +Date: Sun May 6 15:14:47 2012 -0700 + + fix he degree ordering routine + +commit ecd7c8df2af19404dc394b36bbe96e9db3bce840 +Author: Keir Mierle +Date: Sun May 6 00:09:41 2012 -0700 + + First step towards windows compatibilty + + This adds some small changes to Ceres to make it mostly + compile on Windows. There are still issues with the + hash map use in schur_ordering.cc but I will fix those + shortly. + +commit f7898fba1b92f0e996571b5bfa22a37f5e3644de +Author: Keir Mierle +Date: Sat May 5 20:55:08 2012 -0700 + + Add a general sparse iterative solver: CGNR + + This adds a new LinearOperator which implements symmetric + products of a matrix, and a new CGNR solver to leverage + CG to directly solve the normal equations. This also + includes a block diagonal preconditioner. In experiments + on problem-16, the non-preconditioned version is about + 1/5 the speed of SPARSE_SCHUR, and the preconditioned + version using block cholesky is about 20% slower than + SPARSE_SCHUR. + +commit 0a359d6198d257776a8831c3eb98f64ee91cf836 +Author: Keir Mierle +Date: Sat May 5 20:33:46 2012 -0700 + + Comment formatting. + +commit db4ec9312bb2f1ca7b2337812f6bad6cdd75b227 +Author: Keir Mierle +Date: Sat May 5 20:33:16 2012 -0700 + + Comment formatting + +commit f10163aaf3e57f52551bcd60bbdae873890a49dd +Author: Keir Mierle +Date: Fri May 4 21:33:53 2012 -0700 + + Warn about disabled schur specializations. + + This commit brought to you from 30,000ft. + +commit ad7b2b4aaf3ccc51f2b854febd53a9df54686cfe +Author: Keir Mierle +Date: Fri May 4 20:15:28 2012 -0700 + + Add vim swapfiles to .gitignore + +commit 6447219826bf6e47b0c99d9ff0eaf5e2ba573d79 +Author: Sameer Agarwal +Date: Thu May 3 21:53:07 2012 -0700 + + 1. Changes the tutorial to refer to BriefReport. + 2. Some of the enums have commas at the end. + 3. Fix a bug in the default value of circle_fit.cc in the examples. + +commit 30c5f93c7f88dec49f76168663372772e06f17f5 +Author: Sameer Agarwal +Date: Thu May 3 10:44:43 2012 -0700 + + Rework the glog and gtest path checking to be consistent with the rest of the file and disable the dashboard support enabled by the earlier ctesting related patch. + +commit f10b033eb4aca77919987bc551d16d8a88b10110 +Merge: cc38774 e0a52a9 +Author: Sameer Agarwal +Date: Thu May 3 08:45:20 2012 -0700 + + Merge branch 'ctest' + +commit e0a52a993394e73bc7f7db8d520728926feab83e +Author: Sameer Agarwal +Date: Thu May 3 08:43:34 2012 -0700 + + Arnaus Gelas' patch to add better path searching for gflags and glog + +commit a9b8e815e1c026599734510399b10f4cf014c9cd +Author: Sameer Agarwal +Date: Thu May 3 08:41:52 2012 -0700 + + Arnaus Gelas' patch to add .gitignore + +commit a0cefc3347c32b2065053bbaff4f34d11529d931 +Author: Sameer Agarwal +Date: Thu May 3 08:38:33 2012 -0700 + + Arnaus Gelas' patch to move to Ctest + +commit cc38774d74e287704915282425fbd16818a72ec3 +Author: Keir Mierle +Date: Thu May 3 01:27:50 2012 -0700 + + Clarify ProgramEvaluator comments. + +commit 017c9530df557863f78212fb5ccd02814baa9fa8 +Author: Sameer Agarwal +Date: Wed May 2 08:21:59 2012 -0700 + + Mac OS X build instructions are much simpler, as homebrew takes care of gflags when glog is brought in. Also CMAKE does not need any flags to do the default thing + +commit 92d5ab5f8ae6fe355c30b606a5f230415ee0494b +Author: Keir Mierle +Date: Tue May 1 18:33:08 2012 -0700 + + Link BLAS explicitly on non-Mac platforms + + Fixes issue #3. + +commit df3e54eb4a6b001b7f0560a2da73a5bd7f18615e +Author: Keir Mierle +Date: Tue May 1 18:22:51 2012 -0700 + + Fix link order of CHOLMOD + + This was working by accident due to dynamic linking. Fixes issue #2. + +commit f477a3835329e2b48eb20c34c631a480b0f0d5bf +Author: Keir Mierle +Date: Tue May 1 18:10:48 2012 -0700 + + Fix Eigen search paths + + Fixes issue #1 on http://code.google.com/p/ceres-solver. + +commit 17fbc8ebb894c1d22bb3b0b02ea1394b580120f8 +Author: Sameer Agarwal +Date: Tue May 1 00:21:19 2012 -0700 + + Minor changes to the documentation. Formatting, and typos. + +commit 8ebb0730388045570f22b89fe8672c860cd2ad1b +Author: Keir Mierle +Date: Mon Apr 30 23:09:08 2012 -0700 + + Initial commit of Ceres Solver. diff --git a/extern/libmv/third_party/ceres/LICENSE b/extern/libmv/third_party/ceres/LICENSE new file mode 100644 index 00000000000..2e3ead5ed45 --- /dev/null +++ b/extern/libmv/third_party/ceres/LICENSE @@ -0,0 +1,27 @@ +Ceres Solver - A fast non-linear least squares minimizer +Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +http://code.google.com/p/ceres-solver/ + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of Google Inc. nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/extern/libmv/third_party/ceres/README b/extern/libmv/third_party/ceres/README new file mode 100644 index 00000000000..8dd8ccf91a1 --- /dev/null +++ b/extern/libmv/third_party/ceres/README @@ -0,0 +1,3 @@ +Ceres Solver - A non-linear least squares minimizer +================================================== +Please see ceres.pdf in docs/ for a tutorial and reference. diff --git a/extern/libmv/third_party/ceres/SConscript b/extern/libmv/third_party/ceres/SConscript new file mode 100644 index 00000000000..d8b2b8520d7 --- /dev/null +++ b/extern/libmv/third_party/ceres/SConscript @@ -0,0 +1,34 @@ +#!/usr/bin/python + +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + +import sys +import os + +Import('env') + +src = [] +defs = [] + +src += env.Glob('internal/ceres/*.cc') +src += env.Glob('internal/ceres/generated/*.cc') + +defs.append('CERES_HAVE_PTHREAD') +defs.append('CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {') +defs.append('CERES_HASH_NAMESPACE_END=}}') +defs.append('CERES_NO_SUITESPARSE') +defs.append('CERES_DONT_HAVE_PROTOCOL_BUFFERS') + +incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'): + if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): + incs += ' ../msinttypes' + + incs += ' ../glog/src/windows' +else: + incs += ' ../glog/src' + +env.BlenderLib ( libname = 'extern_ceres', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137]) diff --git a/extern/libmv/third_party/ceres/bundle.sh b/extern/libmv/third_party/ceres/bundle.sh new file mode 100755 index 00000000000..d7602f7c171 --- /dev/null +++ b/extern/libmv/third_party/ceres/bundle.sh @@ -0,0 +1,183 @@ +#!/bin/sh + +if [ -d ./.svn ]; then + echo "This script is supposed to work only when using git-svn" + exit 1 +fi + +repo="https://code.google.com/p/ceres-solver/" +branch="windows" +tmp=`mktemp -d` + +GIT="git --git-dir $tmp/ceres/.git --work-tree $tmp/ceres" + +git clone $repo $tmp/ceres + +if [ $branch != "master" ]; then + $GIT checkout -t remotes/origin/$branch +fi + +$GIT log -n 50 > ChangeLog + +for p in `cat ./patches/series`; do + echo "Applying patch $p..." + cat ./patches/$p | patch -d $tmp/ceres -p1 +done + +rm -rf include +rm -rf internal + +cat "files.txt" | while read f; do + mkdir -p `dirname $f` + cp $tmp/ceres/$f $f +done + +rm -rf $tmp + +sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | sort -d` +headers=`find ./include ./internal -type f -iname '*.h' | sed -r 's/^\.\//\t/' | sort -d` + +src_dir=`find ./internal -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort -d | uniq` +src="" +for x in $src_dir $src_third_dir; do + t="" + + if test `echo "$x" | grep -c glog ` -eq 1; then + continue; + fi + + if stat $x/*.cpp > /dev/null 2>&1; then + t="src += env.Glob('`echo $x'/*.cpp'`')" + fi + + if stat $x/*.c > /dev/null 2>&1; then + if [ -z "$t" ]; then + t="src += env.Glob('`echo $x'/*.c'`')" + else + t="$t + env.Glob('`echo $x'/*.c'`')" + fi + fi + + if stat $x/*.cc > /dev/null 2>&1; then + if [ -z "$t" ]; then + t="src += env.Glob('`echo $x'/*.cc'`')" + else + t="$t + env.Glob('`echo $x'/*.cc'`')" + fi + fi + + if [ -z "$src" ]; then + src=$t + else + src=`echo "$src\n$t"` + fi +done + +cat > CMakeLists.txt << EOF +# ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2012, Blender Foundation +# All rights reserved. +# +# Contributor(s): Blender Foundation, +# Sergey Sharybin +# +# ***** END GPL LICENSE BLOCK ***** + +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + +set(INC + . + ../../../Eigen3 + include + internal + ../gflags +) + +set(INC_SYS +) + +set(SRC +${sources} + +${headers} +) + +if(WIN32) + list(APPEND INC + ../glog/src/windows + ) + + if(NOT MINGW) + list(APPEND INC + third_party/msinttypes + ) + endif() +else() + list(APPEND INC + ../glog/src + ) +endif() + +add_definitions( + -DCERES_HAVE_PTHREAD + -D"CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {" + -D"CERES_HASH_NAMESPACE_END=}}" + -DCERES_NO_SUITESPARSE + -DCERES_DONT_HAVE_PROTOCOL_BUFFERS +) + +blender_add_lib(extern_ceres "\${SRC}" "\${INC}" "\${INC_SYS}") +EOF + +cat > SConscript << EOF +#!/usr/bin/python + +# NOTE: This file is automatically generated by bundle.sh script +# If you're doing changes in this file, please update template +# in that script too + +import sys +import os + +Import('env') + +src = [] +defs = [] + +$src + +defs.append('CERES_HAVE_PTHREAD') +defs.append('CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {') +defs.append('CERES_HASH_NAMESPACE_END=}}') +defs.append('CERES_NO_SUITESPARSE') +defs.append('CERES_DONT_HAVE_PROTOCOL_BUFFERS') + +incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'): + if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): + incs += ' ../msinttypes' + + incs += ' ../glog/src/windows' +else: + incs += ' ../glog/src' + +env.BlenderLib ( libname = 'extern_ceres', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137]) +EOF diff --git a/extern/libmv/third_party/ceres/files.txt b/extern/libmv/third_party/ceres/files.txt new file mode 100644 index 00000000000..e9d7f585260 --- /dev/null +++ b/extern/libmv/third_party/ceres/files.txt @@ -0,0 +1,150 @@ +include/ceres/autodiff_cost_function.h +include/ceres/ceres.h +include/ceres/conditioned_cost_function.h +include/ceres/cost_function.h +include/ceres/internal/autodiff.h +include/ceres/internal/eigen.h +include/ceres/internal/fixed_array.h +include/ceres/internal/macros.h +include/ceres/internal/manual_constructor.h +include/ceres/internal/port.h +include/ceres/internal/scoped_ptr.h +include/ceres/iteration_callback.h +include/ceres/jet.h +include/ceres/local_parameterization.h +include/ceres/loss_function.h +include/ceres/normal_prior.h +include/ceres/numeric_diff_cost_function.h +include/ceres/problem.h +include/ceres/rotation.h +include/ceres/sized_cost_function.h +include/ceres/solver.h +include/ceres/types.h +internal/ceres/block_evaluate_preparer.cc +internal/ceres/block_evaluate_preparer.h +internal/ceres/block_jacobian_writer.cc +internal/ceres/block_jacobian_writer.h +internal/ceres/block_jacobi_preconditioner.cc +internal/ceres/block_jacobi_preconditioner.h +internal/ceres/block_random_access_dense_matrix.cc +internal/ceres/block_random_access_dense_matrix.h +internal/ceres/block_random_access_matrix.cc +internal/ceres/block_random_access_matrix.h +internal/ceres/block_random_access_sparse_matrix.cc +internal/ceres/block_random_access_sparse_matrix.h +internal/ceres/block_sparse_matrix.cc +internal/ceres/block_sparse_matrix.h +internal/ceres/block_structure.cc +internal/ceres/block_structure.h +internal/ceres/canonical_views_clustering.cc +internal/ceres/canonical_views_clustering.h +internal/ceres/casts.h +internal/ceres/cgnr_linear_operator.h +internal/ceres/cgnr_solver.cc +internal/ceres/cgnr_solver.h +internal/ceres/collections_port.h +internal/ceres/compressed_row_jacobian_writer.cc +internal/ceres/compressed_row_jacobian_writer.h +internal/ceres/compressed_row_sparse_matrix.cc +internal/ceres/compressed_row_sparse_matrix.h +internal/ceres/conditioned_cost_function.cc +internal/ceres/conjugate_gradients_solver.cc +internal/ceres/conjugate_gradients_solver.h +internal/ceres/corrector.cc +internal/ceres/corrector.h +internal/ceres/dense_jacobian_writer.h +internal/ceres/dense_qr_solver.cc +internal/ceres/dense_qr_solver.h +internal/ceres/dense_sparse_matrix.cc +internal/ceres/dense_sparse_matrix.h +internal/ceres/detect_structure.cc +internal/ceres/detect_structure.h +internal/ceres/evaluator.cc +internal/ceres/evaluator.h +internal/ceres/file.cc +internal/ceres/file.h +internal/ceres/generated/schur_eliminator_2_2_2.cc +internal/ceres/generated/schur_eliminator_2_2_3.cc +internal/ceres/generated/schur_eliminator_2_2_4.cc +internal/ceres/generated/schur_eliminator_2_2_d.cc +internal/ceres/generated/schur_eliminator_2_3_3.cc +internal/ceres/generated/schur_eliminator_2_3_4.cc +internal/ceres/generated/schur_eliminator_2_3_9.cc +internal/ceres/generated/schur_eliminator_2_3_d.cc +internal/ceres/generated/schur_eliminator_2_4_3.cc +internal/ceres/generated/schur_eliminator_2_4_4.cc +internal/ceres/generated/schur_eliminator_2_4_d.cc +internal/ceres/generated/schur_eliminator_4_4_2.cc +internal/ceres/generated/schur_eliminator_4_4_3.cc +internal/ceres/generated/schur_eliminator_4_4_4.cc +internal/ceres/generated/schur_eliminator_4_4_d.cc +internal/ceres/generated/schur_eliminator_d_d_d.cc +internal/ceres/gradient_checking_cost_function.cc +internal/ceres/gradient_checking_cost_function.h +internal/ceres/graph_algorithms.h +internal/ceres/graph.h +internal/ceres/implicit_schur_complement.cc +internal/ceres/implicit_schur_complement.h +internal/ceres/integral_types.h +internal/ceres/iterative_schur_complement_solver.cc +internal/ceres/iterative_schur_complement_solver.h +internal/ceres/levenberg_marquardt.cc +internal/ceres/levenberg_marquardt.h +internal/ceres/linear_least_squares_problems.cc +internal/ceres/linear_least_squares_problems.h +internal/ceres/linear_operator.cc +internal/ceres/linear_operator.h +internal/ceres/linear_solver.cc +internal/ceres/linear_solver.h +internal/ceres/local_parameterization.cc +internal/ceres/loss_function.cc +internal/ceres/map_util.h +internal/ceres/matrix_proto.h +internal/ceres/minimizer.h +internal/ceres/mutex.h +internal/ceres/normal_prior.cc +internal/ceres/parameter_block.h +internal/ceres/partitioned_matrix_view.cc +internal/ceres/partitioned_matrix_view.h +internal/ceres/problem.cc +internal/ceres/problem_impl.cc +internal/ceres/problem_impl.h +internal/ceres/program.cc +internal/ceres/program_evaluator.h +internal/ceres/program.h +internal/ceres/random.h +internal/ceres/residual_block.cc +internal/ceres/residual_block.h +internal/ceres/residual_block_utils.cc +internal/ceres/residual_block_utils.h +internal/ceres/runtime_numeric_diff_cost_function.cc +internal/ceres/runtime_numeric_diff_cost_function.h +internal/ceres/schur_complement_solver.cc +internal/ceres/schur_complement_solver.h +internal/ceres/schur_eliminator.cc +internal/ceres/schur_eliminator.h +internal/ceres/schur_eliminator_impl.h +internal/ceres/schur_ordering.cc +internal/ceres/schur_ordering.h +internal/ceres/scratch_evaluate_preparer.cc +internal/ceres/scratch_evaluate_preparer.h +internal/ceres/solver.cc +internal/ceres/solver_impl.cc +internal/ceres/solver_impl.h +internal/ceres/sparse_matrix.cc +internal/ceres/sparse_matrix.h +internal/ceres/sparse_normal_cholesky_solver.cc +internal/ceres/sparse_normal_cholesky_solver.h +internal/ceres/split.cc +internal/ceres/stl_util.h +internal/ceres/stringprintf.cc +internal/ceres/stringprintf.h +internal/ceres/suitesparse.cc +internal/ceres/suitesparse.h +internal/ceres/triplet_sparse_matrix.cc +internal/ceres/triplet_sparse_matrix.h +internal/ceres/types.cc +internal/ceres/visibility_based_preconditioner.cc +internal/ceres/visibility_based_preconditioner.h +internal/ceres/visibility.cc +internal/ceres/visibility.h diff --git a/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h new file mode 100644 index 00000000000..0ac6240dfab --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h @@ -0,0 +1,170 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Helpers for making CostFunctions as needed by the least squares framework, +// with Jacobians computed via automatic differentiation. For more information +// on automatic differentation, see the wikipedia article at +// http://en.wikipedia.org/wiki/Automatic_differentiation +// +// To get an auto differentiated cost function, you must define a class with a +// templated operator() (a functor) that computes the cost function in terms of +// the template parameter T. The autodiff framework substitutes appropriate +// "jet" objects for T in order to compute the derivative when necessary, but +// this is hidden, and you should write the function as if T were a scalar type +// (e.g. a double-precision floating point number). +// +// The function must write the computed value in the last argument (the only +// non-const one) and return true to indicate success. +// +// For example, consider a scalar error e = k - x'y, where both x and y are +// two-dimensional column vector parameters, the prime sign indicates +// transposition, and k is a constant. The form of this error, which is the +// difference between a constant and an expression, is a common pattern in least +// squares problems. For example, the value x'y might be the model expectation +// for a series of measurements, where there is an instance of the cost function +// for each measurement k. +// +// The actual cost added to the total problem is e^2, or (k - x'k)^2; however, +// the squaring is implicitly done by the optimization framework. +// +// To write an auto-differentiable cost function for the above model, first +// define the object +// +// class MyScalarCostFunction { +// MyScalarCostFunction(double k): k_(k) {} +// +// template +// bool operator()(const T* const x , const T* const y, T* e) const { +// e[0] = T(k_) - x[0] * y[0] + x[1] * y[1]; +// return true; +// } +// +// private: +// double k_; +// }; +// +// Note that in the declaration of operator() the input parameters x and y come +// first, and are passed as const pointers to arrays of T. If there were three +// input parameters, then the third input parameter would come after y. The +// output is always the last parameter, and is also a pointer to an array. In +// the example above, e is a scalar, so only e[0] is set. +// +// Then given this class definition, the auto differentiated cost function for +// it can be constructed as follows. +// +// CostFunction* cost_function +// = new AutoDiffCostFunction( +// new MyScalarCostFunction(1.0)); ^ ^ ^ +// | | | +// Dimension of residual ------+ | | +// Dimension of x ----------------+ | +// Dimension of y -------------------+ +// +// In this example, there is usually an instance for each measumerent of k. +// +// In the instantiation above, the template parameters following +// "MyScalarCostFunction", "1, 2, 2", describe the functor as computing a +// 1-dimensional output from two arguments, both 2-dimensional. +// +// The framework can currently accommodate cost functions of up to 6 independent +// variables, and there is no limit on the dimensionality of each of them. +// +// WARNING #1: Since the functor will get instantiated with different types for +// T, you must to convert from other numeric types to T before mixing +// computations with other variables of type T. In the example above, this is +// seen where instead of using k_ directly, k_ is wrapped with T(k_). +// +// WARNING #2: A common beginner's error when first using autodiff cost +// functions is to get the sizing wrong. In particular, there is a tendency to +// set the template parameters to (dimension of residual, number of parameters) +// instead of passing a dimension parameter for *every parameter*. In the +// example above, that would be , which is missing +// the last '2' argument. Please be careful when setting the size parameters. + +#ifndef CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_ +#define CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_ + +#include +#include "ceres/internal/autodiff.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/sized_cost_function.h" + +namespace ceres { + +// A cost function which computes the derivative of the cost with respect to the +// parameters (a.k.a. the jacobian) using an autodifferentiation framework. The +// first template argument is the functor object, described in the header +// comment. The second argument is the dimension of the residual, and subsequent +// arguments describe the size of the Nth parameter, one per parameter. +// +// The constructor, which takes a cost functor, takes ownership of the functor. +template // Number of parameters in block 5. +class AutoDiffCostFunction : + public SizedCostFunction { + public: + // Takes ownership of functor. + explicit AutoDiffCostFunction(CostFunctor* functor) : functor_(functor) {} + + virtual ~AutoDiffCostFunction() {} + + // Implementation details follow; clients of the autodiff cost function should + // not have to examine below here. + // + // To handle varardic cost functions, some template magic is needed. It's + // mostly hidden inside autodiff.h. + virtual bool Evaluate(double const* const* parameters, + double* residuals, + double** jacobians) const { + if (!jacobians) { + return internal::VariadicEvaluate< + CostFunctor, double, M, N0, N1, N2, N3, N4, N5> + ::Call(*functor_, parameters, residuals); + } + return internal::AutoDiff::Differentiate(*functor_, + parameters, + residuals, + jacobians); + } + + private: + internal::scoped_ptr functor_; +}; + +} // namespace ceres + +#endif // CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/ceres.h b/extern/libmv/third_party/ceres/include/ceres/ceres.h new file mode 100644 index 00000000000..22aaf8ff21a --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/ceres.h @@ -0,0 +1,48 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// This is a forwarding header containing the public symbols exported from +// Ceres. Anything in the "ceres" namespace is available for use. + +#ifndef CERES_PUBLIC_CERES_H_ +#define CERES_PUBLIC_CERES_H_ + +#include "ceres/autodiff_cost_function.h" +#include "ceres/cost_function.h" +#include "ceres/iteration_callback.h" +#include "ceres/local_parameterization.h" +#include "ceres/loss_function.h" +#include "ceres/numeric_diff_cost_function.h" +#include "ceres/problem.h" +#include "ceres/sized_cost_function.h" +#include "ceres/solver.h" +#include "ceres/types.h" + +#endif // CERES_PUBLIC_CERES_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h new file mode 100644 index 00000000000..498d36ee55a --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h @@ -0,0 +1,97 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: wjr@google.com (William Rucklidge) +// +// This file contains a cost function that can apply a transformation to +// each residual value before they are square-summed. + +#ifndef CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_ +#define CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_ + +#include + +#include "ceres/cost_function.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { + +// This class allows you to apply different conditioning to the residual +// values of a wrapped cost function. An example where this is useful is +// where you have an existing cost function that produces N values, but you +// want the total cost to be something other than just the sum of these +// squared values - maybe you want to apply a different scaling to some +// values, to change their contribution to the cost. +// +// Usage: +// +// // my_cost_function produces N residuals +// CostFunction* my_cost_function = ... +// CHECK_EQ(N, my_cost_function->num_residuals()); +// vector conditioners; +// +// // Make N 1x1 cost functions (1 parameter, 1 residual) +// CostFunction* f_1 = ... +// conditioners.push_back(f_1); +// ... +// CostFunction* f_N = ... +// conditioners.push_back(f_N); +// ConditionedCostFunction* ccf = +// new ConditionedCostFunction(my_cost_function, conditioners); +// +// Now ccf's residual i (i=0..N-1) will be passed though the i'th conditioner. +// +// ccf_residual[i] = f_i(my_cost_function_residual[i]) +// +// and the Jacobian will be affected appropriately. +class ConditionedCostFunction : public CostFunction { + public: + // Builds a cost function based on a wrapped cost function, and a + // per-residual conditioner. Takes ownership of all of the wrapped cost + // functions, or not, depending on the ownership parameter. Conditioners + // may be NULL, in which case the corresponding residual is not modified. + ConditionedCostFunction(CostFunction* wrapped_cost_function, + const vector& conditioners, + Ownership ownership); + virtual ~ConditionedCostFunction(); + + virtual bool Evaluate(double const* const* parameters, + double* residuals, + double** jacobians) const; + + private: + internal::scoped_ptr wrapped_cost_function_; + vector conditioners_; + Ownership ownership_; +}; + +} // namespace ceres + + +#endif // CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/cost_function.h b/extern/libmv/third_party/ceres/include/ceres/cost_function.h new file mode 100644 index 00000000000..84403d90636 --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/cost_function.h @@ -0,0 +1,127 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// keir@google.m (Keir Mierle) +// +// This is the interface through which the least squares solver accesses the +// residual and Jacobian of the least squares problem. Users are expected to +// subclass CostFunction to define their own terms in the least squares problem. +// +// It is recommended that users define templated residual functors for use as +// arguments for AutoDiffCostFunction (see autodiff_cost_function.h), instead of +// directly implementing the CostFunction interface. This often results in both +// shorter code and faster execution than hand-coded derivatives. However, +// specialized cases may demand direct implementation of the lower-level +// CostFunction interface; for example, this is true when calling legacy code +// which is not templated on numeric types. + +#ifndef CERES_PUBLIC_COST_FUNCTION_H_ +#define CERES_PUBLIC_COST_FUNCTION_H_ + +#include +#include "ceres/internal/macros.h" +#include "ceres/internal/port.h" +#include "ceres/types.h" + +namespace ceres { + +// This class implements the computation of the cost (a.k.a. residual) terms as +// a function of the input (control) variables, and is the interface for users +// to describe their least squares problem to Ceres. In other words, this is the +// modelling layer between users and the Ceres optimizer. The signature of the +// function (number and sizes of input parameter blocks and number of outputs) +// is stored in parameter_block_sizes_ and num_residuals_ respectively. User +// code inheriting from this class is expected to set these two members with the +// corresponding accessors. This information will be verified by the Problem +// when added with AddResidualBlock(). +class CostFunction { + public: + CostFunction() : num_residuals_(0) {} + + virtual ~CostFunction() {} + + // Inputs: + // + // parameters is an array of pointers to arrays containing the + // various parameter blocks. parameters has the same number of + // elements as parameter_block_sizes_. Parameter blocks are in the + // same order as parameter_block_sizes_.i.e., + // + // parameters_[i] = double[parameter_block_sizes_[i]] + // + // Outputs: + // + // residuals is an array of size num_residuals_. + // + // jacobians is an array of size parameter_block_sizes_ containing + // pointers to storage for jacobian blocks corresponding to each + // parameter block. Jacobian blocks are in the same order as + // parameter_block_sizes, i.e. jacobians[i], is an + // array that contains num_residuals_* parameter_block_sizes_[i] + // elements. Each jacobian block is stored in row-major order, i.e., + // + // jacobians[i][r*parameter_block_size_[i] + c] = + // d residual[r] / d parameters[i][c] + // + // If jacobians is NULL, then no derivatives are returned; this is + // the case when computing cost only. If jacobians[i] is NULL, then + // the jacobian block corresponding to the i'th parameter block must + // not to be returned. + virtual bool Evaluate(double const* const* parameters, + double* residuals, + double** jacobians) const = 0; + + const vector& parameter_block_sizes() const { + return parameter_block_sizes_; + } + + int num_residuals() const { + return num_residuals_; + } + + protected: + vector* mutable_parameter_block_sizes() { + return ¶meter_block_sizes_; + } + + void set_num_residuals(int num_residuals) { + num_residuals_ = num_residuals; + } + + private: + // Cost function signature metadata: number of inputs & their sizes, + // number of outputs (residuals). + vector parameter_block_sizes_; + int num_residuals_; + DISALLOW_COPY_AND_ASSIGN(CostFunction); +}; + +} // namespace ceres + +#endif // CERES_PUBLIC_COST_FUNCTION_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h b/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h new file mode 100644 index 00000000000..1a9d396c9ef --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h @@ -0,0 +1,374 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// Computation of the Jacobian matrix for vector-valued functions of multiple +// variables, using automatic differentiation based on the implementation of +// dual numbers in jet.h. Before reading the rest of this file, it is adivsable +// to read jet.h's header comment in detail. +// +// The helper wrapper AutoDiff::Differentiate() computes the jacobian of +// functors with templated operator() taking this form: +// +// struct F { +// template +// bool operator(const T *x, const T *y, ..., T *z) { +// // Compute z[] based on x[], y[], ... +// // return true if computation succeeded, false otherwise. +// } +// }; +// +// All inputs and outputs may be vector-valued. +// +// To understand how jets are used to compute the jacobian, a +// picture may help. Consider a vector-valued function, F, returning 3 +// dimensions and taking a vector-valued parameter of 4 dimensions: +// +// y x +// [ * ] F [ * ] +// [ * ] <--- [ * ] +// [ * ] [ * ] +// [ * ] +// +// Similar to the 2-parameter example for f described in jet.h, computing the +// jacobian dy/dx is done by substutiting a suitable jet object for x and all +// intermediate steps of the computation of F. Since x is has 4 dimensions, use +// a Jet. +// +// Before substituting a jet object for x, the dual components are set +// appropriately for each dimension of x: +// +// y x +// [ * | * * * * ] f [ * | 1 0 0 0 ] x0 +// [ * | * * * * ] <--- [ * | 0 1 0 0 ] x1 +// [ * | * * * * ] [ * | 0 0 1 0 ] x2 +// ---+--- [ * | 0 0 0 1 ] x3 +// | ^ ^ ^ ^ +// dy/dx | | | +----- infinitesimal for x3 +// | | +------- infinitesimal for x2 +// | +--------- infinitesimal for x1 +// +----------- infinitesimal for x0 +// +// The reason to set the internal 4x4 submatrix to the identity is that we wish +// to take the derivative of y separately with respect to each dimension of x. +// Each column of the 4x4 identity is therefore for a single component of the +// independent variable x. +// +// Then the jacobian of the mapping, dy/dx, is the 3x4 sub-matrix of the +// extended y vector, indicated in the above diagram. +// +// Functors with multiple parameters +// --------------------------------- +// In practice, it is often convenient to use a function f of two or more +// vector-valued parameters, for example, x[3] and z[6]. Unfortunately, the jet +// framework is designed for a single-parameter vector-valued input. The wrapper +// in this file addresses this issue adding support for functions with one or +// more parameter vectors. +// +// To support multiple parameters, all the parameter vectors are concatenated +// into one and treated as a single parameter vector, except that since the +// functor expects different inputs, we need to construct the jets as if they +// were part of a single parameter vector. The extended jets are passed +// separately for each parameter. +// +// For example, consider a functor F taking two vector parameters, p[2] and +// q[3], and producing an output y[4]: +// +// struct F { +// template +// bool operator(const T *p, const T *q, T *z) { +// // ... +// } +// }; +// +// In this case, the necessary jet type is Jet. Here is a +// visualization of the jet objects in this case: +// +// Dual components for p ----+ +// | +// -+- +// y [ * | 1 0 | 0 0 0 ] --- p[0] +// [ * | 0 1 | 0 0 0 ] --- p[1] +// [ * | . . | + + + ] | +// [ * | . . | + + + ] v +// [ * | . . | + + + ] <--- F(p, q) +// [ * | . . | + + + ] ^ +// ^^^ ^^^^^ | +// dy/dp dy/dq [ * | 0 0 | 1 0 0 ] --- q[0] +// [ * | 0 0 | 0 1 0 ] --- q[1] +// [ * | 0 0 | 0 0 1 ] --- q[2] +// --+-- +// | +// Dual components for q --------------+ +// +// where the 4x2 submatrix (marked with ".") and 4x3 submatrix (marked with "+" +// of y in the above diagram are the derivatives of y with respect to p and q +// respectively. This is how autodiff works for functors taking multiple vector +// valued arguments (up to 6). +// +// Jacobian NULL pointers +// ---------------------- +// In general, the functions below will accept NULL pointers for all or some of +// the Jacobian parameters, meaning that those Jacobians will not be computed. + +#ifndef CERES_PUBLIC_INTERNAL_AUTODIFF_H_ +#define CERES_PUBLIC_INTERNAL_AUTODIFF_H_ + +#include + +#include +#include "ceres/jet.h" +#include "ceres/internal/fixed_array.h" + +namespace ceres { +namespace internal { + +// Extends src by a 1st order pertubation for every dimension and puts it in +// dst. The size of src is N. Since this is also used for perturbations in +// blocked arrays, offset is used to shift which part of the jet the +// perturbation occurs. This is used to set up the extended x augmented by an +// identity matrix. The JetT type should be a Jet type, and T should be a +// numeric type (e.g. double). For example, +// +// 0 1 2 3 4 5 6 7 8 +// dst[0] [ * | . . | 1 0 0 | . . . ] +// dst[1] [ * | . . | 0 1 0 | . . . ] +// dst[2] [ * | . . | 0 0 1 | . . . ] +// +// is what would get put in dst if N was 3, offset was 3, and the jet type JetT +// was 8-dimensional. +template +inline void Make1stOrderPerturbation(int offset, int N, const T *src, + JetT *dst) { + DCHECK(src); + DCHECK(dst); + for (int j = 0; j < N; ++j) { + dst[j] = JetT(src[j], offset + j); + } +} + +// Takes the 0th order part of src, assumed to be a Jet type, and puts it in +// dst. This is used to pick out the "vector" part of the extended y. +template +inline void Take0thOrderPart(int M, const JetT *src, T dst) { + DCHECK(src); + for (int i = 0; i < M; ++i) { + dst[i] = src[i].a; + } +} + +// Takes N 1st order parts, starting at index N0, and puts them in the M x N +// matrix 'dst'. This is used to pick out the "matrix" parts of the extended y. +template +inline void Take1stOrderPart(const JetT *src, T *dst) { + DCHECK(src); + DCHECK(dst); + // TODO(keir): Change Jet to use a single array, where v[0] is the + // non-infinitesimal part rather than "a". That way it's possible to use a + // single memcpy or eigen operation, rather than the explicit loop. The loop + // doesn't exploit any SSE or other intrinsics. + for (int i = 0; i < M; ++i) { + for (int j = 0; j < N; ++j) { + dst[N * i + j] = src[i].v[N0 + j]; + } + } +} + +// This block of quasi-repeated code calls the user-supplied functor, which may +// take a variable number of arguments. This is accomplished by specializing the +// struct based on the size of the trailing parameters; parameters with 0 size +// are assumed missing. +// +// Supporting variadic functions is the primary source of complexity in the +// autodiff implementation. + +template +struct VariadicEvaluate { + static bool Call(const Functor& functor, T const *const *input, T* output) { + return functor(input[0], + input[1], + input[2], + input[3], + input[4], + input[5], + output); + } +}; + +template +struct VariadicEvaluate { + static bool Call(const Functor& functor, T const *const *input, T* output) { + return functor(input[0], + input[1], + input[2], + input[3], + input[4], + output); + } +}; + +template +struct VariadicEvaluate { + static bool Call(const Functor& functor, T const *const *input, T* output) { + return functor(input[0], + input[1], + input[2], + input[3], + output); + } +}; + +template +struct VariadicEvaluate { + static bool Call(const Functor& functor, T const *const *input, T* output) { + return functor(input[0], + input[1], + input[2], + output); + } +}; + +template +struct VariadicEvaluate { + static bool Call(const Functor& functor, T const *const *input, T* output) { + return functor(input[0], + input[1], + output); + } +}; + +template +struct VariadicEvaluate { + static bool Call(const Functor& functor, T const *const *input, T* output) { + return functor(input[0], + output); + } +}; + +// This is in a struct because default template parameters on a function are not +// supported in C++03 (though it is available in C++0x). N0 through N5 are the +// dimension of the input arguments to the user supplied functor. +template +struct AutoDiff { + static bool Differentiate(const Functor& functor, + T const *const *parameters, + T *function_value, + T **jacobians) { + typedef Jet JetT; + + DCHECK_GT(N0, 0) + << "Cost functions must have at least one parameter block."; + DCHECK((!N1 && !N2 && !N3 && !N4 && !N5) || + ((N1 > 0) && !N2 && !N3 && !N4 && !N5) || + ((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5) || + ((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5) || + ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5) || + ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0))) + << "Zero block cannot precede a non-zero block. Block sizes are " + << "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", " + << N3 << ", " << N4 << ", " << N5; + + DCHECK_GT(kNumOutputs, 0); + + FixedArray x( + N0 + N1 + N2 + N3 + N4 + N5 + kNumOutputs); + + // It's ugly, but it works. + const int jet0 = 0; + const int jet1 = N0; + const int jet2 = N0 + N1; + const int jet3 = N0 + N1 + N2; + const int jet4 = N0 + N1 + N2 + N3; + const int jet5 = N0 + N1 + N2 + N3 + N4; + const int jet6 = N0 + N1 + N2 + N3 + N4 + N5; + + const JetT *unpacked_parameters[6] = { + x.get() + jet0, + x.get() + jet1, + x.get() + jet2, + x.get() + jet3, + x.get() + jet4, + x.get() + jet5, + }; + JetT *output = x.get() + jet6; + +#define CERES_MAKE_1ST_ORDER_PERTURBATION(i) \ + if (N ## i) { \ + internal::Make1stOrderPerturbation(jet ## i, \ + N ## i, \ + parameters[i], \ + x.get() + jet ## i); \ + } + CERES_MAKE_1ST_ORDER_PERTURBATION(0); + CERES_MAKE_1ST_ORDER_PERTURBATION(1); + CERES_MAKE_1ST_ORDER_PERTURBATION(2); + CERES_MAKE_1ST_ORDER_PERTURBATION(3); + CERES_MAKE_1ST_ORDER_PERTURBATION(4); + CERES_MAKE_1ST_ORDER_PERTURBATION(5); +#undef CERES_MAKE_1ST_ORDER_PERTURBATION + + if (!VariadicEvaluate::Call( + functor, unpacked_parameters, output)) { + return false; + } + + internal::Take0thOrderPart(kNumOutputs, output, function_value); + +#define CERES_TAKE_1ST_ORDER_PERTURBATION(i) \ + if (N ## i) { \ + if (jacobians[i]) { \ + internal::Take1stOrderPart(output, \ + jacobians[i]); \ + } \ + } + CERES_TAKE_1ST_ORDER_PERTURBATION(0); + CERES_TAKE_1ST_ORDER_PERTURBATION(1); + CERES_TAKE_1ST_ORDER_PERTURBATION(2); + CERES_TAKE_1ST_ORDER_PERTURBATION(3); + CERES_TAKE_1ST_ORDER_PERTURBATION(4); + CERES_TAKE_1ST_ORDER_PERTURBATION(5); +#undef CERES_TAKE_1ST_ORDER_PERTURBATION + return true; + } +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_PUBLIC_INTERNAL_AUTODIFF_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/eigen.h b/extern/libmv/third_party/ceres/include/ceres/internal/eigen.h new file mode 100644 index 00000000000..be76f9eff98 --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/internal/eigen.h @@ -0,0 +1,80 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_EIGEN_H_ +#define CERES_INTERNAL_EIGEN_H_ + +#include "Eigen/Core" + +namespace ceres { + +using Eigen::Dynamic; +using Eigen::RowMajor; + +typedef Eigen::Matrix Vector; +typedef Eigen::Matrix Matrix; +typedef Eigen::Map VectorRef; +typedef Eigen::Map MatrixRef; +typedef Eigen::Map AlignedMatrixRef; +typedef Eigen::Map ConstVectorRef; +typedef Eigen::Map ConstAlignedMatrixRef; +typedef Eigen::Map ConstMatrixRef; + +// C++ does not support templated typdefs, thus the need for this +// struct so that we can support statically sized Matrix and Maps. +template +struct EigenTypes { + typedef Eigen::Matrix + Matrix; + + typedef Eigen::Map< + Eigen::Matrix > + MatrixRef; + + typedef Eigen::Matrix + Vector; + + typedef Eigen::Map < + Eigen::Matrix > + VectorRef; + + + typedef Eigen::Map< + const Eigen::Matrix > + ConstMatrixRef; + + typedef Eigen::Map < + const Eigen::Matrix > + ConstVectorRef; +}; + +} // namespace ceres + +#endif // CERES_INTERNAL_EIGEN_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h b/extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h new file mode 100644 index 00000000000..30cc5fc4a6c --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h @@ -0,0 +1,193 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: rennie@google.com (Jeffrey Rennie) +// Author: sanjay@google.com (Sanjay Ghemawat) -- renamed to FixedArray + +#ifndef CERES_PUBLIC_INTERNAL_FIXED_ARRAY_H_ +#define CERES_PUBLIC_INTERNAL_FIXED_ARRAY_H_ + +#include +#include +#include "ceres/internal/manual_constructor.h" + +namespace ceres { +namespace internal { + +// A FixedArray represents a non-resizable array of T where the +// length of the array does not need to be a compile time constant. +// +// FixedArray allocates small arrays inline, and large arrays on +// the heap. It is a good replacement for non-standard and deprecated +// uses of alloca() and variable length arrays (a GCC extension). +// +// FixedArray keeps performance fast for small arrays, because it +// avoids heap operations. It also helps reduce the chances of +// accidentally overflowing your stack if large input is passed to +// your function. +// +// Also, FixedArray is useful for writing portable code. Not all +// compilers support arrays of dynamic size. + +// Most users should not specify an inline_elements argument and let +// FixedArray<> automatically determine the number of elements +// to store inline based on sizeof(T). +// +// If inline_elements is specified, the FixedArray<> implementation +// will store arrays of length <= inline_elements inline. +// +// Finally note that unlike vector FixedArray will not zero-initialize +// simple types like int, double, bool, etc. +// +// Non-POD types will be default-initialized just like regular vectors or +// arrays. + +#if defined(_WIN64) + typedef __int64 ssize_t; +#elif defined(_WIN32) + typedef __int32 ssize_t; +#endif + +template +class FixedArray { + public: + // For playing nicely with stl: + typedef T value_type; + typedef T* iterator; + typedef T const* const_iterator; + typedef T& reference; + typedef T const& const_reference; + typedef T* pointer; + typedef std::ptrdiff_t difference_type; + typedef size_t size_type; + + // REQUIRES: n >= 0 + // Creates an array object that can store "n" elements. + // + // FixedArray will not zero-initialiaze POD (simple) types like int, + // double, bool, etc. + // Non-POD types will be default-initialized just like regular vectors or + // arrays. + explicit FixedArray(size_type n); + + // Releases any resources. + ~FixedArray(); + + // Returns the length of the array. + inline size_type size() const { return size_; } + + // Returns the memory size of the array in bytes. + inline size_t memsize() const { return size_ * sizeof(T); } + + // Returns a pointer to the underlying element array. + inline const T* get() const { return &array_[0].element; } + inline T* get() { return &array_[0].element; } + + // REQUIRES: 0 <= i < size() + // Returns a reference to the "i"th element. + inline T& operator[](size_type i) { + DCHECK_GE(i, 0); + DCHECK_LT(i, size_); + return array_[i].element; + } + + // REQUIRES: 0 <= i < size() + // Returns a reference to the "i"th element. + inline const T& operator[](size_type i) const { + DCHECK_GE(i, 0); + DCHECK_LT(i, size_); + return array_[i].element; + } + + inline iterator begin() { return &array_[0].element; } + inline iterator end() { return &array_[size_].element; } + + inline const_iterator begin() const { return &array_[0].element; } + inline const_iterator end() const { return &array_[size_].element; } + + private: + // Container to hold elements of type T. This is necessary to handle + // the case where T is a a (C-style) array. The size of InnerContainer + // and T must be the same, otherwise callers' assumptions about use + // of this code will be broken. + struct InnerContainer { + T element; + }; + + // How many elements should we store inline? + // a. If not specified, use a default of 256 bytes (256 bytes + // seems small enough to not cause stack overflow or unnecessary + // stack pollution, while still allowing stack allocation for + // reasonably long character arrays. + // b. Never use 0 length arrays (not ISO C++) + static const size_type S1 = ((inline_elements < 0) + ? (256/sizeof(T)) : inline_elements); + static const size_type S2 = (S1 <= 0) ? 1 : S1; + static const size_type kInlineElements = S2; + + size_type const size_; + InnerContainer* const array_; + + // Allocate some space, not an array of elements of type T, so that we can + // skip calling the T constructors and destructors for space we never use. + ManualConstructor inline_space_[kInlineElements]; +}; + +// Implementation details follow + +template +inline FixedArray::FixedArray(typename FixedArray::size_type n) + : size_(n), + array_((n <= kInlineElements + ? reinterpret_cast(inline_space_) + : new InnerContainer[n])) { + DCHECK_GE(n, 0); + + // Construct only the elements actually used. + if (array_ == reinterpret_cast(inline_space_)) { + for (int i = 0; i != size_; ++i) { + inline_space_[i].Init(); + } + } +} + +template +inline FixedArray::~FixedArray() { + if (array_ != reinterpret_cast(inline_space_)) { + delete[] array_; + } else { + for (int i = 0; i != size_; ++i) { + inline_space_[i].Destroy(); + } + } +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_PUBLIC_INTERNAL_FIXED_ARRAY_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/macros.h b/extern/libmv/third_party/ceres/include/ceres/internal/macros.h new file mode 100644 index 00000000000..0cfd773bcca --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/internal/macros.h @@ -0,0 +1,154 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// +// Various Google-specific macros. +// +// This code is compiled directly on many platforms, including client +// platforms like Windows, Mac, and embedded systems. Before making +// any changes here, make sure that you're not breaking any platforms. + +#ifndef CERES_PUBLIC_INTERNAL_MACROS_H_ +#define CERES_PUBLIC_INTERNAL_MACROS_H_ + +#include // For size_t. + +// A macro to disallow the copy constructor and operator= functions +// This should be used in the private: declarations for a class +// +// For disallowing only assign or copy, write the code directly, but declare +// the intend in a comment, for example: +// void operator=(const TypeName&); // DISALLOW_ASSIGN +// Note, that most uses of DISALLOW_ASSIGN and DISALLOW_COPY are broken +// semantically, one should either use disallow both or neither. Try to +// avoid these in new code. +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +// A macro to disallow all the implicit constructors, namely the +// default constructor, copy constructor and operator= functions. +// +// This should be used in the private: declarations for a class +// that wants to prevent anyone from instantiating it. This is +// especially useful for classes containing only static methods. +#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ + TypeName(); \ + DISALLOW_COPY_AND_ASSIGN(TypeName) + +// The arraysize(arr) macro returns the # of elements in an array arr. +// The expression is a compile-time constant, and therefore can be +// used in defining new arrays, for example. If you use arraysize on +// a pointer by mistake, you will get a compile-time error. +// +// One caveat is that arraysize() doesn't accept any array of an +// anonymous type or a type defined inside a function. In these rare +// cases, you have to use the unsafe ARRAYSIZE() macro below. This is +// due to a limitation in C++'s template system. The limitation might +// eventually be removed, but it hasn't happened yet. + +// This template function declaration is used in defining arraysize. +// Note that the function doesn't need an implementation, as we only +// use its type. +template +char (&ArraySizeHelper(T (&array)[N]))[N]; + +// That gcc wants both of these prototypes seems mysterious. VC, for +// its part, can't decide which to use (another mystery). Matching of +// template overloads: the final frontier. +#ifndef _WIN32 +template +char (&ArraySizeHelper(const T (&array)[N]))[N]; +#endif + +#define arraysize(array) (sizeof(ArraySizeHelper(array))) + +// ARRAYSIZE performs essentially the same calculation as arraysize, +// but can be used on anonymous types or types defined inside +// functions. It's less safe than arraysize as it accepts some +// (although not all) pointers. Therefore, you should use arraysize +// whenever possible. +// +// The expression ARRAYSIZE(a) is a compile-time constant of type +// size_t. +// +// ARRAYSIZE catches a few type errors. If you see a compiler error +// +// "warning: division by zero in ..." +// +// when using ARRAYSIZE, you are (wrongfully) giving it a pointer. +// You should only use ARRAYSIZE on statically allocated arrays. +// +// The following comments are on the implementation details, and can +// be ignored by the users. +// +// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in +// the array) and sizeof(*(arr)) (the # of bytes in one array +// element). If the former is divisible by the latter, perhaps arr is +// indeed an array, in which case the division result is the # of +// elements in the array. Otherwise, arr cannot possibly be an array, +// and we generate a compiler error to prevent the code from +// compiling. +// +// Since the size of bool is implementation-defined, we need to cast +// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final +// result has type size_t. +// +// This macro is not perfect as it wrongfully accepts certain +// pointers, namely where the pointer size is divisible by the pointee +// size. Since all our code has to go through a 32-bit compiler, +// where a pointer is 4 bytes, this means all pointers to a type whose +// size is 3 or greater than 4 will be (righteously) rejected. +// +// Kudos to Jorg Brown for this simple and elegant implementation. +// +// - wan 2005-11-16 +// +// Starting with Visual C++ 2005, WinNT.h includes ARRAYSIZE. However, +// the definition comes from the over-broad windows.h header that +// introduces a macro, ERROR, that conflicts with the logging framework +// that Ceres uses. Instead, rename ARRAYSIZE to CERES_ARRAYSIZE. +#define CERES_ARRAYSIZE(a) \ + ((sizeof(a) / sizeof(*(a))) / \ + static_cast(!(sizeof(a) % sizeof(*(a))))) + +// Tell the compiler to warn about unused return values for functions declared +// with this macro. The macro should be used on function declarations +// following the argument list: +// +// Sprocket* AllocateSprocket() MUST_USE_RESULT; +// +#undef MUST_USE_RESULT +#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \ + && !defined(COMPILER_ICC) +#define MUST_USE_RESULT __attribute__ ((warn_unused_result)) +#else +#define MUST_USE_RESULT +#endif + +#endif // CERES_PUBLIC_INTERNAL_MACROS_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h b/extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h new file mode 100644 index 00000000000..a1d1f444e36 --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h @@ -0,0 +1,214 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: kenton@google.com (Kenton Varda) +// +// ManualConstructor statically-allocates space in which to store some +// object, but does not initialize it. You can then call the constructor +// and destructor for the object yourself as you see fit. This is useful +// for memory management optimizations, where you want to initialize and +// destroy an object multiple times but only allocate it once. +// +// (When I say ManualConstructor statically allocates space, I mean that +// the ManualConstructor object itself is forced to be the right size.) + +#ifndef CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_ +#define CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_ + +#include + +namespace ceres { +namespace internal { + +// ------- Define ALIGNED_CHAR_ARRAY -------------------------------- + +#ifndef ALIGNED_CHAR_ARRAY + +// Because MSVC and older GCCs require that the argument to their alignment +// construct to be a literal constant integer, we use a template instantiated +// at all the possible powers of two. +template struct AlignType { }; +template struct AlignType<0, size> { typedef char result[size]; }; +#if defined(_MSC_VER) +#define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __declspec(align(X)) +#define BASE_PORT_H_ALIGN_OF(T) __alignof(T) +#elif defined(__GNUC__) +#define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __attribute__((aligned(X))) +#define BASE_PORT_H_ALIGN_OF(T) __alignof__(T) +#endif + +#if defined(BASE_PORT_H_ALIGN_ATTRIBUTE) + +#define BASE_PORT_H_ALIGNTYPE_TEMPLATE(X) \ + template struct AlignType { \ + typedef BASE_PORT_H_ALIGN_ATTRIBUTE(X) char result[size]; \ + } + +BASE_PORT_H_ALIGNTYPE_TEMPLATE(1); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(2); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(4); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(8); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(16); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(32); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(64); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(128); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(256); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(512); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(1024); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(2048); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(4096); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(8192); +// Any larger and MSVC++ will complain. + +#define ALIGNED_CHAR_ARRAY(T, Size) \ + typename AlignType::result + +#undef BASE_PORT_H_ALIGNTYPE_TEMPLATE +#undef BASE_PORT_H_ALIGN_ATTRIBUTE + +#else // defined(BASE_PORT_H_ALIGN_ATTRIBUTE) +#define ALIGNED_CHAR_ARRAY you_must_define_ALIGNED_CHAR_ARRAY_for_your_compiler +#endif // defined(BASE_PORT_H_ALIGN_ATTRIBUTE) + +#undef BASE_PORT_H_ALIGNTYPE_TEMPLATE +#undef BASE_PORT_H_ALIGN_ATTRIBUTE + +#endif // ALIGNED_CHAR_ARRAY + +template +class ManualConstructor { + public: + // No constructor or destructor because one of the most useful uses of + // this class is as part of a union, and members of a union cannot have + // constructors or destructors. And, anyway, the whole point of this + // class is to bypass these. + + inline Type* get() { + return reinterpret_cast(space_); + } + inline const Type* get() const { + return reinterpret_cast(space_); + } + + inline Type* operator->() { return get(); } + inline const Type* operator->() const { return get(); } + + inline Type& operator*() { return *get(); } + inline const Type& operator*() const { return *get(); } + + // You can pass up to four constructor arguments as arguments of Init(). + inline void Init() { + new(space_) Type; + } + + template + inline void Init(const T1& p1) { + new(space_) Type(p1); + } + + template + inline void Init(const T1& p1, const T2& p2) { + new(space_) Type(p1, p2); + } + + template + inline void Init(const T1& p1, const T2& p2, const T3& p3) { + new(space_) Type(p1, p2, p3); + } + + template + inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4) { + new(space_) Type(p1, p2, p3, p4); + } + + template + inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4, + const T5& p5) { + new(space_) Type(p1, p2, p3, p4, p5); + } + + template + inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4, + const T5& p5, const T6& p6) { + new(space_) Type(p1, p2, p3, p4, p5, p6); + } + + template + inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4, + const T5& p5, const T6& p6, const T7& p7) { + new(space_) Type(p1, p2, p3, p4, p5, p6, p7); + } + + template + inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4, + const T5& p5, const T6& p6, const T7& p7, const T8& p8) { + new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8); + } + + template + inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4, + const T5& p5, const T6& p6, const T7& p7, const T8& p8, + const T9& p9) { + new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + + template + inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4, + const T5& p5, const T6& p6, const T7& p7, const T8& p8, + const T9& p9, const T10& p10) { + new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + + template + inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4, + const T5& p5, const T6& p6, const T7& p7, const T8& p8, + const T9& p9, const T10& p10, const T11& p11) { + new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); + } + + inline void Destroy() { + get()->~Type(); + } + + private: + ALIGNED_CHAR_ARRAY(Type, 1) space_; +}; + +#undef ALIGNED_CHAR_ARRAY + +} // namespace internal +} // namespace ceres + +#endif // CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/port.h b/extern/libmv/third_party/ceres/include/ceres/internal/port.h new file mode 100644 index 00000000000..9a3e5cced58 --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/internal/port.h @@ -0,0 +1,44 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#ifndef CERES_PUBLIC_INTERNAL_PORT_H_ +#define CERES_PUBLIC_INTERNAL_PORT_H_ + +namespace ceres { + +// It is unfortunate that this import of the entire standard namespace is +// necessary. The reasons are historical and won't be explained here, but +// suffice to say it is not a mistake and can't be removed without breaking +// things outside of the Ceres optimization package. +using namespace std; + +} // namespace ceres + +#endif // CERES_PUBLIC_INTERNAL_PORT_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h b/extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h new file mode 100644 index 00000000000..44f198b339d --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h @@ -0,0 +1,311 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: jorg@google.com (Jorg Brown) +// +// This is an implementation designed to match the anticipated future TR2 +// implementation of the scoped_ptr class, and its closely-related brethren, +// scoped_array, scoped_ptr_malloc, and make_scoped_ptr. + +#ifndef CERES_PUBLIC_INTERNAL_SCOPED_PTR_H_ +#define CERES_PUBLIC_INTERNAL_SCOPED_PTR_H_ + +#include +#include +#include + +namespace ceres { +namespace internal { + +template class scoped_ptr; +template class scoped_ptr_malloc; +template class scoped_array; + +template +scoped_ptr make_scoped_ptr(C *); + +// A scoped_ptr is like a T*, except that the destructor of scoped_ptr +// automatically deletes the pointer it holds (if any). That is, scoped_ptr +// owns the T object that it points to. Like a T*, a scoped_ptr may hold +// either NULL or a pointer to a T object. Also like T*, scoped_ptr is +// thread-compatible, and once you dereference it, you get the threadsafety +// guarantees of T. +// +// The size of a scoped_ptr is small: sizeof(scoped_ptr) == sizeof(C*) +template +class scoped_ptr { + public: + + // The element type + typedef C element_type; + + // Constructor. Defaults to intializing with NULL. + // There is no way to create an uninitialized scoped_ptr. + // The input parameter must be allocated with new. + explicit scoped_ptr(C* p = NULL) : ptr_(p) { } + + // Destructor. If there is a C object, delete it. + // We don't need to test ptr_ == NULL because C++ does that for us. + ~scoped_ptr() { + enum { type_must_be_complete = sizeof(C) }; + delete ptr_; + } + + // Reset. Deletes the current owned object, if any. + // Then takes ownership of a new object, if given. + // this->reset(this->get()) works. + void reset(C* p = NULL) { + if (p != ptr_) { + enum { type_must_be_complete = sizeof(C) }; + delete ptr_; + ptr_ = p; + } + } + + // Accessors to get the owned object. + // operator* and operator-> will assert() if there is no current object. + C& operator*() const { + assert(ptr_ != NULL); + return *ptr_; + } + C* operator->() const { + assert(ptr_ != NULL); + return ptr_; + } + C* get() const { return ptr_; } + + // Comparison operators. + // These return whether a scoped_ptr and a raw pointer refer to + // the same object, not just to two different but equal objects. + bool operator==(const C* p) const { return ptr_ == p; } + bool operator!=(const C* p) const { return ptr_ != p; } + + // Swap two scoped pointers. + void swap(scoped_ptr& p2) { + C* tmp = ptr_; + ptr_ = p2.ptr_; + p2.ptr_ = tmp; + } + + // Release a pointer. + // The return value is the current pointer held by this object. + // If this object holds a NULL pointer, the return value is NULL. + // After this operation, this object will hold a NULL pointer, + // and will not own the object any more. + C* release() { + C* retVal = ptr_; + ptr_ = NULL; + return retVal; + } + + private: + C* ptr_; + + // google3 friend class that can access copy ctor (although if it actually + // calls a copy ctor, there will be a problem) see below + friend scoped_ptr make_scoped_ptr(C *p); + + // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't + // make sense, and if C2 == C, it still doesn't make sense because you should + // never have the same object owned by two different scoped_ptrs. + template bool operator==(scoped_ptr const& p2) const; + template bool operator!=(scoped_ptr const& p2) const; + + // Disallow evil constructors + scoped_ptr(const scoped_ptr&); + void operator=(const scoped_ptr&); +}; + +// Free functions +template +inline void swap(scoped_ptr& p1, scoped_ptr& p2) { + p1.swap(p2); +} + +template +inline bool operator==(const C* p1, const scoped_ptr& p2) { + return p1 == p2.get(); +} + +template +inline bool operator==(const C* p1, const scoped_ptr& p2) { + return p1 == p2.get(); +} + +template +inline bool operator!=(const C* p1, const scoped_ptr& p2) { + return p1 != p2.get(); +} + +template +inline bool operator!=(const C* p1, const scoped_ptr& p2) { + return p1 != p2.get(); +} + +template +scoped_ptr make_scoped_ptr(C *p) { + // This does nothing but to return a scoped_ptr of the type that the passed + // pointer is of. (This eliminates the need to specify the name of T when + // making a scoped_ptr that is used anonymously/temporarily.) From an + // access control point of view, we construct an unnamed scoped_ptr here + // which we return and thus copy-construct. Hence, we need to have access + // to scoped_ptr::scoped_ptr(scoped_ptr const &). However, it is guaranteed + // that we never actually call the copy constructor, which is a good thing + // as we would call the temporary's object destructor (and thus delete p) + // if we actually did copy some object, here. + return scoped_ptr(p); +} + +// scoped_array is like scoped_ptr, except that the caller must allocate +// with new [] and the destructor deletes objects with delete []. +// +// As with scoped_ptr, a scoped_array either points to an object +// or is NULL. A scoped_array owns the object that it points to. +// scoped_array is thread-compatible, and once you index into it, +// the returned objects have only the threadsafety guarantees of T. +// +// Size: sizeof(scoped_array) == sizeof(C*) +template +class scoped_array { + public: + + // The element type + typedef C element_type; + + // Constructor. Defaults to intializing with NULL. + // There is no way to create an uninitialized scoped_array. + // The input parameter must be allocated with new []. + explicit scoped_array(C* p = NULL) : array_(p) { } + + // Destructor. If there is a C object, delete it. + // We don't need to test ptr_ == NULL because C++ does that for us. + ~scoped_array() { + enum { type_must_be_complete = sizeof(C) }; + delete[] array_; + } + + // Reset. Deletes the current owned object, if any. + // Then takes ownership of a new object, if given. + // this->reset(this->get()) works. + void reset(C* p = NULL) { + if (p != array_) { + enum { type_must_be_complete = sizeof(C) }; + delete[] array_; + array_ = p; + } + } + + // Get one element of the current object. + // Will assert() if there is no current object, or index i is negative. + C& operator[](std::ptrdiff_t i) const { + assert(i >= 0); + assert(array_ != NULL); + return array_[i]; + } + + // Get a pointer to the zeroth element of the current object. + // If there is no current object, return NULL. + C* get() const { + return array_; + } + + // Comparison operators. + // These return whether a scoped_array and a raw pointer refer to + // the same array, not just to two different but equal arrays. + bool operator==(const C* p) const { return array_ == p; } + bool operator!=(const C* p) const { return array_ != p; } + + // Swap two scoped arrays. + void swap(scoped_array& p2) { + C* tmp = array_; + array_ = p2.array_; + p2.array_ = tmp; + } + + // Release an array. + // The return value is the current pointer held by this object. + // If this object holds a NULL pointer, the return value is NULL. + // After this operation, this object will hold a NULL pointer, + // and will not own the object any more. + C* release() { + C* retVal = array_; + array_ = NULL; + return retVal; + } + + private: + C* array_; + + // Forbid comparison of different scoped_array types. + template bool operator==(scoped_array const& p2) const; + template bool operator!=(scoped_array const& p2) const; + + // Disallow evil constructors + scoped_array(const scoped_array&); + void operator=(const scoped_array&); +}; + +// Free functions +template +inline void swap(scoped_array& p1, scoped_array& p2) { + p1.swap(p2); +} + +template +inline bool operator==(const C* p1, const scoped_array& p2) { + return p1 == p2.get(); +} + +template +inline bool operator==(const C* p1, const scoped_array& p2) { + return p1 == p2.get(); +} + +template +inline bool operator!=(const C* p1, const scoped_array& p2) { + return p1 != p2.get(); +} + +template +inline bool operator!=(const C* p1, const scoped_array& p2) { + return p1 != p2.get(); +} + +// This class wraps the c library function free() in a class that can be +// passed as a template argument to scoped_ptr_malloc below. +class ScopedPtrMallocFree { + public: + inline void operator()(void* x) const { + free(x); + } +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_PUBLIC_INTERNAL_SCOPED_PTR_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h b/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h new file mode 100644 index 00000000000..88da992d0c5 --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h @@ -0,0 +1,159 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// When an iteration callback is specified, Ceres calls the callback after each +// optimizer step and pass it an IterationSummary object, defined below. + +#ifndef CERES_PUBLIC_ITERATION_CALLBACK_H_ +#define CERES_PUBLIC_ITERATION_CALLBACK_H_ + +#include "ceres/types.h" + +namespace ceres { + +// This struct describes the state of the optimizer after each +// iteration of the minimization. +struct IterationSummary { + // Current iteration number. + int32 iteration; + + // Whether or not the algorithm made progress in this iteration. + bool step_is_successful; + + // Value of the objective function. + double cost; + + // Change in the value of the objective function in this + // iteration. This can be positive or negative. Negative change + // means that the step was not successful. + double cost_change; + + // Infinity norm of the gradient vector. + double gradient_max_norm; + + // 2-norm of the size of the step computed by the optimization + // algorithm. + double step_norm; + + // For trust region algorithms, the ratio of the actual change in + // cost and the change in the cost of the linearized approximation. + double relative_decrease; + + // Value of the regularization parameter for Levenberg-Marquardt + // algorithm at the end of the current iteration. + double mu; + + // For the inexact step Levenberg-Marquardt algorithm, this is the + // relative accuracy with which the Newton(LM) step is solved. This + // number affects only the iterative solvers capable of solving + // linear systems inexactly. Factorization-based exact solvers + // ignore it. + double eta; + + // Number of iterations taken by the linear solver to solve for the + // Newton step. + int linear_solver_iterations; + + // TODO(sameeragarwal): Change to use a higher precision timer using + // clock_gettime. + // Time (in seconds) spent inside the linear least squares solver. + int iteration_time_sec; + + // Time (in seconds) spent inside the linear least squares solver. + int linear_solver_time_sec; +}; + +// Interface for specifying callbacks that are executed at the end of +// each iteration of the Minimizer. The solver uses the return value +// of operator() to decide whether to continue solving or to +// terminate. The user can return three values. +// +// SOLVER_ABORT indicates that the callback detected an abnormal +// situation. The solver returns without updating the parameter blocks +// (unless Solver::Options::update_state_every_iteration is set +// true). Solver returns with Solver::Summary::termination_type set to +// USER_ABORT. +// +// SOLVER_TERMINATE_SUCCESSFULLY indicates that there is no need to +// optimize anymore (some user specified termination criterion has +// been met). Solver returns with Solver::Summary::termination_type +// set to USER_SUCCESS. +// +// SOLVER_CONTINUE indicates that the solver should continue +// optimizing. +// +// For example, the following Callback is used internally by Ceres to +// log the progress of the optimization. +// +// Callback for logging the state of the minimizer to STDERR or STDOUT +// depending on the user's preferences and logging level. +// +// class LoggingCallback : public IterationCallback { +// public: +// explicit LoggingCallback(bool log_to_stdout) +// : log_to_stdout_(log_to_stdout) {} +// +// ~LoggingCallback() {} +// +// CallbackReturnType operator()(const IterationSummary& summary) { +// const char* kReportRowFormat = +// "% 4d: f:% 8e d:% 3.2e g:% 3.2e h:% 3.2e " +// "rho:% 3.2e mu:% 3.2e eta:% 3.2e li:% 3d"; +// string output = StringPrintf(kReportRowFormat, +// summary.iteration, +// summary.cost, +// summary.cost_change, +// summary.gradient_max_norm, +// summary.step_norm, +// summary.relative_decrease, +// summary.mu, +// summary.eta, +// summary.linear_solver_iterations); +// if (log_to_stdout_) { +// cout << output << endl; +// } else { +// VLOG(1) << output; +// } +// return SOLVER_CONTINUE; +// } +// +// private: +// const bool log_to_stdout_; +// }; +// +class IterationCallback { + public: + virtual ~IterationCallback() {} + virtual CallbackReturnType operator()(const IterationSummary& summary) = 0; +}; + +} // namespace ceres + +#endif // CERES_PUBLIC_ITERATION_CALLBACK_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/jet.h b/extern/libmv/third_party/ceres/include/ceres/jet.h new file mode 100644 index 00000000000..f73c6988951 --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/jet.h @@ -0,0 +1,671 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// A simple implementation of N-dimensional dual numbers, for automatically +// computing exact derivatives of functions. +// +// While a complete treatment of the mechanics of automatic differentation is +// beyond the scope of this header (see +// http://en.wikipedia.org/wiki/Automatic_differentiation for details), the +// basic idea is to extend normal arithmetic with an extra element, "e," often +// denoted with the greek symbol epsilon, such that e != 0 but e^2 = 0. Dual +// numbers are extensions of the real numbers analogous to complex numbers: +// whereas complex numbers augment the reals by introducing an imaginary unit i +// such that i^2 = -1, dual numbers introduce an "infinitesimal" unit e such +// that e^2 = 0. Dual numbers have two components: the "real" component and the +// "infinitesimal" component, generally written as x + y*e. Surprisingly, this +// leads to a convenient method for computing exact derivatives without needing +// to manipulate complicated symbolic expressions. +// +// For example, consider the function +// +// f(x) = x^2 , +// +// evaluated at 10. Using normal arithmetic, f(10) = 100, and df/dx(10) = 20. +// Next, augument 10 with an infinitesimal to get: +// +// f(10 + e) = (10 + e)^2 +// = 100 + 2 * 10 * e + e^2 +// = 100 + 20 * e -+- +// -- | +// | +--- This is zero, since e^2 = 0 +// | +// +----------------- This is df/dx! +// +// Note that the derivative of f with respect to x is simply the infinitesimal +// component of the value of f(x + e). So, in order to take the derivative of +// any function, it is only necessary to replace the numeric "object" used in +// the function with one extended with infinitesimals. The class Jet, defined in +// this header, is one such example of this, where substitution is done with +// templates. +// +// To handle derivatives of functions taking multiple arguments, different +// infinitesimals are used, one for each variable to take the derivative of. For +// example, consider a scalar function of two scalar parameters x and y: +// +// f(x, y) = x^2 + x * y +// +// Following the technique above, to compute the derivatives df/dx and df/dy for +// f(1, 3) involves doing two evaluations of f, the first time replacing x with +// x + e, the second time replacing y with y + e. +// +// For df/dx: +// +// f(1 + e, y) = (1 + e)^2 + (1 + e) * 3 +// = 1 + 2 * e + 3 + 3 * e +// = 4 + 5 * e +// +// --> df/dx = 5 +// +// For df/dy: +// +// f(1, 3 + e) = 1^2 + 1 * (3 + e) +// = 1 + 3 + e +// = 4 + e +// +// --> df/dy = 1 +// +// To take the gradient of f with the implementation of dual numbers ("jets") in +// this file, it is necessary to create a single jet type which has components +// for the derivative in x and y, and passing them to a templated version of f: +// +// template +// T f(const T &x, const T &y) { +// return x * x + x * y; +// } +// +// // The "2" means there should be 2 dual number components. +// Jet x(0); // Pick the 0th dual number for x. +// Jet y(1); // Pick the 1st dual number for y. +// Jet z = f(x, y); +// +// LG << "df/dx = " << z.a[0] +// << "df/dy = " << z.a[1]; +// +// Most users should not use Jet objects directly; a wrapper around Jet objects, +// which makes computing the derivative, gradient, or jacobian of templated +// functors simple, is in autodiff.h. Even autodiff.h should not be used +// directly; instead autodiff_cost_function.h is typically the file of interest. +// +// For the more mathematically inclined, this file implements first-order +// "jets". A 1st order jet is an element of the ring +// +// T[N] = T[t_1, ..., t_N] / (t_1, ..., t_N)^2 +// +// which essentially means that each jet consists of a "scalar" value 'a' from T +// and a 1st order perturbation vector 'v' of length N: +// +// x = a + \sum_i v[i] t_i +// +// A shorthand is to write an element as x = a + u, where u is the pertubation. +// Then, the main point about the arithmetic of jets is that the product of +// perturbations is zero: +// +// (a + u) * (b + v) = ab + av + bu + uv +// = ab + (av + bu) + 0 +// +// which is what operator* implements below. Addition is simpler: +// +// (a + u) + (b + v) = (a + b) + (u + v). +// +// The only remaining question is how to evaluate the function of a jet, for +// which we use the chain rule: +// +// f(a + u) = f(a) + f'(a) u +// +// where f'(a) is the (scalar) derivative of f at a. +// +// By pushing these things through sufficiently and suitably templated +// functions, we can do automatic differentiation. Just be sure to turn on +// function inlining and common-subexpression elimination, or it will be very +// slow! +// +// WARNING: Most Ceres users should not directly include this file or know the +// details of how jets work. Instead the suggested method for automatic +// derivatives is to use autodiff_cost_function.h, which is a wrapper around +// both jets.h and autodiff.h to make taking derivatives of cost functions for +// use in Ceres easier. + +#ifndef CERES_PUBLIC_JET_H_ +#define CERES_PUBLIC_JET_H_ + +#include +#include +#include // NOLINT +#include + +#include "Eigen/Core" + +// Visual Studio 2010 or older version +#if defined(_MSC_VER) && _MSC_VER <= 1600 +namespace std { +inline bool isfinite(double x) { return _finite(x); } +inline bool isinf (double x) { return !_finite(x) && !_isnan(x); } +inline bool isnan (double x) { return _isnan(x); } +inline bool isnormal(double x) { return _finite(x) && x != 0.0; } +} // namespace std +#endif + +namespace ceres { + +template +struct Jet { + enum { DIMENSION = N }; + + // Default-construct "a" because otherwise this can lead to false errors about + // uninitialized uses when other classes relying on default constructed T + // (where T is a Jet). This usually only happens in opt mode. Note that + // the C++ standard mandates that e.g. default constructed doubles are + // initialized to 0.0; see sections 8.5 of the C++03 standard. + Jet() : a() {} + + // Constructor from scalar: a + 0. + explicit Jet(const T& value) { + a = value; + v.setZero(); + } + + // Constructor from scalar plus variable: a + t_i. + Jet(const T& value, int k) { + a = value; + v.setZero(); + v[k] = T(1.0); + } + + // Compound operators + Jet& operator+=(const Jet &y) { + *this = *this + y; + return *this; + } + + Jet& operator-=(const Jet &y) { + *this = *this - y; + return *this; + } + + Jet& operator*=(const Jet &y) { + *this = *this * y; + return *this; + } + + Jet& operator/=(const Jet &y) { + *this = *this / y; + return *this; + } + + T a; // The scalar part. + Eigen::Matrix v; // The infinitesimal part. +}; + +// Unary + +template inline +Jet const& operator+(const Jet& f) { + return f; +} + +// TODO(keir): Try adding __attribute__((always_inline)) to these functions to +// see if it causes a performance increase. + +// Unary - +template inline +Jet operator-(const Jet&f) { + Jet g; + g.a = -f.a; + g.v = -f.v; + return g; +} + +// Binary + +template inline +Jet operator+(const Jet& f, + const Jet& g) { + Jet h; + h.a = f.a + g.a; + h.v = f.v + g.v; + return h; +} + +// Binary + with a scalar: x + s +template inline +Jet operator+(const Jet& f, T s) { + Jet h; + h.a = f.a + s; + h.v = f.v; + return h; +} + +// Binary + with a scalar: s + x +template inline +Jet operator+(T s, const Jet& f) { + Jet h; + h.a = f.a + s; + h.v = f.v; + return h; +} + +// Binary - +template inline +Jet operator-(const Jet& f, + const Jet& g) { + Jet h; + h.a = f.a - g.a; + h.v = f.v - g.v; + return h; +} + +// Binary - with a scalar: x - s +template inline +Jet operator-(const Jet& f, T s) { + Jet h; + h.a = f.a - s; + h.v = f.v; + return h; +} + +// Binary - with a scalar: s - x +template inline +Jet operator-(T s, const Jet& f) { + Jet h; + h.a = s - f.a; + h.v = -f.v; + return h; +} + +// Binary * +template inline +Jet operator*(const Jet& f, + const Jet& g) { + Jet h; + h.a = f.a * g.a; + h.v = f.a * g.v + f.v * g.a; + return h; +} + +// Binary * with a scalar: x * s +template inline +Jet operator*(const Jet& f, T s) { + Jet h; + h.a = f.a * s; + h.v = f.v * s; + return h; +} + +// Binary * with a scalar: s * x +template inline +Jet operator*(T s, const Jet& f) { + Jet h; + h.a = f.a * s; + h.v = f.v * s; + return h; +} + +// Binary / +template inline +Jet operator/(const Jet& f, + const Jet& g) { + Jet h; + // This uses: + // + // a + u (a + u)(b - v) (a + u)(b - v) + // ----- = -------------- = -------------- + // b + v (b + v)(b - v) b^2 + // + // which holds because v*v = 0. + h.a = f.a / g.a; + h.v = (f.v - f.a / g.a * g.v) / g.a; + return h; +} + +// Binary / with a scalar: s / x +template inline +Jet operator/(T s, const Jet& g) { + Jet h; + h.a = s / g.a; + h.v = - s * g.v / (g.a * g.a); + return h; +} + +// Binary / with a scalar: x / s +template inline +Jet operator/(const Jet& f, T s) { + Jet h; + h.a = f.a / s; + h.v = f.v / s; + return h; +} + +// Binary comparison operators for both scalars and jets. +#define CERES_DEFINE_JET_COMPARISON_OPERATOR(op) \ +template inline \ +bool operator op(const Jet& f, const Jet& g) { \ + return f.a op g.a; \ +} \ +template inline \ +bool operator op(const T& s, const Jet& g) { \ + return s op g.a; \ +} \ +template inline \ +bool operator op(const Jet& f, const T& s) { \ + return f.a op s; \ +} +CERES_DEFINE_JET_COMPARISON_OPERATOR( < ) // NOLINT +CERES_DEFINE_JET_COMPARISON_OPERATOR( <= ) // NOLINT +CERES_DEFINE_JET_COMPARISON_OPERATOR( > ) // NOLINT +CERES_DEFINE_JET_COMPARISON_OPERATOR( >= ) // NOLINT +CERES_DEFINE_JET_COMPARISON_OPERATOR( == ) // NOLINT +CERES_DEFINE_JET_COMPARISON_OPERATOR( != ) // NOLINT +#undef CERES_DEFINE_JET_COMPARISON_OPERATOR + +// Pull some functions from namespace std. +// +// This is necessary because we want to use the same name (e.g. 'sqrt') for +// double-valued and Jet-valued functions, but we are not allowed to put +// Jet-valued functions inside namespace std. +// +// Missing: cosh, sinh, tanh, tan +// TODO(keir): Switch to "using". +inline double abs (double x) { return std::abs(x); } +inline double log (double x) { return std::log(x); } +inline double exp (double x) { return std::exp(x); } +inline double sqrt (double x) { return std::sqrt(x); } +inline double cos (double x) { return std::cos(x); } +inline double acos (double x) { return std::acos(x); } +inline double sin (double x) { return std::sin(x); } +inline double asin (double x) { return std::asin(x); } +inline bool isfinite(double x) { return std::isfinite(x); } +inline bool isinf (double x) { return std::isinf(x); } +inline bool isnan (double x) { return std::isnan(x); } +inline bool isnormal(double x) { return std::isnormal(x); } +inline double pow (double x, double y) { return std::pow(x, y); } +inline double atan2(double y, double x) { return std::atan2(y, x); } + +// In general, f(a + h) ~= f(a) + f'(a) h, via the chain rule. + +// abs(x + h) ~= x + h or -(x + h) +template inline +Jet abs(const Jet& f) { + return f.a < T(0.0) ? -f : f; +} + +// log(a + h) ~= log(a) + h / a +template inline +Jet log(const Jet& f) { + Jet g; + g.a = log(f.a); + g.v = f.v / f.a; + return g; +} + +// exp(a + h) ~= exp(a) + exp(a) h +template inline +Jet exp(const Jet& f) { + Jet g; + g.a = exp(f.a); + g.v = g.a * f.v; + return g; +} + +// sqrt(a + h) ~= sqrt(a) + h / (2 sqrt(a)) +template inline +Jet sqrt(const Jet& f) { + Jet g; + g.a = sqrt(f.a); + g.v = f.v / (T(2.0) * g.a); + return g; +} + +// cos(a + h) ~= cos(a) - sin(a) h +template inline +Jet cos(const Jet& f) { + Jet g; + g.a = cos(f.a); + T sin_a = sin(f.a); + g.v = - sin_a * f.v; + return g; +} + +// acos(a + h) ~= acos(a) - 1 / sqrt(1 - a^2) h +template inline +Jet acos(const Jet& f) { + Jet g; + g.a = acos(f.a); + g.v = - T(1.0) / sqrt(T(1.0) - f.a * f.a) * f.v; + return g; +} + +// sin(a + h) ~= sin(a) + cos(a) h +template inline +Jet sin(const Jet& f) { + Jet g; + g.a = sin(f.a); + T cos_a = cos(f.a); + g.v = cos_a * f.v; + return g; +} + +// asin(a + h) ~= asin(a) + 1 / sqrt(1 - a^2) h +template inline +Jet asin(const Jet& f) { + Jet g; + g.a = asin(f.a); + g.v = T(1.0) / sqrt(T(1.0) - f.a * f.a) * f.v; + return g; +} + +// Jet Classification. It is not clear what the appropriate semantics are for +// these classifications. This picks that isfinite and isnormal are "all" +// operations, i.e. all elements of the jet must be finite for the jet itself to +// be finite (or normal). For isnan and isinf, the answer is less clear. This +// takes a "any" approach for isnan and isinf such that if any part of a jet is +// nan or inf, then the entire jet is nan or inf. This leads to strange +// situations like a jet can be both isinf and isnan, but in practice the "any" +// semantics are the most useful for e.g. checking that derivatives are sane. + +// The jet is finite if all parts of the jet are finite. +template inline +bool isfinite(const Jet& f) { + if (!isfinite(f.a)) { + return false; + } + for (int i = 0; i < N; ++i) { + if (!isfinite(f.v[i])) { + return false; + } + } + return true; +} + +// The jet is infinite if any part of the jet is infinite. +template inline +bool isinf(const Jet& f) { + if (isinf(f.a)) { + return true; + } + for (int i = 0; i < N; i++) { + if (isinf(f.v[i])) { + return true; + } + } + return false; +} + +// The jet is NaN if any part of the jet is NaN. +template inline +bool isnan(const Jet& f) { + if (isnan(f.a)) { + return true; + } + for (int i = 0; i < N; ++i) { + if (isnan(f.v[i])) { + return true; + } + } + return false; +} + +// The jet is normal if all parts of the jet are normal. +template inline +bool isnormal(const Jet& f) { + if (!isnormal(f.a)) { + return false; + } + for (int i = 0; i < N; ++i) { + if (!isnormal(f.v[i])) { + return false; + } + } + return true; +} + +// atan2(b + db, a + da) ~= atan2(b, a) + (- b da + a db) / (a^2 + b^2) +// +// In words: the rate of change of theta is 1/r times the rate of +// change of (x, y) in the positive angular direction. +template inline +Jet atan2(const Jet& g, const Jet& f) { + // Note order of arguments: + // + // f = a + da + // g = b + db + + Jet out; + + out.a = atan2(g.a, f.a); + + T const temp = T(1.0) / (f.a * f.a + g.a * g.a); + out.v = temp * (- g.a * f.v + f.a * g.v); + return out; +} + + +// pow -- base is a differentiatble function, exponent is a constant. +// (a+da)^p ~= a^p + p*a^(p-1) da +template inline +Jet pow(const Jet& f, double g) { + Jet out; + out.a = pow(f.a, g); + T const temp = g * pow(f.a, g - T(1.0)); + out.v = temp * f.v; + return out; +} + +// pow -- base is a constant, exponent is a differentiable function. +// (a)^(p+dp) ~= a^p + a^p log(a) dp +template inline +Jet pow(double f, const Jet& g) { + Jet out; + out.a = pow(f, g.a); + T const temp = log(f) * out.a; + out.v = temp * g.v; + return out; +} + + +// pow -- both base and exponent are differentiable functions. +// (a+da)^(b+db) ~= a^b + b * a^(b-1) da + a^b log(a) * db +template inline +Jet pow(const Jet& f, const Jet& g) { + Jet out; + + T const temp1 = pow(f.a, g.a); + T const temp2 = g.a * pow(f.a, g.a - T(1.0)); + T const temp3 = temp1 * log(f.a); + + out.a = temp1; + out.v = temp2 * f.v + temp3 * g.v; + return out; +} + +// Define the helper functions Eigen needs to embed Jet types. +// +// NOTE(keir): machine_epsilon() and precision() are missing, because they don't +// work with nested template types (e.g. where the scalar is itself templated). +// Among other things, this means that decompositions of Jet's does not work, +// for example +// +// Matrix ... > A, x, b; +// ... +// A.solve(b, &x) +// +// does not work and will fail with a strange compiler error. +// +// TODO(keir): This is an Eigen 2.0 limitation that is lifted in 3.0. When we +// switch to 3.0, also add the rest of the specialization functionality. +template inline const Jet& ei_conj(const Jet& x) { return x; } // NOLINT +template inline const Jet& ei_real(const Jet& x) { return x; } // NOLINT +template inline Jet ei_imag(const Jet& ) { return Jet(0.0); } // NOLINT +template inline Jet ei_abs (const Jet& x) { return fabs(x); } // NOLINT +template inline Jet ei_abs2(const Jet& x) { return x * x; } // NOLINT +template inline Jet ei_sqrt(const Jet& x) { return sqrt(x); } // NOLINT +template inline Jet ei_exp (const Jet& x) { return exp(x); } // NOLINT +template inline Jet ei_log (const Jet& x) { return log(x); } // NOLINT +template inline Jet ei_sin (const Jet& x) { return sin(x); } // NOLINT +template inline Jet ei_cos (const Jet& x) { return cos(x); } // NOLINT +template inline Jet ei_pow (const Jet& x, Jet y) { return pow(x, y); } // NOLINT + +// Note: This has to be in the ceres namespace for argument dependent lookup to +// function correctly. Otherwise statements like CHECK_LE(x, 2.0) fail with +// strange compile errors. +template +inline std::ostream &operator<<(std::ostream &s, const Jet& z) { + return s << "[" << z.a << " ; " << z.v.transpose() << "]"; +} + +} // namespace ceres + +namespace Eigen { + +// Creating a specialization of NumTraits enables placing Jet objects inside +// Eigen arrays, getting all the goodness of Eigen combined with autodiff. +template +struct NumTraits > { + typedef ceres::Jet Real; + typedef ceres::Jet NonInteger; + typedef ceres::Jet Nested; + + static typename ceres::Jet dummy_precision() { + return ceres::Jet(1e-12); + } + + enum { + IsComplex = 0, + IsInteger = 0, + IsSigned, + ReadCost = 1, + AddCost = 1, + // For Jet types, multiplication is more expensive than addition. + MulCost = 3, + HasFloatingPoint = 1 + }; +}; + +} // namespace Eigen + +#endif // CERES_PUBLIC_JET_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/local_parameterization.h b/extern/libmv/third_party/ceres/include/ceres/local_parameterization.h new file mode 100644 index 00000000000..c0f7dc77a57 --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/local_parameterization.h @@ -0,0 +1,189 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_PUBLIC_LOCAL_PARAMETERIZATION_H_ +#define CERES_PUBLIC_LOCAL_PARAMETERIZATION_H_ + +#include +#include "ceres/internal/port.h" + +namespace ceres { + +// Purpose: Sometimes parameter blocks x can overparameterize a problem +// +// min f(x) +// x +// +// In that case it is desirable to choose a parameterization for the +// block itself to remove the null directions of the cost. More +// generally, if x lies on a manifold of a smaller dimension than the +// ambient space that it is embedded in, then it is numerically and +// computationally more effective to optimize it using a +// parameterization that lives in the tangent space of that manifold +// at each point. +// +// For example, a sphere in three dimensions is a 2 dimensional +// manifold, embedded in a three dimensional space. At each point on +// the sphere, the plane tangent to it defines a two dimensional +// tangent space. For a cost function defined on this sphere, given a +// point x, moving in the direction normal to the sphere at that point +// is not useful. Thus a better way to do a local optimization is to +// optimize over two dimensional vector delta in the tangent space at +// that point and then "move" to the point x + delta, where the move +// operation involves projecting back onto the sphere. Doing so +// removes a redundent dimension from the optimization, making it +// numerically more robust and efficient. +// +// More generally we can define a function +// +// x_plus_delta = Plus(x, delta), +// +// where x_plus_delta has the same size as x, and delta is of size +// less than or equal to x. The function Plus, generalizes the +// definition of vector addition. Thus it satisfies the identify +// +// Plus(x, 0) = x, for all x. +// +// A trivial version of Plus is when delta is of the same size as x +// and +// +// Plus(x, delta) = x + delta +// +// A more interesting case if x is two dimensional vector, and the +// user wishes to hold the first coordinate constant. Then, delta is a +// scalar and Plus is defined as +// +// Plus(x, delta) = x + [0] * delta +// [1] +// +// An example that occurs commonly in Structure from Motion problems +// is when camera rotations are parameterized using Quaternion. There, +// it is useful only make updates orthogonal to that 4-vector defining +// the quaternion. One way to do this is to let delta be a 3 +// dimensional vector and define Plus to be +// +// Plus(x, delta) = [cos(|delta|), sin(|delta|) delta / |delta|] * x +// +// The multiplication between the two 4-vectors on the RHS is the +// standard quaternion product. +// +// Given g and a point x, optimizing f can now be restated as +// +// min f(Plus(x, delta)) +// delta +// +// Given a solution delta to this problem, the optimal value is then +// given by +// +// x* = Plus(x, delta) +// +// The class LocalParameterization defines the function Plus and its +// Jacobian which is needed to compute the Jacobian of f w.r.t delta. +class LocalParameterization { + public: + virtual ~LocalParameterization() {} + + // Generalization of the addition operation, + // + // x_plus_delta = Plus(x, delta) + // + // with the condition that Plus(x, 0) = x. + virtual bool Plus(const double* x, + const double* delta, + double* x_plus_delta) const = 0; + + // The jacobian of Plus(x, delta) w.r.t delta at delta = 0. + virtual bool ComputeJacobian(const double* x, double* jacobian) const = 0; + + // Size of x. + virtual int GlobalSize() const = 0; + + // Size of delta. + virtual int LocalSize() const = 0; +}; + +// Some basic parameterizations + +// Identity Parameterization: Plus(x, delta) = x + delta +class IdentityParameterization : public LocalParameterization { + public: + explicit IdentityParameterization(int size); + virtual ~IdentityParameterization() {} + virtual bool Plus(const double* x, + const double* delta, + double* x_plus_delta) const; + virtual bool ComputeJacobian(const double* x, + double* jacobian) const; + virtual int GlobalSize() const { return size_; } + virtual int LocalSize() const { return size_; } + + private: + const int size_; +}; + +// Hold a subset of the parameters inside a parameter block constant. +class SubsetParameterization : public LocalParameterization { + public: + explicit SubsetParameterization(int size, + const vector& constant_parameters); + virtual ~SubsetParameterization() {} + virtual bool Plus(const double* x, + const double* delta, + double* x_plus_delta) const; + virtual bool ComputeJacobian(const double* x, + double* jacobian) const; + virtual int GlobalSize() const { return constancy_mask_.size(); } + virtual int LocalSize() const { return local_size_; } + + private: + const int local_size_; + vector constancy_mask_; +}; + +// Plus(x, delta) = [cos(|delta|), sin(|delta|) delta / |delta|] * x +// with * being the quaternion multiplication operator. Here we assume +// that the first element of the quaternion vector is the real (cos +// theta) part. +class QuaternionParameterization : public LocalParameterization { + public: + virtual ~QuaternionParameterization() {} + virtual bool Plus(const double* x, + const double* delta, + double* x_plus_delta) const; + virtual bool ComputeJacobian(const double* x, + double* jacobian) const; + virtual int GlobalSize() const { return 4; } + virtual int LocalSize() const { return 3; } +}; + +} // namespace ceres + +#endif // CERES_PUBLIC_LOCAL_PARAMETERIZATION_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/loss_function.h b/extern/libmv/third_party/ceres/include/ceres/loss_function.h new file mode 100644 index 00000000000..81add02cdee --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/loss_function.h @@ -0,0 +1,322 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// The LossFunction interface is the way users describe how residuals +// are converted to cost terms for the overall problem cost function. +// For the exact manner in which loss functions are converted to the +// overall cost for a problem, see problem.h. +// +// For least squares problem where there are no outliers and standard +// squared loss is expected, it is not necessary to create a loss +// function; instead passing a NULL to the problem when adding +// residuals implies a standard squared loss. +// +// For least squares problems where the minimization may encounter +// input terms that contain outliers, that is, completely bogus +// measurements, it is important to use a loss function that reduces +// their associated penalty. +// +// Consider a structure from motion problem. The unknowns are 3D +// points and camera parameters, and the measurements are image +// coordinates describing the expected reprojected position for a +// point in a camera. For example, we want to model the geometry of a +// street scene with fire hydrants and cars, observed by a moving +// camera with unknown parameters, and the only 3D points we care +// about are the pointy tippy-tops of the fire hydrants. Our magic +// image processing algorithm, which is responsible for producing the +// measurements that are input to Ceres, has found and matched all +// such tippy-tops in all image frames, except that in one of the +// frame it mistook a car's headlight for a hydrant. If we didn't do +// anything special (i.e. if we used a basic quadratic loss), the +// residual for the erroneous measurement will result in extreme error +// due to the quadratic nature of squared loss. This results in the +// entire solution getting pulled away from the optimimum to reduce +// the large error that would otherwise be attributed to the wrong +// measurement. +// +// Using a robust loss function, the cost for large residuals is +// reduced. In the example above, this leads to outlier terms getting +// downweighted so they do not overly influence the final solution. +// +// What cost function is best? +// +// In general, there isn't a principled way to select a robust loss +// function. The authors suggest starting with a non-robust cost, then +// only experimenting with robust loss functions if standard squared +// loss doesn't work. + +#ifndef CERES_PUBLIC_LOSS_FUNCTION_H_ +#define CERES_PUBLIC_LOSS_FUNCTION_H_ + +#include +#include "ceres/internal/macros.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { + +class LossFunction { + public: + virtual ~LossFunction() {} + + // For a residual vector with squared 2-norm 'sq_norm', this method + // is required to fill in the value and derivatives of the loss + // function (rho in this example): + // + // out[0] = rho(sq_norm), + // out[1] = rho'(sq_norm), + // out[2] = rho''(sq_norm), + // + // Here the convention is that the contribution of a term to the + // cost function is given by 1/2 rho(s), where + // + // s = ||residuals||^2. + // + // Calling the method with a negative value of 's' is an error and + // the implementations are not required to handle that case. + // + // Most sane choices of rho() satisfy: + // + // rho(0) = 0, + // rho'(0) = 1, + // rho'(s) < 1 in outlier region, + // rho''(s) < 0 in outlier region, + // + // so that they mimic the least squares cost for small residuals. + virtual void Evaluate(double sq_norm, double out[3]) const = 0; +}; + +// Some common implementations follow below. +// +// Note: in the region of interest (i.e. s < 3) we have: +// TrivialLoss >= HuberLoss >= SoftLOneLoss >= CauchyLoss + + +// This corresponds to no robustification. +// +// rho(s) = s +// +// At s = 0: rho = [0, 1, 0]. +// +// It is not normally necessary to use this, as passing NULL for the +// loss function when building the problem accomplishes the same +// thing. +class TrivialLoss : public LossFunction { + public: + virtual void Evaluate(double, double*) const; +}; + +// Scaling +// ------- +// Given one robustifier +// s -> rho(s) +// one can change the length scale at which robustification takes +// place, by adding a scale factor 'a' as follows: +// +// s -> a^2 rho(s / a^2). +// +// The first and second derivatives are: +// +// s -> rho'(s / a^2), +// s -> (1 / a^2) rho''(s / a^2), +// +// but the behaviour near s = 0 is the same as the original function, +// i.e. +// +// rho(s) = s + higher order terms, +// a^2 rho(s / a^2) = s + higher order terms. +// +// The scalar 'a' should be positive. +// +// The reason for the appearance of squaring is that 'a' is in the +// units of the residual vector norm whereas 's' is a squared +// norm. For applications it is more convenient to specify 'a' than +// its square. The commonly used robustifiers below are described in +// un-scaled format (a = 1) but their implementations work for any +// non-zero value of 'a'. + +// Huber. +// +// rho(s) = s for s <= 1, +// rho(s) = 2 sqrt(s) - 1 for s >= 1. +// +// At s = 0: rho = [0, 1, 0]. +// +// The scaling parameter 'a' corresponds to 'delta' on this page: +// http://en.wikipedia.org/wiki/Huber_Loss_Function +class HuberLoss : public LossFunction { + public: + explicit HuberLoss(double a) : a_(a), b_(a * a) { } + virtual void Evaluate(double, double*) const; + private: + const double a_; + // b = a^2. + const double b_; +}; + +// Soft L1, similar to Huber but smooth. +// +// rho(s) = 2 (sqrt(1 + s) - 1). +// +// At s = 0: rho = [0, 1, -1/2]. +class SoftLOneLoss : public LossFunction { + public: + explicit SoftLOneLoss(double a) : b_(a * a), c_(1 / b_) { } + virtual void Evaluate(double, double*) const; + private: + // b = a^2. + const double b_; + // c = 1 / a^2. + const double c_; +}; + +// Inspired by the Cauchy distribution +// +// rho(s) = log(1 + s). +// +// At s = 0: rho = [0, 1, -1]. +class CauchyLoss : public LossFunction { + public: + explicit CauchyLoss(double a) : b_(a * a), c_(1 / b_) { } + virtual void Evaluate(double, double*) const; + private: + // b = a^2. + const double b_; + // c = 1 / a^2. + const double c_; +}; + +// The discussion above has to do with length scaling: it affects the space +// in which s is measured. Sometimes you want to simply scale the output +// value of the robustifier. For example, you might want to weight +// different error terms differently (e.g., weight pixel reprojection +// errors differently from terrain errors). +// +// If rho is the wrapped robustifier, then this simply outputs +// s -> a * rho(s) +// +// The first and second derivatives are, not surprisingly +// s -> a * rho'(s) +// s -> a * rho''(s) +// +// Since we treat the a NULL Loss function as the Identity loss +// function, rho = NULL is a valid input and will result in the input +// being scaled by a. This provides a simple way of implementing a +// scaled ResidualBlock. +class ScaledLoss : public LossFunction { + public: + // Constructs a ScaledLoss wrapping another loss function. Takes + // ownership of the wrapped loss function or not depending on the + // ownership parameter. + ScaledLoss(const LossFunction* rho, double a, Ownership ownership) : + rho_(rho), a_(a), ownership_(ownership) { } + + virtual ~ScaledLoss() { + if (ownership_ == DO_NOT_TAKE_OWNERSHIP) { + rho_.release(); + } + } + virtual void Evaluate(double, double*) const; + + private: + internal::scoped_ptr rho_; + const double a_; + const Ownership ownership_; + DISALLOW_COPY_AND_ASSIGN(ScaledLoss); +}; + +// Sometimes after the optimization problem has been constructed, we +// wish to mutate the scale of the loss function. For example, when +// performing estimation from data which has substantial outliers, +// convergence can be improved by starting out with a large scale, +// optimizing the problem and then reducing the scale. This can have +// better convergence behaviour than just using a loss function with a +// small scale. +// +// This templated class allows the user to implement a loss function +// whose scale can be mutated after an optimization problem has been +// constructed. +// +// Example usage +// +// Problem problem; +// +// // Add parameter blocks +// +// CostFunction* cost_function = +// new AutoDiffCostFunction < UW_Camera_Mapper, 2, 9, 3>( +// new UW_Camera_Mapper(data->observations[2*i + 0], +// data->observations[2*i + 1])); +// +// LossFunctionWrapper* loss_function(new HuberLoss(1.0), TAKE_OWNERSHIP); +// +// problem.AddResidualBlock(cost_function, loss_function, parameters); +// +// Solver::Options options; +// scoped_ptr summary1(Solve(problem, options)); +// +// loss_function->Reset(new HuberLoss(1.0), TAKE_OWNERSHIP); +// +// scoped_ptr summary2(Solve(problem, options)); +// +class LossFunctionWrapper : public LossFunction { + public: + LossFunctionWrapper(LossFunction* rho, Ownership ownership) + : rho_(rho), ownership_(ownership) { + } + + virtual ~LossFunctionWrapper() { + if (ownership_ == DO_NOT_TAKE_OWNERSHIP) { + rho_.release(); + } + } + + virtual void Evaluate(double sq_norm, double out[3]) const { + CHECK_NOTNULL(rho_.get()); + rho_->Evaluate(sq_norm, out); + } + + void Reset(LossFunction* rho, Ownership ownership) { + if (ownership_ == DO_NOT_TAKE_OWNERSHIP) { + rho_.release(); + } + rho_.reset(rho); + ownership_ = ownership; + } + + private: + internal::scoped_ptr rho_; + Ownership ownership_; + DISALLOW_COPY_AND_ASSIGN(LossFunctionWrapper); +}; + +} // namespace ceres + +#endif // CERES_PUBLIC_LOSS_FUNCTION_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/normal_prior.h b/extern/libmv/third_party/ceres/include/ceres/normal_prior.h new file mode 100644 index 00000000000..480a07474a7 --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/normal_prior.h @@ -0,0 +1,75 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Cost term that implements a prior on a parameter block using a +// normal distribution. + +#ifndef CERES_PUBLIC_NORMAL_PRIOR_H_ +#define CERES_PUBLIC_NORMAL_PRIOR_H_ + +#include "ceres/cost_function.h" +#include "ceres/internal/eigen.h" + +namespace ceres { + +// Implements a cost function of the form +// +// cost(x) = ||A(x - b)||^2 +// +// where, the matrix A and the vector b are fixed and x is the +// variable. In case the user is interested in implementing a cost +// function of the form +// +// cost(x) = (x - mu)^T S^{-1} (x - mu) +// +// where, mu is a vector and S is a covariance matrix, then, A = +// S^{-1/2}, i.e the matrix A is the square root of the inverse of the +// covariance, also known as the stiffness matrix. There are however +// no restrictions on the shape of A. It is free to be rectangular, +// which would be the case if the covariance matrix S is rank +// deficient. + +class NormalPrior: public CostFunction { + public: + // Check that the number of rows in the vector b are the same as the + // number of columns in the matrix A, crash otherwise. + NormalPrior(const Matrix& A, const Vector& b); + + virtual bool Evaluate(double const* const* parameters, + double* residuals, + double** jacobians) const; + private: + Matrix A_; + Vector b_; +}; + +} // namespace ceres + +#endif // CERES_PUBLIC_NORMAL_PRIOR_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h new file mode 100644 index 00000000000..bbaefca5b6c --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h @@ -0,0 +1,283 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// Create CostFunctions as needed by the least squares framework with jacobians +// computed via numeric (a.k.a. finite) differentiation. For more details see +// http://en.wikipedia.org/wiki/Numerical_differentiation. +// +// To get a numerically differentiated cost function, define a subclass of +// CostFunction such that the Evaluate() function ignores the jacobian +// parameter. The numeric differentiation wrapper will fill in the jacobian +// parameter if nececssary by repeatedly calling the Evaluate() function with +// small changes to the appropriate parameters, and computing the slope. For +// performance, the numeric differentiation wrapper class is templated on the +// concrete cost function, even though it could be implemented only in terms of +// the virtual CostFunction interface. +// +// The numerically differentiated version of a cost function for a cost function +// can be constructed as follows: +// +// CostFunction* cost_function +// = new NumericDiffCostFunction( +// new MyCostFunction(...), TAKE_OWNERSHIP); +// +// where MyCostFunction has 1 residual and 2 parameter blocks with sizes 4 and 8 +// respectively. Look at the tests for a more detailed example. +// +// The central difference method is considerably more accurate at the cost of +// twice as many function evaluations than forward difference. Consider using +// central differences begin with, and only after that works, trying forward +// difference to improve performance. +// +// TODO(keir): Characterize accuracy; mention pitfalls; provide alternatives. + +#ifndef CERES_PUBLIC_NUMERIC_DIFF_COST_FUNCTION_H_ +#define CERES_PUBLIC_NUMERIC_DIFF_COST_FUNCTION_H_ + +#include +#include +#include "Eigen/Dense" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/sized_cost_function.h" +#include "ceres/types.h" + +namespace ceres { + +enum NumericDiffMethod { + CENTRAL, + FORWARD +}; + +// This is split from the main class because C++ doesn't allow partial template +// specializations for member functions. The alternative is to repeat the main +// class for differing numbers of parameters, which is also unfortunate. +template +struct Differencer { + // Mutates parameters but must restore them before return. + static bool EvaluateJacobianForParameterBlock( + const CostFunctionNoJacobian *function, + double const* residuals_at_eval_point, + double **parameters, + double **jacobians) { + using Eigen::Map; + using Eigen::Matrix; + using Eigen::RowMajor; + + typedef Matrix ResidualVector; + typedef Matrix ParameterVector; + typedef Matrix + JacobianMatrix; + + Map parameter_jacobian(jacobians[parameter_block], + num_residuals, + parameter_block_size); + + // Mutate 1 element at a time and then restore. + Map x_plus_delta(parameters[parameter_block], + parameter_block_size); + ParameterVector x(x_plus_delta); + + // TODO(keir): Pick a smarter number! In theory a good choice is sqrt(eps) * + // x, which for doubles means about 1e-8 * x. However, I have found this + // number too optimistic. This number should be exposed for users to change. + const double kRelativeStepSize = 1e-6; + + ParameterVector step_size = x.array().abs() * kRelativeStepSize; + + // To handle cases where a parameter is exactly zero, instead use the mean + // step_size for the other dimensions. + double fallback_step_size = step_size.sum() / step_size.rows(); + if (fallback_step_size == 0.0) { + // If all the parameters are zero, there's no good answer. Take + // kRelativeStepSize as a guess and hope for the best. + fallback_step_size = kRelativeStepSize; + } + + // For each parameter in the parameter block, use finite differences to + // compute the derivative for that parameter. + for (int j = 0; j < parameter_block_size; ++j) { + if (step_size(j) == 0.0) { + // The parameter is exactly zero, so compromise and use the mean + // step_size from the other parameters. This can break in many cases, + // but it's hard to pick a good number without problem specific + // knowledge. + step_size(j) = fallback_step_size; + } + x_plus_delta(j) = x(j) + step_size(j); + + double residuals[num_residuals]; // NOLINT + if (!function->Evaluate(parameters, residuals, NULL)) { + // Something went wrong; bail. + return false; + } + + // Compute this column of the jacobian in 3 steps: + // 1. Store residuals for the forward part. + // 2. Subtract residuals for the backward (or 0) part. + // 3. Divide out the run. + parameter_jacobian.col(j) = + Map(residuals, num_residuals); + + double one_over_h = 1 / step_size(j); + if (method == CENTRAL) { + // Compute the function on the other side of x(j). + x_plus_delta(j) = x(j) - step_size(j); + + if (!function->Evaluate(parameters, residuals, NULL)) { + // Something went wrong; bail. + return false; + } + parameter_jacobian.col(j) -= + Map(residuals, num_residuals, 1); + one_over_h /= 2; + } else { + // Forward difference only; reuse existing residuals evaluation. + parameter_jacobian.col(j) -= + Map(residuals_at_eval_point, num_residuals); + } + x_plus_delta(j) = x(j); // Restore x_plus_delta. + + // Divide out the run to get slope. + parameter_jacobian.col(j) *= one_over_h; + } + return true; + } +}; + +// Prevent invalid instantiations. +template +struct Differencer { + static bool EvaluateJacobianForParameterBlock( + const CostFunctionNoJacobian *function, + double const* residuals_at_eval_point, + double **parameters, + double **jacobians) { + LOG(FATAL) << "Shouldn't get here."; + return true; + } +}; + +template +class NumericDiffCostFunction + : public SizedCostFunction { + public: + NumericDiffCostFunction(CostFunctionNoJacobian* function, + Ownership ownership) + : function_(function), ownership_(ownership) {} + + virtual ~NumericDiffCostFunction() { + if (ownership_ != TAKE_OWNERSHIP) { + function_.release(); + } + } + + virtual bool Evaluate(double const* const* parameters, + double* residuals, + double** jacobians) const { + // Get the function value (residuals) at the the point to evaluate. + bool success = function_->Evaluate(parameters, residuals, NULL); + if (!success) { + // Something went wrong; ignore the jacobian. + return false; + } + if (!jacobians) { + // Nothing to do; just forward. + return true; + } + + // Create a copy of the parameters which will get mutated. + const int kParametersSize = N0 + N1 + N2 + N3 + N4 + N5; + double parameters_copy[kParametersSize]; + double *parameters_references_copy[6]; + parameters_references_copy[0] = ¶meters_copy[0]; + parameters_references_copy[1] = ¶meters_copy[0] + N0; + parameters_references_copy[2] = ¶meters_copy[0] + N0 + N1; + parameters_references_copy[3] = ¶meters_copy[0] + N0 + N1 + N2; + parameters_references_copy[4] = ¶meters_copy[0] + N0 + N1 + N2 + N3; + parameters_references_copy[5] = + ¶meters_copy[0] + N0 + N1 + N2 + N3 + N4; + +#define COPY_PARAMETER_BLOCK(block) \ + if (N ## block) memcpy(parameters_references_copy[block], \ + parameters[block], \ + sizeof(double) * N ## block); // NOLINT + COPY_PARAMETER_BLOCK(0); + COPY_PARAMETER_BLOCK(1); + COPY_PARAMETER_BLOCK(2); + COPY_PARAMETER_BLOCK(3); + COPY_PARAMETER_BLOCK(4); + COPY_PARAMETER_BLOCK(5); +#undef COPY_PARAMETER_BLOCK + +#define EVALUATE_JACOBIAN_FOR_BLOCK(block) \ + if (N ## block && jacobians[block]) { \ + if (!Differencer::EvaluateJacobianForParameterBlock( \ + function_.get(), \ + residuals, \ + parameters_references_copy, \ + jacobians)) { \ + return false; \ + } \ + } + EVALUATE_JACOBIAN_FOR_BLOCK(0); + EVALUATE_JACOBIAN_FOR_BLOCK(1); + EVALUATE_JACOBIAN_FOR_BLOCK(2); + EVALUATE_JACOBIAN_FOR_BLOCK(3); + EVALUATE_JACOBIAN_FOR_BLOCK(4); + EVALUATE_JACOBIAN_FOR_BLOCK(5); +#undef EVALUATE_JACOBIAN_FOR_BLOCK + return true; + } + + private: + internal::scoped_ptr function_; + Ownership ownership_; +}; + +} // namespace ceres + +#endif // CERES_PUBLIC_NUMERIC_DIFF_COST_FUNCTION_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/problem.h b/extern/libmv/third_party/ceres/include/ceres/problem.h new file mode 100644 index 00000000000..0ca61006bdb --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/problem.h @@ -0,0 +1,265 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// keir@google.com (Keir Mierle) +// +// The Problem object is used to build and hold least squares problems. + +#ifndef CERES_PUBLIC_PROBLEM_H_ +#define CERES_PUBLIC_PROBLEM_H_ + +#include +#include +#include +#include + +#include +#include "ceres/internal/macros.h" +#include "ceres/internal/port.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { + +class CostFunction; +class LossFunction; +class LocalParameterization; + +namespace internal { +class Preprocessor; +class ProblemImpl; +class ParameterBlock; +class ResidualBlock; +class SolverImpl; +} // namespace internal + +// A ResidualBlockId is a handle clients can use to delete residual +// blocks after creating them. They are opaque for any purposes other +// than that. +typedef const internal::ResidualBlock* ResidualBlockId; + +// A class to represent non-linear least squares problems. Such +// problems have a cost function that is a sum of error terms (known +// as "residuals"), where each residual is a function of some subset +// of the parameters. The cost function takes the form +// +// N 1 +// SUM --- loss( || r_i1, r_i2,..., r_ik ||^2 ), +// i=1 2 +// +// where +// +// r_ij is residual number i, component j; the residual is a +// function of some subset of the parameters x1...xk. For +// example, in a structure from motion problem a residual +// might be the difference between a measured point in an +// image and the reprojected position for the matching +// camera, point pair. The residual would have two +// components, error in x and error in y. +// +// loss(y) is the loss function; for example, squared error or +// Huber L1 loss. If loss(y) = y, then the cost function is +// non-robustified least squares. +// +// This class is specifically designed to address the important subset +// of "sparse" least squares problems, where each component of the +// residual depends only on a small number number of parameters, even +// though the total number of residuals and parameters may be very +// large. This property affords tremendous gains in scale, allowing +// efficient solving of large problems that are otherwise +// inaccessible. +// +// The canonical example of a sparse least squares problem is +// "structure-from-motion" (SFM), where the parameters are points and +// cameras, and residuals are reprojection errors. Typically a single +// residual will depend only on 9 parameters (3 for the point, 6 for +// the camera). +// +// To create a least squares problem, use the AddResidualBlock() and +// AddParameterBlock() methods, documented below. Here is an example least +// squares problem containing 3 parameter blocks of sizes 3, 4 and 5 +// respectively and two residual terms of size 2 and 6: +// +// double x1[] = { 1.0, 2.0, 3.0 }; +// double x2[] = { 1.0, 2.0, 3.0, 5.0 }; +// double x3[] = { 1.0, 2.0, 3.0, 6.0, 7.0 }; +// +// Problem problem; +// +// problem.AddResidualBlock(new MyUnaryCostFunction(...), x1); +// problem.AddResidualBlock(new MyBinaryCostFunction(...), x2, x3); +// +// Please see cost_function.h for details of the CostFunction object. +class Problem { + public: + struct Options { + Options() + : cost_function_ownership(TAKE_OWNERSHIP), + loss_function_ownership(TAKE_OWNERSHIP), + local_parameterization_ownership(TAKE_OWNERSHIP) {} + + // These flags control whether the Problem object owns the cost + // functions, loss functions, and parameterizations passed into + // the Problem. If set to TAKE_OWNERSHIP, then the problem object + // will delete the corresponding cost or loss functions on + // destruction. The destructor is careful to delete the pointers + // only once, since sharing cost/loss/parameterizations is + // allowed. + Ownership cost_function_ownership; + Ownership loss_function_ownership; + Ownership local_parameterization_ownership; + }; + + // The default constructor is equivalent to the + // invocation Problem(Problem::Options()). + Problem(); + explicit Problem(const Options& options); + + ~Problem(); + + // Add a residual block to the overall cost function. The cost + // function carries with it information about the sizes of the + // parameter blocks it expects. The function checks that these match + // the sizes of the parameter blocks listed in parameter_blocks. The + // program aborts if a mismatch is detected. loss_function can be + // NULL, in which case the cost of the term is just the squared norm + // of the residuals. + // + // The user has the option of explicitly adding the parameter blocks + // using AddParameterBlock. This causes additional correctness + // checking; however, AddResidualBlock implicitly adds the parameter + // blocks if they are not present, so calling AddParameterBlock + // explicitly is not required. + // + // The Problem object by default takes ownership of the + // cost_function and loss_function pointers. These objects remain + // live for the life of the Problem object. If the user wishes to + // keep control over the destruction of these objects, then they can + // do this by setting the corresponding enums in the Options struct. + // + // Note: Even though the Problem takes ownership of cost_function + // and loss_function, it does not preclude the user from re-using + // them in another residual block. The destructor takes care to call + // delete on each cost_function or loss_function pointer only once, + // regardless of how many residual blocks refer to them. + // + // Example usage: + // + // double x1[] = {1.0, 2.0, 3.0}; + // double x2[] = {1.0, 2.0, 5.0, 6.0}; + // double x3[] = {3.0, 6.0, 2.0, 5.0, 1.0}; + // + // Problem problem; + // + // problem.AddResidualBlock(new MyUnaryCostFunction(...), NULL, x1); + // problem.AddResidualBlock(new MyBinaryCostFunction(...), NULL, x2, x1); + // + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + const vector& parameter_blocks); + + // Convenience methods for adding residuals with a small number of + // parameters. This is the common case. Instead of specifying the + // parameter block arguments as a vector, list them as pointers. + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0); + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1); + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2); + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, + double* x3); + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, + double* x3, double* x4); + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, + double* x3, double* x4, double* x5); + + // Add a parameter block with appropriate size to the problem. + // Repeated calls with the same arguments are ignored. Repeated + // calls with the same double pointer but a different size results + // in undefined behaviour. + void AddParameterBlock(double* values, int size); + + // Add a parameter block with appropriate size and parameterization + // to the problem. Repeated calls with the same arguments are + // ignored. Repeated calls with the same double pointer but a + // different size results in undefined behaviour. + void AddParameterBlock(double* values, + int size, + LocalParameterization* local_parameterization); + + // Hold the indicated parameter block constant during optimization. + void SetParameterBlockConstant(double* values); + + // Allow the indicated parameter to vary during optimization. + void SetParameterBlockVariable(double* values); + + // Set the local parameterization for one of the parameter blocks. + // The local_parameterization is owned by the Problem by default. It + // is acceptable to set the same parameterization for multiple + // parameters; the destructor is careful to delete local + // parameterizations only once. The local parameterization can only + // be set once per parameter, and cannot be changed once set. + void SetParameterization(double* values, + LocalParameterization* local_parameterization); + + // Number of parameter blocks in the problem. Always equals + // parameter_blocks().size() and parameter_block_sizes().size(). + int NumParameterBlocks() const; + + // The size of the parameter vector obtained by summing over the + // sizes of all the parameter blocks. + int NumParameters() const; + + // Number of residual blocks in the problem. Always equals + // residual_blocks().size(). + int NumResidualBlocks() const; + + // The size of the residual vector obtained by summing over the + // sizes of all of the residual blocks. + int NumResiduals() const; + + private: + friend class internal::SolverImpl; + internal::scoped_ptr problem_impl_; + DISALLOW_COPY_AND_ASSIGN(Problem); +}; + +} // namespace ceres + +#endif // CERES_PUBLIC_PROBLEM_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/rotation.h b/extern/libmv/third_party/ceres/include/ceres/rotation.h new file mode 100644 index 00000000000..e4227e78b9a --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/rotation.h @@ -0,0 +1,526 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// sameeragarwal@google.com (Sameer Agarwal) +// +// Templated functions for manipulating rotations. The templated +// functions are useful when implementing functors for automatic +// differentiation. +// +// In the following, the Quaternions are laid out as 4-vectors, thus: +// +// q[0] scalar part. +// q[1] coefficient of i. +// q[2] coefficient of j. +// q[3] coefficient of k. +// +// where: i*i = j*j = k*k = -1 and i*j = k, j*k = i, k*i = j. + +#ifndef CERES_PUBLIC_ROTATION_H_ +#define CERES_PUBLIC_ROTATION_H_ + +#include +#include + +namespace ceres { + +// Convert a value in combined axis-angle representation to a quaternion. +// The value angle_axis is a triple whose norm is an angle in radians, +// and whose direction is aligned with the axis of rotation, +// and quaternion is a 4-tuple that will contain the resulting quaternion. +// The implementation may be used with auto-differentiation up to the first +// derivative, higher derivatives may have unexpected results near the origin. +template +void AngleAxisToQuaternion(T const* angle_axis, T* quaternion); + +// Convert a quaternion to the equivalent combined axis-angle representation. +// The value quaternion must be a unit quaternion - it is not normalized first, +// and angle_axis will be filled with a value whose norm is the angle of +// rotation in radians, and whose direction is the axis of rotation. +// The implemention may be used with auto-differentiation up to the first +// derivative, higher derivatives may have unexpected results near the origin. +template +void QuaternionToAngleAxis(T const* quaternion, T* angle_axis); + +// Conversions between 3x3 rotation matrix (in column major order) and +// axis-angle rotation representations. Templated for use with +// autodifferentiation. +template +void RotationMatrixToAngleAxis(T const * R, T * angle_axis); +template +void AngleAxisToRotationMatrix(T const * angle_axis, T * R); + +// Conversions between 3x3 rotation matrix (in row major order) and +// Euler angle (in degrees) rotation representations. +// +// The {pitch,roll,yaw} Euler angles are rotations around the {x,y,z} +// axes, respectively. They are applied in that same order, so the +// total rotation R is Rz * Ry * Rx. +template +void EulerAnglesToRotationMatrix(const T* euler, int row_stride, T* R); + +// Convert a 4-vector to a 3x3 scaled rotation matrix. +// +// The choice of rotation is such that the quaternion [1 0 0 0] goes to an +// identity matrix and for small a, b, c the quaternion [1 a b c] goes to +// the matrix +// +// [ 0 -c b ] +// I + 2 [ c 0 -a ] + higher order terms +// [ -b a 0 ] +// +// which corresponds to a Rodrigues approximation, the last matrix being +// the cross-product matrix of [a b c]. Together with the property that +// R(q1 * q2) = R(q1) * R(q2) this uniquely defines the mapping from q to R. +// +// The rotation matrix is row-major. +// +// No normalization of the quaternion is performed, i.e. +// R = ||q||^2 * Q, where Q is an orthonormal matrix +// such that det(Q) = 1 and Q*Q' = I +template inline +void QuaternionToScaledRotation(const T q[4], T R[3 * 3]); + +// Same as above except that the rotation matrix is normalized by the +// Frobenius norm, so that R * R' = I (and det(R) = 1). +template inline +void QuaternionToRotation(const T q[4], T R[3 * 3]); + +// Rotates a point pt by a quaternion q: +// +// result = R(q) * pt +// +// Assumes the quaternion is unit norm. This assumption allows us to +// write the transform as (something)*pt + pt, as is clear from the +// formula below. If you pass in a quaternion with |q|^2 = 2 then you +// WILL NOT get back 2 times the result you get for a unit quaternion. +template inline +void UnitQuaternionRotatePoint(const T q[4], const T pt[3], T result[3]); + +// With this function you do not need to assume that q has unit norm. +// It does assume that the norm is non-zero. +template inline +void QuaternionRotatePoint(const T q[4], const T pt[3], T result[3]); + +// zw = z * w, where * is the Quaternion product between 4 vectors. +template inline +void QuaternionProduct(const T z[4], const T w[4], T zw[4]); + +// xy = x cross y; +template inline +void CrossProduct(const T x[3], const T y[3], T x_cross_y[3]); + +template inline +T DotProduct(const T x[3], const T y[3]); + +// y = R(angle_axis) * x; +template inline +void AngleAxisRotatePoint(const T angle_axis[3], const T pt[3], T result[3]); + +// --- IMPLEMENTATION + +// Duplicate rather than decorate every use of cmath with _USE_MATH_CONSTANTS. +// Necessitated by Windows. +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#define CERES_NEED_M_PI_UNDEF +#endif + +template +inline void AngleAxisToQuaternion(const T* angle_axis, T* quaternion) { + const T &a0 = angle_axis[0]; + const T &a1 = angle_axis[1]; + const T &a2 = angle_axis[2]; + const T theta_squared = a0 * a0 + a1 * a1 + a2 * a2; + + // For points not at the origin, the full conversion is numerically stable. + if (theta_squared > T(0.0)) { + const T theta = sqrt(theta_squared); + const T half_theta = theta * T(0.5); + const T k = sin(half_theta) / theta; + quaternion[0] = cos(half_theta); + quaternion[1] = a0 * k; + quaternion[2] = a1 * k; + quaternion[3] = a2 * k; + } else { + // At the origin, sqrt() will produce NaN in the derivative since + // the argument is zero. By approximating with a Taylor series, + // and truncating at one term, the value and first derivatives will be + // computed correctly when Jets are used. + const T k(0.5); + quaternion[0] = T(1.0); + quaternion[1] = a0 * k; + quaternion[2] = a1 * k; + quaternion[3] = a2 * k; + } +} + +template +inline void QuaternionToAngleAxis(const T* quaternion, T* angle_axis) { + const T &q1 = quaternion[1]; + const T &q2 = quaternion[2]; + const T &q3 = quaternion[3]; + const T sin_squared = q1 * q1 + q2 * q2 + q3 * q3; + + // For quaternions representing non-zero rotation, the conversion + // is numerically stable. + if (sin_squared > T(0.0)) { + const T sin_theta = sqrt(sin_squared); + const T k = T(2.0) * atan2(sin_theta, quaternion[0]) / sin_theta; + angle_axis[0] = q1 * k; + angle_axis[1] = q2 * k; + angle_axis[2] = q3 * k; + } else { + // For zero rotation, sqrt() will produce NaN in the derivative since + // the argument is zero. By approximating with a Taylor series, + // and truncating at one term, the value and first derivatives will be + // computed correctly when Jets are used. + const T k(2.0); + angle_axis[0] = q1 * k; + angle_axis[1] = q2 * k; + angle_axis[2] = q3 * k; + } +} + +// The conversion of a rotation matrix to the angle-axis form is +// numerically problematic when then rotation angle is close to zero +// or to Pi. The following implementation detects when these two cases +// occurs and deals with them by taking code paths that are guaranteed +// to not perform division by a small number. +template +inline void RotationMatrixToAngleAxis(const T * R, T * angle_axis) { + // x = k * 2 * sin(theta), where k is the axis of rotation. + angle_axis[0] = R[5] - R[7]; + angle_axis[1] = R[6] - R[2]; + angle_axis[2] = R[1] - R[3]; + + static const T kOne = T(1.0); + static const T kTwo = T(2.0); + + // Since the right hand side may give numbers just above 1.0 or + // below -1.0 leading to atan misbehaving, we threshold. + T costheta = std::min(std::max((R[0] + R[4] + R[8] - kOne) / kTwo, + T(-1.0)), + kOne); + + // sqrt is guaranteed to give non-negative results, so we only + // threshold above. + T sintheta = std::min(sqrt(angle_axis[0] * angle_axis[0] + + angle_axis[1] * angle_axis[1] + + angle_axis[2] * angle_axis[2]) / kTwo, + kOne); + + // Use the arctan2 to get the right sign on theta + const T theta = atan2(sintheta, costheta); + + // Case 1: sin(theta) is large enough, so dividing by it is not a + // problem. We do not use abs here, because while jets.h imports + // std::abs into the namespace, here in this file, abs resolves to + // the int version of the function, which returns zero always. + // + // We use a threshold much larger then the machine epsilon, because + // if sin(theta) is small, not only do we risk overflow but even if + // that does not occur, just dividing by a small number will result + // in numerical garbage. So we play it safe. + static const double kThreshold = 1e-12; + if ((sintheta > kThreshold) || (sintheta < -kThreshold)) { + const T r = theta / (kTwo * sintheta); + for (int i = 0; i < 3; ++i) { + angle_axis[i] *= r; + } + return; + } + + // Case 2: theta ~ 0, means sin(theta) ~ theta to a good + // approximation. + if (costheta > 0) { + const T kHalf = T(0.5); + for (int i = 0; i < 3; ++i) { + angle_axis[i] *= kHalf; + } + return; + } + + // Case 3: theta ~ pi, this is the hard case. Since theta is large, + // and sin(theta) is small. Dividing by theta by sin(theta) will + // either give an overflow or worse still numerically meaningless + // results. Thus we use an alternate more complicated formula + // here. + + // Since cos(theta) is negative, division by (1-cos(theta)) cannot + // overflow. + const T inv_one_minus_costheta = kOne / (kOne - costheta); + + // We now compute the absolute value of coordinates of the axis + // vector using the diagonal entries of R. To resolve the sign of + // these entries, we compare the sign of angle_axis[i]*sin(theta) + // with the sign of sin(theta). If they are the same, then + // angle_axis[i] should be positive, otherwise negative. + for (int i = 0; i < 3; ++i) { + angle_axis[i] = theta * sqrt((R[i*4] - costheta) * inv_one_minus_costheta); + if (((sintheta < 0) && (angle_axis[i] > 0)) || + ((sintheta > 0) && (angle_axis[i] < 0))) { + angle_axis[i] = -angle_axis[i]; + } + } +} + +template +inline void AngleAxisToRotationMatrix(const T * angle_axis, T * R) { + static const T kOne = T(1.0); + const T theta2 = DotProduct(angle_axis, angle_axis); + if (theta2 > 0.0) { + // We want to be careful to only evaluate the square root if the + // norm of the angle_axis vector is greater than zero. Otherwise + // we get a division by zero. + const T theta = sqrt(theta2); + const T wx = angle_axis[0] / theta; + const T wy = angle_axis[1] / theta; + const T wz = angle_axis[2] / theta; + + const T costheta = cos(theta); + const T sintheta = sin(theta); + + R[0] = costheta + wx*wx*(kOne - costheta); + R[1] = wz*sintheta + wx*wy*(kOne - costheta); + R[2] = -wy*sintheta + wx*wz*(kOne - costheta); + R[3] = wx*wy*(kOne - costheta) - wz*sintheta; + R[4] = costheta + wy*wy*(kOne - costheta); + R[5] = wx*sintheta + wy*wz*(kOne - costheta); + R[6] = wy*sintheta + wx*wz*(kOne - costheta); + R[7] = -wx*sintheta + wy*wz*(kOne - costheta); + R[8] = costheta + wz*wz*(kOne - costheta); + } else { + // At zero, we switch to using the first order Taylor expansion. + R[0] = kOne; + R[1] = -angle_axis[2]; + R[2] = angle_axis[1]; + R[3] = angle_axis[2]; + R[4] = kOne; + R[5] = -angle_axis[0]; + R[6] = -angle_axis[1]; + R[7] = angle_axis[0]; + R[8] = kOne; + } +} + +template +inline void EulerAnglesToRotationMatrix(const T* euler, + const int row_stride, + T* R) { + const T degrees_to_radians(M_PI / 180.0); + + const T pitch(euler[0] * degrees_to_radians); + const T roll(euler[1] * degrees_to_radians); + const T yaw(euler[2] * degrees_to_radians); + + const T c1 = cos(yaw); + const T s1 = sin(yaw); + const T c2 = cos(roll); + const T s2 = sin(roll); + const T c3 = cos(pitch); + const T s3 = sin(pitch); + + // Rows of the rotation matrix. + T* R1 = R; + T* R2 = R1 + row_stride; + T* R3 = R2 + row_stride; + + R1[0] = c1*c2; + R1[1] = -s1*c3 + c1*s2*s3; + R1[2] = s1*s3 + c1*s2*c3; + + R2[0] = s1*c2; + R2[1] = c1*c3 + s1*s2*s3; + R2[2] = -c1*s3 + s1*s2*c3; + + R3[0] = -s2; + R3[1] = c2*s3; + R3[2] = c2*c3; +} + +template inline +void QuaternionToScaledRotation(const T q[4], T R[3 * 3]) { + // Make convenient names for elements of q. + T a = q[0]; + T b = q[1]; + T c = q[2]; + T d = q[3]; + // This is not to eliminate common sub-expression, but to + // make the lines shorter so that they fit in 80 columns! + T aa = a * a; + T ab = a * b; + T ac = a * c; + T ad = a * d; + T bb = b * b; + T bc = b * c; + T bd = b * d; + T cc = c * c; + T cd = c * d; + T dd = d * d; + + R[0] = aa + bb - cc - dd; R[1] = T(2) * (bc - ad); R[2] = T(2) * (ac + bd); // NOLINT + R[3] = T(2) * (ad + bc); R[4] = aa - bb + cc - dd; R[5] = T(2) * (cd - ab); // NOLINT + R[6] = T(2) * (bd - ac); R[7] = T(2) * (ab + cd); R[8] = aa - bb - cc + dd; // NOLINT +} + +template inline +void QuaternionToRotation(const T q[4], T R[3 * 3]) { + QuaternionToScaledRotation(q, R); + + T normalizer = q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]; + CHECK_NE(normalizer, T(0)); + normalizer = T(1) / normalizer; + + for (int i = 0; i < 9; ++i) { + R[i] *= normalizer; + } +} + +template inline +void UnitQuaternionRotatePoint(const T q[4], const T pt[3], T result[3]) { + const T t2 = q[0] * q[1]; + const T t3 = q[0] * q[2]; + const T t4 = q[0] * q[3]; + const T t5 = -q[1] * q[1]; + const T t6 = q[1] * q[2]; + const T t7 = q[1] * q[3]; + const T t8 = -q[2] * q[2]; + const T t9 = q[2] * q[3]; + const T t1 = -q[3] * q[3]; + result[0] = T(2) * ((t8 + t1) * pt[0] + (t6 - t4) * pt[1] + (t3 + t7) * pt[2]) + pt[0]; // NOLINT + result[1] = T(2) * ((t4 + t6) * pt[0] + (t5 + t1) * pt[1] + (t9 - t2) * pt[2]) + pt[1]; // NOLINT + result[2] = T(2) * ((t7 - t3) * pt[0] + (t2 + t9) * pt[1] + (t5 + t8) * pt[2]) + pt[2]; // NOLINT +} + + +template inline +void QuaternionRotatePoint(const T q[4], const T pt[3], T result[3]) { + // 'scale' is 1 / norm(q). + const T scale = T(1) / sqrt(q[0] * q[0] + + q[1] * q[1] + + q[2] * q[2] + + q[3] * q[3]); + + // Make unit-norm version of q. + const T unit[4] = { + scale * q[0], + scale * q[1], + scale * q[2], + scale * q[3], + }; + + UnitQuaternionRotatePoint(unit, pt, result); +} + +template inline +void QuaternionProduct(const T z[4], const T w[4], T zw[4]) { + zw[0] = z[0] * w[0] - z[1] * w[1] - z[2] * w[2] - z[3] * w[3]; + zw[1] = z[0] * w[1] + z[1] * w[0] + z[2] * w[3] - z[3] * w[2]; + zw[2] = z[0] * w[2] - z[1] * w[3] + z[2] * w[0] + z[3] * w[1]; + zw[3] = z[0] * w[3] + z[1] * w[2] - z[2] * w[1] + z[3] * w[0]; +} + +// xy = x cross y; +template inline +void CrossProduct(const T x[3], const T y[3], T x_cross_y[3]) { + x_cross_y[0] = x[1] * y[2] - x[2] * y[1]; + x_cross_y[1] = x[2] * y[0] - x[0] * y[2]; + x_cross_y[2] = x[0] * y[1] - x[1] * y[0]; +} + +template inline +T DotProduct(const T x[3], const T y[3]) { + return (x[0] * y[0] + x[1] * y[1] + x[2] * y[2]); +} + +template inline +void AngleAxisRotatePoint(const T angle_axis[3], const T pt[3], T result[3]) { + T w[3]; + T sintheta; + T costheta; + + const T theta2 = DotProduct(angle_axis, angle_axis); + if (theta2 > 0.0) { + // Away from zero, use the rodriguez formula + // + // result = pt costheta + + // (w x pt) * sintheta + + // w (w . pt) (1 - costheta) + // + // We want to be careful to only evaluate the square root if the + // norm of the angle_axis vector is greater than zero. Otherwise + // we get a division by zero. + // + const T theta = sqrt(theta2); + w[0] = angle_axis[0] / theta; + w[1] = angle_axis[1] / theta; + w[2] = angle_axis[2] / theta; + costheta = cos(theta); + sintheta = sin(theta); + T w_cross_pt[3]; + CrossProduct(w, pt, w_cross_pt); + T w_dot_pt = DotProduct(w, pt); + for (int i = 0; i < 3; ++i) { + result[i] = pt[i] * costheta + + w_cross_pt[i] * sintheta + + w[i] * (T(1.0) - costheta) * w_dot_pt; + } + } else { + // Near zero, the first order Taylor approximation of the rotation + // matrix R corresponding to a vector w and angle w is + // + // R = I + hat(w) * sin(theta) + // + // But sintheta ~ theta and theta * w = angle_axis, which gives us + // + // R = I + hat(w) + // + // and actually performing multiplication with the point pt, gives us + // R * pt = pt + w x pt. + // + // Switching to the Taylor expansion at zero helps avoid all sorts + // of numerical nastiness. + T w_cross_pt[3]; + CrossProduct(angle_axis, pt, w_cross_pt); + for (int i = 0; i < 3; ++i) { + result[i] = pt[i] + w_cross_pt[i]; + } + } +} + +} // namespace ceres + +// Clean define pollution. +#ifdef CERES_NEED_M_PI_UNDEF +#undef CERES_NEED_M_PI_UNDEF +#undef M_PI +#endif + +#endif // CERES_PUBLIC_ROTATION_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h new file mode 100644 index 00000000000..968285b8f1e --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h @@ -0,0 +1,82 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// A convenience class for cost functions which are statically sized. +// Compared to the dynamically-sized base class, this reduces boilerplate. + +#ifndef CERES_PUBLIC_SIZED_COST_FUNCTION_H_ +#define CERES_PUBLIC_SIZED_COST_FUNCTION_H_ + +#include +#include "ceres/cost_function.h" + +namespace ceres { + +template +class SizedCostFunction : public CostFunction { + public: + SizedCostFunction() { + // Sanity checking. + DCHECK_GT(kNumResiduals, 0) << "Cost functions must have at least " + << "one residual block."; + DCHECK_GT(N0, 0) + << "Cost functions must have at least one parameter block."; + DCHECK((!N1 && !N2 && !N3 && !N4 && !N5) || + ((N1 > 0) && !N2 && !N3 && !N4 && !N5) || + ((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5) || + ((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5) || + ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5) || + ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0))) + << "Zero block cannot precede a non-zero block. Block sizes are " + << "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", " + << N3 << ", " << N4 << ", " << N5; + + set_num_residuals(kNumResiduals); + +#define ADD_PARAMETER_BLOCK(N) \ + if (N) mutable_parameter_block_sizes()->push_back(N); + ADD_PARAMETER_BLOCK(N0); + ADD_PARAMETER_BLOCK(N1); + ADD_PARAMETER_BLOCK(N2); + ADD_PARAMETER_BLOCK(N3); + ADD_PARAMETER_BLOCK(N4); + ADD_PARAMETER_BLOCK(N5); +#undef ADD_PARAMETER_BLOCK + } + + virtual ~SizedCostFunction() { } + + // Subclasses must implement Evaluate(). +}; + +} // namespace ceres + +#endif // CERES_PUBLIC_SIZED_COST_FUNCTION_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/solver.h b/extern/libmv/third_party/ceres/include/ceres/solver.h new file mode 100644 index 00000000000..15fd7332d21 --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/solver.h @@ -0,0 +1,379 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_PUBLIC_SOLVER_H_ +#define CERES_PUBLIC_SOLVER_H_ + +#include +#include +#include + +#include "ceres/iteration_callback.h" +#include "ceres/internal/macros.h" +#include "ceres/internal/port.h" +#include "ceres/types.h" + +namespace ceres { + +class Problem; + +// Interface for non-linear least squares solvers. +class Solver { + public: + virtual ~Solver(); + + // The options structure contains, not surprisingly, options that control how + // the solver operates. The defaults should be suitable for a wide range of + // problems; however, better performance is often obtainable with tweaking. + // + // The constants are defined inside types.h + struct Options { + // Default constructor that sets up a generic sparse problem. + Options() { + minimizer_type = LEVENBERG_MARQUARDT; + max_num_iterations = 50; + max_solver_time_sec = 1.0e9; + num_threads = 1; + tau = 1e-4; + min_relative_decrease = 1e-3; + function_tolerance = 1e-6; + gradient_tolerance = 1e-10; + parameter_tolerance = 1e-8; +#ifndef CERES_NO_SUITESPARSE + linear_solver_type = SPARSE_NORMAL_CHOLESKY; +#else + linear_solver_type = DENSE_QR; +#endif // CERES_NO_SUITESPARSE + preconditioner_type = JACOBI; + num_linear_solver_threads = 1; + num_eliminate_blocks = 0; + ordering_type = NATURAL; + linear_solver_min_num_iterations = 1; + linear_solver_max_num_iterations = 500; + eta = 1e-1; + jacobi_scaling = true; + logging_type = PER_MINIMIZER_ITERATION; + minimizer_progress_to_stdout = false; + return_initial_residuals = false; + return_final_residuals = false; + lsqp_dump_format = "lm_iteration_%03d.lsqp"; + crash_and_dump_lsqp_on_failure = false; + check_gradients = false; + gradient_check_relative_precision = 1e-8; + numeric_derivative_relative_step_size = 1e-6; + update_state_every_iteration = false; + } + + // Minimizer options ---------------------------------------- + + MinimizerType minimizer_type; + + // Maximum number of iterations for the minimizer to run for. + int max_num_iterations; + + // Maximum time for which the minimizer should run for. + double max_solver_time_sec; + + // Number of threads used by Ceres for evaluating the cost and + // jacobians. + int num_threads; + + // For Levenberg-Marquardt, the initial value for the + // regularizer. This is the inversely related to the size of the + // initial trust region. + double tau; + + // For trust region methods, this is lower threshold for the + // relative decrease before a step is accepted. + double min_relative_decrease; + + // Minimizer terminates when + // + // (new_cost - old_cost) < function_tolerance * old_cost; + // + double function_tolerance; + + // Minimizer terminates when + // + // max_i |gradient_i| < gradient_tolerance * max_i|initial_gradient_i| + // + // This value should typically be 1e-4 * function_tolerance. + double gradient_tolerance; + + // Minimizer terminates when + // + // |step|_2 <= parameter_tolerance * ( |x|_2 + parameter_tolerance) + // + double parameter_tolerance; + + // Linear least squares solver options ------------------------------------- + + LinearSolverType linear_solver_type; + + // Type of preconditioner to use with the iterative linear solvers. + PreconditionerType preconditioner_type; + + // Number of threads used by Ceres to solve the Newton + // step. Currently only the SPARSE_SCHUR solver is capable of + // using this setting. + int num_linear_solver_threads; + + // For Schur reduction based methods, the first 0 to num blocks are + // eliminated using the Schur reduction. For example, when solving + // traditional structure from motion problems where the parameters are in + // two classes (cameras and points) then num_eliminate_blocks would be the + // number of points. + // + // This parameter is used in conjunction with the ordering. + // Applies to: Preprocessor and linear least squares solver. + int num_eliminate_blocks; + + // Internally Ceres reorders the parameter blocks to help the + // various linear solvers. This parameter allows the user to + // influence the re-ordering strategy used. For structure from + // motion problems use SCHUR, for other problems NATURAL (default) + // is a good choice. In case you wish to specify your own ordering + // scheme, for example in conjunction with num_eliminate_blocks, + // use USER. + OrderingType ordering_type; + + // The ordering of the parameter blocks. The solver pays attention + // to it if the ordering_type is set to USER and the vector is + // non-empty. + vector ordering; + + + // Minimum number of iterations for which the linear solver should + // run, even if the convergence criterion is satisfied. + int linear_solver_min_num_iterations; + + // Maximum number of iterations for which the linear solver should + // run. If the solver does not converge in less than + // linear_solver_max_num_iterations, then it returns + // MAX_ITERATIONS, as its termination type. + int linear_solver_max_num_iterations; + + // Forcing sequence parameter. The truncated Newton solver uses + // this number to control the relative accuracy with which the + // Newton step is computed. + // + // This constant is passed to ConjugateGradientsSolver which uses + // it to terminate the iterations when + // + // (Q_i - Q_{i-1})/Q_i < eta/i + double eta; + + // Normalize the jacobian using Jacobi scaling before calling + // the linear least squares solver. + bool jacobi_scaling; + + // Logging options --------------------------------------------------------- + + LoggingType logging_type; + + // By default the Minimizer progress is logged to VLOG(1), which + // is sent to STDERR depending on the vlog level. If this flag is + // set to true, and logging_type is not SILENT, the logging output + // is sent to STDOUT. + bool minimizer_progress_to_stdout; + + bool return_initial_residuals; + bool return_final_residuals; + + // List of iterations at which the optimizer should dump the + // linear least squares problem to disk. Useful for testing and + // benchmarking. If empty (default), no problems are dumped. + // + // This is ignored if protocol buffers are disabled. + vector lsqp_iterations_to_dump; + + // Format string for the file name used for dumping the least + // squares problem to disk. If the format is 'ascii', then the + // problem is logged to the screen; don't try this with large + // problems or expect a frozen terminal. + string lsqp_dump_format; + + // Dump the linear least squares problem to disk if the minimizer + // fails due to NUMERICAL_FAILURE and crash the process. This flag + // is useful for generating debugging information. The problem is + // dumped in a file whose name is determined by + // Solver::Options::lsqp_dump_format. + // + // Note: This requires a version of Ceres built with protocol buffers. + bool crash_and_dump_lsqp_on_failure; + + // Finite differences options ---------------------------------------------- + + // Check all jacobians computed by each residual block with finite + // differences. This is expensive since it involves computing the + // derivative by normal means (e.g. user specified, autodiff, + // etc), then also computing it using finite differences. The + // results are compared, and if they differ substantially, details + // are printed to the log. + bool check_gradients; + + // Relative precision to check for in the gradient checker. If the + // relative difference between an element in a jacobian exceeds + // this number, then the jacobian for that cost term is dumped. + double gradient_check_relative_precision; + + // Relative shift used for taking numeric derivatives. For finite + // differencing, each dimension is evaluated at slightly shifted + // values; for the case of central difference, this is what gets + // evaluated: + // + // delta = numeric_derivative_relative_step_size; + // f_initial = f(x) + // f_forward = f((1 + delta) * x) + // f_backward = f((1 - delta) * x) + // + // The finite differencing is done along each dimension. The + // reason to use a relative (rather than absolute) step size is + // that this way, numeric differentation works for functions where + // the arguments are typically large (e.g. 1e9) and when the + // values are small (e.g. 1e-5). It is possible to construct + // "torture cases" which break this finite difference heuristic, + // but they do not come up often in practice. + // + // TODO(keir): Pick a smarter number than the default above! In + // theory a good choice is sqrt(eps) * x, which for doubles means + // about 1e-8 * x. However, I have found this number too + // optimistic. This number should be exposed for users to change. + double numeric_derivative_relative_step_size; + + // If true, the user's parameter blocks are updated at the end of + // every Minimizer iteration, otherwise they are updated when the + // Minimizer terminates. This is useful if, for example, the user + // wishes to visualize the state of the optimization every + // iteration. + bool update_state_every_iteration; + + // Callbacks that are executed at the end of each iteration of the + // Minimizer. They are executed in the order that they are + // specified in this vector. By default, parameter blocks are + // updated only at the end of the optimization, i.e when the + // Minimizer terminates. This behaviour is controlled by + // update_state_every_variable. If the user wishes to have access + // to the update parameter blocks when his/her callbacks are + // executed, then set update_state_every_iteration to true. + // + // The solver does NOT take ownership of these pointers. + vector callbacks; + }; + + struct Summary { + Summary(); + + // A brief one line description of the state of the solver after + // termination. + string BriefReport() const; + + // A full multiline description of the state of the solver after + // termination. + string FullReport() const; + + // Minimizer summary ------------------------------------------------- + SolverTerminationType termination_type; + + // If the solver did not run, or there was a failure, a + // description of the error. + string error; + + // Cost of the problem before and after the optimization. See + // problem.h for definition of the cost of a problem. + double initial_cost; + double final_cost; + + // The part of the total cost that comes from residual blocks that + // were held fixed by the preprocessor because all the parameter + // blocks that they depend on were fixed. + double fixed_cost; + + // Residuals before and after the optimization. Each vector + // contains problem.NumResiduals() elements. Residuals are in the + // same order in which they were added to the problem object when + // constructing this problem. + vector initial_residuals; + vector final_residuals; + + vector iterations; + + int num_successful_steps; + int num_unsuccessful_steps; + + double preprocessor_time_in_seconds; + double minimizer_time_in_seconds; + double total_time_in_seconds; + + // Preprocessor summary. + int num_parameter_blocks; + int num_parameters; + int num_residual_blocks; + int num_residuals; + + int num_parameter_blocks_reduced; + int num_parameters_reduced; + int num_residual_blocks_reduced; + int num_residuals_reduced; + + int num_eliminate_blocks_given; + int num_eliminate_blocks_used; + + int num_threads_given; + int num_threads_used; + + int num_linear_solver_threads_given; + int num_linear_solver_threads_used; + + LinearSolverType linear_solver_type_given; + LinearSolverType linear_solver_type_used; + + PreconditionerType preconditioner_type; + OrderingType ordering_type; + }; + + // Once a least squares problem has been built, this function takes + // the problem and optimizes it based on the values of the options + // parameters. Upon return, a detailed summary of the work performed + // by the preprocessor, the non-linear minmizer and the linear + // solver are reported in the summary object. + virtual void Solve(const Options& options, + Problem* problem, + Solver::Summary* summary); +}; + +// Helper function which avoids going through the interface. +void Solve(const Solver::Options& options, + Problem* problem, + Solver::Summary* summary); + +} // namespace ceres + +#endif // CERES_PUBLIC_SOLVER_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/types.h b/extern/libmv/third_party/ceres/include/ceres/types.h new file mode 100644 index 00000000000..b83a266d1ba --- /dev/null +++ b/extern/libmv/third_party/ceres/include/ceres/types.h @@ -0,0 +1,224 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Enums and other top level class definitions. +// +// Note: internal/types.cc defines stringification routines for some +// of these enums. Please update those routines if you extend or +// remove enums from here. + +#ifndef CERES_PUBLIC_TYPES_H_ +#define CERES_PUBLIC_TYPES_H_ + +namespace ceres { + +// Basic integer types. These typedefs are in the Ceres namespace to avoid +// conflicts with other packages having similar typedefs. +typedef short int16; +typedef int int32; + +// Argument type used in interfaces that can optionally take ownership +// of a passed in argument. If TAKE_OWNERSHIP is passed, the called +// object takes ownership of the pointer argument, and will call +// delete on it upon completion. +enum Ownership { + DO_NOT_TAKE_OWNERSHIP, + TAKE_OWNERSHIP +}; + +// TODO(keir): Considerably expand the explanations of each solver type. +enum LinearSolverType { + // These solvers are for general rectangular systems formed from the + // normal equations A'A x = A'b. They are direct solvers and do not + // assume any special problem structure. + + // Solve the normal equations using a sparse cholesky solver; based + // on CHOLMOD. + SPARSE_NORMAL_CHOLESKY, + + // Solve the normal equations using a dense QR solver; based on + // Eigen. + DENSE_QR, + + // Specialized solvers, specific to problems with a generalized + // bi-partitite structure. + + // Solves the reduced linear system using a dense Cholesky solver; + // based on Eigen. + DENSE_SCHUR, + + // Solves the reduced linear system using a sparse Cholesky solver; + // based on CHOLMOD. + SPARSE_SCHUR, + + // Solves the reduced linear system using Conjugate Gradients, based + // on a new Ceres implementation. Suitable for large scale + // problems. + ITERATIVE_SCHUR, + + // Conjugate gradients on the normal equations. + CGNR +}; + +enum PreconditionerType { + // Trivial preconditioner - the identity matrix. + IDENTITY, + + // Block diagonal of the Gauss-Newton Hessian. + JACOBI, + + // Block diagonal of the Schur complement. This preconditioner may + // only be used with the ITERATIVE_SCHUR solver. Requires + // SuiteSparse/CHOLMOD. + SCHUR_JACOBI, + + // Visibility clustering based preconditioners. + // + // These preconditioners are well suited for Structure from Motion + // problems, particularly problems arising from community photo + // collections. These preconditioners use the visibility structure + // of the scene to determine the sparsity structure of the + // preconditioner. Requires SuiteSparse/CHOLMOD. + CLUSTER_JACOBI, + CLUSTER_TRIDIAGONAL +}; + +enum LinearSolverTerminationType { + // Termination criterion was met. For factorization based solvers + // the tolerance is assumed to be zero. Any user provided values are + // ignored. + TOLERANCE, + + // Solver ran for max_num_iterations and terminated before the + // termination tolerance could be satified. + MAX_ITERATIONS, + + // Solver is stuck and further iterations will not result in any + // measurable progress. + STAGNATION, + + // Solver failed. Solver was terminated due to numerical errors. The + // exact cause of failure depends on the particular solver being + // used. + FAILURE +}; + +enum OrderingType { + // The order in which the parameter blocks were defined. + NATURAL, + + // Use the ordering specificed in the vector ordering. + USER, + + // Automatically figure out the best ordering to use the schur + // complement based solver. + SCHUR +}; + +// Logging options +// The options get progressively noisier. +enum LoggingType { + SILENT, + PER_MINIMIZER_ITERATION +}; + +enum MinimizerType { + LEVENBERG_MARQUARDT +}; + +enum SolverTerminationType { + // The minimizer did not run at all; usually due to errors in the user's + // Problem or the solver options. + DID_NOT_RUN, + + // The solver ran for maximum number of iterations specified by the + // user, but none of the convergence criterion specified by the user + // were met. + NO_CONVERGENCE, + + // Minimizer terminated because + // (new_cost - old_cost) < function_tolerance * old_cost; + FUNCTION_TOLERANCE, + + // Minimizer terminated because + // max_i |gradient_i| < gradient_tolerance * max_i|initial_gradient_i| + GRADIENT_TOLERANCE, + + // Minimized terminated because + // |step|_2 <= parameter_tolerance * ( |x|_2 + parameter_tolerance) + PARAMETER_TOLERANCE, + + // The minimizer terminated because it encountered a numerical error + // that it could not recover from. + NUMERICAL_FAILURE, + + // Using an IterationCallback object, user code can control the + // minimizer. The following enums indicate that the user code was + // responsible for termination. + + // User's IterationCallback returned SOLVER_ABORT. + USER_ABORT, + + // User's IterationCallback returned SOLVER_TERMINATE_SUCCESSFULLY + USER_SUCCESS +}; + +// Enums used by the IterationCallback instances to indicate to the +// solver whether it should continue solving, the user detected an +// error or the solution is good enough and the solver should +// terminate. +enum CallbackReturnType { + // Continue solving to next iteration. + SOLVER_CONTINUE, + + // Terminate solver, and do not update the parameter blocks upon + // return. Unless the user has set + // Solver:Options:::update_state_every_iteration, in which case the + // state would have been updated every iteration + // anyways. Solver::Summary::termination_type is set to USER_ABORT. + SOLVER_ABORT, + + // Terminate solver, update state and + // return. Solver::Summary::termination_type is set to USER_SUCCESS. + SOLVER_TERMINATE_SUCCESSFULLY +}; + +const char* LinearSolverTypeToString(LinearSolverType type); +const char* PreconditionerTypeToString(PreconditionerType type); +const char* LinearSolverTerminationTypeToString( + LinearSolverTerminationType type); +const char* OrderingTypeToString(OrderingType type); +const char* SolverTerminationTypeToString(SolverTerminationType type); + +bool IsSchurType(LinearSolverType type); + +} // namespace ceres + +#endif // CERES_PUBLIC_TYPES_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_evaluate_preparer.cc b/extern/libmv/third_party/ceres/internal/ceres/block_evaluate_preparer.cc new file mode 100644 index 00000000000..05e63eb560b --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_evaluate_preparer.cc @@ -0,0 +1,73 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include "ceres/block_evaluate_preparer.h" + +#include +#include "ceres/block_sparse_matrix.h" +#include "ceres/casts.h" +#include "ceres/parameter_block.h" +#include "ceres/residual_block.h" +#include "ceres/sparse_matrix.h" + +namespace ceres { +namespace internal { + +void BlockEvaluatePreparer::Init(int** jacobian_layout) { + jacobian_layout_ = jacobian_layout; +} + +// Point the jacobian blocks directly into the block sparse matrix. +void BlockEvaluatePreparer::Prepare(const ResidualBlock* residual_block, + int residual_block_index, + SparseMatrix* jacobian, + double** jacobians) const { + CHECK(jacobian != NULL); + double* jacobian_values = + down_cast(jacobian)->mutable_values(); + + const int* jacobian_block_offset = jacobian_layout_[residual_block_index]; + const int num_parameter_blocks = residual_block->NumParameterBlocks(); + for (int j = 0; j < num_parameter_blocks; ++j) { + if (!residual_block->parameter_blocks()[j]->IsConstant()) { + jacobians[j] = jacobian_values + *jacobian_block_offset; + + // The jacobian_block_offset can't be indexed with 'j' since the code + // that creates the layout strips out any blocks for inactive + // parameters. Instead, bump the pointer for active parameters only. + jacobian_block_offset++; + } else { + jacobians[j] = NULL; + } + } +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_evaluate_preparer.h b/extern/libmv/third_party/ceres/internal/ceres/block_evaluate_preparer.h new file mode 100644 index 00000000000..a7869311e6e --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_evaluate_preparer.h @@ -0,0 +1,67 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// A evaluate preparer which puts jacobian the evaluated jacobian blocks +// directly into their final resting place in an overall block sparse matrix. +// The evaluator takes care to avoid evaluating the jacobian for fixed +// parameters. + +#ifndef CERES_INTERNAL_BLOCK_EVALUATE_PREPARER_H_ +#define CERES_INTERNAL_BLOCK_EVALUATE_PREPARER_H_ + +namespace ceres { +namespace internal { + +class ResidualBlock; +class SparseMatrix; + +class BlockEvaluatePreparer { + public: + // Using Init() instead of a constructor allows for allocating this structure + // with new[]. This is because C++ doesn't allow passing arguments to objects + // constructed with new[] (as opposed to plain 'new'). + void Init(int** jacobian_layout); + + // EvaluatePreparer interface + + // Point the jacobian blocks directly into the block sparse matrix. + void Prepare(const ResidualBlock* residual_block, + int residual_block_index, + SparseMatrix* jacobian, + double** jacobians) const; + + private: + int const* const* jacobian_layout_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_BLOCK_EVALUATE_PREPARER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc new file mode 100644 index 00000000000..1a5001f9c71 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc @@ -0,0 +1,136 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include "ceres/block_jacobi_preconditioner.h" + +#include "Eigen/Cholesky" +#include "ceres/block_sparse_matrix.h" +#include "ceres/block_structure.h" +#include "ceres/casts.h" +#include "ceres/integral_types.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +BlockJacobiPreconditioner::BlockJacobiPreconditioner( + const LinearOperator& A) + : block_structure_( + *(down_cast(&A)->block_structure())), + num_rows_(A.num_rows()) { + // Calculate the amount of storage needed. + int storage_needed = 0; + for (int c = 0; c < block_structure_.cols.size(); ++c) { + int size = block_structure_.cols[c].size; + storage_needed += size * size; + } + + // Size the offsets and storage. + blocks_.resize(block_structure_.cols.size()); + block_storage_.resize(storage_needed); + + // Put pointers to the storage in the offsets. + double* block_cursor = &block_storage_[0]; + for (int c = 0; c < block_structure_.cols.size(); ++c) { + int size = block_structure_.cols[c].size; + blocks_[c] = block_cursor; + block_cursor += size * size; + } +} + +BlockJacobiPreconditioner::~BlockJacobiPreconditioner() { +} + +void BlockJacobiPreconditioner::Update(const LinearOperator& matrix, const double* D) { + const BlockSparseMatrix& A = *(down_cast(&matrix)); + const CompressedRowBlockStructure* bs = A.block_structure(); + + // Compute the diagonal blocks by block inner products. + std::fill(block_storage_.begin(), block_storage_.end(), 0.0); + for (int r = 0; r < bs->rows.size(); ++r) { + const int row_block_size = bs->rows[r].block.size; + const vector& cells = bs->rows[r].cells; + const double* row_values = A.RowBlockValues(r); + for (int c = 0; c < cells.size(); ++c) { + const int col_block_size = bs->cols[cells[c].block_id].size; + ConstMatrixRef m(row_values + cells[c].position, + row_block_size, + col_block_size); + + MatrixRef(blocks_[cells[c].block_id], + col_block_size, + col_block_size).noalias() += m.transpose() * m; + + // TODO(keir): Figure out when the below expression is actually faster + // than doing the full rank update. The issue is that for smaller sizes, + // the rankUpdate() function is slower than the full product done above. + // + // On the typical bundling problems, the above product is ~5% faster. + // + // MatrixRef(blocks_[cells[c].block_id], + // col_block_size, + // col_block_size).selfadjointView().rankUpdate(m); + // + } + } + + // Add the diagonal and invert each block. + for (int c = 0; c < bs->cols.size(); ++c) { + const int size = block_structure_.cols[c].size; + const int position = block_structure_.cols[c].position; + MatrixRef block(blocks_[c], size, size); + + if (D != NULL) { + block.diagonal() += ConstVectorRef(D + position, size).array().square().matrix(); + } + + block = block.selfadjointView() + .ldlt() + .solve(Matrix::Identity(size, size)); + } +} + +void BlockJacobiPreconditioner::RightMultiply(const double* x, double* y) const { + for (int c = 0; c < block_structure_.cols.size(); ++c) { + const int size = block_structure_.cols[c].size; + const int position = block_structure_.cols[c].position; + ConstMatrixRef D(blocks_[c], size, size); + ConstVectorRef x_block(x + position, size); + VectorRef y_block(y + position, size); + y_block += D * x_block; + } +} + +void BlockJacobiPreconditioner::LeftMultiply(const double* x, double* y) const { + RightMultiply(x, y); +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h new file mode 100644 index 00000000000..91cfeddb688 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h @@ -0,0 +1,84 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#ifndef CERES_INTERNAL_BLOCK_JACOBI_PRECONDITIONER_H_ +#define CERES_INTERNAL_BLOCK_JACOBI_PRECONDITIONER_H_ + +#include +#include "ceres/linear_operator.h" + +namespace ceres { +namespace internal { + +class CompressedRowBlockStructure; +class LinearOperator; +class SparseMatrix; + +// A block Jacobi preconditioner. This is intended for use with conjugate +// gradients, or other iterative symmetric solvers. To use the preconditioner, +// create one by passing a BlockSparseMatrix as the linear operator "A" to the +// constructor. This fixes the sparsity pattern to the pattern of the matrix +// A^TA. +// +// Before each use of the preconditioner in a solve with conjugate gradients, +// update the matrix by running Update(A, D). The values of the matrix A are +// inspected to construct the preconditioner. The vector D is applied as the +// D^TD diagonal term. +class BlockJacobiPreconditioner : public LinearOperator { + public: + // A must remain valid while the BlockJacobiPreconditioner is. + BlockJacobiPreconditioner(const LinearOperator& A); + virtual ~BlockJacobiPreconditioner(); + + // Update the preconditioner with the values found in A. The sparsity pattern + // must match that of the A passed to the constructor. D is a vector that + // must have the same number of rows as A, and is applied as a diagonal in + // addition to the block diagonals of A. + void Update(const LinearOperator& A, const double* D); + + // LinearOperator interface. + virtual void RightMultiply(const double* x, double* y) const; + virtual void LeftMultiply(const double* x, double* y) const; + virtual int num_rows() const { return num_rows_; } + virtual int num_cols() const { return num_rows_; } + + private: + std::vector blocks_; + std::vector block_storage_; + int num_rows_; + + // The block structure of the matrix this preconditioner is for (e.g. J). + const CompressedRowBlockStructure& block_structure_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_BLOCK_JACOBI_PRECONDITIONER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_jacobian_writer.cc b/extern/libmv/third_party/ceres/internal/ceres/block_jacobian_writer.cc new file mode 100644 index 00000000000..52a58bb43a6 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_jacobian_writer.cc @@ -0,0 +1,209 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include "ceres/block_jacobian_writer.h" + +#include "ceres/block_evaluate_preparer.h" +#include "ceres/block_sparse_matrix.h" +#include "ceres/parameter_block.h" +#include "ceres/program.h" +#include "ceres/residual_block.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { +namespace { + +// Given the residual block ordering, build a lookup table to determine which +// per-parameter jacobian goes where in the overall program jacobian. +// +// Since we expect to use a Schur type linear solver to solve the LM step, take +// extra care to place the E blocks and the F blocks contiguously. E blocks are +// the first num_eliminate_blocks parameter blocks as indicated by the parameter +// block ordering. The remaining parameter blocks are the F blocks. +// +// TODO(keir): Consider if we should use a boolean for each parameter block +// instead of num_eliminate_blocks. +void BuildJacobianLayout(const Program& program, + int num_eliminate_blocks, + vector* jacobian_layout, + vector* jacobian_layout_storage) { + const vector& residual_blocks = program.residual_blocks(); + + // Iterate over all the active residual blocks and determine how many E blocks + // are there. This will determine where the F blocks start in the jacobian + // matrix. Also compute the number of jacobian blocks. + int f_block_pos = 0; + int num_jacobian_blocks = 0; + for (int i = 0; i < residual_blocks.size(); ++i) { + ResidualBlock* residual_block = residual_blocks[i]; + const int num_residuals = residual_block->NumResiduals(); + const int num_parameter_blocks = residual_block->NumParameterBlocks(); + + // Advance f_block_pos over each E block for this residual. + for (int j = 0; j < num_parameter_blocks; ++j) { + ParameterBlock* parameter_block = residual_block->parameter_blocks()[j]; + if (!parameter_block->IsConstant()) { + // Only count blocks for active parameters. + num_jacobian_blocks++; + if (parameter_block->index() < num_eliminate_blocks) { + f_block_pos += num_residuals * parameter_block->LocalSize(); + } + } + } + } + + // We now know that the E blocks are laid out starting at zero, and the F + // blocks are laid out starting at f_block_pos. Iterate over the residual + // blocks again, and this time fill the jacobian_layout array with the + // position information. + + jacobian_layout->resize(program.NumResidualBlocks()); + jacobian_layout_storage->resize(num_jacobian_blocks); + + int e_block_pos = 0; + int* jacobian_pos = &(*jacobian_layout_storage)[0]; + for (int i = 0; i < residual_blocks.size(); ++i) { + const ResidualBlock* residual_block = residual_blocks[i]; + const int num_residuals = residual_block->NumResiduals(); + const int num_parameter_blocks = residual_block->NumParameterBlocks(); + + (*jacobian_layout)[i] = jacobian_pos; + for (int j = 0; j < num_parameter_blocks; ++j) { + ParameterBlock* parameter_block = residual_block->parameter_blocks()[j]; + const int parameter_block_index = parameter_block->index(); + if (parameter_block->IsConstant()) { + continue; + } + const int jacobian_block_size = + num_residuals * parameter_block->LocalSize(); + if (parameter_block_index < num_eliminate_blocks) { + *jacobian_pos = e_block_pos; + e_block_pos += jacobian_block_size; + } else { + *jacobian_pos = f_block_pos; + f_block_pos += jacobian_block_size; + } + jacobian_pos++; + } + } +} + +} // namespace + +BlockJacobianWriter::BlockJacobianWriter(const Evaluator::Options& options, + Program* program) + : program_(program) { + CHECK_GE(options.num_eliminate_blocks, 0) + << "num_eliminate_blocks must be greater than 0."; + + BuildJacobianLayout(*program, + options.num_eliminate_blocks, + &jacobian_layout_, + &jacobian_layout_storage_); +} + +// Create evaluate prepareres that point directly into the final jacobian. This +// makes the final Write() a nop. +BlockEvaluatePreparer* BlockJacobianWriter::CreateEvaluatePreparers( + int num_threads) { + BlockEvaluatePreparer* preparers = new BlockEvaluatePreparer[num_threads]; + for (int i = 0; i < num_threads; i++) { + preparers[i].Init(&jacobian_layout_[0]); + } + return preparers; +} + +SparseMatrix* BlockJacobianWriter::CreateJacobian() const { + CompressedRowBlockStructure* bs = new CompressedRowBlockStructure; + + const vector& parameter_blocks = + program_->parameter_blocks(); + + // Construct the column blocks. + bs->cols.resize(parameter_blocks.size()); + for (int i = 0, cursor = 0; i < parameter_blocks.size(); ++i) { + CHECK_NE(parameter_blocks[i]->index(), -1); + CHECK(!parameter_blocks[i]->IsConstant()); + bs->cols[i].size = parameter_blocks[i]->LocalSize(); + bs->cols[i].position = cursor; + cursor += bs->cols[i].size; + } + + // Construct the cells in each row. + const vector& residual_blocks = + program_->residual_blocks(); + int row_block_position = 0; + bs->rows.resize(residual_blocks.size()); + for (int i = 0; i < residual_blocks.size(); ++i) { + const ResidualBlock* residual_block = residual_blocks[i]; + CompressedRow* row = &bs->rows[i]; + + row->block.size = residual_block->NumResiduals(); + row->block.position = row_block_position; + row_block_position += row->block.size; + + // Size the row by the number of active parameters in this residual. + const int num_parameter_blocks = residual_block->NumParameterBlocks(); + int num_active_parameter_blocks = 0; + for (int j = 0; j < num_parameter_blocks; ++j) { + if (residual_block->parameter_blocks()[j]->index() != -1) { + num_active_parameter_blocks++; + } + } + row->cells.resize(num_active_parameter_blocks); + + // Add layout information for the active parameters in this row. + for (int j = 0, k = 0; j < num_parameter_blocks; ++j) { + const ParameterBlock* parameter_block = + residual_block->parameter_blocks()[j]; + if (!parameter_block->IsConstant()) { + Cell& cell = row->cells[k]; + cell.block_id = parameter_block->index(); + cell.position = jacobian_layout_[i][k]; + + // Only increment k for active parameters, since there is only layout + // information for active parameters. + k++; + } + } + + sort(row->cells.begin(), row->cells.end(), CellLessThan); + } + + BlockSparseMatrix* jacobian = new BlockSparseMatrix(bs); + CHECK_NOTNULL(jacobian); + return jacobian; +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_jacobian_writer.h b/extern/libmv/third_party/ceres/internal/ceres/block_jacobian_writer.h new file mode 100644 index 00000000000..140c7211129 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_jacobian_writer.h @@ -0,0 +1,127 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// A jacobian writer that writes to block sparse matrices. The "writer" name is +// misleading, since the Write() operation on the block jacobian writer does not +// write anything. Instead, the Prepare() method on the BlockEvaluatePreparers +// makes a jacobians array which has direct pointers into the block sparse +// jacobian. When the cost function is evaluated, the jacobian blocks get placed +// directly in their final location. + +#ifndef CERES_INTERNAL_BLOCK_JACOBIAN_WRITER_H_ +#define CERES_INTERNAL_BLOCK_JACOBIAN_WRITER_H_ + +#include +#include "ceres/evaluator.h" +#include "ceres/internal/port.h" + +namespace ceres { +namespace internal { + +class BlockEvaluatePreparer; +class Program; +class SparseMatrix; + +class BlockJacobianWriter { + public: + BlockJacobianWriter(const Evaluator::Options& options, + Program* program); + + // JacobianWriter interface. + + // Create evaluate prepareres that point directly into the final jacobian. + // This makes the final Write() a nop. + BlockEvaluatePreparer* CreateEvaluatePreparers(int num_threads); + + SparseMatrix* CreateJacobian() const; + + void Write(int /* residual_id */, + int /* residual_offset */, + double** /* jacobians */, + SparseMatrix* /* jacobian */) { + // This is a noop since the blocks were written directly into their final + // position by the outside evaluate call, thanks to the jacobians array + // prepared by the BlockEvaluatePreparers. + } + + private: + Program* program_; + + // Stores the position of each residual / parameter jacobian. + // + // The block sparse matrix that this writer writes to is stored as a set of + // contiguos dense blocks, one after each other; see BlockSparseMatrix. The + // "double* values_" member of the block sparse matrix contains all of these + // blocks. Given a pointer to the first element of a block and the size of + // that block, it's possible to write to it. + // + // In the case of a block sparse jacobian, the jacobian writer needs a way to + // find the offset in the values_ array of each residual/parameter jacobian + // block. + // + // That is the purpose of jacobian_layout_. + // + // In particular, jacobian_layout_[i][j] is the offset in the values_ array of + // the derivative of residual block i with respect to the parameter block at + // active argument position j. + // + // The active qualifier means that non-active parameters do not count. Care + // must be taken when indexing into jacobian_layout_ to account for this. + // Consider a single residual example: + // + // r(x, y, z) + // + // with r in R^3, x in R^4, y in R^2, and z in R^5. + // Take y as a constant (non-active) parameter. + // Take r as residual number 0. + // + // In this case, the active arguments are only (x, z), so the active argument + // position for x is 0, and the active argument position for z is 1. This is + // similar to thinking of r as taking only 2 parameters: + // + // r(x, z) + // + // There are only 2 jacobian blocks: dr/dx and dr/dz. jacobian_layout_ would + // have the following contents: + // + // jacobian_layout_[0] = { 0, 12 } + // + // which indicates that dr/dx is located at values_[0], and dr/dz is at + // values_[12]. See BlockEvaluatePreparer::Prepare()'s comments about 'j'. + vector jacobian_layout_; + + // The pointers in jacobian_layout_ point directly into this vector. + vector jacobian_layout_storage_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_BLOCK_JACOBIAN_WRITER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc new file mode 100644 index 00000000000..2afaf5e2ea2 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc @@ -0,0 +1,83 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/block_random_access_dense_matrix.h" + +#include +#include +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { + +BlockRandomAccessDenseMatrix::BlockRandomAccessDenseMatrix( + const vector& blocks) { + block_layout_.resize(blocks.size(), 0); + num_rows_ = 0; + for (int i = 0; i < blocks.size(); ++i) { + block_layout_[i] = num_rows_; + num_rows_ += blocks[i]; + } + + values_.reset(new double[num_rows_ * num_rows_]); + CHECK_NOTNULL(values_.get()); + cell_info_.values = values_.get(); + SetZero(); +} + +// Assume that the user does not hold any locks on any cell blocks +// when they are calling SetZero. +BlockRandomAccessDenseMatrix::~BlockRandomAccessDenseMatrix() { +} + +CellInfo* BlockRandomAccessDenseMatrix::GetCell(const int row_block_id, + const int col_block_id, + int* row, + int* col, + int* row_stride, + int* col_stride) { + *row = block_layout_[row_block_id]; + *col = block_layout_[col_block_id]; + *row_stride = num_rows_; + *col_stride = num_rows_; + return &cell_info_; +} + +// Assume that the user does not hold any locks on any cell blocks +// when they are calling SetZero. +void BlockRandomAccessDenseMatrix::SetZero() { + if (num_rows_) { + VectorRef(values_.get(), num_rows_ * num_rows_).setZero(); + } +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.h new file mode 100644 index 00000000000..3a0096209f7 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.h @@ -0,0 +1,98 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_BLOCK_RANDOM_ACCESS_DENSE_MATRIX_H_ +#define CERES_INTERNAL_BLOCK_RANDOM_ACCESS_DENSE_MATRIX_H_ + +#include "ceres/block_random_access_matrix.h" + +#include + +#include "ceres/internal/macros.h" +#include "ceres/internal/port.h" +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { + +// A square block random accessible matrix with the same row and +// column block structure. All cells are stored in the same single +// array, so that its also accessible as a dense matrix of size +// num_rows x num_cols. +// +// This class is NOT thread safe. Since all n^2 cells are stored, +// GetCell never returns NULL for any (row_block_id, col_block_id) +// pair. +// +// ReturnCell is a nop. +class BlockRandomAccessDenseMatrix : public BlockRandomAccessMatrix { + public: + // blocks is a vector of block sizes. The resulting matrix has + // blocks.size() * blocks.size() cells. + explicit BlockRandomAccessDenseMatrix(const vector& blocks); + + // The destructor is not thread safe. It assumes that no one is + // modifying any cells when the matrix is being destroyed. + virtual ~BlockRandomAccessDenseMatrix(); + + // BlockRandomAccessMatrix interface. + virtual CellInfo* GetCell(int row_block_id, + int col_block_id, + int* row, + int* col, + int* row_stride, + int* col_stride); + + // This is not a thread safe method, it assumes that no cell is + // locked. + virtual void SetZero(); + + // Since the matrix is square with the same row and column block + // structure, num_rows() = num_cols(). + virtual int num_rows() const { return num_rows_; } + virtual int num_cols() const { return num_rows_; } + + // The underlying matrix storing the cells. + const double* values() const { return values_.get(); } + double* mutable_values() { return values_.get(); } + + private: + CellInfo cell_info_; + int num_rows_; + vector block_layout_; + scoped_array values_; + + DISALLOW_COPY_AND_ASSIGN(BlockRandomAccessDenseMatrix); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_BLOCK_RANDOM_ACCESS_DENSE_MATRIX_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_matrix.cc new file mode 100644 index 00000000000..58fe4a10de3 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_matrix.cc @@ -0,0 +1,40 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/block_random_access_matrix.h" + +namespace ceres { +namespace internal { + +BlockRandomAccessMatrix::~BlockRandomAccessMatrix() { +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_matrix.h new file mode 100644 index 00000000000..f398af3be87 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_matrix.h @@ -0,0 +1,132 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Interface for matrices that allow block based random access. + +#ifndef CERES_INTERNAL_BLOCK_RANDOM_ACCESS_MATRIX_H_ +#define CERES_INTERNAL_BLOCK_RANDOM_ACCESS_MATRIX_H_ + +#include "ceres/mutex.h" + +namespace ceres { +namespace internal { + +// A matrix implementing the BlockRandomAccessMatrix interface is a +// matrix whose rows and columns are divided into blocks. For example +// the matrix A: +// +// 3 4 5 +// A = 5 [c_11 c_12 c_13] +// 4 [c_21 c_22 c_23] +// +// has row blocks of size 5 and 4, and column blocks of size 3, 4 and +// 5. It has six cells corresponding to the six row-column block +// combinations. +// +// BlockRandomAccessMatrix objects provide access to cells c_ij using +// the GetCell method. when a cell is present, GetCell will return a +// CellInfo object containing a pointer to an array which contains the +// cell as a submatrix and a mutex that guards this submatrix. If the +// user is accessing the matrix concurrently, it is his responsibility +// to use the mutex to exclude other writers from writing to the cell +// concurrently. +// +// There is no requirement that all cells be present, i.e. the matrix +// itself can be block sparse. When a cell is not present, the GetCell +// method will return a NULL pointer. +// +// There is no requirement about how the cells are stored beyond that +// form a dense submatrix of a larger dense matrix. Like everywhere +// else in Ceres, RowMajor storage assumed. +// +// Example usage: +// +// BlockRandomAccessMatrix* A = new BlockRandomAccessMatrixSubClass(...) +// +// int row, col, row_stride, col_stride; +// CellInfo* cell = A->GetCell(row_block_id, col_block_id, +// &row, &col, +// &row_stride, &col_stride); +// +// if (cell != NULL) { +// MatrixRef m(cell->values, row_stride, col_stride); +// MutexLock l(&cell->m); +// m.block(row, col, row_block_size, col_block_size) = ... +// } + +// Structure to carry a pointer to the array containing a cell and the +// Mutex guarding it. +struct CellInfo { + CellInfo() + : values(NULL) { + } + + explicit CellInfo(double* ptr) + : values(ptr) { + } + + double* values; + Mutex m; +}; + +class BlockRandomAccessMatrix { + public: + virtual ~BlockRandomAccessMatrix(); + + // If the cell (row_block_id, col_block_id) is present, then return + // a CellInfo with a pointer to the dense matrix containing it, + // otherwise return NULL. The dense matrix containing this cell has + // size row_stride, col_stride and the cell is located at position + // (row, col) within this matrix. + // + // The size of the cell is row_block_size x col_block_size is + // assumed known to the caller. row_block_size less than or equal to + // row_stride and col_block_size is upper bounded by col_stride. + virtual CellInfo* GetCell(int row_block_id, + int col_block_id, + int* row, + int* col, + int* row_stride, + int* col_stride) = 0; + + // Zero out the values of the array. The structure of the matrix + // (size and sparsity) is preserved. + virtual void SetZero() = 0; + + // Number of scalar rows and columns in the matrix, i.e the sum of + // all row blocks and column block sizes respectively. + virtual int num_rows() const = 0; + virtual int num_cols() const = 0; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_BLOCK_RANDOM_ACCESS_MATRIX_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc new file mode 100644 index 00000000000..c496fcd13de --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc @@ -0,0 +1,158 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/block_random_access_sparse_matrix.h" + +#include +#include +#include +#include +#include +#include "ceres/mutex.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/internal/port.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +BlockRandomAccessSparseMatrix::BlockRandomAccessSparseMatrix( + const vector& blocks, + const set >& block_pairs) + : kMaxRowBlocks(10 * 1000 * 1000), + blocks_(blocks) { + CHECK_LT(blocks.size(), kMaxRowBlocks); + + // Build the row/column layout vector and count the number of scalar + // rows/columns. + int num_cols = 0; + vector col_layout; + for (int i = 0; i < blocks_.size(); ++i) { + col_layout.push_back(num_cols); + num_cols += blocks_[i]; + } + + // Count the number of scalar non-zero entries and build the layout + // object for looking into the values array of the + // TripletSparseMatrix. + int num_nonzeros = 0; + for (set >::const_iterator it = block_pairs.begin(); + it != block_pairs.end(); + ++it) { + const int row_block_size = blocks_[it->first]; + const int col_block_size = blocks_[it->second]; + num_nonzeros += row_block_size * col_block_size; + } + + VLOG(1) << "Matrix Size [" << num_cols + << "," << num_cols + << "] " << num_nonzeros; + + tsm_.reset(new TripletSparseMatrix(num_cols, num_cols, num_nonzeros)); + tsm_->set_num_nonzeros(num_nonzeros); + int* rows = tsm_->mutable_rows(); + int* cols = tsm_->mutable_cols(); + double* values = tsm_->mutable_values(); + + int pos = 0; + for (set >::const_iterator it = block_pairs.begin(); + it != block_pairs.end(); + ++it) { + const int row_block_size = blocks_[it->first]; + const int col_block_size = blocks_[it->second]; + layout_[IntPairToLong(it->first, it->second)] = + new CellInfo(values + pos); + pos += row_block_size * col_block_size; + } + + // Fill the sparsity pattern of the underlying matrix. + for (set >::const_iterator it = block_pairs.begin(); + it != block_pairs.end(); + ++it) { + const int row_block_id = it->first; + const int col_block_id = it->second; + const int row_block_size = blocks_[row_block_id]; + const int col_block_size = blocks_[col_block_id]; + int pos = + layout_[IntPairToLong(row_block_id, col_block_id)]->values - values; + for (int r = 0; r < row_block_size; ++r) { + for (int c = 0; c < col_block_size; ++c, ++pos) { + rows[pos] = col_layout[row_block_id] + r; + cols[pos] = col_layout[col_block_id] + c; + values[pos] = 1.0; + DCHECK_LT(rows[pos], tsm_->num_rows()); + DCHECK_LT(cols[pos], tsm_->num_rows()); + } + } + } +} + +// Assume that the user does not hold any locks on any cell blocks +// when they are calling SetZero. +BlockRandomAccessSparseMatrix::~BlockRandomAccessSparseMatrix() { + for (LayoutType::iterator it = layout_.begin(); + it != layout_.end(); + ++it) { + delete it->second; + } +} + +CellInfo* BlockRandomAccessSparseMatrix::GetCell(int row_block_id, + int col_block_id, + int* row, + int* col, + int* row_stride, + int* col_stride) { + const LayoutType::iterator it = + layout_.find(IntPairToLong(row_block_id, col_block_id)); + if (it == layout_.end()) { + return NULL; + } + + // Each cell is stored contiguously as its own little dense matrix. + *row = 0; + *col = 0; + *row_stride = blocks_[row_block_id]; + *col_stride = blocks_[col_block_id]; + return it->second; +} + +// Assume that the user does not hold any locks on any cell blocks +// when they are calling SetZero. +void BlockRandomAccessSparseMatrix::SetZero() { + if (tsm_->num_nonzeros()) { + VectorRef(tsm_->mutable_values(), + tsm_->num_nonzeros()).setZero(); + } +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.h new file mode 100644 index 00000000000..12613c3daa0 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.h @@ -0,0 +1,109 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_BLOCK_RANDOM_ACCESS_SPARSE_MATRIX_H_ +#define CERES_INTERNAL_BLOCK_RANDOM_ACCESS_SPARSE_MATRIX_H_ + +#include +#include +#include +#include "ceres/mutex.h" +#include "ceres/block_random_access_matrix.h" +#include "ceres/collections_port.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/internal/macros.h" +#include "ceres/internal/port.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +// A threaf safe square block sparse implementation of +// BlockRandomAccessMatrix. Internally a TripletSparseMatrix is used +// for doing the actual storage. This class augments this matrix with +// an unordered_map that allows random read/write access. +class BlockRandomAccessSparseMatrix : public BlockRandomAccessMatrix { + public: + // blocks is an array of block sizes. block_pairs is a set of + // pairs to identify the non-zero cells + // of this matrix. + BlockRandomAccessSparseMatrix(const vector& blocks, + const set >& block_pairs); + + // The destructor is not thread safe. It assumes that no one is + // modifying any cells when the matrix is being destroyed. + virtual ~BlockRandomAccessSparseMatrix(); + + // BlockRandomAccessMatrix Interface. + virtual CellInfo* GetCell(int row_block_id, + int col_block_id, + int* row, + int* col, + int* row_stride, + int* col_stride); + + // This is not a thread safe method, it assumes that no cell is + // locked. + virtual void SetZero(); + virtual bool IsThreadSafe() const { return true; } + + // Since the matrix is square, num_rows() == num_cols(). + virtual int num_rows() const { return tsm_->num_rows(); } + virtual int num_cols() const { return tsm_->num_cols(); } + + // Access to the underlying matrix object. + const TripletSparseMatrix* matrix() const { return tsm_.get(); } + TripletSparseMatrix* mutable_matrix() { return tsm_.get(); } + + private: + long int IntPairToLong(int a, int b) { + return a * kMaxRowBlocks + b; + } + + const int kMaxRowBlocks; + // row/column block sizes. + const vector blocks_; + + // A mapping from to the position in + // the values array of tsm_ where the block is stored. + typedef HashMap LayoutType; + LayoutType layout_; + + // The underlying matrix object which actually stores the cells. + scoped_ptr tsm_; + + DISALLOW_COPY_AND_ASSIGN(BlockRandomAccessSparseMatrix); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_BLOCK_RANDOM_ACCESS_SPARSE_MATRIX_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc new file mode 100644 index 00000000000..c1be9402b78 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc @@ -0,0 +1,263 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/block_sparse_matrix.h" + +#include +#include +#include +#include +#include "ceres/block_structure.h" +#include "ceres/matrix_proto.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +BlockSparseMatrix::~BlockSparseMatrix() {} + +BlockSparseMatrix::BlockSparseMatrix( + CompressedRowBlockStructure* block_structure) + : num_rows_(0), + num_cols_(0), + num_nonzeros_(0), + values_(NULL), + block_structure_(block_structure) { + CHECK_NOTNULL(block_structure_.get()); + + // Count the number of columns in the matrix. + for (int i = 0; i < block_structure_->cols.size(); ++i) { + num_cols_ += block_structure_->cols[i].size; + } + + // Count the number of non-zero entries and the number of rows in + // the matrix. + for (int i = 0; i < block_structure_->rows.size(); ++i) { + int row_block_size = block_structure_->rows[i].block.size; + num_rows_ += row_block_size; + + const vector& cells = block_structure_->rows[i].cells; + for (int j = 0; j < cells.size(); ++j) { + int col_block_id = cells[j].block_id; + int col_block_size = block_structure_->cols[col_block_id].size; + num_nonzeros_ += col_block_size * row_block_size; + } + } + + CHECK_GE(num_rows_, 0); + CHECK_GE(num_cols_, 0); + CHECK_GE(num_nonzeros_, 0); + VLOG(2) << "Allocating values array with " + << num_nonzeros_ * sizeof(double) << " bytes."; // NOLINT + values_.reset(new double[num_nonzeros_]); + CHECK_NOTNULL(values_.get()); +} + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +BlockSparseMatrix::BlockSparseMatrix(const SparseMatrixProto& outer_proto) { + CHECK(outer_proto.has_block_matrix()); + + const BlockSparseMatrixProto& proto = outer_proto.block_matrix(); + CHECK(proto.has_num_rows()); + CHECK(proto.has_num_cols()); + CHECK_EQ(proto.num_nonzeros(), proto.values_size()); + + num_rows_ = proto.num_rows(); + num_cols_ = proto.num_cols(); + num_nonzeros_ = proto.num_nonzeros(); + + // Copy out the values into *this. + values_.reset(new double[num_nonzeros_]); + for (int i = 0; i < proto.num_nonzeros(); ++i) { + values_[i] = proto.values(i); + } + + // Create the block structure according to the proto. + block_structure_.reset(new CompressedRowBlockStructure); + ProtoToBlockStructure(proto.block_structure(), block_structure_.get()); +} +#endif + +void BlockSparseMatrix::SetZero() { + fill(values_.get(), values_.get() + num_nonzeros_, 0.0); +} + +void BlockSparseMatrix::RightMultiply(const double* x, double* y) const { + CHECK_NOTNULL(x); + CHECK_NOTNULL(y); + + for (int i = 0; i < block_structure_->rows.size(); ++i) { + int row_block_pos = block_structure_->rows[i].block.position; + int row_block_size = block_structure_->rows[i].block.size; + VectorRef yref(y + row_block_pos, row_block_size); + const vector& cells = block_structure_->rows[i].cells; + for (int j = 0; j < cells.size(); ++j) { + int col_block_id = cells[j].block_id; + int col_block_size = block_structure_->cols[col_block_id].size; + int col_block_pos = block_structure_->cols[col_block_id].position; + ConstVectorRef xref(x + col_block_pos, col_block_size); + MatrixRef m(values_.get() + cells[j].position, + row_block_size, col_block_size); + yref += m.lazyProduct(xref); + } + } +} + +void BlockSparseMatrix::LeftMultiply(const double* x, double* y) const { + CHECK_NOTNULL(x); + CHECK_NOTNULL(y); + + for (int i = 0; i < block_structure_->rows.size(); ++i) { + int row_block_pos = block_structure_->rows[i].block.position; + int row_block_size = block_structure_->rows[i].block.size; + const ConstVectorRef xref(x + row_block_pos, row_block_size); + const vector& cells = block_structure_->rows[i].cells; + for (int j = 0; j < cells.size(); ++j) { + int col_block_id = cells[j].block_id; + int col_block_size = block_structure_->cols[col_block_id].size; + int col_block_pos = block_structure_->cols[col_block_id].position; + VectorRef yref(y + col_block_pos, col_block_size); + MatrixRef m(values_.get() + cells[j].position, + row_block_size, col_block_size); + yref += m.transpose().lazyProduct(xref); + } + } +} + +void BlockSparseMatrix::SquaredColumnNorm(double* x) const { + CHECK_NOTNULL(x); + VectorRef(x, num_cols_).setZero(); + for (int i = 0; i < block_structure_->rows.size(); ++i) { + int row_block_size = block_structure_->rows[i].block.size; + const vector& cells = block_structure_->rows[i].cells; + for (int j = 0; j < cells.size(); ++j) { + int col_block_id = cells[j].block_id; + int col_block_size = block_structure_->cols[col_block_id].size; + int col_block_pos = block_structure_->cols[col_block_id].position; + const MatrixRef m(values_.get() + cells[j].position, + row_block_size, col_block_size); + VectorRef(x + col_block_pos, col_block_size) += m.colwise().squaredNorm(); + } + } +} + +void BlockSparseMatrix::ScaleColumns(const double* scale) { + CHECK_NOTNULL(scale); + + for (int i = 0; i < block_structure_->rows.size(); ++i) { + int row_block_size = block_structure_->rows[i].block.size; + const vector& cells = block_structure_->rows[i].cells; + for (int j = 0; j < cells.size(); ++j) { + int col_block_id = cells[j].block_id; + int col_block_size = block_structure_->cols[col_block_id].size; + int col_block_pos = block_structure_->cols[col_block_id].position; + MatrixRef m(values_.get() + cells[j].position, + row_block_size, col_block_size); + m *= ConstVectorRef(scale + col_block_pos, col_block_size).asDiagonal(); + } + } +} + +void BlockSparseMatrix::ToDenseMatrix(Matrix* dense_matrix) const { + CHECK_NOTNULL(dense_matrix); + + dense_matrix->resize(num_rows_, num_cols_); + dense_matrix->setZero(); + Matrix& m = *dense_matrix; + + for (int i = 0; i < block_structure_->rows.size(); ++i) { + int row_block_pos = block_structure_->rows[i].block.position; + int row_block_size = block_structure_->rows[i].block.size; + const vector& cells = block_structure_->rows[i].cells; + for (int j = 0; j < cells.size(); ++j) { + int col_block_id = cells[j].block_id; + int col_block_size = block_structure_->cols[col_block_id].size; + int col_block_pos = block_structure_->cols[col_block_id].position; + int jac_pos = cells[j].position; + m.block(row_block_pos, col_block_pos, row_block_size, col_block_size) + += MatrixRef(values_.get() + jac_pos, row_block_size, col_block_size); + } + } +} + +void BlockSparseMatrix::ToTripletSparseMatrix( + TripletSparseMatrix* matrix) const { + CHECK_NOTNULL(matrix); + + matrix->Reserve(num_nonzeros_); + matrix->Resize(num_rows_, num_cols_); + matrix->SetZero(); + + for (int i = 0; i < block_structure_->rows.size(); ++i) { + int row_block_pos = block_structure_->rows[i].block.position; + int row_block_size = block_structure_->rows[i].block.size; + const vector& cells = block_structure_->rows[i].cells; + for (int j = 0; j < cells.size(); ++j) { + int col_block_id = cells[j].block_id; + int col_block_size = block_structure_->cols[col_block_id].size; + int col_block_pos = block_structure_->cols[col_block_id].position; + int jac_pos = cells[j].position; + for (int r = 0; r < row_block_size; ++r) { + for (int c = 0; c < col_block_size; ++c, ++jac_pos) { + matrix->mutable_rows()[jac_pos] = row_block_pos + r; + matrix->mutable_cols()[jac_pos] = col_block_pos + c; + matrix->mutable_values()[jac_pos] = values_[jac_pos]; + } + } + } + } + matrix->set_num_nonzeros(num_nonzeros_); +} + +// Return a pointer to the block structure. We continue to hold +// ownership of the object though. +const CompressedRowBlockStructure* BlockSparseMatrix::block_structure() + const { + return block_structure_.get(); +} + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +void BlockSparseMatrix::ToProto(SparseMatrixProto* outer_proto) const { + outer_proto->Clear(); + + BlockSparseMatrixProto* proto = outer_proto->mutable_block_matrix(); + proto->set_num_rows(num_rows_); + proto->set_num_cols(num_cols_); + proto->set_num_nonzeros(num_nonzeros_); + for (int i = 0; i < num_nonzeros_; ++i) { + proto->add_values(values_[i]); + } + BlockStructureToProto(*block_structure_, proto->mutable_block_structure()); +} +#endif + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.h new file mode 100644 index 00000000000..b151dd0e248 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.h @@ -0,0 +1,142 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Implementation of the SparseMatrix interface for block sparse +// matrices. + +#ifndef CERES_INTERNAL_BLOCK_SPARSE_MATRIX_H_ +#define CERES_INTERNAL_BLOCK_SPARSE_MATRIX_H_ + +#include "ceres/block_structure.h" +#include "ceres/sparse_matrix.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/macros.h" +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { + +class SparseMatrixProto; +class TripletSparseMatrix; + +// A further extension of the SparseMatrix interface to support block-oriented +// matrices. The key addition is the RowBlockValues() accessor, which enables +// the lazy block sparse matrix implementation. +class BlockSparseMatrixBase : public SparseMatrix { + public: + BlockSparseMatrixBase() {} + virtual ~BlockSparseMatrixBase() {} + + // Convert this matrix into a triplet sparse matrix. + virtual void ToTripletSparseMatrix(TripletSparseMatrix* matrix) const = 0; + + // Returns a pointer to the block structure. Does not transfer + // ownership. + virtual const CompressedRowBlockStructure* block_structure() const = 0; + + // Returns a pointer to a row of the matrix. The returned array is only valid + // until the next call to RowBlockValues. The caller does not own the result. + // + // The returned array is laid out such that cells on the specified row are + // contiguous in the returned array, though neighbouring cells in row order + // may not be contiguous in the row values. The cell values for cell + // (row_block, cell_block) are found at offset + // + // block_structure()->rows[row_block].cells[cell_block].position + // + virtual const double* RowBlockValues(int row_block_index) const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(BlockSparseMatrixBase); +}; + +// This class implements the SparseMatrix interface for storing and +// manipulating block sparse matrices. The block structure is stored +// in the CompressedRowBlockStructure object and one is needed to +// initialize the matrix. For details on how the blocks structure of +// the matrix is stored please see the documentation +// +// internal/ceres/block_structure.h +// +class BlockSparseMatrix : public BlockSparseMatrixBase { + public: + // Construct a block sparse matrix with a fully initialized + // CompressedRowBlockStructure objected. The matrix takes over + // ownership of this object and destroys it upon destruction. + // + // TODO(sameeragarwal): Add a function which will validate legal + // CompressedRowBlockStructure objects. + explicit BlockSparseMatrix(CompressedRowBlockStructure* block_structure); + + // Construct a block sparse matrix from a protocol buffer. +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS + explicit BlockSparseMatrix(const SparseMatrixProto& proto); +#endif + + BlockSparseMatrix(); + virtual ~BlockSparseMatrix(); + + // Implementation of SparseMatrix interface. + virtual void SetZero(); + virtual void RightMultiply(const double* x, double* y) const; + virtual void LeftMultiply(const double* x, double* y) const; + virtual void SquaredColumnNorm(double* x) const; + virtual void ScaleColumns(const double* scale); + virtual void ToDenseMatrix(Matrix* dense_matrix) const; +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS + virtual void ToProto(SparseMatrixProto* proto) const; +#endif + virtual int num_rows() const { return num_rows_; } + virtual int num_cols() const { return num_cols_; } + virtual int num_nonzeros() const { return num_nonzeros_; } + virtual const double* values() const { return values_.get(); } + virtual double* mutable_values() { return values_.get(); } + + // Implementation of BlockSparseMatrixBase interface. + virtual void ToTripletSparseMatrix(TripletSparseMatrix* matrix) const; + virtual const CompressedRowBlockStructure* block_structure() const; + virtual const double* RowBlockValues(int row_block_index) const { + return values_.get(); + } + + private: + int num_rows_; + int num_cols_; + int max_num_nonzeros_; + int num_nonzeros_; + scoped_array values_; + scoped_ptr block_structure_; + DISALLOW_COPY_AND_ASSIGN(BlockSparseMatrix); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_BLOCK_SPARSE_MATRIX_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_structure.cc b/extern/libmv/third_party/ceres/internal/ceres/block_structure.cc new file mode 100644 index 00000000000..5add4f3b94d --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_structure.cc @@ -0,0 +1,92 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/block_structure.h" +#include "ceres/matrix_proto.h" + +namespace ceres { +namespace internal { + +bool CellLessThan(const Cell& lhs, const Cell& rhs) { + return (lhs.block_id < rhs.block_id); +} + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +void ProtoToBlockStructure(const BlockStructureProto &proto, + CompressedRowBlockStructure *block_structure) { + // Decode the column blocks. + block_structure->cols.resize(proto.cols_size()); + for (int i = 0; i < proto.cols_size(); ++i) { + block_structure->cols[i].size = proto.cols(i).size(); + block_structure->cols[i].position = + proto.cols(i).position(); + } + // Decode the row structure. + block_structure->rows.resize(proto.rows_size()); + for (int i = 0; i < proto.rows_size(); ++i) { + const CompressedRowProto &row = proto.rows(i); + block_structure->rows[i].block.size = row.block().size(); + block_structure->rows[i].block.position = row.block().position(); + + // Copy the cells within the row. + block_structure->rows[i].cells.resize(row.cells_size()); + for (int j = 0; j < row.cells_size(); ++j) { + const CellProto &cell = row.cells(j); + block_structure->rows[i].cells[j].block_id = cell.block_id(); + block_structure->rows[i].cells[j].position = cell.position(); + } + } +} + +void BlockStructureToProto(const CompressedRowBlockStructure &block_structure, + BlockStructureProto *proto) { + // Encode the column blocks. + for (int i = 0; i < block_structure.cols.size(); ++i) { + BlockProto *block = proto->add_cols(); + block->set_size(block_structure.cols[i].size); + block->set_position(block_structure.cols[i].position); + } + // Encode the row structure. + for (int i = 0; i < block_structure.rows.size(); ++i) { + CompressedRowProto *row = proto->add_rows(); + BlockProto *block = row->mutable_block(); + block->set_size(block_structure.rows[i].block.size); + block->set_position(block_structure.rows[i].block.position); + for (int j = 0; j < block_structure.rows[i].cells.size(); ++j) { + CellProto *cell = row->add_cells(); + cell->set_block_id(block_structure.rows[i].cells[j].block_id); + cell->set_position(block_structure.rows[i].cells[j].position); + } + } +} +#endif + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_structure.h b/extern/libmv/third_party/ceres/internal/ceres/block_structure.h new file mode 100644 index 00000000000..f509067d216 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/block_structure.h @@ -0,0 +1,105 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Block structure objects are used to carry information about the +// dense block structure of sparse matrices. The BlockSparseMatrix +// object uses the BlockStructure objects to keep track of the matrix +// structure and operate upon it. This allows us to use more cache +// friendly block oriented linear algebra operations on the matrix +// instead of accessing it one scalar entry at a time. + +#ifndef CERES_INTERNAL_BLOCK_STRUCTURE_H_ +#define CERES_INTERNAL_BLOCK_STRUCTURE_H_ + +#include +#include "ceres/internal/port.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +class BlockStructureProto; + +typedef int16 BlockSize; + +struct Block { + Block() : size(-1), position(-1) {} + Block(int size_, int position_) : size(size_), position(position_) {} + + BlockSize size; + int position; // Position along the row/column. +}; + +struct Cell { + Cell() : block_id(-1), position(-1) {} + Cell(int block_id_, int position_) + : block_id(block_id_), position(position_) {} + + // Column or row block id as the case maybe. + int block_id; + // Where in the values array of the jacobian is this cell located. + int position; +}; + +// Order cell by their block_id; +bool CellLessThan(const Cell& lhs, const Cell& rhs); + +struct CompressedList { + Block block; + vector cells; +}; + +typedef CompressedList CompressedRow; +typedef CompressedList CompressedColumn; + +struct CompressedRowBlockStructure { + vector cols; + vector rows; +}; + +struct CompressedColumnBlockStructure { + vector rows; + vector cols; +}; + +// Deserialize the given block structure proto to the given block structure. +// Destroys previous contents of block_structure. +void ProtoToBlockStructure(const BlockStructureProto &proto, + CompressedRowBlockStructure *block_structure); + +// Serialize the given block structure to the given proto. Destroys previous +// contents of proto. +void BlockStructureToProto(const CompressedRowBlockStructure &block_structure, + BlockStructureProto *proto); + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_BLOCK_STRUCTURE_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.cc b/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.cc new file mode 100644 index 00000000000..53190ada6fc --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.cc @@ -0,0 +1,238 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: David Gallup (dgallup@google.com) +// Sameer Agarwal (sameeragarwal@google.com) + +#include "ceres/canonical_views_clustering.h" + +#include +#include "ceres/graph.h" +#include "ceres/collections_port.h" +#include "ceres/map_util.h" +#include "ceres/internal/macros.h" + +namespace ceres { +namespace internal { + +typedef HashMap IntMap; +typedef HashSet IntSet; + +class CanonicalViewsClustering { + public: + CanonicalViewsClustering() {} + + // Compute the canonical views clustering of the vertices of the + // graph. centers will contain the vertices that are the identified + // as the canonical views/cluster centers, and membership is a map + // from vertices to cluster_ids. The i^th cluster center corresponds + // to the i^th cluster. It is possible depending on the + // configuration of the clustering algorithm that some of the + // vertices may not be assigned to any cluster. In this case they + // are assigned to a cluster with id = kInvalidClusterId. + void ComputeClustering(const Graph& graph, + const CanonicalViewsClusteringOptions& options, + vector* centers, + IntMap* membership); + + private: + void FindValidViews(IntSet* valid_views) const; + double ComputeClusteringQualityDifference(const int candidate, + const vector& centers) const; + void UpdateCanonicalViewAssignments(const int canonical_view); + void ComputeClusterMembership(const vector& centers, + IntMap* membership) const; + + CanonicalViewsClusteringOptions options_; + const Graph* graph_; + // Maps a view to its representative canonical view (its cluster + // center). + IntMap view_to_canonical_view_; + // Maps a view to its similarity to its current cluster center. + HashMap view_to_canonical_view_similarity_; + DISALLOW_COPY_AND_ASSIGN(CanonicalViewsClustering); +}; + +void ComputeCanonicalViewsClustering( + const Graph& graph, + const CanonicalViewsClusteringOptions& options, + vector* centers, + IntMap* membership) { + time_t start_time = time(NULL); + CanonicalViewsClustering cv; + cv.ComputeClustering(graph, options, centers, membership); + VLOG(2) << "Canonical views clustering time (secs): " + << time(NULL) - start_time; +} + +// Implementation of CanonicalViewsClustering +void CanonicalViewsClustering::ComputeClustering( + const Graph& graph, + const CanonicalViewsClusteringOptions& options, + vector* centers, + IntMap* membership) { + options_ = options; + CHECK_NOTNULL(centers)->clear(); + CHECK_NOTNULL(membership)->clear(); + graph_ = &graph; + + IntSet valid_views; + FindValidViews(&valid_views); + while (valid_views.size() > 0) { + // Find the next best canonical view. + double best_difference = -std::numeric_limits::max(); + int best_view = 0; + + // TODO(sameeragarwal): Make this loop multi-threaded. + for (IntSet::const_iterator view = valid_views.begin(); + view != valid_views.end(); + ++view) { + const double difference = + ComputeClusteringQualityDifference(*view, *centers); + if (difference > best_difference) { + best_difference = difference; + best_view = *view; + } + } + + CHECK_GT(best_difference, -std::numeric_limits::max()); + + // Add canonical view if quality improves, or if minimum is not + // yet met, otherwise break. + if ((best_difference <= 0) && + (centers->size() >= options_.min_views)) { + break; + } + + centers->push_back(best_view); + valid_views.erase(best_view); + UpdateCanonicalViewAssignments(best_view); + } + + ComputeClusterMembership(*centers, membership); +} + +// Return the set of vertices of the graph which have valid vertex +// weights. +void CanonicalViewsClustering::FindValidViews( + IntSet* valid_views) const { + const IntSet& views = graph_->vertices(); + for (IntSet::const_iterator view = views.begin(); + view != views.end(); + ++view) { + if (graph_->VertexWeight(*view) != Graph::InvalidWeight()) { + valid_views->insert(*view); + } + } +} + +// Computes the difference in the quality score if 'candidate' were +// added to the set of canonical views. +double CanonicalViewsClustering::ComputeClusteringQualityDifference( + const int candidate, + const vector& centers) const { + // View score. + double difference = + options_.view_score_weight * graph_->VertexWeight(candidate); + + // Compute how much the quality score changes if the candidate view + // was added to the list of canonical views and its nearest + // neighbors became members of its cluster. + const IntSet& neighbors = graph_->Neighbors(candidate); + for (IntSet::const_iterator neighbor = neighbors.begin(); + neighbor != neighbors.end(); + ++neighbor) { + const double old_similarity = + FindWithDefault(view_to_canonical_view_similarity_, *neighbor, 0.0); + const double new_similarity = graph_->EdgeWeight(*neighbor, candidate); + if (new_similarity > old_similarity) { + difference += new_similarity - old_similarity; + } + } + + // Number of views penalty. + difference -= options_.size_penalty_weight; + + // Orthogonality. + for (int i = 0; i < centers.size(); ++i) { + difference -= options_.similarity_penalty_weight * + graph_->EdgeWeight(centers[i], candidate); + } + + return difference; +} + +// Reassign views if they're more similar to the new canonical view. +void CanonicalViewsClustering::UpdateCanonicalViewAssignments( + const int canonical_view) { + const IntSet& neighbors = graph_->Neighbors(canonical_view); + for (IntSet::const_iterator neighbor = neighbors.begin(); + neighbor != neighbors.end(); + ++neighbor) { + const double old_similarity = + FindWithDefault(view_to_canonical_view_similarity_, *neighbor, 0.0); + const double new_similarity = + graph_->EdgeWeight(*neighbor, canonical_view); + if (new_similarity > old_similarity) { + view_to_canonical_view_[*neighbor] = canonical_view; + view_to_canonical_view_similarity_[*neighbor] = new_similarity; + } + } +} + +// Assign a cluster id to each view. +void CanonicalViewsClustering::ComputeClusterMembership( + const vector& centers, + IntMap* membership) const { + CHECK_NOTNULL(membership)->clear(); + + // The i^th cluster has cluster id i. + IntMap center_to_cluster_id; + for (int i = 0; i < centers.size(); ++i) { + center_to_cluster_id[centers[i]] = i; + } + + static const int kInvalidClusterId = -1; + + const IntSet& views = graph_->vertices(); + for (IntSet::const_iterator view = views.begin(); + view != views.end(); + ++view) { + IntMap::const_iterator it = + view_to_canonical_view_.find(*view); + int cluster_id = kInvalidClusterId; + if (it != view_to_canonical_view_.end()) { + cluster_id = FindOrDie(center_to_cluster_id, it->second); + } + + InsertOrDie(membership, *view, cluster_id); + } +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h b/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h new file mode 100644 index 00000000000..2d1eb403995 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h @@ -0,0 +1,133 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// An implementation of the Canonical Views clustering algorithm from +// "Scene Summarization for Online Image Collections", Ian Simon, Noah +// Snavely, Steven M. Seitz, ICCV 2007. +// +// More details can be found at +// http://grail.cs.washington.edu/projects/canonview/ +// +// Ceres uses this algorithm to perform view clustering for +// constructing visibility based preconditioners. + +#ifndef CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_ +#define CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_ + +#include + +#include +#include "ceres/collections_port.h" +#include "ceres/graph.h" +#include "ceres/map_util.h" +#include "ceres/internal/macros.h" + +namespace ceres { +namespace internal { + +class CanonicalViewsClusteringOptions; + +// Compute a partitioning of the vertices of the graph using the +// canonical views clustering algorithm. +// +// In the following we will use the terms vertices and views +// interchangably. Given a weighted Graph G(V,E), the canonical views +// of G are the the set of vertices that best "summarize" the content +// of the graph. If w_ij i s the weight connecting the vertex i to +// vertex j, and C is the set of canonical views. Then the objective +// of the canonical views algorithm is +// +// E[C] = sum_[i in V] max_[j in C] w_ij +// - size_penalty_weight * |C| +// - similarity_penalty_weight * sum_[i in C, j in C, j > i] w_ij +// +// alpha is the size penalty that penalizes large number of canonical +// views. +// +// beta is the similarity penalty that penalizes canonical views that +// are too similar to other canonical views. +// +// Thus the canonical views algorithm tries to find a canonical view +// for each vertex in the graph which best explains it, while trying +// to minimize the number of canonical views and the overlap between +// them. +// +// We further augment the above objective function by allowing for per +// vertex weights, higher weights indicating a higher preference for +// being chosen as a canonical view. Thus if w_i is the vertex weight +// for vertex i, the objective function is then +// +// E[C] = sum_[i in V] max_[j in C] w_ij +// - size_penalty_weight * |C| +// - similarity_penalty_weight * sum_[i in C, j in C, j > i] w_ij +// + view_score_weight * sum_[i in C] w_i +// +// centers will contain the vertices that are the identified +// as the canonical views/cluster centers, and membership is a map +// from vertices to cluster_ids. The i^th cluster center corresponds +// to the i^th cluster. +// +// It is possible depending on the configuration of the clustering +// algorithm that some of the vertices may not be assigned to any +// cluster. In this case they are assigned to a cluster with id = -1; +void ComputeCanonicalViewsClustering( + const Graph& graph, + const CanonicalViewsClusteringOptions& options, + vector* centers, + HashMap* membership); + +struct CanonicalViewsClusteringOptions { + CanonicalViewsClusteringOptions() + : min_views(3), + size_penalty_weight(5.75), + similarity_penalty_weight(100.0), + view_score_weight(0.0) { + } + // The minimum number of canonical views to compute. + int min_views; + + // Penalty weight for the number of canonical views. A higher + // number will result in fewer canonical views. + double size_penalty_weight; + + // Penalty weight for the diversity (orthogonality) of the + // canonical views. A higher number will encourage less similar + // canonical views. + double similarity_penalty_weight; + + // Weight for per-view scores. Lower weight places less + // confidence in the view scores. + double view_score_weight; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/casts.h b/extern/libmv/third_party/ceres/internal/ceres/casts.h new file mode 100644 index 00000000000..99cf2186cc7 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/casts.h @@ -0,0 +1,108 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#ifndef CERES_INTERNAL_CASTS_H_ +#define CERES_INTERNAL_CASTS_H_ + +#include +#include // For NULL. + +namespace ceres { + +// Identity metafunction. +template +struct identity_ { + typedef T type; +}; + +// Use implicit_cast as a safe version of static_cast or const_cast +// for implicit conversions. For example: +// - Upcasting in a type hierarchy. +// - Performing arithmetic conversions (int32 to int64, int to double, etc.). +// - Adding const or volatile qualifiers. +// +// In general, implicit_cast can be used to convert this code +// To to = from; +// DoSomething(to); +// to this +// DoSomething(implicit_cast(from)); +// +// base::identity_ is used to make a non-deduced context, which +// forces all callers to explicitly specify the template argument. +template +inline To implicit_cast(typename identity_::type to) { + return to; +} + +// This version of implicit_cast is used when two template arguments +// are specified. It's obsolete and should not be used. +template +inline To implicit_cast(typename identity_::type const &f) { + return f; +} + +// When you upcast (that is, cast a pointer from type Foo to type +// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts +// always succeed. When you downcast (that is, cast a pointer from +// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because +// how do you know the pointer is really of type SubclassOfFoo? It +// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, +// when you downcast, you should use this macro. In debug mode, we +// use dynamic_cast<> to double-check the downcast is legal (we die +// if it's not). In normal mode, we do the efficient static_cast<> +// instead. Thus, it's important to test in debug mode to make sure +// the cast is legal! +// This is the only place in the code we should use dynamic_cast<>. +// In particular, you SHOULDN'T be using dynamic_cast<> in order to +// do RTTI (eg code like this: +// if (dynamic_cast(foo)) HandleASubclass1Object(foo); +// if (dynamic_cast(foo)) HandleASubclass2Object(foo); +// You should design the code some other way not to need this. + +template // use like this: down_cast(foo); +inline To down_cast(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + + // TODO(csilvers): This should use COMPILE_ASSERT. + if (false) { + implicit_cast(NULL); + } + + // uses RTTI in dbg and fastbuild. asserts are disabled in opt builds. + assert(f == NULL || dynamic_cast(f) != NULL); // NOLINT + return static_cast(f); +} + +} // namespace ceres + +#endif // CERES_INTERNAL_CASTS_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/cgnr_linear_operator.h b/extern/libmv/third_party/ceres/internal/ceres/cgnr_linear_operator.h new file mode 100644 index 00000000000..f32d8d95c19 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/cgnr_linear_operator.h @@ -0,0 +1,120 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#ifndef CERES_INTERNAL_CGNR_LINEAR_OPERATOR_H_ +#define CERES_INTERNAL_CGNR_LINEAR_OPERATOR_H_ + +#include +#include "ceres/linear_operator.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +class SparseMatrix; + +// A linear operator which takes a matrix A and a diagonal vector D and +// performs products of the form +// +// (A^T A + D^T D)x +// +// This is used to implement iterative general sparse linear solving with +// conjugate gradients, where A is the Jacobian and D is a regularizing +// parameter. A brief proof that D^T D is the correct regularizer: +// +// Given a regularized least squares problem: +// +// min ||Ax - b||^2 + ||Dx||^2 +// x +// +// First expand into matrix notation: +// +// (Ax - b)^T (Ax - b) + xD^TDx +// +// Then multiply out to get: +// +// = xA^TAx - 2b^T Ax + b^Tb + xD^TDx +// +// Take the derivative: +// +// 0 = 2A^TAx - 2A^T b + 2 D^TDx +// 0 = A^TAx - A^T b + D^TDx +// 0 = (A^TA + D^TD)x - A^T b +// +// Thus, the symmetric system we need to solve for CGNR is +// +// Sx = z +// +// with S = A^TA + D^TD +// and z = A^T b +// +// Note: This class is not thread safe, since it uses some temporary storage. +class CgnrLinearOperator : public LinearOperator { + public: + CgnrLinearOperator(const LinearOperator& A, const double *D) + : A_(A), D_(D), z_(new double[A.num_rows()]) { + } + virtual ~CgnrLinearOperator() {} + + virtual void RightMultiply(const double* x, double* y) const { + std::fill(z_.get(), z_.get() + A_.num_rows(), 0.0); + + // z = Ax + A_.RightMultiply(x, z_.get()); + + // y = y + Atz + A_.LeftMultiply(z_.get(), y); + + // y = y + DtDx + if (D_ != NULL) { + int n = A_.num_cols(); + VectorRef(y, n).array() += ConstVectorRef(D_, n).array().square() * + ConstVectorRef(x, n).array(); + } + } + + virtual void LeftMultiply(const double* x, double* y) const { + RightMultiply(x, y); + } + + virtual int num_rows() const { return A_.num_cols(); } + virtual int num_cols() const { return A_.num_cols(); } + + private: + const LinearOperator& A_; + const double* D_; + scoped_array z_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_CGNR_LINEAR_OPERATOR_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.cc new file mode 100644 index 00000000000..ccc8026f9f7 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.cc @@ -0,0 +1,80 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include "ceres/cgnr_solver.h" + +#include "glog/logging.h" +#include "ceres/linear_solver.h" +#include "ceres/cgnr_linear_operator.h" +#include "ceres/conjugate_gradients_solver.h" +#include "ceres/block_jacobi_preconditioner.h" + +namespace ceres { +namespace internal { + +CgnrSolver::CgnrSolver(const LinearSolver::Options& options) + : options_(options), + jacobi_preconditioner_(NULL) { +} + +LinearSolver::Summary CgnrSolver::Solve( + LinearOperator* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double* x) { + // Form z = Atb. + scoped_array z(new double[A->num_cols()]); + std::fill(z.get(), z.get() + A->num_cols(), 0.0); + A->LeftMultiply(b, z.get()); + + // Precondition if necessary. + LinearSolver::PerSolveOptions cg_per_solve_options = per_solve_options; + if (options_.preconditioner_type == JACOBI) { + if (jacobi_preconditioner_.get() == NULL) { + jacobi_preconditioner_.reset(new BlockJacobiPreconditioner(*A)); + } + jacobi_preconditioner_->Update(*A, per_solve_options.D); + cg_per_solve_options.preconditioner = jacobi_preconditioner_.get(); + } else if (options_.preconditioner_type != IDENTITY) { + LOG(FATAL) << "CGNR only supports IDENTITY and JACOBI preconditioners."; + } + + // Solve (AtA + DtD)x = z (= Atb). + std::fill(x, x + A->num_cols(), 0.0); + CgnrLinearOperator lhs(*A, per_solve_options.D); + ConjugateGradientsSolver conjugate_gradient_solver(options_); + return conjugate_gradient_solver.Solve(&lhs, + z.get(), + cg_per_solve_options, + x); +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.h b/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.h new file mode 100644 index 00000000000..dd36f99006b --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.h @@ -0,0 +1,66 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#ifndef CERES_INTERNAL_CGNR_SOLVER_H_ +#define CERES_INTERNAL_CGNR_SOLVER_H_ + +#include "ceres/internal/scoped_ptr.h" +#include "ceres/linear_solver.h" + +namespace ceres { +namespace internal { + +class BlockJacobiPreconditioner; + +// A conjugate gradients on the normal equations solver. This directly solves +// for the solution to +// +// (A^T A + D^T D)x = A^T b +// +// as required for solving for x in the least squares sense. Currently only +// block diagonal preconditioning is supported. +class CgnrSolver : public LinearSolver { + public: + explicit CgnrSolver(const LinearSolver::Options& options); + virtual Summary Solve(LinearOperator* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double* x); + + private: + const LinearSolver::Options options_; + scoped_ptr jacobi_preconditioner_; + DISALLOW_COPY_AND_ASSIGN(CgnrSolver); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_CGNR_SOLVER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/collections_port.h b/extern/libmv/third_party/ceres/internal/ceres/collections_port.h new file mode 100644 index 00000000000..e125f3fffcd --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/collections_port.h @@ -0,0 +1,141 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// Portable HashMap and HashSet, and a specialized overload for hashing pairs. + +#ifndef CERES_INTERNAL_COLLECTIONS_PORT_H_ +#define CERES_INTERNAL_COLLECTIONS_PORT_H_ + +#if defined(_MSC_VER) && _MSC_VER <= 1600 +#include +#include +#else +#include +#include +#endif +#include +#include "ceres/integral_types.h" +#include "ceres/internal/port.h" + +namespace ceres { +namespace internal { + +template +struct HashMap : tr1::unordered_map {}; + +template +struct HashSet : tr1::unordered_set {}; + +#ifdef _WIN32 +#define GG_LONGLONG(x) x##I64 +#define GG_ULONGLONG(x) x##UI64 +#else +#define GG_LONGLONG(x) x##LL +#define GG_ULONGLONG(x) x##ULL +#endif + +// The hash function is due to Bob Jenkins (see +// http://burtleburtle.net/bob/hash/index.html). Each mix takes 36 instructions, +// in 18 cycles if you're lucky. On x86 architectures, this requires 45 +// instructions in 27 cycles, if you're lucky. +// +// 32bit version +inline void hash_mix(uint32& a, uint32& b, uint32& c) { + a -= b; a -= c; a ^= (c>>13); + b -= c; b -= a; b ^= (a<<8); + c -= a; c -= b; c ^= (b>>13); + a -= b; a -= c; a ^= (c>>12); + b -= c; b -= a; b ^= (a<<16); + c -= a; c -= b; c ^= (b>>5); + a -= b; a -= c; a ^= (c>>3); + b -= c; b -= a; b ^= (a<<10); + c -= a; c -= b; c ^= (b>>15); +} + +// 64bit version +inline void hash_mix(uint64& a, uint64& b, uint64& c) { + a -= b; a -= c; a ^= (c>>43); + b -= c; b -= a; b ^= (a<<9); + c -= a; c -= b; c ^= (b>>8); + a -= b; a -= c; a ^= (c>>38); + b -= c; b -= a; b ^= (a<<23); + c -= a; c -= b; c ^= (b>>5); + a -= b; a -= c; a ^= (c>>35); + b -= c; b -= a; b ^= (a<<49); + c -= a; c -= b; c ^= (b>>11); +} + +inline uint32 Hash32NumWithSeed(uint32 num, uint32 c) { + // The golden ratio; an arbitrary value. + uint32 b = 0x9e3779b9UL; + hash_mix(num, b, c); + return c; +} + +inline uint64 Hash64NumWithSeed(uint64 num, uint64 c) { + // More of the golden ratio. + uint64 b = GG_ULONGLONG(0xe08c1d668b756f82); + hash_mix(num, b, c); + return c; +} + +} // namespace internal +} // namespace ceres + +// Since on some platforms this is a doubly-nested namespace (std::tr1) and +// others it is not, the entire namespace line must be in a macro. +CERES_HASH_NAMESPACE_START + +// The outrageously annoying specializations below are for portability reasons. +// In short, it's not possible to have two overloads of hash + +// Hasher for STL pairs. Requires hashers for both members to be defined. +template +struct hash > { + size_t operator()(const pair& p) const { + size_t h1 = hash()(p.first); + size_t h2 = hash()(p.second); + // The decision below is at compile time + return (sizeof(h1) <= sizeof(ceres::internal::uint32)) ? + ceres::internal::Hash32NumWithSeed(h1, h2) : + ceres::internal::Hash64NumWithSeed(h1, h2); + } + // Less than operator for MSVC. + bool operator()(const pair& a, + const pair& b) const { + return a < b; + } + static const size_t bucket_size = 4; // These are required by MSVC + static const size_t min_buckets = 8; // 4 and 8 are defaults. +}; + +CERES_HASH_NAMESPACE_END + +#endif // CERES_INTERNAL_COLLECTIONS_PORT_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.cc b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.cc new file mode 100644 index 00000000000..aa883b7d353 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.cc @@ -0,0 +1,201 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include "ceres/compressed_row_jacobian_writer.h" + +#include "ceres/casts.h" +#include "ceres/compressed_row_sparse_matrix.h" +#include "ceres/parameter_block.h" +#include "ceres/program.h" +#include "ceres/residual_block.h" +#include "ceres/scratch_evaluate_preparer.h" + +namespace ceres { +namespace internal { + +SparseMatrix* CompressedRowJacobianWriter::CreateJacobian() const { + const vector& residual_blocks = + program_->residual_blocks(); + + int total_num_residuals = program_->NumResiduals(); + int total_num_effective_parameters = program_->NumEffectiveParameters(); + + // Count the number of jacobian nonzeros. + int num_jacobian_nonzeros = 0; + for (int i = 0; i < residual_blocks.size(); ++i) { + ResidualBlock* residual_block = residual_blocks[i]; + const int num_residuals = residual_block->NumResiduals(); + const int num_parameter_blocks = residual_block->NumParameterBlocks(); + for (int j = 0; j < num_parameter_blocks; ++j) { + ParameterBlock* parameter_block = residual_block->parameter_blocks()[j]; + if (!parameter_block->IsConstant()) { + num_jacobian_nonzeros += num_residuals * parameter_block->LocalSize(); + } + } + } + + // Allocate storage for the jacobian with some extra space at the end. + // Allocate more space than needed to store the jacobian so that when the LM + // algorithm adds the diagonal, no reallocation is necessary. This reduces + // peak memory usage significantly. + CompressedRowSparseMatrix* jacobian = + new CompressedRowSparseMatrix( + total_num_residuals, + total_num_effective_parameters, + num_jacobian_nonzeros + total_num_effective_parameters); + + // At this stage, the CompressedSparseMatrix is an invalid state. But this + // seems to be the only way to construct it without doing a memory copy. + int* rows = jacobian->mutable_rows(); + int* cols = jacobian->mutable_cols(); + int row_pos = 0; + rows[0] = 0; + for (int i = 0; i < residual_blocks.size(); ++i) { + const ResidualBlock* residual_block = residual_blocks[i]; + const int num_parameter_blocks = residual_block->NumParameterBlocks(); + + // Count the number of derivatives for a row of this residual block and + // build a list of active parameter block indices. + int num_derivatives = 0; + vector parameter_indices; + for (int j = 0; j < num_parameter_blocks; ++j) { + ParameterBlock* parameter_block = residual_block->parameter_blocks()[j]; + if (!parameter_block->IsConstant()) { + parameter_indices.push_back(parameter_block->index()); + num_derivatives += parameter_block->LocalSize(); + } + } + + // Sort the parameters by their position in the state vector. + sort(parameter_indices.begin(), parameter_indices.end()); + CHECK(unique(parameter_indices.begin(), parameter_indices.end()) == + parameter_indices.end()) + << "Ceres internal error: " + << "Duplicate parameter blocks detected in a cost function. " + << "This should never happen. Please report this to " + << "the Ceres developers."; + + // Update the row indices. + const int num_residuals = residual_block->NumResiduals(); + for (int j = 0; j < num_residuals; ++j) { + rows[row_pos + j + 1] = rows[row_pos + j] + num_derivatives; + } + + // Iterate over parameter blocks in the order which they occur in the + // parameter vector. This code mirrors that in Write(), where jacobian + // values are updated. + int col_pos = 0; + for (int j = 0; j < parameter_indices.size(); ++j) { + ParameterBlock* parameter_block = + program_->parameter_blocks()[parameter_indices[j]]; + const int parameter_block_size = parameter_block->LocalSize(); + + for (int r = 0; r < num_residuals; ++r) { + // This is the position in the values array of the jacobian where this + // row of the jacobian block should go. + const int column_block_begin = rows[row_pos + r] + col_pos; + + for (int c = 0; c < parameter_block_size; ++c) { + cols[column_block_begin + c] = parameter_block->delta_offset() + c; + } + } + col_pos += parameter_block_size; + } + row_pos += num_residuals; + } + + CHECK_EQ(num_jacobian_nonzeros, rows[total_num_residuals]); + return jacobian; +} + +void CompressedRowJacobianWriter::Write(int residual_id, + int residual_offset, + double **jacobians, + SparseMatrix* base_jacobian) { + CompressedRowSparseMatrix* jacobian = + down_cast(base_jacobian); + + double* jacobian_values = jacobian->mutable_values(); + const int* jacobian_rows = jacobian->rows(); + + const ResidualBlock* residual_block = + program_->residual_blocks()[residual_id]; + const int num_parameter_blocks = residual_block->NumParameterBlocks(); + const int num_residuals = residual_block->NumResiduals(); + + // It is necessary to determine the order of the jacobian blocks before + // copying them into the CompressedRowSparseMatrix. Just because a cost + // function uses parameter blocks 1 after 2 in its arguments does not mean + // that the block 1 occurs before block 2 in the column layout of the + // jacobian. Thus, determine the order by sorting the jacobian blocks by their + // position in the state vector. + vector > evaluated_jacobian_blocks; + for (int j = 0; j < num_parameter_blocks; ++j) { + const ParameterBlock* parameter_block = + residual_block->parameter_blocks()[j]; + if (!parameter_block->IsConstant()) { + evaluated_jacobian_blocks.push_back( + make_pair(parameter_block->index(), j)); + } + } + sort(evaluated_jacobian_blocks.begin(), evaluated_jacobian_blocks.end()); + + // Where in the current row does the jacobian for a parameter block begin. + int col_pos = 0; + + // Iterate over the jacobian blocks in increasing order of their + // positions in the reduced parameter vector. + for (int i = 0; i < evaluated_jacobian_blocks.size(); ++i) { + const ParameterBlock* parameter_block = + program_->parameter_blocks()[evaluated_jacobian_blocks[i].first]; + const int argument = evaluated_jacobian_blocks[i].second; + const int parameter_block_size = parameter_block->LocalSize(); + + // Copy one row of the jacobian block at a time. + for (int r = 0; r < num_residuals; ++r) { + // Position of the r^th row of the current jacobian block. + const double* block_row_begin = + jacobians[argument] + r * parameter_block_size; + + // Position in the values array of the jacobian where this + // row of the jacobian block should go. + double* column_block_begin = + jacobian_values + jacobian_rows[residual_offset + r] + col_pos; + + copy(block_row_begin, + block_row_begin + parameter_block_size, + column_block_begin); + } + col_pos += parameter_block_size; + } +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.h b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.h new file mode 100644 index 00000000000..c103165eaf1 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.h @@ -0,0 +1,75 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// A jacobian writer that directly writes to compressed row sparse matrices. + +#ifndef CERES_INTERNAL_COMPRESSED_ROW_JACOBIAN_WRITER_H_ +#define CERES_INTERNAL_COMPRESSED_ROW_JACOBIAN_WRITER_H_ + +#include "ceres/evaluator.h" +#include "ceres/scratch_evaluate_preparer.h" + +namespace ceres { +namespace internal { + +class Program; +class SparseMatrix; + +class CompressedRowJacobianWriter { + public: + CompressedRowJacobianWriter(Evaluator::Options /* ignored */, + Program* program) + : program_(program) { + } + + // JacobianWriter interface. + + // Since the compressed row matrix has different layout than that assumed by + // the cost functions, use scratch space to store the jacobians temporarily + // then copy them over to the larger jacobian in the Write() function. + ScratchEvaluatePreparer* CreateEvaluatePreparers(int num_threads) { + return ScratchEvaluatePreparer::Create(*program_, num_threads); + } + + SparseMatrix* CreateJacobian() const; + + void Write(int residual_id, + int residual_offset, + double **jacobians, + SparseMatrix* base_jacobian); + + private: + Program* program_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_COMPRESSED_ROW_JACOBIAN_WRITER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.cc new file mode 100644 index 00000000000..8fd568ffcc3 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.cc @@ -0,0 +1,325 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/compressed_row_sparse_matrix.h" + +#include +#include +#include "ceres/matrix_proto.h" +#include "ceres/internal/port.h" + +namespace ceres { +namespace internal { +namespace { + +// Helper functor used by the constructor for reordering the contents +// of a TripletSparseMatrix. +struct RowColLessThan { + RowColLessThan(const int* rows, const int* cols) + : rows(rows), cols(cols) { + } + + bool operator()(const int x, const int y) const { + if (rows[x] == rows[y]) { + return (cols[x] < cols[y]); + } + return (rows[x] < rows[y]); + } + + const int* rows; + const int* cols; +}; + +} // namespace + +// This constructor gives you a semi-initialized CompressedRowSparseMatrix. +CompressedRowSparseMatrix::CompressedRowSparseMatrix(int num_rows, + int num_cols, + int max_num_nonzeros) { + num_rows_ = num_rows; + num_cols_ = num_cols; + max_num_nonzeros_ = max_num_nonzeros; + + VLOG(1) << "# of rows: " << num_rows_ << " # of columns: " << num_cols_ + << " max_num_nonzeros: " << max_num_nonzeros_ + << ". Allocating " << (num_rows_ + 1) * sizeof(int) + // NOLINT + max_num_nonzeros_ * sizeof(int) + // NOLINT + max_num_nonzeros_ * sizeof(double); // NOLINT + + rows_.reset(new int[num_rows_ + 1]); + cols_.reset(new int[max_num_nonzeros_]); + values_.reset(new double[max_num_nonzeros_]); + + fill(rows_.get(), rows_.get() + num_rows_ + 1, 0); + fill(cols_.get(), cols_.get() + max_num_nonzeros_, 0); + fill(values_.get(), values_.get() + max_num_nonzeros_, 0); +} + +CompressedRowSparseMatrix::CompressedRowSparseMatrix( + const TripletSparseMatrix& m) { + num_rows_ = m.num_rows(); + num_cols_ = m.num_cols(); + max_num_nonzeros_ = m.max_num_nonzeros(); + + // index is the list of indices into the TripletSparseMatrix m. + vector index(m.num_nonzeros(), 0); + for (int i = 0; i < m.num_nonzeros(); ++i) { + index[i] = i; + } + + // Sort index such that the entries of m are ordered by row and ties + // are broken by column. + sort(index.begin(), index.end(), RowColLessThan(m.rows(), m.cols())); + + VLOG(1) << "# of rows: " << num_rows_ << " # of columns: " << num_cols_ + << " max_num_nonzeros: " << max_num_nonzeros_ + << ". Allocating " << (num_rows_ + 1) * sizeof(int) + // NOLINT + max_num_nonzeros_ * sizeof(int) + // NOLINT + max_num_nonzeros_ * sizeof(double); // NOLINT + + rows_.reset(new int[num_rows_ + 1]); + cols_.reset(new int[max_num_nonzeros_]); + values_.reset(new double[max_num_nonzeros_]); + + // rows_ = 0 + fill(rows_.get(), rows_.get() + num_rows_ + 1, 0); + + // Copy the contents of the cols and values array in the order given + // by index and count the number of entries in each row. + for (int i = 0; i < m.num_nonzeros(); ++i) { + const int idx = index[i]; + ++rows_[m.rows()[idx] + 1]; + cols_[i] = m.cols()[idx]; + values_[i] = m.values()[idx]; + } + + // Find the cumulative sum of the row counts. + for (int i = 1; i < num_rows_ + 1; ++i) { + rows_[i] += rows_[i-1]; + } + + CHECK_EQ(num_nonzeros(), m.num_nonzeros()); +} + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +CompressedRowSparseMatrix::CompressedRowSparseMatrix( + const SparseMatrixProto& outer_proto) { + CHECK(outer_proto.has_compressed_row_matrix()); + + const CompressedRowSparseMatrixProto& proto = + outer_proto.compressed_row_matrix(); + + num_rows_ = proto.num_rows(); + num_cols_ = proto.num_cols(); + + rows_.reset(new int[proto.rows_size()]); + cols_.reset(new int[proto.cols_size()]); + values_.reset(new double[proto.values_size()]); + + for (int i = 0; i < proto.rows_size(); ++i) { + rows_[i] = proto.rows(i); + } + + CHECK_EQ(proto.rows_size(), num_rows_ + 1); + CHECK_EQ(proto.cols_size(), proto.values_size()); + CHECK_EQ(proto.cols_size(), rows_[num_rows_]); + + for (int i = 0; i < proto.cols_size(); ++i) { + cols_[i] = proto.cols(i); + values_[i] = proto.values(i); + } + + max_num_nonzeros_ = proto.cols_size(); +} +#endif + +CompressedRowSparseMatrix::CompressedRowSparseMatrix(const double* diagonal, + int num_rows) { + CHECK_NOTNULL(diagonal); + + num_rows_ = num_rows; + num_cols_ = num_rows; + max_num_nonzeros_ = num_rows; + + rows_.reset(new int[num_rows_ + 1]); + cols_.reset(new int[num_rows_]); + values_.reset(new double[num_rows_]); + + rows_[0] = 0; + for (int i = 0; i < num_rows_; ++i) { + cols_[i] = i; + values_[i] = diagonal[i]; + rows_[i + 1] = i + 1; + } + + CHECK_EQ(num_nonzeros(), num_rows); +} + +CompressedRowSparseMatrix::~CompressedRowSparseMatrix() { +} + +void CompressedRowSparseMatrix::SetZero() { + fill(values_.get(), values_.get() + num_nonzeros(), 0.0); +} + +void CompressedRowSparseMatrix::RightMultiply(const double* x, + double* y) const { + CHECK_NOTNULL(x); + CHECK_NOTNULL(y); + + for (int r = 0; r < num_rows_; ++r) { + for (int idx = rows_[r]; idx < rows_[r + 1]; ++idx) { + y[r] += values_[idx] * x[cols_[idx]]; + } + } +} + +void CompressedRowSparseMatrix::LeftMultiply(const double* x, double* y) const { + CHECK_NOTNULL(x); + CHECK_NOTNULL(y); + + for (int r = 0; r < num_rows_; ++r) { + for (int idx = rows_[r]; idx < rows_[r + 1]; ++idx) { + y[cols_[idx]] += values_[idx] * x[r]; + } + } +} + +void CompressedRowSparseMatrix::SquaredColumnNorm(double* x) const { + CHECK_NOTNULL(x); + + fill(x, x + num_cols_, 0.0); + for (int idx = 0; idx < rows_[num_rows_]; ++idx) { + x[cols_[idx]] += values_[idx] * values_[idx]; + } +} + +void CompressedRowSparseMatrix::ScaleColumns(const double* scale) { + CHECK_NOTNULL(scale); + + for (int idx = 0; idx < rows_[num_rows_]; ++idx) { + values_[idx] *= scale[cols_[idx]]; + } +} + +void CompressedRowSparseMatrix::ToDenseMatrix(Matrix* dense_matrix) const { + CHECK_NOTNULL(dense_matrix); + dense_matrix->resize(num_rows_, num_cols_); + dense_matrix->setZero(); + + for (int r = 0; r < num_rows_; ++r) { + for (int idx = rows_[r]; idx < rows_[r + 1]; ++idx) { + (*dense_matrix)(r, cols_[idx]) = values_[idx]; + } + } +} + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +void CompressedRowSparseMatrix::ToProto(SparseMatrixProto* outer_proto) const { + CHECK_NOTNULL(outer_proto); + + outer_proto->Clear(); + CompressedRowSparseMatrixProto* proto + = outer_proto->mutable_compressed_row_matrix(); + + proto->set_num_rows(num_rows_); + proto->set_num_cols(num_cols_); + + for (int r = 0; r < num_rows_ + 1; ++r) { + proto->add_rows(rows_[r]); + } + + for (int idx = 0; idx < rows_[num_rows_]; ++idx) { + proto->add_cols(cols_[idx]); + proto->add_values(values_[idx]); + } +} +#endif + +void CompressedRowSparseMatrix::DeleteRows(int delta_rows) { + CHECK_GE(delta_rows, 0); + CHECK_LE(delta_rows, num_rows_); + + int new_num_rows = num_rows_ - delta_rows; + + num_rows_ = new_num_rows; + int* new_rows = new int[num_rows_ + 1]; + copy(rows_.get(), rows_.get() + num_rows_ + 1, new_rows); + rows_.reset(new_rows); +} + +void CompressedRowSparseMatrix::AppendRows(const CompressedRowSparseMatrix& m) { + CHECK_EQ(m.num_cols(), num_cols_); + + // Check if there is enough space. If not, then allocate new arrays + // to hold the combined matrix and copy the contents of this matrix + // into it. + if (max_num_nonzeros_ < num_nonzeros() + m.num_nonzeros()) { + int new_max_num_nonzeros = num_nonzeros() + m.num_nonzeros(); + + VLOG(1) << "Reallocating " << sizeof(int) * new_max_num_nonzeros; // NOLINT + + int* new_cols = new int[new_max_num_nonzeros]; + copy(cols_.get(), cols_.get() + max_num_nonzeros_, new_cols); + cols_.reset(new_cols); + + double* new_values = new double[new_max_num_nonzeros]; + copy(values_.get(), values_.get() + max_num_nonzeros_, new_values); + values_.reset(new_values); + + max_num_nonzeros_ = new_max_num_nonzeros; + } + + // Copy the contents of m into this matrix. + copy(m.cols(), m.cols() + m.num_nonzeros(), cols_.get() + num_nonzeros()); + copy(m.values(), + m.values() + m.num_nonzeros(), + values_.get() + num_nonzeros()); + + // Create the new rows array to hold the enlarged matrix. + int* new_rows = new int[num_rows_ + m.num_rows() + 1]; + // The first num_rows_ entries are the same + copy(rows_.get(), rows_.get() + num_rows_, new_rows); + + // new_rows = [rows_, m.row() + rows_[num_rows_]] + fill(new_rows + num_rows_, + new_rows + num_rows_ + m.num_rows() + 1, + rows_[num_rows_]); + + for (int r = 0; r < m.num_rows() + 1; ++r) { + new_rows[num_rows_ + r] += m.rows()[r]; + } + + rows_.reset(new_rows); + num_rows_ += m.num_rows(); +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h new file mode 100644 index 00000000000..43712a86640 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h @@ -0,0 +1,129 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_COMPRESSED_ROW_SPARSE_MATRIX_H_ +#define CERES_INTERNAL_COMPRESSED_ROW_SPARSE_MATRIX_H_ + +#include +#include "ceres/sparse_matrix.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/macros.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +class SparseMatrixProto; + +class CompressedRowSparseMatrix : public SparseMatrix { + public: + // Build a matrix with the same content as the TripletSparseMatrix + // m. TripletSparseMatrix objects are easier to construct + // incrementally, so we use them to initialize SparseMatrix + // objects. + // + // We assume that m does not have any repeated entries. + explicit CompressedRowSparseMatrix(const TripletSparseMatrix& m); +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS + explicit CompressedRowSparseMatrix(const SparseMatrixProto& proto); +#endif + + // Use this constructor only if you know what you are doing. This + // creates a "blank" matrix with the appropriate amount of memory + // allocated. However, the object itself is in an inconsistent state + // as the rows and cols matrices do not match the values of + // num_rows, num_cols and max_num_nonzeros. + // + // The use case for this constructor is that when the user knows the + // size of the matrix to begin with and wants to update the layout + // manually, instead of going via the indirect route of first + // constructing a TripletSparseMatrix, which leads to more than + // double the peak memory usage. + CompressedRowSparseMatrix(int num_rows, + int num_cols, + int max_num_nonzeros); + + // Build a square sparse diagonal matrix with num_rows rows and + // columns. The diagonal m(i,i) = diagonal(i); + CompressedRowSparseMatrix(const double* diagonal, int num_rows); + + virtual ~CompressedRowSparseMatrix(); + + // SparseMatrix interface. + virtual void SetZero(); + virtual void RightMultiply(const double* x, double* y) const; + virtual void LeftMultiply(const double* x, double* y) const; + virtual void SquaredColumnNorm(double* x) const; + virtual void ScaleColumns(const double* scale); + + virtual void ToDenseMatrix(Matrix* dense_matrix) const; +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS + virtual void ToProto(SparseMatrixProto* proto) const; +#endif + + virtual int num_rows() const { return num_rows_; } + virtual int num_cols() const { return num_cols_; } + virtual int num_nonzeros() const { return rows_[num_rows_]; } + virtual const double* values() const { return values_.get(); } + virtual double* mutable_values() { return values_.get(); } + + // Delete the bottom delta_rows. + // num_rows -= delta_rows + void DeleteRows(int delta_rows); + + // Append the contents of m to the bottom of this matrix. m must + // have the same number of columns as this matrix. + void AppendRows(const CompressedRowSparseMatrix& m); + + // Low level access methods that expose the structure of the matrix. + const int* cols() const { return cols_.get(); } + int* mutable_cols() { return cols_.get(); } + + const int* rows() const { return rows_.get(); } + int* mutable_rows() { return rows_.get(); } + + private: + scoped_array cols_; + scoped_array rows_; + scoped_array values_; + + int num_rows_; + int num_cols_; + + int max_num_nonzeros_; + + DISALLOW_COPY_AND_ASSIGN(CompressedRowSparseMatrix); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_COMPRESSED_ROW_SPARSE_MATRIX_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/conditioned_cost_function.cc b/extern/libmv/third_party/ceres/internal/ceres/conditioned_cost_function.cc new file mode 100644 index 00000000000..ca80bfb9c9d --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/conditioned_cost_function.cc @@ -0,0 +1,130 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: wjr@google.com (William Rucklidge) +// +// This file contains the implementation of the conditioned cost function. + +#include "ceres/conditioned_cost_function.h" + +#include + +#include +#include "ceres/stl_util.h" +#include "ceres/internal/eigen.h" +#include "ceres/types.h" + +namespace ceres { + +// This cost function has the same dimensions (parameters, residuals) as +// the one it's wrapping. +ConditionedCostFunction::ConditionedCostFunction( + CostFunction* wrapped_cost_function, + const vector& conditioners, + Ownership ownership) + : wrapped_cost_function_(wrapped_cost_function), + conditioners_(conditioners), + ownership_(ownership) { + // Set up our dimensions. + set_num_residuals(wrapped_cost_function_->num_residuals()); + *mutable_parameter_block_sizes() = + wrapped_cost_function_->parameter_block_sizes(); + + // Sanity-check the conditioners' dimensions. + CHECK_EQ(wrapped_cost_function_->num_residuals(), conditioners_.size()); + for (int i = 0; i < wrapped_cost_function_->num_residuals(); i++) { + if (conditioners[i]) { + CHECK_EQ(1, conditioners[i]->num_residuals()); + CHECK_EQ(1, conditioners[i]->parameter_block_sizes().size()); + CHECK_EQ(1, conditioners[i]->parameter_block_sizes()[0]); + } + } +} + +ConditionedCostFunction::~ConditionedCostFunction() { + if (ownership_ == TAKE_OWNERSHIP) { + STLDeleteElements(&conditioners_); + } else { + wrapped_cost_function_.release(); + } +} + +bool ConditionedCostFunction::Evaluate(double const* const* parameters, + double* residuals, + double** jacobians) const { + bool success = wrapped_cost_function_->Evaluate(parameters, residuals, + jacobians); + if (!success) { + return false; + } + + for (int r = 0; r < wrapped_cost_function_->num_residuals(); r++) { + // On output, we want to have + // residuals[r] = conditioners[r](wrapped_residuals[r]) + // For parameter block i, column c, + // jacobians[i][r*parameter_block_size_[i] + c] = + // = d residual[r] / d parameters[i][c] + // = conditioners[r]'(wrapped_residuals[r]) * + // d wrapped_residuals[r] / d parameters[i][c] + if (conditioners_[r]) { + double conditioner_derivative; + double* conditioner_derivative_pointer = &conditioner_derivative; + double** conditioner_derivative_pointer2 = + &conditioner_derivative_pointer; + if (!jacobians) { + conditioner_derivative_pointer2 = NULL; + } + + double unconditioned_residual = residuals[r]; + double* parameter_pointer = &unconditioned_residual; + success = conditioners_[r]->Evaluate(¶meter_pointer, + &residuals[r], + conditioner_derivative_pointer2); + if (!success) { + return false; + } + + if (jacobians) { + for (int i = 0; + i < wrapped_cost_function_->parameter_block_sizes().size(); + i++) { + if (jacobians[i]) { + int parameter_block_size = + wrapped_cost_function_->parameter_block_sizes()[i]; + VectorRef jacobian_row(jacobians[i] + r * parameter_block_size, + parameter_block_size, 1); + jacobian_row *= conditioner_derivative; + } + } + } + } + } + return true; +} + +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.cc new file mode 100644 index 00000000000..75f9e043fa5 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.cc @@ -0,0 +1,233 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// A preconditioned conjugate gradients solver +// (ConjugateGradientsSolver) for positive semidefinite linear +// systems. +// +// We have also augmented the termination criterion used by this +// solver to support not just residual based termination but also +// termination based on decrease in the value of the quadratic model +// that CG optimizes. + +#include "ceres/conjugate_gradients_solver.h" + +#include +#include +#include +#include "ceres/linear_operator.h" +#include "ceres/internal/eigen.h" +#include "ceres/types.h" +#include "ceres/jet.h" + +namespace ceres { +namespace internal { +namespace { + +bool IsZeroOrInfinity(double x) { + return ((x == 0.0) || (isinf(x))); +} + +// Constant used in the MATLAB implementation ~ 2 * eps. +const double kEpsilon = 2.2204e-16; + +} // namespace + +ConjugateGradientsSolver::ConjugateGradientsSolver( + const LinearSolver::Options& options) + : options_(options) { +} + +LinearSolver::Summary ConjugateGradientsSolver::Solve( + LinearOperator* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double* x) { + CHECK_NOTNULL(A); + CHECK_NOTNULL(x); + CHECK_NOTNULL(b); + CHECK_EQ(A->num_rows(), A->num_cols()); + + LinearSolver::Summary summary; + summary.termination_type = MAX_ITERATIONS; + summary.num_iterations = 0; + + int num_cols = A->num_cols(); + VectorRef xref(x, num_cols); + ConstVectorRef bref(b, num_cols); + + double norm_b = bref.norm(); + if (norm_b == 0.0) { + xref.setZero(); + summary.termination_type = TOLERANCE; + return summary; + } + + Vector r(num_cols); + Vector p(num_cols); + Vector z(num_cols); + Vector tmp(num_cols); + + double tol_r = per_solve_options.r_tolerance * norm_b; + + tmp.setZero(); + A->RightMultiply(x, tmp.data()); + r = bref - tmp; + double norm_r = r.norm(); + + if (norm_r <= tol_r) { + summary.termination_type = TOLERANCE; + return summary; + } + + double rho = 1.0; + + // Initial value of the quadratic model Q = x'Ax - 2 * b'x. + double Q0 = -1.0 * xref.dot(bref + r); + + for (summary.num_iterations = 1; + summary.num_iterations < options_.max_num_iterations; + ++summary.num_iterations) { + VLOG(2) << "cg iteration " << summary.num_iterations; + + // Apply preconditioner + if (per_solve_options.preconditioner != NULL) { + z.setZero(); + per_solve_options.preconditioner->RightMultiply(r.data(), z.data()); + } else { + z = r; + } + + double last_rho = rho; + rho = r.dot(z); + + if (IsZeroOrInfinity(rho)) { + LOG(ERROR) << "Numerical failure. rho = " << rho; + summary.termination_type = FAILURE; + break; + }; + + if (summary.num_iterations == 1) { + p = z; + } else { + double beta = rho / last_rho; + if (IsZeroOrInfinity(beta)) { + LOG(ERROR) << "Numerical failure. beta = " << beta; + summary.termination_type = FAILURE; + break; + } + p = z + beta * p; + } + + Vector& q = z; + q.setZero(); + A->RightMultiply(p.data(), q.data()); + double pq = p.dot(q); + + if ((pq <= 0) || isinf(pq)) { + LOG(ERROR) << "Numerical failure. pq = " << pq; + summary.termination_type = FAILURE; + break; + } + + double alpha = rho / pq; + if (isinf(alpha)) { + LOG(ERROR) << "Numerical failure. alpha " << alpha; + summary.termination_type = FAILURE; + break; + } + + xref = xref + alpha * p; + + // Ideally we would just use the update r = r - alpha*q to keep + // track of the residual vector. However this estimate tends to + // drift over time due to round off errors. Thus every + // residual_reset_period iterations, we calculate the residual as + // r = b - Ax. We do not do this every iteration because this + // requires an additional matrix vector multiply which would + // double the complexity of the CG algorithm. + if (summary.num_iterations % options_.residual_reset_period == 0) { + tmp.setZero(); + A->RightMultiply(x, tmp.data()); + r = bref - tmp; + } else { + r = r - alpha * q; + } + + // Quadratic model based termination. + // Q1 = x'Ax - 2 * b' x. + double Q1 = -1.0 * xref.dot(bref + r); + + // For PSD matrices A, let + // + // Q(x) = x'Ax - 2b'x + // + // be the cost of the quadratic function defined by A and b. Then, + // the solver terminates at iteration i if + // + // i * (Q(x_i) - Q(x_i-1)) / Q(x_i) < q_tolerance. + // + // This termination criterion is more useful when using CG to + // solve the Newton step. This particular convergence test comes + // from Stephen Nash's work on truncated Newton + // methods. References: + // + // 1. Stephen G. Nash & Ariela Sofer, Assessing A Search + // Direction Within A Truncated Newton Method, Operation + // Research Letters 9(1990) 219-221. + // + // 2. Stephen G. Nash, A Survey of Truncated Newton Methods, + // Journal of Computational and Applied Mathematics, + // 124(1-2), 45-59, 2000. + // + double zeta = summary.num_iterations * (Q1 - Q0) / Q1; + VLOG(2) << "Q termination: zeta " << zeta + << " " << per_solve_options.q_tolerance; + if (zeta < per_solve_options.q_tolerance) { + summary.termination_type = TOLERANCE; + break; + } + Q0 = Q1; + + // Residual based termination. + norm_r = r. norm(); + VLOG(2) << "R termination: norm_r " << norm_r + << " " << tol_r; + if (norm_r <= tol_r) { + summary.termination_type = TOLERANCE; + break; + } + } + + return summary; +}; + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.h b/extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.h new file mode 100644 index 00000000000..57f99e31db7 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.h @@ -0,0 +1,74 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Preconditioned Conjugate Gradients based solver for positive +// semidefinite linear systems. + +#ifndef CERES_INTERNAL_CONJUGATE_GRADIENTS_SOLVER_H_ +#define CERES_INTERNAL_CONJUGATE_GRADIENTS_SOLVER_H_ + +#include "ceres/linear_solver.h" +#include "ceres/internal/macros.h" + +namespace ceres { +namespace internal { + +class LinearOperator; + +// This class implements the now classical Conjugate Gradients +// algorithm of Hestenes & Stiefel for solving postive semidefinite +// linear sytems. Optionally it can use a preconditioner also to +// reduce the condition number of the linear system and improve the +// convergence rate. Modern references for Conjugate Gradients are the +// books by Yousef Saad and Trefethen & Bau. This implementation of CG +// has been augmented with additional termination tests that are +// needed for forcing early termination when used as part of an +// inexact Newton solver. +// +// For more details see the documentation for +// LinearSolver::PerSolveOptions::r_tolerance and +// LinearSolver::PerSolveOptions::q_tolerance in linear_solver.h. +class ConjugateGradientsSolver : public LinearSolver { + public: + explicit ConjugateGradientsSolver(const LinearSolver::Options& options); + virtual Summary Solve(LinearOperator* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double* x); + + private: + const LinearSolver::Options options_; + DISALLOW_COPY_AND_ASSIGN(ConjugateGradientsSolver); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_CONJUGATE_GRADIENTS_SOLVER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/corrector.cc b/extern/libmv/third_party/ceres/internal/ceres/corrector.cc new file mode 100644 index 00000000000..4ca2c6f6c86 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/corrector.cc @@ -0,0 +1,125 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/corrector.h" + +#include +#include +#include +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +Corrector::Corrector(double sq_norm, const double rho[3]) { + CHECK_GE(sq_norm, 0.0); + CHECK_GT(rho[1], 0.0); + sqrt_rho1_ = sqrt(rho[1]); + + // If sq_norm = 0.0, the correction becomes trivial, the residual + // and the jacobian are scaled by the squareroot of the derivative + // of rho. Handling this case explicitly avoids the divide by zero + // error that would occur below. + // + // The case where rho'' < 0 also gets special handling. Technically + // it shouldn't, and the computation of the scaling should proceed + // as below, however we found in experiments that applying the + // curvature correction when rho'' < 0, which is the case when we + // are in the outlier region slows down the convergence of the + // algorithm significantly. + // + // Thus, we have divided the action of the robustifier into two + // parts. In the inliner region, we do the full second order + // correction which re-wights the gradient of the function by the + // square root of the derivative of rho, and the Gauss-Newton + // Hessian gets both the scaling and the rank-1 curvature + // correction. Normaly, alpha is upper bounded by one, but with this + // change, alpha is bounded above by zero. + // + // Empirically we have observed that the full Triggs correction and + // the clamped correction both start out as very good approximations + // to the loss function when we are in the convex part of the + // function, but as the function starts transitioning from convex to + // concave, the Triggs approximation diverges more and more and + // ultimately becomes linear. The clamped Triggs model however + // remains quadratic. + // + // The reason why the Triggs approximation becomes so poor is + // because the curvature correction that it applies to the gauss + // newton hessian goes from being a full rank correction to a rank + // deficient correction making the inversion of the Hessian fraught + // with all sorts of misery and suffering. + // + // The clamped correction retains its quadratic nature and inverting it + // is always well formed. + if ((sq_norm == 0.0) || (rho[2] <= 0.0)) { + residual_scaling_ = sqrt_rho1_; + alpha_sq_norm_ = 0.0; + return; + } + + // Calculate the smaller of the two solutions to the equation + // + // 0.5 * alpha^2 - alpha - rho'' / rho' * z'z = 0. + // + // Start by calculating the discriminant D. + const double D = 1.0 + 2.0 * sq_norm*rho[2] / rho[1]; + + // Since both rho[1] and rho[2] are guaranteed to be positive at + // this point, we know that D > 1.0. + + const double alpha = 1.0 - sqrt(D); + + // Calculate the constants needed by the correction routines. + residual_scaling_ = sqrt_rho1_ / (1 - alpha); + alpha_sq_norm_ = alpha / sq_norm; +} + +void Corrector::CorrectResiduals(int nrow, double* residuals) { + DCHECK(residuals != NULL); + VectorRef r_ref(residuals, nrow); + // Equation 11 in BANS. + r_ref *= residual_scaling_; +} + +void Corrector::CorrectJacobian(int nrow, int ncol, + double* residuals, double* jacobian) { + DCHECK(residuals != NULL); + DCHECK(jacobian != NULL); + ConstVectorRef r_ref(residuals, nrow); + MatrixRef j_ref(jacobian, nrow, ncol); + + // Equation 11 in BANS. + j_ref = sqrt_rho1_ * (j_ref - alpha_sq_norm_ * + r_ref * (r_ref.transpose() * j_ref)); +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/corrector.h b/extern/libmv/third_party/ceres/internal/ceres/corrector.h new file mode 100644 index 00000000000..9914641cb01 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/corrector.h @@ -0,0 +1,88 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Class definition for the object that is responsible for applying a +// second order correction to the Gauss-Newton based on the ideas in +// BANS by Triggs et al. + +#ifndef CERES_INTERNAL_CORRECTOR_H_ +#define CERES_INTERNAL_CORRECTOR_H_ + +namespace ceres { +namespace internal { + +// Corrector is responsible for applying the second order correction +// to the residual and jacobian of a least squares problem based on a +// radial robust loss. +// +// The key idea here is to look at the expressions for the robustified +// gauss newton approximation and then take its squareroot to get the +// corresponding corrections to the residual and jacobian. For the +// full expressions see Eq. 10 and 11 in BANS by Triggs et al. +class Corrector { + public: + // The constructor takes the squared norm, the value, the first and + // second derivatives of the LossFunction. It precalculates some of + // the constants that are needed to apply the correction. The + // correction constant alpha is constrained to be smaller than 1, if + // it becomes larger than 1, then it will reverse the sign of the + // residual and the correction. If alpha is equal to 1 will result + // in a divide by zero error. Thus we constrain alpha to be upper + // bounded by 1 - epsilon_. + // + // rho[1] needs to be positive. The constructor will crash if this + // condition is not met. + // + // In practical use CorrectJacobian should always be called before + // CorrectResidual, because the jacobian correction depends on the + // value of the uncorrected residual values. + explicit Corrector(double sq_norm, const double rho[3]); + + // residuals *= sqrt(rho[1]) / (1 - alpha) + void CorrectResiduals(int nrow, double* residuals); + + // jacobian = sqrt(rho[1]) * jacobian - + // sqrt(rho[1]) * alpha / sq_norm * residuals residuals' * jacobian. + // + // The method assumes that the jacobian has row-major storage. It is + // the caller's responsibility to ensure that the pointer to + // jacobian is not null. + void CorrectJacobian(int nrow, int ncol, + double* residuals, double* jacobian); + + private: + double sqrt_rho1_; + double residual_scaling_; + double alpha_sq_norm_; +}; +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_CORRECTOR_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_jacobian_writer.h b/extern/libmv/third_party/ceres/internal/ceres/dense_jacobian_writer.h new file mode 100644 index 00000000000..1177b83a556 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/dense_jacobian_writer.h @@ -0,0 +1,110 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// A jacobian writer that writes to dense Eigen matrices. + +#ifndef CERES_INTERNAL_DENSE_JACOBIAN_WRITER_H_ +#define CERES_INTERNAL_DENSE_JACOBIAN_WRITER_H_ + +#include "ceres/casts.h" +#include "ceres/dense_sparse_matrix.h" +#include "ceres/parameter_block.h" +#include "ceres/program.h" +#include "ceres/residual_block.h" +#include "ceres/scratch_evaluate_preparer.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +class DenseJacobianWriter { + public: + DenseJacobianWriter(Evaluator::Options /* ignored */, + Program* program) + : program_(program) { + } + + // JacobianWriter interface. + + // Since the dense matrix has different layout than that assumed by the cost + // functions, use scratch space to store the jacobians temporarily then copy + // them over to the larger jacobian later. + ScratchEvaluatePreparer* CreateEvaluatePreparers(int num_threads) { + return ScratchEvaluatePreparer::Create(*program_, num_threads); + } + + SparseMatrix* CreateJacobian() const { + return new DenseSparseMatrix(program_->NumResiduals(), + program_->NumEffectiveParameters()); + } + + void Write(int residual_id, + int residual_offset, + double **jacobians, + SparseMatrix* jacobian) { + DenseSparseMatrix* dense_jacobian; + if (jacobian != NULL) { + dense_jacobian = down_cast(jacobian); + } + const ResidualBlock* residual_block = + program_->residual_blocks()[residual_id]; + int num_parameter_blocks = residual_block->NumParameterBlocks(); + int num_residuals = residual_block->NumResiduals(); + + // Now copy the jacobians for each parameter into the dense jacobian matrix. + for (int j = 0; j < num_parameter_blocks; ++j) { + ParameterBlock* parameter_block = residual_block->parameter_blocks()[j]; + + // If the parameter block is fixed, then there is nothing to do. + if (parameter_block->IsConstant()) { + continue; + } + + int parameter_block_size = parameter_block->LocalSize(); + MatrixRef parameter_jacobian(jacobians[j], + num_residuals, + parameter_block_size); + + dense_jacobian->mutable_matrix().block( + residual_offset, + parameter_block->delta_offset(), + num_residuals, + parameter_block_size) = parameter_jacobian; + } + } + + private: + Program* program_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_DENSE_JACOBIAN_WRITER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.cc new file mode 100644 index 00000000000..328505404d7 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.cc @@ -0,0 +1,93 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/dense_qr_solver.h" + +#include + +#include "Eigen/Dense" +#include "ceres/linear_solver.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +DenseQRSolver::DenseQRSolver(const LinearSolver::Options& options) + : options_(options) {} + +LinearSolver::Summary DenseQRSolver::SolveImpl( + DenseSparseMatrix* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double* x) { + const int num_rows = A->num_rows(); + const int num_cols = A->num_cols(); + VLOG(2) << "DenseQRSolver: " + << num_rows << " x " << num_cols << " system."; + + if (per_solve_options.D != NULL) { + // Temporarily append a diagonal block to the A matrix, but undo + // it before returning the matrix to the user. + A->AppendDiagonal(per_solve_options.D); + } + + // rhs = [b;0] to account for the additional rows in the lhs. + Vector rhs(num_rows + ((per_solve_options.D !=NULL) ? num_cols : 0)); + rhs.setZero(); + rhs.head(num_rows) = ConstVectorRef(b, num_rows); + + // Solve the system. + VectorRef(x, num_cols) = A->matrix().colPivHouseholderQr().solve(rhs); + + VLOG(3) << "A:\n" << A->matrix(); + VLOG(3) << "x:\n" << VectorRef(x, num_cols); + VLOG(3) << "b:\n" << rhs; + VLOG(3) << "error: " << (A->matrix() * VectorRef(x, num_cols) - rhs).norm(); + + + if (per_solve_options.D != NULL) { + // Undo the modifications to the matrix A. + A->RemoveDiagonal(); + } + + // We always succeed, since the QR solver returns the best solution + // it can. It is the job of the caller to determine if the solution + // is good enough or not. + LinearSolver::Summary summary; + summary.num_iterations = 1; + summary.termination_type = TOLERANCE; + return summary; +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.h b/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.h new file mode 100644 index 00000000000..990c8d445eb --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.h @@ -0,0 +1,99 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Solve dense rectangular systems Ax = b using the QR factoriztion. +#ifndef CERES_INTERNAL_DENSE_QR_SOLVER_H_ +#define CERES_INTERNAL_DENSE_QR_SOLVER_H_ + +#include "ceres/linear_solver.h" +#include "ceres/internal/macros.h" + +namespace ceres { +namespace internal { + +class DenseSparseMatrix; + +// This class implements the LinearSolver interface for solving +// rectangular/unsymmetric (well constrained) linear systems of the +// form +// +// Ax = b +// +// Since there does not usually exist a solution that satisfies these +// equations, the solver instead solves the linear least squares +// problem +// +// min_x |Ax - b|^2 +// +// The solution strategy is based on computing the QR decomposition of +// A, i.e. +// +// A = QR +// +// Where Q is an orthonormal matrix and R is an upper triangular +// matrix. Then +// +// Ax = b +// QRx = b +// Q'QRx = Q'b +// Rx = Q'b +// x = R^{-1} Q'b +// +// If the PerSolveOptions struct has a non-null array D, then the +// augmented/regularized linear system +// +// [ A ]x = [b] +// [ diag(D) ] [0] +// +// is solved. +// +// This class uses the dense QR factorization routines from the Eigen +// library. This solver always returns a solution, it is the user's +// responsibility to judge if the solution is good enough for their +// purposes. +class DenseQRSolver: public DenseSparseMatrixSolver { + public: + explicit DenseQRSolver(const LinearSolver::Options& options); + + private: + virtual LinearSolver::Summary SolveImpl( + DenseSparseMatrix* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double* x); + + const LinearSolver::Options options_; + DISALLOW_COPY_AND_ASSIGN(DenseQRSolver); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_DENSE_QR_SOLVER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc new file mode 100644 index 00000000000..ffbfab61de1 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc @@ -0,0 +1,184 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include "ceres/dense_sparse_matrix.h" + +#include +#include "ceres/matrix_proto.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" + +namespace ceres { +namespace internal { + +DenseSparseMatrix::DenseSparseMatrix(int num_rows, int num_cols) + : has_diagonal_appended_(false), + has_diagonal_reserved_(false) { + // Allocate enough space for the diagonal. + m_.resize(num_rows, num_cols); + m_.setZero(); +} + +DenseSparseMatrix::DenseSparseMatrix(const TripletSparseMatrix& m) + : m_(Eigen::MatrixXd::Zero(m.num_rows(), m.num_cols())), + has_diagonal_appended_(false), + has_diagonal_reserved_(false) { + const double *values = m.values(); + const int *rows = m.rows(); + const int *cols = m.cols(); + int num_nonzeros = m.num_nonzeros(); + + for (int i = 0; i < num_nonzeros; ++i) { + m_(rows[i], cols[i]) += values[i]; + } +} + +DenseSparseMatrix::DenseSparseMatrix(const Matrix& m) + : m_(m), + has_diagonal_appended_(false), + has_diagonal_reserved_(false) { +} + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +DenseSparseMatrix::DenseSparseMatrix(const SparseMatrixProto& outer_proto) + : m_(Eigen::MatrixXd::Zero( + outer_proto.dense_matrix().num_rows(), + outer_proto.dense_matrix().num_cols())), + has_diagonal_appended_(false), + has_diagonal_reserved_(false) { + const DenseSparseMatrixProto& proto = outer_proto.dense_matrix(); + for (int i = 0; i < m_.rows(); ++i) { + for (int j = 0; j < m_.cols(); ++j) { + m_(i, j) = proto.values(m_.cols() * i + j); + } + } +} +#endif + +void DenseSparseMatrix::SetZero() { + m_.setZero(); +} + +void DenseSparseMatrix::RightMultiply(const double* x, double* y) const { + VectorRef(y, num_rows()) += matrix() * ConstVectorRef(x, num_cols()); +} + +void DenseSparseMatrix::LeftMultiply(const double* x, double* y) const { + VectorRef(y, num_cols()) += + matrix().transpose() * ConstVectorRef(x, num_rows()); +} + +void DenseSparseMatrix::SquaredColumnNorm(double* x) const { + VectorRef(x, num_cols()) = m_.colwise().squaredNorm(); +} + +void DenseSparseMatrix::ScaleColumns(const double* scale) { + m_ *= ConstVectorRef(scale, num_cols()).asDiagonal(); +} + +void DenseSparseMatrix::ToDenseMatrix(Matrix* dense_matrix) const { + *dense_matrix = m_; +} + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +void DenseSparseMatrix::ToProto(SparseMatrixProto* outer_proto) const { + CHECK(!has_diagonal_appended_) << "Not supported."; + outer_proto->Clear(); + DenseSparseMatrixProto* proto = outer_proto->mutable_dense_matrix(); + + proto->set_num_rows(num_rows()); + proto->set_num_cols(num_cols()); + + int num_nnz = num_nonzeros(); + for (int i = 0; i < num_nnz; ++i) { + proto->add_values(m_.data()[i]); + } +} +#endif + +void DenseSparseMatrix::AppendDiagonal(double *d) { + CHECK(!has_diagonal_appended_); + if (!has_diagonal_reserved_) { + Matrix tmp = m_; + m_.resize(m_.rows() + m_.cols(), m_.cols()); + m_.setZero(); + m_.block(0, 0, tmp.rows(), tmp.cols()) = tmp; + has_diagonal_reserved_ = true; + } + + m_.bottomLeftCorner(m_.cols(), m_.cols()) = + ConstVectorRef(d, m_.cols()).asDiagonal(); + has_diagonal_appended_ = true; +} + +void DenseSparseMatrix::RemoveDiagonal() { + CHECK(has_diagonal_appended_); + has_diagonal_appended_ = false; + // Leave the diagonal reserved. +} + +int DenseSparseMatrix::num_rows() const { + if (has_diagonal_reserved_ && !has_diagonal_appended_) { + return m_.rows() - m_.cols(); + } + return m_.rows(); +} + +int DenseSparseMatrix::num_cols() const { + return m_.cols(); +} + +int DenseSparseMatrix::num_nonzeros() const { + if (has_diagonal_reserved_ && !has_diagonal_appended_) { + return (m_.rows() - m_.cols()) * m_.cols(); + } + return m_.rows() * m_.cols(); +} + +ConstAlignedMatrixRef DenseSparseMatrix::matrix() const { + if (has_diagonal_reserved_ && !has_diagonal_appended_) { + return ConstAlignedMatrixRef( + m_.data(), m_.rows() - m_.cols(), m_.cols()); + } + return ConstAlignedMatrixRef(m_.data(), m_.rows(), m_.cols()); +} + +AlignedMatrixRef DenseSparseMatrix::mutable_matrix() { + if (has_diagonal_reserved_ && !has_diagonal_appended_) { + return AlignedMatrixRef( + m_.data(), m_.rows() - m_.cols(), m_.cols()); + } + return AlignedMatrixRef(m_.data(), m_.rows(), m_.cols()); +} + + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h new file mode 100644 index 00000000000..5ce29eef51b --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h @@ -0,0 +1,115 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// A dense matrix implemented under the SparseMatrix interface. + +#ifndef CERES_INTERNAL_DENSE_SPARSE_MATRIX_H_ +#define CERES_INTERNAL_DENSE_SPARSE_MATRIX_H_ + +#include +#include "ceres/sparse_matrix.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/macros.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +class SparseMatrixProto; +class TripletSparseMatrix; + +class DenseSparseMatrix : public SparseMatrix { + public: + // Build a matrix with the same content as the TripletSparseMatrix + // m. This assumes that m does not have any repeated entries. + explicit DenseSparseMatrix(const TripletSparseMatrix& m); + explicit DenseSparseMatrix(const Matrix& m); +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS + explicit DenseSparseMatrix(const SparseMatrixProto& proto); +#endif + + DenseSparseMatrix(int num_rows, int num_cols); + + virtual ~DenseSparseMatrix() {} + + // SparseMatrix interface. + virtual void SetZero(); + virtual void RightMultiply(const double* x, double* y) const; + virtual void LeftMultiply(const double* x, double* y) const; + virtual void SquaredColumnNorm(double* x) const; + virtual void ScaleColumns(const double* scale); + virtual void ToDenseMatrix(Matrix* dense_matrix) const; +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS + virtual void ToProto(SparseMatrixProto* proto) const; +#endif + virtual int num_rows() const; + virtual int num_cols() const; + virtual int num_nonzeros() const; + virtual const double* values() const { return m_.data(); } + virtual double* mutable_values() { return m_.data(); } + + ConstAlignedMatrixRef matrix() const; + AlignedMatrixRef mutable_matrix(); + + // Only one diagonal can be appended at a time. The diagonal is appended to + // as a new set of rows, e.g. + // + // Original matrix: + // + // x x x + // x x x + // x x x + // + // After append diagonal (1, 2, 3): + // + // x x x + // x x x + // x x x + // 1 0 0 + // 0 2 0 + // 0 0 3 + // + // Calling RemoveDiagonal removes the block. It is a fatal error to append a + // diagonal to a matrix that already has an appended diagonal, and it is also + // a fatal error to remove a diagonal from a matrix that has none. + void AppendDiagonal(double *d); + void RemoveDiagonal(); + + private: + Matrix m_; + bool has_diagonal_appended_; + bool has_diagonal_reserved_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_DENSE_SPARSE_MATRIX_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/detect_structure.cc b/extern/libmv/third_party/ceres/internal/ceres/detect_structure.cc new file mode 100644 index 00000000000..e9755043bab --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/detect_structure.cc @@ -0,0 +1,114 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include +#include "ceres/detect_structure.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +void DetectStructure(const CompressedRowBlockStructure& bs, + const int num_eliminate_blocks, + int* row_block_size, + int* e_block_size, + int* f_block_size) { + const int num_row_blocks = bs.rows.size(); + *row_block_size = 0; + *e_block_size = 0; + *f_block_size = 0; + + // Iterate over row blocks of the matrix, checking if row_block, + // e_block or f_block sizes remain constant. + for (int r = 0; r < num_row_blocks; ++r) { + const CompressedRow& row = bs.rows[r]; + // We do not care about the sizes of the blocks in rows which do + // not contain e_blocks. + if (row.cells.front().block_id >= num_eliminate_blocks) { + break; + } + const int e_block_id = row.cells.front().block_id; + + if (*row_block_size == 0) { + *row_block_size = row.block.size; + } else if (*row_block_size != Eigen::Dynamic && + *row_block_size != row.block.size) { + *row_block_size = Eigen::Dynamic; + VLOG(2) << "Dynamic row block size because the block size changed from " + << *row_block_size << " to " + << row.block.size; + } + + + if (*e_block_size == 0) { + *e_block_size = bs.cols[e_block_id].size; + } else if (*e_block_size != Eigen::Dynamic && + *e_block_size != bs.cols[e_block_id].size) { + *e_block_size = Eigen::Dynamic; + VLOG(2) << "Dynamic e block size because the block size changed from " + << *e_block_size << " to " + << bs.cols[e_block_id].size; + } + + if (*f_block_size == 0) { + if (row.cells.size() > 1) { + const int f_block_id = row.cells[1].block_id; + *f_block_size = bs.cols[f_block_id].size; + } + } else if (*f_block_size != Eigen::Dynamic) { + for (int c = 1; c < row.cells.size(); ++c) { + if (*f_block_size != bs.cols[row.cells[c].block_id].size) { + *f_block_size = Eigen::Dynamic; + VLOG(2) << "Dynamic f block size because the block size " + << "changed from " << *f_block_size << " to " + << bs.cols[row.cells[c].block_id].size; + break; + } + } + } + + const bool is_everything_dynamic = (*row_block_size == Eigen::Dynamic && + *e_block_size == Eigen::Dynamic && + *f_block_size == Eigen::Dynamic); + if (is_everything_dynamic) { + break; + } + } + + CHECK_NE(*row_block_size, 0) << "No rows found"; + CHECK_NE(*e_block_size, 0) << "No e type blocks found"; + VLOG(1) << "Schur complement static structure <" + << *row_block_size << "," + << *e_block_size << "," + << *f_block_size << ">."; +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/detect_structure.h b/extern/libmv/third_party/ceres/internal/ceres/detect_structure.h new file mode 100644 index 00000000000..8af4f236690 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/detect_structure.h @@ -0,0 +1,63 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_DETECT_STRUCTURE_H_ +#define CERES_INTERNAL_DETECT_STRUCTURE_H_ + +#include "ceres/block_structure.h" + +namespace ceres { +namespace internal { + +// Detect static blocks in the problem sparsity. For rows containing +// e_blocks, we are interested in detecting if the size of the row +// blocks, e_blocks and the f_blocks remain constant. If they do, then +// we can use template specialization to improve the performance of +// the block level linear algebra operations used by the +// SchurEliminator. +// +// If a block size is not constant, we return Eigen::Dynamic as the +// value. This just means that the eliminator uses dynamically sized +// linear algebra operations rather than static operations whose size +// is known as compile time. +// +// For more details about e_blocks and f_blocks, see +// schur_complement.h. This information is used to initialized an +// appropriate template specialization of SchurEliminator. +void DetectStructure(const CompressedRowBlockStructure& bs, + const int num_eliminate_blocks, + int* row_block_size, + int* e_block_size, + int* f_block_size); + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_DETECT_STRUCTURE_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/evaluator.cc b/extern/libmv/third_party/ceres/internal/ceres/evaluator.cc new file mode 100644 index 00000000000..ea05aefec8c --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/evaluator.cc @@ -0,0 +1,71 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include +#include "ceres/evaluator.h" +#include "ceres/block_evaluate_preparer.h" +#include "ceres/block_jacobian_writer.h" +#include "ceres/compressed_row_jacobian_writer.h" +#include "ceres/scratch_evaluate_preparer.h" +#include "ceres/dense_jacobian_writer.h" +#include "ceres/program_evaluator.h" + +namespace ceres { +namespace internal { + +Evaluator::~Evaluator() {} + +Evaluator* Evaluator::Create(const Evaluator::Options& options, + Program* program, + string* error) { + switch (options.linear_solver_type) { + case DENSE_QR: + return new ProgramEvaluator(options, + program); + case DENSE_SCHUR: + case SPARSE_SCHUR: + case ITERATIVE_SCHUR: + case CGNR: + return new ProgramEvaluator(options, + program); + case SPARSE_NORMAL_CHOLESKY: + return new ProgramEvaluator(options, + program); + default: + *error = "Invalid Linear Solver Type. Unable to create evaluator."; + return NULL; + } +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/evaluator.h b/extern/libmv/third_party/ceres/internal/ceres/evaluator.h new file mode 100644 index 00000000000..adefdd26660 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/evaluator.h @@ -0,0 +1,129 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// keir@google.com (Keir Mierle) + +#ifndef CERES_INTERNAL_EVALUATOR_H_ +#define CERES_INTERNAL_EVALUATOR_H_ + +#include +#include "ceres/internal/port.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +class Program; +class SparseMatrix; + +// The Evaluator interface offers a way to interact with a least squares cost +// function that is useful for an optimizer that wants to minimize the least +// squares objective. This insulates the optimizer from issues like Jacobian +// storage, parameterization, etc. +class Evaluator { + public: + virtual ~Evaluator(); + + struct Options { + Options() + : num_threads(1), + num_eliminate_blocks(-1), + linear_solver_type(DENSE_QR) {} + + int num_threads; + int num_eliminate_blocks; + LinearSolverType linear_solver_type; + }; + + static Evaluator* Create(const Options& options, + Program* program, + string* error); + + // Build and return a sparse matrix for storing and working with the Jacobian + // of the objective function. The jacobian has dimensions + // NumEffectiveParameters() by NumParameters(), and is typically extremely + // sparse. Since the sparsity pattern of the Jacobian remains constant over + // the lifetime of the optimization problem, this method is used to + // instantiate a SparseMatrix object with the appropriate sparsity structure + // (which can be an expensive operation) and then reused by the optimization + // algorithm and the various linear solvers. + // + // It is expected that the classes implementing this interface will be aware + // of their client's requirements for the kind of sparse matrix storage and + // layout that is needed for an efficient implementation. For example + // CompressedRowOptimizationProblem creates a compressed row representation of + // the jacobian for use with CHOLMOD, where as BlockOptimizationProblem + // creates a BlockSparseMatrix representation of the jacobian for use in the + // Schur complement based methods. + virtual SparseMatrix* CreateJacobian() const = 0; + + // Evaluate the cost function for the given state. Returns the cost, + // residuals, and jacobian in the corresponding arguments. Both residuals and + // jacobian are optional; to avoid computing them, pass NULL. + // + // If non-NULL, the Jacobian must have a suitable sparsity pattern; only the + // values array of the jacobian is modified. + // + // state is an array of size NumParameters(), cost is a pointer to a single + // double, and residuals is an array of doubles of size NumResiduals(). + virtual bool Evaluate(const double* state, + double* cost, + double* residuals, + SparseMatrix* jacobian) = 0; + + // Make a change delta (of size NumEffectiveParameters()) to state (of size + // NumParameters()) and store the result in state_plus_delta. + // + // In the case that there are no parameterizations used, this is equivalent to + // + // state_plus_delta[i] = state[i] + delta[i] ; + // + // however, the mapping is more complicated in the case of parameterizations + // like quaternions. This is the same as the "Plus()" operation in + // local_parameterization.h, but operating over the entire state vector for a + // problem. + virtual bool Plus(const double* state, + const double* delta, + double* state_plus_delta) const = 0; + + // The number of parameters in the optimization problem. + virtual int NumParameters() const = 0; + + // This is the effective number of parameters that the optimizer may adjust. + // This applies when there are parameterizations on some of the parameters. + virtual int NumEffectiveParameters() const = 0; + + // The number of residuals in the optimization problem. + virtual int NumResiduals() const = 0; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_EVALUATOR_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/file.cc b/extern/libmv/third_party/ceres/internal/ceres/file.cc new file mode 100644 index 00000000000..5fc9d220861 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/file.cc @@ -0,0 +1,93 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// Really simple file IO. + +#include +#include + +namespace ceres { +namespace internal { + +using std::string; + +void WriteStringToFileOrDie(const string &data, const string &filename) { + FILE* file_descriptor = fopen(filename.c_str(), "wb"); + if (!file_descriptor) { + LOG(FATAL) << "Couldn't write to file: " << filename; + } + fwrite(data.c_str(), 1, data.size(), file_descriptor); + fclose(file_descriptor); +} + +void ReadFileToStringOrDie(const string &filename, string *data) { + FILE* file_descriptor = file_descriptor = fopen(filename.c_str(), "r"); + + if (!file_descriptor) { + LOG(FATAL) << "Couldn't read file: " << filename; + } + + // Resize the input buffer appropriately. + fseek(file_descriptor, 0L, SEEK_END); + int num_bytes = ftell(file_descriptor); + data->resize(num_bytes); + + // Read the data. + fseek(file_descriptor, 0L, SEEK_SET); + int num_read = fread(&((*data)[0]), + sizeof((*data)[0]), + num_bytes, + file_descriptor); + if (num_read != num_bytes) { + LOG(FATAL) << "Couldn't read all of " << filename + << "expected bytes: " << num_bytes * sizeof((*data)[0]) + << "actual bytes: " << num_read; + } + fclose(file_descriptor); +} + +string JoinPath(const string& dirname, const string& basename) { +#ifdef _WIN32 + static const char separator = '\\'; +#else + static const char separator = '/'; +#endif // _WIN32 + + if ((!basename.empty() && basename[0] == separator) || dirname.empty()) { + return basename; + } else if (dirname[dirname.size() - 1] == separator) { + return dirname + basename; + } else { + return dirname + string(&separator, 1) + basename; + } +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/file.h b/extern/libmv/third_party/ceres/internal/ceres/file.h new file mode 100644 index 00000000000..4741d650646 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/file.h @@ -0,0 +1,52 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// Simple file IO support. This is a portability shim. + +#ifndef CERES_INTERNAL_FILE_H_ +#define CERES_INTERNAL_FILE_H_ + +#include +#include "ceres/internal/port.h" + +namespace ceres { +namespace internal { + +void WriteStringToFileOrDie(const string &data, const string &filename); +void ReadFileToStringOrDie(const string &filename, string *data); + +// Join two path components, adding a slash if necessary. If basename is an +// absolute path then JoinPath ignores dirname and simply returns basename. +string JoinPath(const string& dirname, const string& basename); + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_FILE_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_2.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_2.cc new file mode 100644 index 00000000000..5529386e485 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_2.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<2, 2, 2>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_3.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_3.cc new file mode 100644 index 00000000000..fd7af95192e --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_3.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<2, 2, 3>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_4.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_4.cc new file mode 100644 index 00000000000..109483e9fc0 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_4.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<2, 2, 4>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_d.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_d.cc new file mode 100644 index 00000000000..b93e82fe2fa --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_d.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<2, 2, Dynamic>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_3.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_3.cc new file mode 100644 index 00000000000..86352c07304 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_3.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<2, 3, 3>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_4.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_4.cc new file mode 100644 index 00000000000..200df7f5931 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_4.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<2, 3, 4>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_9.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_9.cc new file mode 100644 index 00000000000..1fda3434bef --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_9.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<2, 3, 9>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_d.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_d.cc new file mode 100644 index 00000000000..385cd2d70c9 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_d.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<2, 3, Dynamic>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_3.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_3.cc new file mode 100644 index 00000000000..7b15d6366ac --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_3.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<2, 4, 3>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_4.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_4.cc new file mode 100644 index 00000000000..29a610d743e --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_4.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<2, 4, 4>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_d.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_d.cc new file mode 100644 index 00000000000..a3bc4dc6f83 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_d.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<2, 4, Dynamic>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_2.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_2.cc new file mode 100644 index 00000000000..f71a4f62944 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_2.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<4, 4, 2>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_3.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_3.cc new file mode 100644 index 00000000000..52259fb1a67 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_3.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<4, 4, 3>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_4.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_4.cc new file mode 100644 index 00000000000..775424e6c8f --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_4.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<4, 4, 4>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_d.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_d.cc new file mode 100644 index 00000000000..97cde594059 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_d.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator<4, 4, Dynamic>; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_d_d_d.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_d_d_d.cc new file mode 100644 index 00000000000..4cba32e26c8 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_d_d_d.cc @@ -0,0 +1,53 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Template specialization of SchurEliminator. +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_eliminator_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/schur_eliminator_impl.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +template class SchurEliminator; + +} // namespace internal +} // namespace ceres + diff --git a/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc b/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc new file mode 100644 index 00000000000..abba40824ef --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc @@ -0,0 +1,308 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include "ceres/gradient_checking_cost_function.h" + +#include +#include +#include +#include +#include + +#include +#include "ceres/parameter_block.h" +#include "ceres/problem_impl.h" +#include "ceres/program.h" +#include "ceres/residual_block.h" +#include "ceres/runtime_numeric_diff_cost_function.h" +#include "ceres/stringprintf.h" +#include "ceres/cost_function.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/problem.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { +namespace { + +// True if x and y have an absolute relative difference less than +// relative_precision and false otherwise. Stores the relative and absolute +// difference in relative/absolute_error if non-NULL. +bool IsClose(double x, double y, double relative_precision, + double *relative_error, + double *absolute_error) { + double local_absolute_error; + double local_relative_error; + if (!absolute_error) { + absolute_error = &local_absolute_error; + } + if (!relative_error) { + relative_error = &local_relative_error; + } + *absolute_error = fabs(x - y); + *relative_error = *absolute_error / max(fabs(x), fabs(y)); + if (x == 0 || y == 0) { + // If x or y is exactly zero, then relative difference doesn't have any + // meaning. Take the absolute difference instead. + *relative_error = *absolute_error; + } + return fabs(*relative_error) < fabs(relative_precision); +} + +class GradientCheckingCostFunction : public CostFunction { + public: + GradientCheckingCostFunction(const CostFunction* function, + double relative_step_size, + double relative_precision, + const string& extra_info) + : function_(function), + finite_diff_cost_function_( + CreateRuntimeNumericDiffCostFunction(function, + CENTRAL, + relative_step_size)), + relative_precision_(relative_precision), + extra_info_(extra_info) { + *mutable_parameter_block_sizes() = function->parameter_block_sizes(); + set_num_residuals(function->num_residuals()); + } + + virtual ~GradientCheckingCostFunction() { } + + virtual bool Evaluate(double const* const* parameters, + double* residuals, + double** jacobians) const { + if (!jacobians) { + // Nothing to check in this case; just forward. + return function_->Evaluate(parameters, residuals, NULL); + } + + int num_residuals = function_->num_residuals(); + + // Make space for the jacobians of the two methods. + const vector& block_sizes = function_->parameter_block_sizes(); + vector term_jacobians(block_sizes.size()); + vector finite_difference_jacobians(block_sizes.size()); + vector term_jacobian_pointers(block_sizes.size()); + vector finite_difference_jacobian_pointers(block_sizes.size()); + for (int i = 0; i < block_sizes.size(); i++) { + term_jacobians[i].resize(num_residuals, block_sizes[i]); + term_jacobian_pointers[i] = term_jacobians[i].data(); + finite_difference_jacobians[i].resize(num_residuals, block_sizes[i]); + finite_difference_jacobian_pointers[i] = + finite_difference_jacobians[i].data(); + } + + // Evaluate the derivative using the user supplied code. + if (!function_->Evaluate(parameters, + residuals, + &term_jacobian_pointers[0])) { + LOG(WARNING) << "Function evaluation failed."; + return false; + } + + // Evaluate the derivative using numeric derivatives. + finite_diff_cost_function_->Evaluate( + parameters, + residuals, + &finite_difference_jacobian_pointers[0]); + + // See if any elements have relative error larger than the threshold. + int num_bad_jacobian_components = 0; + double worst_relative_error = 0; + + // Accumulate the error message for all the jacobians, since it won't get + // output if there are no bad jacobian components. + string m; + for (int k = 0; k < block_sizes.size(); k++) { + // Copy the original jacobian blocks into the jacobians array. + if (jacobians[k] != NULL) { + MatrixRef(jacobians[k], + term_jacobians[k].rows(), + term_jacobians[k].cols()) = term_jacobians[k]; + } + + StringAppendF(&m, + "========== " + "Jacobian for " "block %d: (%ld by %ld)) " + "==========\n", + k, + term_jacobians[k].rows(), + term_jacobians[k].cols()); + // The funny spacing creates appropriately aligned column headers. + m += " block row col user dx/dy num diff dx/dy " + "abs error relative error parameter residual\n"; + + for (int i = 0; i < term_jacobians[k].rows(); i++) { + for (int j = 0; j < term_jacobians[k].cols(); j++) { + double term_jacobian = term_jacobians[k](i, j); + double finite_jacobian = finite_difference_jacobians[k](i, j); + double relative_error, absolute_error; + bool bad_jacobian_entry = + !IsClose(term_jacobian, + finite_jacobian, + relative_precision_, + &relative_error, + &absolute_error); + worst_relative_error = std::max(worst_relative_error, + relative_error); + + StringAppendF(&m, "%6d %4d %4d %17g %17g %17g %17g %17g %17g", + k, i, j, + term_jacobian, finite_jacobian, + absolute_error, relative_error, + parameters[k][j], + residuals[i]); + + if (bad_jacobian_entry) { + num_bad_jacobian_components++; + StringAppendF( + &m, " ------ (%d,%d,%d) Relative error worse than %g", + k, i, j, relative_precision_); + } + m += "\n"; + } + } + } + + // Since there were some bad errors, dump comprehensive debug info. + if (num_bad_jacobian_components) { + string header = StringPrintf("Detected %d bad jacobian component(s). " + "Worst relative error was %g.\n", + num_bad_jacobian_components, + worst_relative_error); + if (!extra_info_.empty()) { + header += "Extra info for this residual: " + extra_info_ + "\n"; + } + LOG(WARNING) << "\n" << header << m; + } + return true; + } + + private: + const CostFunction* function_; + internal::scoped_ptr finite_diff_cost_function_; + double relative_precision_; + string extra_info_; +}; + +} // namespace + +CostFunction *CreateGradientCheckingCostFunction( + const CostFunction *cost_function, + double relative_step_size, + double relative_precision, + const string& extra_info) { + return new GradientCheckingCostFunction(cost_function, + relative_step_size, + relative_precision, + extra_info); +} + +ProblemImpl* CreateGradientCheckingProblemImpl(ProblemImpl* problem_impl, + double relative_step_size, + double relative_precision) { + // We create new CostFunctions by wrapping the original CostFunction + // in a gradient checking CostFunction. So its okay for the + // ProblemImpl to take ownership of it and destroy it. The + // LossFunctions and LocalParameterizations are reused and since + // they are owned by problem_impl, gradient_checking_problem_impl + // should not take ownership of it. + Problem::Options gradient_checking_problem_options; + gradient_checking_problem_options.cost_function_ownership = TAKE_OWNERSHIP; + gradient_checking_problem_options.loss_function_ownership = + DO_NOT_TAKE_OWNERSHIP; + gradient_checking_problem_options.local_parameterization_ownership = + DO_NOT_TAKE_OWNERSHIP; + + ProblemImpl* gradient_checking_problem_impl = new ProblemImpl( + gradient_checking_problem_options); + + Program* program = problem_impl->mutable_program(); + + // For every ParameterBlock in problem_impl, create a new parameter + // block with the same local parameterization and constancy. + const vector& parameter_blocks = program->parameter_blocks(); + for (int i = 0; i < parameter_blocks.size(); ++i) { + ParameterBlock* parameter_block = parameter_blocks[i]; + gradient_checking_problem_impl->AddParameterBlock( + parameter_block->mutable_user_state(), + parameter_block->Size(), + parameter_block->mutable_local_parameterization()); + + if (parameter_block->IsConstant()) { + gradient_checking_problem_impl->SetParameterBlockConstant( + parameter_block->mutable_user_state()); + } + } + + // For every ResidualBlock in problem_impl, create a new + // ResidualBlock by wrapping its CostFunction inside a + // GradientCheckingCostFunction. + const vector& residual_blocks = program->residual_blocks(); + for (int i = 0; i < residual_blocks.size(); ++i) { + ResidualBlock* residual_block = residual_blocks[i]; + + // Build a human readable string which identifies the + // ResidualBlock. This is used by the GradientCheckingCostFunction + // when logging debugging information. + string extra_info = StringPrintf( + "Residual block id %d; depends on parameters [", i); + vector parameter_blocks; + for (int j = 0; j < residual_block->NumParameterBlocks(); ++j) { + ParameterBlock* parameter_block = residual_block->parameter_blocks()[j]; + parameter_blocks.push_back(parameter_block->mutable_user_state()); + StringAppendF(&extra_info, "%p", parameter_block->mutable_user_state()); + extra_info += (j < residual_block->NumParameterBlocks() - 1) ? ", " : "]"; + } + + // Wrap the original CostFunction in a GradientCheckingCostFunction. + CostFunction* gradient_checking_cost_function = + CreateGradientCheckingCostFunction(residual_block->cost_function(), + relative_step_size, + relative_precision, + extra_info); + + // The const_cast is necessary because + // ProblemImpl::AddResidualBlock can potentially take ownership of + // the LossFunction, but in this case we are guaranteed that this + // will not be the case, so this const_cast is harmless. + gradient_checking_problem_impl->AddResidualBlock( + gradient_checking_cost_function, + const_cast(residual_block->loss_function()), + parameter_blocks); + } + + return gradient_checking_problem_impl; +} + + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.h b/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.h new file mode 100644 index 00000000000..d49c8e6c244 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.h @@ -0,0 +1,85 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#ifndef CERES_INTERNAL_GRADIENT_CHECKING_COST_FUNCTION_H_ +#define CERES_INTERNAL_GRADIENT_CHECKING_COST_FUNCTION_H_ + +#include + +#include "ceres/cost_function.h" + +namespace ceres { +namespace internal { + +class ProblemImpl; + +// Creates a CostFunction that checks the jacobians that cost_function computes +// with finite differences. Bad results are logged; required precision is +// controlled by relative_precision and the numeric differentiation step size is +// controlled with relative_step_size. See solver.h for a better explanation of +// relative_step_size. Caller owns result. +// +// The condition enforced is that +// +// (J_actual(i, j) - J_numeric(i, j)) +// ------------------------------------ < relative_precision +// max(J_actual(i, j), J_numeric(i, j)) +// +// where J_actual(i, j) is the jacobian as computed by the supplied cost +// function (by the user) and J_numeric is the jacobian as computed by finite +// differences. +// +// Note: This is quite inefficient and is intended only for debugging. +CostFunction* CreateGradientCheckingCostFunction( + const CostFunction* cost_function, + double relative_step_size, + double relative_precision, + const string& extra_info); + +// Create a new ProblemImpl object from the input problem_impl, where +// each CostFunctions in problem_impl are wrapped inside a +// GradientCheckingCostFunctions. This gives us a ProblemImpl object +// which checks its derivatives against estimates from numeric +// differentiation everytime a ResidualBlock is evaluated. +// +// relative_step_size and relative_precision are parameters to control +// the numeric differentiation and the relative tolerance between the +// jacobian computed by the CostFunctions in problem_impl and +// jacobians obtained by numerically differentiating them. For more +// details see the documentation for +// CreateGradientCheckingCostFunction above. +ProblemImpl* CreateGradientCheckingProblemImpl(ProblemImpl* problem_impl, + double relative_step_size, + double relative_precision); + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_GRADIENT_CHECKING_COST_FUNCTION_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/graph.h b/extern/libmv/third_party/ceres/internal/ceres/graph.h new file mode 100644 index 00000000000..fd7a224f0aa --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/graph.h @@ -0,0 +1,138 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_GRAPH_H_ +#define CERES_INTERNAL_GRAPH_H_ + +#include +#include +#include "ceres/integral_types.h" +#include "ceres/map_util.h" +#include "ceres/collections_port.h" +#include "ceres/internal/macros.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +// A weighted undirected graph templated over the vertex ids. Vertex +// should be hashable and comparable. +template +class Graph { + public: + Graph() {} + + // Add a weighted vertex. If the vertex already exists in the graph, + // its weight is set to the new weight. + void AddVertex(const Vertex& vertex, double weight) { + if (vertices_.find(vertex) == vertices_.end()) { + vertices_.insert(vertex); + edges_[vertex] = HashSet(); + } + vertex_weights_[vertex] = weight; + } + + // Uses weight = 1.0. If vertex already exists, its weight is set to + // 1.0. + void AddVertex(const Vertex& vertex) { + AddVertex(vertex, 1.0); + } + + // Add a weighted edge between the vertex1 and vertex2. Calling + // AddEdge on a pair of vertices which do not exist in the graph yet + // will result in undefined behavior. + // + // It is legal to call this method repeatedly for the same set of + // vertices. + void AddEdge(const Vertex& vertex1, const Vertex& vertex2, double weight) { + DCHECK(vertices_.find(vertex1) != vertices_.end()); + DCHECK(vertices_.find(vertex2) != vertices_.end()); + + if (edges_[vertex1].insert(vertex2).second) { + edges_[vertex2].insert(vertex1); + } + + if (vertex1 < vertex2) { + edge_weights_[make_pair(vertex1, vertex2)] = weight; + } else { + edge_weights_[make_pair(vertex2, vertex1)] = weight; + } + } + + // Uses weight = 1.0. + void AddEdge(const Vertex& vertex1, const Vertex& vertex2) { + AddEdge(vertex1, vertex2, 1.0); + } + + // Calling VertexWeight on a vertex not in the graph will result in + // undefined behavior. + double VertexWeight(const Vertex& vertex) const { + return FindOrDie(vertex_weights_, vertex); + } + + // Calling EdgeWeight on a pair of vertices where either one of the + // vertices is not present in the graph will result in undefined + // behaviour. If there is no edge connecting vertex1 and vertex2, + // the edge weight is zero. + double EdgeWeight(const Vertex& vertex1, const Vertex& vertex2) const { + if (vertex1 < vertex2) { + return FindWithDefault(edge_weights_, make_pair(vertex1, vertex2), 0.0); + } else { + return FindWithDefault(edge_weights_, make_pair(vertex2, vertex1), 0.0); + } + } + + // Calling Neighbors on a vertex not in the graph will result in + // undefined behaviour. + const HashSet& Neighbors(const Vertex& vertex) const { + return FindOrDie(edges_, vertex); + } + + const HashSet& vertices() const { + return vertices_; + } + + static double InvalidWeight() { + return std::numeric_limits::quiet_NaN(); + }; + + private: + HashSet vertices_; + HashMap vertex_weights_; + HashMap > edges_; + HashMap, double> edge_weights_; + + DISALLOW_COPY_AND_ASSIGN(Graph); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_GRAPH_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h b/extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h new file mode 100644 index 00000000000..3b42d936336 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h @@ -0,0 +1,270 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Various algorithms that operate on undirected graphs. + +#ifndef CERES_INTERNAL_GRAPH_ALGORITHMS_H_ +#define CERES_INTERNAL_GRAPH_ALGORITHMS_H_ + +#include +#include +#include "ceres/collections_port.h" +#include "ceres/graph.h" + +namespace ceres { +namespace internal { + +// Compare two vertices of a graph by their degrees. +template +class VertexDegreeLessThan { + public: + explicit VertexDegreeLessThan(const Graph& graph) + : graph_(graph) {} + + bool operator()(const Vertex& lhs, const Vertex& rhs) const { + if (graph_.Neighbors(lhs).size() == graph_.Neighbors(rhs).size()) { + return lhs < rhs; + } + return graph_.Neighbors(lhs).size() < graph_.Neighbors(rhs).size(); + } + + private: + const Graph& graph_; +}; + +// Order the vertices of a graph using its (approximately) largest +// independent set, where an independent set of a graph is a set of +// vertices that have no edges connecting them. The maximum +// independent set problem is NP-Hard, but there are effective +// approximation algorithms available. The implementation here uses a +// breadth first search that explores the vertices in order of +// increasing degree. The same idea is used by Saad & Li in "MIQR: A +// multilevel incomplete QR preconditioner for large sparse +// least-squares problems", SIMAX, 2007. +// +// Given a undirected graph G(V,E), the algorithm is a greedy BFS +// search where the vertices are explored in increasing order of their +// degree. The output vector ordering contains elements of S in +// increasing order of their degree, followed by elements of V - S in +// increasing order of degree. The return value of the function is the +// cardinality of S. +template +int IndependentSetOrdering(const Graph& graph, + vector* ordering) { + const HashSet& vertices = graph.vertices(); + const int num_vertices = vertices.size(); + + CHECK_NOTNULL(ordering); + ordering->clear(); + ordering->reserve(num_vertices); + + // Colors for labeling the graph during the BFS. + const char kWhite = 0; + const char kGrey = 1; + const char kBlack = 2; + + // Mark all vertices white. + HashMap vertex_color; + vector vertex_queue; + for (typename HashSet::const_iterator it = vertices.begin(); + it != vertices.end(); + ++it) { + vertex_color[*it] = kWhite; + vertex_queue.push_back(*it); + } + + + sort(vertex_queue.begin(), vertex_queue.end(), + VertexDegreeLessThan(graph)); + + // Iterate over vertex_queue. Pick the first white vertex, add it + // to the independent set. Mark it black and its neighbors grey. + for (int i = 0; i < vertex_queue.size(); ++i) { + const Vertex& vertex = vertex_queue[i]; + if (vertex_color[vertex] != kWhite) { + continue; + } + + ordering->push_back(vertex); + vertex_color[vertex] = kBlack; + const HashSet& neighbors = graph.Neighbors(vertex); + for (typename HashSet::const_iterator it = neighbors.begin(); + it != neighbors.end(); + ++it) { + vertex_color[*it] = kGrey; + } + } + + int independent_set_size = ordering->size(); + + // Iterate over the vertices and add all the grey vertices to the + // ordering. At this stage there should only be black or grey + // vertices in the graph. + for (typename vector::const_iterator it = vertex_queue.begin(); + it != vertex_queue.end(); + ++it) { + const Vertex vertex = *it; + DCHECK(vertex_color[vertex] != kWhite); + if (vertex_color[vertex] != kBlack) { + ordering->push_back(vertex); + } + } + + CHECK_EQ(ordering->size(), num_vertices); + return independent_set_size; +} + +// Find the connected component for a vertex implemented using the +// find and update operation for disjoint-set. Recursively traverse +// the disjoint set structure till you reach a vertex whose connected +// component has the same id as the vertex itself. Along the way +// update the connected components of all the vertices. This updating +// is what gives this data structure its efficiency. +template +Vertex FindConnectedComponent(const Vertex& vertex, + HashMap* union_find) { + typename HashMap::iterator it = union_find->find(vertex); + DCHECK(it != union_find->end()); + if (it->second != vertex) { + it->second = FindConnectedComponent(it->second, union_find); + } + + return it->second; +} + +// Compute a degree two constrained Maximum Spanning Tree/forest of +// the input graph. Caller owns the result. +// +// Finding degree 2 spanning tree of a graph is not always +// possible. For example a star graph, i.e. a graph with n-nodes +// where one node is connected to the other n-1 nodes does not have +// a any spanning trees of degree less than n-1.Even if such a tree +// exists, finding such a tree is NP-Hard. + +// We get around both of these problems by using a greedy, degree +// constrained variant of Kruskal's algorithm. We start with a graph +// G_T with the same vertex set V as the input graph G(V,E) but an +// empty edge set. We then iterate over the edges of G in decreasing +// order of weight, adding them to G_T if doing so does not create a +// cycle in G_T} and the degree of all the vertices in G_T remains +// bounded by two. This O(|E|) algorithm results in a degree-2 +// spanning forest, or a collection of linear paths that span the +// graph G. +template +Graph* +Degree2MaximumSpanningForest(const Graph& graph) { + // Array of edges sorted in decreasing order of their weights. + vector > > weighted_edges; + Graph* forest = new Graph(); + + // Disjoint-set to keep track of the connected components in the + // maximum spanning tree. + HashMap disjoint_set; + + // Sort of the edges in the graph in decreasing order of their + // weight. Also add the vertices of the graph to the Maximum + // Spanning Tree graph and set each vertex to be its own connected + // component in the disjoint_set structure. + const HashSet& vertices = graph.vertices(); + for (typename HashSet::const_iterator it = vertices.begin(); + it != vertices.end(); + ++it) { + const Vertex vertex1 = *it; + forest->AddVertex(vertex1, graph.VertexWeight(vertex1)); + disjoint_set[vertex1] = vertex1; + + const HashSet& neighbors = graph.Neighbors(vertex1); + for (typename HashSet::const_iterator it2 = neighbors.begin(); + it2 != neighbors.end(); + ++it2) { + const Vertex vertex2 = *it2; + if (vertex1 >= vertex2) { + continue; + } + const double weight = graph.EdgeWeight(vertex1, vertex2); + weighted_edges.push_back(make_pair(weight, make_pair(vertex1, vertex2))); + } + } + + // The elements of this vector, are pairs. Sorting it using the reverse iterators gives us the edges + // in decreasing order of edges. + sort(weighted_edges.rbegin(), weighted_edges.rend()); + + // Greedily add edges to the spanning tree/forest as long as they do + // not violate the degree/cycle constraint. + for (int i =0; i < weighted_edges.size(); ++i) { + const pair& edge = weighted_edges[i].second; + const Vertex vertex1 = edge.first; + const Vertex vertex2 = edge.second; + + // Check if either of the vertices are of degree 2 already, in + // which case adding this edge will violate the degree 2 + // constraint. + if ((forest->Neighbors(vertex1).size() == 2) || + (forest->Neighbors(vertex2).size() == 2)) { + continue; + } + + // Find the id of the connected component to which the two + // vertices belong to. If the id is the same, it means that the + // two of them are already connected to each other via some other + // vertex, and adding this edge will create a cycle. + Vertex root1 = FindConnectedComponent(vertex1, &disjoint_set); + Vertex root2 = FindConnectedComponent(vertex2, &disjoint_set); + + if (root1 == root2) { + continue; + } + + // This edge can be added, add an edge in either direction with + // the same weight as the original graph. + const double edge_weight = graph.EdgeWeight(vertex1, vertex2); + forest->AddEdge(vertex1, vertex2, edge_weight); + forest->AddEdge(vertex2, vertex1, edge_weight); + + // Connected the two connected components by updating the + // disjoint_set structure. Always connect the connected component + // with the greater index with the connected component with the + // smaller index. This should ensure shallower trees, for quicker + // lookup. + if (root2 < root1) { + std::swap(root1, root2); + }; + + disjoint_set[root2] = root1; + } + return forest; +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_GRAPH_ALGORITHMS_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/implicit_schur_complement.cc b/extern/libmv/third_party/ceres/internal/ceres/implicit_schur_complement.cc new file mode 100644 index 00000000000..bd908846362 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/implicit_schur_complement.cc @@ -0,0 +1,237 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/implicit_schur_complement.h" + +#include +#include "Eigen/Dense" +#include "ceres/block_sparse_matrix.h" +#include "ceres/block_structure.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +ImplicitSchurComplement::ImplicitSchurComplement(int num_eliminate_blocks, + bool constant_sparsity, + bool preconditioner) + : num_eliminate_blocks_(num_eliminate_blocks), + constant_sparsity_(constant_sparsity), + preconditioner_(preconditioner), + A_(NULL), + D_(NULL), + b_(NULL), + block_diagonal_EtE_inverse_(NULL), + block_diagonal_FtF_inverse_(NULL) { +} + +ImplicitSchurComplement::~ImplicitSchurComplement() { +} + +void ImplicitSchurComplement::Init(const BlockSparseMatrixBase& A, + const double* D, + const double* b) { + // Since initialization is reasonably heavy, perhaps we can save on + // constructing a new object everytime. + if ((A_ == NULL) || !constant_sparsity_) { + A_.reset(new PartitionedMatrixView(A, num_eliminate_blocks_)); + } + + D_ = D; + b_ = b; + + // Initialize temporary storage and compute the block diagonals of + // E'E and F'E. + if ((!constant_sparsity_) || (block_diagonal_EtE_inverse_ == NULL)) { + block_diagonal_EtE_inverse_.reset(A_->CreateBlockDiagonalEtE()); + if (preconditioner_) { + block_diagonal_FtF_inverse_.reset(A_->CreateBlockDiagonalFtF()); + } + rhs_.resize(A_->num_cols_f()); + rhs_.setZero(); + tmp_rows_.resize(A_->num_rows()); + tmp_e_cols_.resize(A_->num_cols_e()); + tmp_e_cols_2_.resize(A_->num_cols_e()); + tmp_f_cols_.resize(A_->num_cols_f()); + } else { + A_->UpdateBlockDiagonalEtE(block_diagonal_EtE_inverse_.get()); + if (preconditioner_) { + A_->UpdateBlockDiagonalFtF(block_diagonal_FtF_inverse_.get()); + } + } + + // The block diagonals of the augmented linear system contain + // contributions from the diagonal D if it is non-null. Add that to + // the block diagonals and invert them. + if (D_ != NULL) { + AddDiagonalAndInvert(D_, block_diagonal_EtE_inverse_.get()); + if (preconditioner_) { + AddDiagonalAndInvert(D_ + A_->num_cols_e(), + block_diagonal_FtF_inverse_.get()); + } + } else { + AddDiagonalAndInvert(NULL, block_diagonal_EtE_inverse_.get()); + if (preconditioner_) { + AddDiagonalAndInvert(NULL, block_diagonal_FtF_inverse_.get()); + } + } + + // Compute the RHS of the Schur complement system. + UpdateRhs(); +} + +// Evaluate the product +// +// Sx = [F'F - F'E (E'E)^-1 E'F]x +// +// By breaking it down into individual matrix vector products +// involving the matrices E and F. This is implemented using a +// PartitionedMatrixView of the input matrix A. +void ImplicitSchurComplement::RightMultiply(const double* x, double* y) const { + // y1 = F x + tmp_rows_.setZero(); + A_->RightMultiplyF(x, tmp_rows_.data()); + + // y2 = E' y1 + tmp_e_cols_.setZero(); + A_->LeftMultiplyE(tmp_rows_.data(), tmp_e_cols_.data()); + + // y3 = -(E'E)^-1 y2 + tmp_e_cols_2_.setZero(); + block_diagonal_EtE_inverse_->RightMultiply(tmp_e_cols_.data(), + tmp_e_cols_2_.data()); + tmp_e_cols_2_ *= -1.0; + + // y1 = y1 + E y3 + A_->RightMultiplyE(tmp_e_cols_2_.data(), tmp_rows_.data()); + + // y5 = D * x + if (D_ != NULL) { + ConstVectorRef Dref(D_ + A_->num_cols_e(), num_cols()); + VectorRef(y, num_cols()) = + (Dref.array().square() * + ConstVectorRef(x, num_cols()).array()).matrix(); + } else { + VectorRef(y, num_cols()).setZero(); + } + + // y = y5 + F' y1 + A_->LeftMultiplyF(tmp_rows_.data(), y); +} + +// Given a block diagonal matrix and an optional array of diagonal +// entries D, add them to the diagonal of the matrix and compute the +// inverse of each diagonal block. +void ImplicitSchurComplement::AddDiagonalAndInvert( + const double* D, + BlockSparseMatrix* block_diagonal) { + const CompressedRowBlockStructure* block_diagonal_structure = + block_diagonal->block_structure(); + for (int r = 0; r < block_diagonal_structure->rows.size(); ++r) { + const int row_block_pos = block_diagonal_structure->rows[r].block.position; + const int row_block_size = block_diagonal_structure->rows[r].block.size; + const Cell& cell = block_diagonal_structure->rows[r].cells[0]; + MatrixRef m(block_diagonal->mutable_values() + cell.position, + row_block_size, row_block_size); + + if (D != NULL) { + ConstVectorRef d(D + row_block_pos, row_block_size); + m += d.array().square().matrix().asDiagonal(); + } + + m = m + .selfadjointView() + .ldlt() + .solve(Matrix::Identity(row_block_size, row_block_size)); + } +} + +// Similar to RightMultiply, use the block structure of the matrix A +// to compute y = (E'E)^-1 (E'b - E'F x). +void ImplicitSchurComplement::BackSubstitute(const double* x, double* y) { + const int num_cols_e = A_->num_cols_e(); + const int num_cols_f = A_->num_cols_f(); + const int num_cols = A_->num_cols(); + const int num_rows = A_->num_rows(); + + // y1 = F x + tmp_rows_.setZero(); + A_->RightMultiplyF(x, tmp_rows_.data()); + + // y2 = b - y1 + tmp_rows_ = ConstVectorRef(b_, num_rows) - tmp_rows_; + + // y3 = E' y2 + tmp_e_cols_.setZero(); + A_->LeftMultiplyE(tmp_rows_.data(), tmp_e_cols_.data()); + + // y = (E'E)^-1 y3 + VectorRef(y, num_cols).setZero(); + block_diagonal_EtE_inverse_->RightMultiply(tmp_e_cols_.data(), y); + + // The full solution vector y has two blocks. The first block of + // variables corresponds to the eliminated variables, which we just + // computed via back substitution. The second block of variables + // corresponds to the Schur complement system, so we just copy those + // values from the solution to the Schur complement. + VectorRef(y + num_cols_e, num_cols_f) = ConstVectorRef(x, num_cols_f); +} + +// Compute the RHS of the Schur complement system. +// +// rhs = F'b - F'E (E'E)^-1 E'b +// +// Like BackSubstitute, we use the block structure of A to implement +// this using a series of matrix vector products. +void ImplicitSchurComplement::UpdateRhs() { + // y1 = E'b + tmp_e_cols_.setZero(); + A_->LeftMultiplyE(b_, tmp_e_cols_.data()); + + // y2 = (E'E)^-1 y1 + Vector y2 = Vector::Zero(A_->num_cols_e()); + block_diagonal_EtE_inverse_->RightMultiply(tmp_e_cols_.data(), y2.data()); + + // y3 = E y2 + tmp_rows_.setZero(); + A_->RightMultiplyE(y2.data(), tmp_rows_.data()); + + // y3 = b - y3 + tmp_rows_ = ConstVectorRef(b_, A_->num_rows()) - tmp_rows_; + + // rhs = F' y3 + rhs_.setZero(); + A_->LeftMultiplyF(tmp_rows_.data(), rhs_.data()); +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/implicit_schur_complement.h b/extern/libmv/third_party/ceres/internal/ceres/implicit_schur_complement.h new file mode 100644 index 00000000000..37a319f9c57 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/implicit_schur_complement.h @@ -0,0 +1,176 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// An iterative solver for solving the Schur complement/reduced camera +// linear system that arise in SfM problems. + +#ifndef CERES_INTERNAL_IMPLICIT_SCHUR_COMPLEMENT_H_ +#define CERES_INTERNAL_IMPLICIT_SCHUR_COMPLEMENT_H_ + +#include "ceres/linear_operator.h" +#include "ceres/partitioned_matrix_view.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +class BlockSparseMatrix; +class BlockSparseMatrixBase; + +// This class implements various linear algebraic operations related +// to the Schur complement without explicitly forming it. +// +// +// Given a reactangular linear system Ax = b, where +// +// A = [E F] +// +// The normal equations are given by +// +// A'Ax = A'b +// +// |E'E E'F||y| = |E'b| +// |F'E F'F||z| |F'b| +// +// and the Schur complement system is given by +// +// [F'F - F'E (E'E)^-1 E'F] z = F'b - F'E (E'E)^-1 E'b +// +// Now if we wish to solve Ax = b in the least squares sense, one way +// is to form this Schur complement system and solve it using +// Preconditioned Conjugate Gradients. +// +// The key operation in a conjugate gradient solver is the evaluation of the +// matrix vector product with the Schur complement +// +// S = F'F - F'E (E'E)^-1 E'F +// +// It is straightforward to see that matrix vector products with S can +// be evaluated without storing S in memory. Instead, given (E'E)^-1 +// (which for our purposes is an easily inverted block diagonal +// matrix), it can be done in terms of matrix vector products with E, +// F and (E'E)^-1. This class implements this functionality and other +// auxilliary bits needed to implement a CG solver on the Schur +// complement using the PartitionedMatrixView object. +// +// THREAD SAFETY: This class is nqot thread safe. In particular, the +// RightMultiply (and the LeftMultiply) methods are not thread safe as +// they depend on mutable arrays used for the temporaries needed to +// compute the product y += Sx; +class ImplicitSchurComplement : public LinearOperator { + public: + // num_eliminate_blocks is the number of E blocks in the matrix + // A. + // + // constant_sparsity indicates if across calls to Init, the sparsity + // structure of the matrix A remains constant or not. This makes for + // significant savings across multiple matrices A, e.g. when used in + // conjunction with an optimization algorithm. + // + // preconditioner indicates whether the inverse of the matrix F'F + // should be computed or not as a preconditioner for the Schur + // Complement. + // + // TODO(sameeragarwal): Get rid of the two bools below and replace + // them with enums. + ImplicitSchurComplement(int num_eliminate_blocks, + bool constant_sparsity, + bool preconditioner); + virtual ~ImplicitSchurComplement(); + + // Initialize the Schur complement for a linear least squares + // problem of the form + // + // |A | x = |b| + // |diag(D)| |0| + // + // If D is null, then it is treated as a zero dimensional matrix. It + // is important that the matrix A have a BlockStructure object + // associated with it and has a block structure that is compatible + // with the SchurComplement solver. + void Init(const BlockSparseMatrixBase& A, const double* D, const double* b); + + // y += Sx, where S is the Schur complement. + virtual void RightMultiply(const double* x, double* y) const; + + // The Schur complement is a symmetric positive definite matrix, + // thus the left and right multiply operators are the same. + virtual void LeftMultiply(const double* x, double* y) const { + RightMultiply(x, y); + } + + // y = (E'E)^-1 (E'b - E'F x). Given an estimate of the solution to + // the Schur complement system, this method computes the value of + // the e_block variables that were eliminated to form the Schur + // complement. + void BackSubstitute(const double* x, double* y); + + virtual int num_rows() const { return A_->num_cols_f(); } + virtual int num_cols() const { return A_->num_cols_f(); } + const Vector& rhs() const { return rhs_; } + + const BlockSparseMatrix* block_diagonal_EtE_inverse() const { + return block_diagonal_EtE_inverse_.get(); + } + + const BlockSparseMatrix* block_diagonal_FtF_inverse() const { + return block_diagonal_FtF_inverse_.get(); + } + + private: + void AddDiagonalAndInvert(const double* D, BlockSparseMatrix* matrix); + void UpdateRhs(); + + int num_eliminate_blocks_; + bool constant_sparsity_; + bool preconditioner_; + + scoped_ptr A_; + const double* D_; + const double* b_; + + scoped_ptr block_diagonal_EtE_inverse_; + scoped_ptr block_diagonal_FtF_inverse_; + + Vector rhs_; + + // Temporary storage vectors used to implement RightMultiply. + mutable Vector tmp_rows_; + mutable Vector tmp_e_cols_; + mutable Vector tmp_e_cols_2_; + mutable Vector tmp_f_cols_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_IMPLICIT_SCHUR_COMPLEMENT_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/integral_types.h b/extern/libmv/third_party/ceres/internal/ceres/integral_types.h new file mode 100644 index 00000000000..01e04937e3e --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/integral_types.h @@ -0,0 +1,92 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// Portable typedefs for various fixed-size integers. Uses template +// metaprogramming instead of fragile compiler defines. + +#ifndef CERES_INTERNAL_INTEGRAL_TYPES_H_ +#define CERES_INTERNAL_INTEGRAL_TYPES_H_ + +namespace ceres { +namespace internal { + +// Compile time ternary on types. +template +struct Ternary { + typedef kTrueType type; +}; +template +struct Ternary { + typedef kFalseType type; +}; + +#define CERES_INTSIZE(TYPE) \ + typename Ternary +struct Integer { + typedef + CERES_INTSIZE(char) + CERES_INTSIZE(short) + CERES_INTSIZE(int) + CERES_INTSIZE(long int) + CERES_INTSIZE(long long) + void>::type >::type >::type >::type >::type + type; +}; + +template +struct UnsignedInteger { + typedef + CERES_INTSIZE(unsigned char) + CERES_INTSIZE(unsigned short) + CERES_INTSIZE(unsigned int) + CERES_INTSIZE(unsigned long int) + CERES_INTSIZE(unsigned long long) + void>::type >::type >::type >::type >::type + type; +}; + +#undef CERES_INTSIZE + +typedef Integer< 8>::type int8; +typedef Integer<16>::type int16; +typedef Integer<32>::type int32; +typedef Integer<64>::type int64; + +typedef UnsignedInteger< 8>::type uint8; +typedef UnsignedInteger<16>::type uint16; +typedef UnsignedInteger<32>::type uint32; +typedef UnsignedInteger<64>::type uint64; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_INTEGRAL_TYPES_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc new file mode 100644 index 00000000000..51303195317 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc @@ -0,0 +1,150 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/iterative_schur_complement_solver.h" + +#include +#include +#include + +#include +#include "Eigen/Dense" +#include "ceres/block_sparse_matrix.h" +#include "ceres/block_structure.h" +#include "ceres/conjugate_gradients_solver.h" +#include "ceres/implicit_schur_complement.h" +#include "ceres/linear_solver.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/visibility_based_preconditioner.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/linear_solver.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/types.h" +#include "ceres/visibility_based_preconditioner.h" + +namespace ceres { +namespace internal { + +IterativeSchurComplementSolver::IterativeSchurComplementSolver( + const LinearSolver::Options& options) + : options_(options) { +} + +IterativeSchurComplementSolver::~IterativeSchurComplementSolver() { +} + +LinearSolver::Summary IterativeSchurComplementSolver::SolveImpl( + BlockSparseMatrixBase* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double* x) { + CHECK_NOTNULL(A->block_structure()); + + // Initialize a ImplicitSchurComplement object. + if ((schur_complement_ == NULL) || (!options_.constant_sparsity)) { + schur_complement_.reset( + new ImplicitSchurComplement(options_.num_eliminate_blocks, + options_.constant_sparsity, + options_.preconditioner_type == JACOBI)); + } + schur_complement_->Init(*A, per_solve_options.D, b); + + // Initialize the solution to the Schur complement system to zero. + // + // TODO(sameeragarwal): There maybe a better initialization than an + // all zeros solution. Explore other cheap starting points. + reduced_linear_system_solution_.resize(schur_complement_->num_rows()); + reduced_linear_system_solution_.setZero(); + + // Instantiate a conjugate gradient solver that runs on the Schur complement + // matrix with the block diagonal of the matrix F'F as the preconditioner. + LinearSolver::Options cg_options; + cg_options.max_num_iterations = options_.max_num_iterations; + ConjugateGradientsSolver cg_solver(cg_options); + LinearSolver::PerSolveOptions cg_per_solve_options; + + cg_per_solve_options.r_tolerance = per_solve_options.r_tolerance; + cg_per_solve_options.q_tolerance = per_solve_options.q_tolerance; + + bool is_preconditioner_good = false; + switch (options_.preconditioner_type) { + case IDENTITY: + is_preconditioner_good = true; + break; + case JACOBI: + // We need to strip the constness of the block_diagonal_FtF_inverse + // matrix here because the only other way to initialize the struct + // cg_solve_options would be to add a constructor to it. We know + // that the only method ever called on the preconditioner is the + // RightMultiply which is a const method so we don't need to worry + // about the object getting modified. + cg_per_solve_options.preconditioner = + const_cast( + schur_complement_->block_diagonal_FtF_inverse()); + is_preconditioner_good = true; + break; + case SCHUR_JACOBI: + case CLUSTER_JACOBI: + case CLUSTER_TRIDIAGONAL: + if (visibility_based_preconditioner_.get() == NULL) { + visibility_based_preconditioner_.reset( + new VisibilityBasedPreconditioner(*A->block_structure(), options_)); + } + is_preconditioner_good = + visibility_based_preconditioner_->Compute(*A, per_solve_options.D); + cg_per_solve_options.preconditioner = + visibility_based_preconditioner_.get(); + break; + default: + LOG(FATAL) << "Unknown Preconditioner Type"; + } + + LinearSolver::Summary cg_summary; + cg_summary.num_iterations = 0; + cg_summary.termination_type = FAILURE; + + if (is_preconditioner_good) { + cg_summary = cg_solver.Solve(schur_complement_.get(), + schur_complement_->rhs().data(), + cg_per_solve_options, + reduced_linear_system_solution_.data()); + if (cg_summary.termination_type != FAILURE) { + schur_complement_->BackSubstitute( + reduced_linear_system_solution_.data(), x); + } + } + + VLOG(2) << "CG Iterations : " << cg_summary.num_iterations; + return cg_summary; +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.h b/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.h new file mode 100644 index 00000000000..cfeb65e1eec --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.h @@ -0,0 +1,94 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_ITERATIVE_SCHUR_COMPLEMENT_SOLVER_H_ +#define CERES_INTERNAL_ITERATIVE_SCHUR_COMPLEMENT_SOLVER_H_ + +#include "ceres/linear_solver.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +class BlockSparseMatrix; +class BlockSparseMatrixBase; +class ImplicitSchurComplement; +class VisibilityBasedPreconditioner; + +// This class implements an iterative solver for the linear least +// squares problems that have a bi-partitte sparsity structure common +// to Structure from Motion problems. +// +// The algorithm used by this solver was developed in a series of +// papers - "Agarwal et al, Bundle Adjustment in the Large, ECCV 2010" +// and "Wu et al, Multicore Bundle Adjustment, submitted to CVPR +// 2011" at the Univeristy of Washington. +// +// The key idea is that one can run Conjugate Gradients on the Schur +// Complement system without explicitly forming the Schur Complement +// in memory. The heavy lifting for this is done by the +// ImplicitSchurComplement class. Not forming the Schur complement in +// memory and factoring it results in substantial savings in time and +// memory. Further, iterative solvers like this open up the +// possibility of solving the Newton equations in a non-linear solver +// only approximately and terminating early, thereby saving even more +// time. +// +// For the curious, running CG on the Schur complement is the same as +// running CG on the Normal Equations with an SSOR preconditioner. For +// a proof of this fact and others related to this solver please see +// the section on Domain Decomposition Methods in Saad's book +// "Iterative Methods for Sparse Linear Systems". +class IterativeSchurComplementSolver : public BlockSparseMatrixBaseSolver { + public: + explicit IterativeSchurComplementSolver( + const LinearSolver::Options& options); + + virtual ~IterativeSchurComplementSolver(); + + private: + virtual LinearSolver::Summary SolveImpl( + BlockSparseMatrixBase* A, + const double* b, + const LinearSolver::PerSolveOptions& options, + double* x); + + LinearSolver::Options options_; + scoped_ptr schur_complement_; + scoped_ptr visibility_based_preconditioner_; + Vector reduced_linear_system_solution_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_ITERATIVE_SCHUR_COMPLEMENT_SOLVER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.cc b/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.cc new file mode 100644 index 00000000000..3ad359e63e4 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.cc @@ -0,0 +1,620 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Implementation of a simple LM algorithm which uses the step sizing +// rule of "Methods for Nonlinear Least Squares" by K. Madsen, +// H.B. Nielsen and O. Tingleff. Available to download from +// +// http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf +// +// The basic algorithm described in this note is an exact step +// algorithm that depends on the Newton(LM) step being solved exactly +// in each iteration. When a suitable iterative solver is available to +// solve the Newton(LM) step, the algorithm will automatically switch +// to an inexact step solution method. This trades some slowdown in +// convergence for significant savings in solve time and memory +// usage. Our implementation of the Truncated Newton algorithm follows +// the discussion and recommendataions in "Stephen G. Nash, A Survey +// of Truncated Newton Methods, Journal of Computational and Applied +// Mathematics, 124(1-2), 45-59, 2000. + +#include "ceres/levenberg_marquardt.h" + +#include +#include +#include +#include +#include +#include + +#include +#include "Eigen/Core" +#include "ceres/evaluator.h" +#include "ceres/file.h" +#include "ceres/linear_solver.h" +#include "ceres/matrix_proto.h" +#include "ceres/sparse_matrix.h" +#include "ceres/stringprintf.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { +namespace { + +// Numbers for clamping the size of the LM diagonal. The size of these +// numbers is heuristic. We will probably be adjusting them in the +// future based on more numerical experience. With jacobi scaling +// enabled, these numbers should be all but redundant. +const double kMinLevenbergMarquardtDiagonal = 1e-6; +const double kMaxLevenbergMarquardtDiagonal = 1e32; + +// Small constant for various floating point issues. +const double kEpsilon = 1e-12; + +// Number of times the linear solver should be retried in case of +// numerical failure. The retries are done by exponentially scaling up +// mu at each retry. This leads to stronger and stronger +// regularization making the linear least squares problem better +// conditioned at each retry. +const int kMaxLinearSolverRetries = 5; + +// D = 1/sqrt(diag(J^T * J)) +void EstimateScale(const SparseMatrix& jacobian, double* D) { + CHECK_NOTNULL(D); + jacobian.SquaredColumnNorm(D); + for (int i = 0; i < jacobian.num_cols(); ++i) { + D[i] = 1.0 / (kEpsilon + sqrt(D[i])); + } +} + +// D = diag(J^T * J) +void LevenbergMarquardtDiagonal(const SparseMatrix& jacobian, + double* D) { + CHECK_NOTNULL(D); + jacobian.SquaredColumnNorm(D); + for (int i = 0; i < jacobian.num_cols(); ++i) { + D[i] = min(max(D[i], kMinLevenbergMarquardtDiagonal), + kMaxLevenbergMarquardtDiagonal); + } +} + +string DumpLinearSolverProblem( + int iteration, + const SparseMatrix* A, + const double* D, + const double* b, + const double* x, + const Minimizer::Options& solver_options) { + if (solver_options.lsqp_dump_format == "ascii") { + // Dump to the screen instead of to file. Useful for debugging. + Matrix AA; + A->ToDenseMatrix(&AA); + LOG(INFO) << "A^T: \n" << AA.transpose(); + if (D) { + LOG(INFO) << "A's appended diagonal:\n" + << ConstVectorRef(D, A->num_cols()); + } + LOG(INFO) << "b: \n" << ConstVectorRef(b, A->num_rows()); + LOG(INFO) << "x: \n" << ConstVectorRef(x, A->num_cols()); + return ""; + } +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS + LinearLeastSquaresProblemProto lsqp; + A->ToProto(lsqp.mutable_a()); + for (int i = 0; i < A->num_rows(); ++i) { + lsqp.add_b(b[i]); + } + if (D) { + for (int i = 0; i < A->num_cols(); ++i) { + lsqp.add_d(D[i]); + } + } + if (x) { + for (int i = 0; i < A->num_cols(); ++i) { + lsqp.add_x(x[i]); + } + } + + lsqp.set_num_eliminate_blocks(solver_options.num_eliminate_blocks); + + CHECK(solver_options.lsqp_dump_format.size()); + string filename = + StringPrintf(solver_options.lsqp_dump_format.c_str(), // NOLINT + iteration); + VLOG(1) << "Dumping least squares problem for iteration " << iteration + << " to disk. File: " << filename; + WriteStringToFileOrDie(lsqp.SerializeAsString(), filename); + VLOG(2) << "Done dumping to disk"; + return filename; +#else + LOG(ERROR) << "Dumping least squares problems is only " + << "supported when Ceres is compiled with " + << "protocol buffer support."; + return ""; +#endif +} + +bool RunCallback(IterationCallback* callback, + const IterationSummary& iteration_summary, + Solver::Summary* summary) { + const CallbackReturnType status = (*callback)(iteration_summary); + switch (status) { + case SOLVER_TERMINATE_SUCCESSFULLY: + summary->termination_type = USER_SUCCESS; + VLOG(1) << "Terminating on USER_SUCCESS."; + return false; + case SOLVER_ABORT: + summary->termination_type = USER_ABORT; + VLOG(1) << "Terminating on USER_ABORT."; + return false; + case SOLVER_CONTINUE: + return true; + default: + LOG(FATAL) << "Unknown status returned by callback: " + << status; + return NULL; + } +} + +} // namespace + +LevenbergMarquardt::~LevenbergMarquardt() {} + +void LevenbergMarquardt::Minimize(const Minimizer::Options& options, + Evaluator* evaluator, + LinearSolver* linear_solver, + const double* initial_parameters, + double* final_parameters, + Solver::Summary* summary) { + time_t start_time = time(NULL); + const int num_parameters = evaluator->NumParameters(); + const int num_effective_parameters = evaluator->NumEffectiveParameters(); + const int num_residuals = evaluator->NumResiduals(); + + summary->termination_type = NO_CONVERGENCE; + summary->num_successful_steps = 0; + summary->num_unsuccessful_steps = 0; + + // Allocate the various vectors needed by the algorithm. + memcpy(final_parameters, initial_parameters, + num_parameters * sizeof(*initial_parameters)); + + VectorRef x(final_parameters, num_parameters); + Vector x_new(num_parameters); + + Vector lm_step(num_effective_parameters); + Vector gradient(num_effective_parameters); + Vector scaled_gradient(num_effective_parameters); + // Jacobi scaling vector + Vector scale(num_effective_parameters); + + Vector f_model(num_residuals); + Vector f(num_residuals); + Vector f_new(num_residuals); + Vector D(num_parameters); + Vector muD(num_parameters); + + // Ask the Evaluator to create the jacobian matrix. The sparsity + // pattern of this matrix is going to remain constant, so we only do + // this once and then re-use this matrix for all subsequent Jacobian + // computations. + scoped_ptr jacobian(evaluator->CreateJacobian()); + + double x_norm = x.norm(); + + double cost = 0.0; + D.setOnes(); + f.setZero(); + + // Do initial cost and Jacobian evaluation. + if (!evaluator->Evaluate(x.data(), &cost, f.data(), jacobian.get())) { + LOG(WARNING) << "Failed to compute residuals and Jacobian. " + << "Terminating."; + summary->termination_type = NUMERICAL_FAILURE; + return; + } + + if (options.jacobi_scaling) { + EstimateScale(*jacobian, scale.data()); + jacobian->ScaleColumns(scale.data()); + } else { + scale.setOnes(); + } + + // This is a poor way to do this computation. Even if fixed_cost is + // zero, because we are subtracting two possibly large numbers, we + // are depending on exact cancellation to give us a zero here. But + // initial_cost and cost have been computed by two different + // evaluators. One which runs on the whole problem (in + // solver_impl.cc) in single threaded mode and another which runs + // here on the reduced problem, so fixed_cost can (and does) contain + // some numerical garbage with a relative magnitude of 1e-14. + // + // The right way to do this, would be to compute the fixed cost on + // just the set of residual blocks which are held constant and were + // removed from the original problem when the reduced problem was + // constructed. + summary->fixed_cost = summary->initial_cost - cost; + + double model_cost = f.squaredNorm() / 2.0; + double total_cost = summary->fixed_cost + cost; + + scaled_gradient.setZero(); + jacobian->LeftMultiply(f.data(), scaled_gradient.data()); + gradient = scaled_gradient.array() / scale.array(); + + double gradient_max_norm = gradient.lpNorm(); + // We need the max here to guard againt the gradient being zero. + const double gradient_max_norm_0 = max(gradient_max_norm, kEpsilon); + double gradient_tolerance = options.gradient_tolerance * gradient_max_norm_0; + + double mu = options.tau; + double nu = 2.0; + int iteration = 0; + double actual_cost_change = 0.0; + double step_norm = 0.0; + double relative_decrease = 0.0; + + // Insane steps are steps which are not sane, i.e. there is some + // numerical kookiness going on with them. There are various reasons + // for this kookiness, some easier to diagnose then others. From the + // point of view of the non-linear solver, they are steps which + // cannot be used. We return with NUMERICAL_FAILURE after + // kMaxLinearSolverRetries consecutive insane steps. + bool step_is_sane = false; + int num_consecutive_insane_steps = 0; + + // Whether the step resulted in a sufficient decrease in the + // objective function when compared to the decrease in the value of + // the lineariztion. + bool step_is_successful = false; + + // Parse the iterations for which to dump the linear problem. + vector iterations_to_dump = options.lsqp_iterations_to_dump; + sort(iterations_to_dump.begin(), iterations_to_dump.end()); + + IterationSummary iteration_summary; + iteration_summary.iteration = iteration; + iteration_summary.step_is_successful = false; + iteration_summary.cost = total_cost; + iteration_summary.cost_change = actual_cost_change; + iteration_summary.gradient_max_norm = gradient_max_norm; + iteration_summary.step_norm = step_norm; + iteration_summary.relative_decrease = relative_decrease; + iteration_summary.mu = mu; + iteration_summary.eta = options.eta; + iteration_summary.linear_solver_iterations = 0; + iteration_summary.linear_solver_time_sec = 0.0; + iteration_summary.iteration_time_sec = (time(NULL) - start_time); + if (options.logging_type >= PER_MINIMIZER_ITERATION) { + summary->iterations.push_back(iteration_summary); + } + + // Check if the starting point is an optimum. + VLOG(2) << "Gradient max norm: " << gradient_max_norm + << " tolerance: " << gradient_tolerance + << " ratio: " << gradient_max_norm / gradient_max_norm_0 + << " tolerance: " << options.gradient_tolerance; + if (gradient_max_norm <= gradient_tolerance) { + summary->termination_type = GRADIENT_TOLERANCE; + VLOG(1) << "Terminating on GRADIENT_TOLERANCE. " + << "Relative gradient max norm: " + << gradient_max_norm / gradient_max_norm_0 + << " <= " << options.gradient_tolerance; + return; + } + + // Call the various callbacks. + for (int i = 0; i < options.callbacks.size(); ++i) { + if (!RunCallback(options.callbacks[i], iteration_summary, summary)) { + return; + } + } + + // We only need the LM diagonal if we are actually going to do at + // least one iteration of the optimization. So we wait to do it + // until now. + LevenbergMarquardtDiagonal(*jacobian, D.data()); + + while ((iteration < options.max_num_iterations) && + (time(NULL) - start_time) <= options.max_solver_time_sec) { + time_t iteration_start_time = time(NULL); + step_is_sane = false; + step_is_successful = false; + + IterationSummary iteration_summary; + // The while loop here is just to provide an easily breakable + // control structure. We are guaranteed to always exit this loop + // at the end of one iteration or before. + while (1) { + muD = (mu * D).array().sqrt(); + LinearSolver::PerSolveOptions solve_options; + solve_options.D = muD.data(); + solve_options.q_tolerance = options.eta; + // Disable r_tolerance checking. Since we only care about + // termination via the q_tolerance. As Nash and Sofer show, + // r_tolerance based termination is essentially useless in + // Truncated Newton methods. + solve_options.r_tolerance = -1.0; + + const time_t linear_solver_start_time = time(NULL); + LinearSolver::Summary linear_solver_summary = + linear_solver->Solve(jacobian.get(), + f.data(), + solve_options, + lm_step.data()); + iteration_summary.linear_solver_time_sec = + (time(NULL) - linear_solver_start_time); + iteration_summary.linear_solver_iterations = + linear_solver_summary.num_iterations; + + if (binary_search(iterations_to_dump.begin(), + iterations_to_dump.end(), + iteration)) { + DumpLinearSolverProblem(iteration, + jacobian.get(), + muD.data(), + f.data(), + lm_step.data(), + options); + } + + // We ignore the case where the linear solver did not converge, + // since the partial solution computed by it still maybe of use, + // and there is no reason to ignore it, especially since we + // spent so much time computing it. + if ((linear_solver_summary.termination_type != TOLERANCE) && + (linear_solver_summary.termination_type != MAX_ITERATIONS)) { + VLOG(1) << "Linear solver failure: retrying with a higher mu"; + break; + } + + step_norm = (lm_step.array() * scale.array()).matrix().norm(); + + // Check step length based convergence. If the step length is + // too small, then we are done. + const double step_size_tolerance = options.parameter_tolerance * + (x_norm + options.parameter_tolerance); + + VLOG(2) << "Step size: " << step_norm + << " tolerance: " << step_size_tolerance + << " ratio: " << step_norm / step_size_tolerance + << " tolerance: " << options.parameter_tolerance; + if (step_norm <= options.parameter_tolerance * + (x_norm + options.parameter_tolerance)) { + summary->termination_type = PARAMETER_TOLERANCE; + VLOG(1) << "Terminating on PARAMETER_TOLERANCE." + << "Relative step size: " << step_norm / step_size_tolerance + << " <= " << options.parameter_tolerance; + return; + } + + Vector delta = -(lm_step.array() * scale.array()).matrix(); + if (!evaluator->Plus(x.data(), delta.data(), x_new.data())) { + LOG(WARNING) << "Failed to compute Plus(x, delta, x_plus_delta). " + << "Terminating."; + summary->termination_type = NUMERICAL_FAILURE; + return; + } + + double cost_new = 0.0; + if (!evaluator->Evaluate(x_new.data(), &cost_new, NULL, NULL)) { + LOG(WARNING) << "Failed to compute the value of the objective " + << "function. Terminating."; + summary->termination_type = NUMERICAL_FAILURE; + return; + } + + f_model.setZero(); + jacobian->RightMultiply(lm_step.data(), f_model.data()); + const double model_cost_new = + (f.segment(0, num_residuals) - f_model).squaredNorm() / 2; + + actual_cost_change = cost - cost_new; + double model_cost_change = model_cost - model_cost_new; + + VLOG(2) << "[Model cost] current: " << model_cost + << " new : " << model_cost_new + << " change: " << model_cost_change; + + VLOG(2) << "[Nonlinear cost] current: " << cost + << " new : " << cost_new + << " change: " << actual_cost_change + << " relative change: " << fabs(actual_cost_change) / cost + << " tolerance: " << options.function_tolerance; + + // In exact arithmetic model_cost_change should never be + // negative. But due to numerical precision issues, we may end up + // with a small negative number. model_cost_change which are + // negative and large in absolute value are indicative of a + // numerical failure in the solver. + if (model_cost_change < -kEpsilon) { + VLOG(1) << "Model cost change is negative.\n" + << "Current : " << model_cost + << " new : " << model_cost_new + << " change: " << model_cost_change << "\n"; + break; + } + + // If we have reached this far, then we are willing to trust the + // numerical quality of the step. + step_is_sane = true; + num_consecutive_insane_steps = 0; + + // Check function value based convergence. + if (fabs(actual_cost_change) < options.function_tolerance * cost) { + VLOG(1) << "Termination on FUNCTION_TOLERANCE." + << " Relative cost change: " << fabs(actual_cost_change) / cost + << " tolerance: " << options.function_tolerance; + summary->termination_type = FUNCTION_TOLERANCE; + return; + } + + // Clamp model_cost_change at kEpsilon from below. + if (model_cost_change < kEpsilon) { + VLOG(1) << "Clamping model cost change " << model_cost_change + << " to " << kEpsilon; + model_cost_change = kEpsilon; + } + + relative_decrease = actual_cost_change / model_cost_change; + VLOG(2) << "actual_cost_change / model_cost_change = " + << relative_decrease; + + if (relative_decrease < options.min_relative_decrease) { + VLOG(2) << "Unsuccessful step."; + break; + } + + VLOG(2) << "Successful step."; + + ++summary->num_successful_steps; + x = x_new; + x_norm = x.norm(); + + if (!evaluator->Evaluate(x.data(), &cost, f.data(), jacobian.get())) { + LOG(WARNING) << "Failed to compute residuals and jacobian. " + << "Terminating."; + summary->termination_type = NUMERICAL_FAILURE; + return; + } + + if (options.jacobi_scaling) { + jacobian->ScaleColumns(scale.data()); + } + + model_cost = f.squaredNorm() / 2.0; + LevenbergMarquardtDiagonal(*jacobian, D.data()); + scaled_gradient.setZero(); + jacobian->LeftMultiply(f.data(), scaled_gradient.data()); + gradient = scaled_gradient.array() / scale.array(); + gradient_max_norm = gradient.lpNorm(); + + // Check gradient based convergence. + VLOG(2) << "Gradient max norm: " << gradient_max_norm + << " tolerance: " << gradient_tolerance + << " ratio: " << gradient_max_norm / gradient_max_norm_0 + << " tolerance: " << options.gradient_tolerance; + if (gradient_max_norm <= gradient_tolerance) { + summary->termination_type = GRADIENT_TOLERANCE; + VLOG(1) << "Terminating on GRADIENT_TOLERANCE. " + << "Relative gradient max norm: " + << gradient_max_norm / gradient_max_norm_0 + << " <= " << options.gradient_tolerance + << " (tolerance)."; + return; + } + + mu = mu * max(1.0 / 3.0, 1 - pow(2 * relative_decrease - 1, 3)); + nu = 2.0; + step_is_successful = true; + break; + } + + if (!step_is_sane) { + ++num_consecutive_insane_steps; + } + + if (num_consecutive_insane_steps == kMaxLinearSolverRetries) { + VLOG(1) << "Too many consecutive retries; ending with numerical fail."; + summary->termination_type = NUMERICAL_FAILURE; + + if (!options.crash_and_dump_lsqp_on_failure) { + return; + } + + // Dump debugging information to disk. + CHECK(!options.lsqp_dump_format.empty()) + << "Dumping the linear least squares problem on crash " + << "requires Solver::Options::lsqp_dump_format set a " + << "filename"; + CHECK_NE(options.lsqp_dump_format, "ascii") + << "Dumping the linear least squares problem on crash " + << "requires Solver::Options::lsqp_dump_format set a " + << "filename"; + + const string filename = DumpLinearSolverProblem(iteration, + jacobian.get(), + muD.data(), + f.data(), + lm_step.data(), + options); + LOG(FATAL) << "Linear least squares problem saved to " << filename + << " please provide this to the Ceres developers for " + << " debugging along with the v=2 log."; + return; + } + + if (!step_is_successful) { + // Either the step did not lead to a decrease in cost or there + // was numerical failure. In either case we will scale mu up and + // retry. If it was a numerical failure, we hope that the + // stronger regularization will make the linear system better + // conditioned. If it was numerically sane, but there was no + // decrease in cost, then increasing mu reduces the size of the + // trust region and we look for a decrease closer to the + // linearization point. + ++summary->num_unsuccessful_steps; + mu = mu * nu; + nu = 2 * nu; + } + + ++iteration; + + total_cost = summary->fixed_cost + cost; + + iteration_summary.iteration = iteration; + iteration_summary.step_is_successful = step_is_successful; + iteration_summary.cost = total_cost; + iteration_summary.cost_change = actual_cost_change; + iteration_summary.gradient_max_norm = gradient_max_norm; + iteration_summary.step_norm = step_norm; + iteration_summary.relative_decrease = relative_decrease; + iteration_summary.mu = mu; + iteration_summary.eta = options.eta; + iteration_summary.iteration_time_sec = (time(NULL) - iteration_start_time); + + if (options.logging_type >= PER_MINIMIZER_ITERATION) { + summary->iterations.push_back(iteration_summary); + } + + // Call the various callbacks. + for (int i = 0; i < options.callbacks.size(); ++i) { + if (!RunCallback(options.callbacks[i], iteration_summary, summary)) { + return; + } + } + } +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.h b/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.h new file mode 100644 index 00000000000..d00bb9095be --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.h @@ -0,0 +1,65 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Implmentation of Levenberg Marquardt algorithm based on "Methods for +// Nonlinear Least Squares" by K. Madsen, H.B. Nielsen and +// O. Tingleff. Available to download from +// +// http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf +// + +#ifndef CERES_INTERNAL_LEVENBERG_MARQUARDT_H_ +#define CERES_INTERNAL_LEVENBERG_MARQUARDT_H_ + +#include "ceres/minimizer.h" +#include "ceres/solver.h" + +namespace ceres { +namespace internal { + +class Evaluator; +class LinearSolver; + +class LevenbergMarquardt : public Minimizer { + public: + virtual ~LevenbergMarquardt(); + + virtual void Minimize(const Minimizer::Options& options, + Evaluator* evaluator, + LinearSolver* linear_solver, + const double* initial_parameters, + double* final_parameters, + Solver::Summary* summary); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_LEVENBERG_MARQUARDT_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc new file mode 100644 index 00000000000..9fc5ff8a1c7 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc @@ -0,0 +1,574 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/linear_least_squares_problems.h" + +#include +#include +#include +#include "ceres/block_sparse_matrix.h" +#include "ceres/block_structure.h" +#include "ceres/compressed_row_sparse_matrix.h" +#include "ceres/file.h" +#include "ceres/matrix_proto.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +LinearLeastSquaresProblem* CreateLinearLeastSquaresProblemFromId(int id) { + switch (id) { + case 0: + return LinearLeastSquaresProblem0(); + case 1: + return LinearLeastSquaresProblem1(); + case 2: + return LinearLeastSquaresProblem2(); + case 3: + return LinearLeastSquaresProblem3(); + default: + LOG(FATAL) << "Unknown problem id requested " << id; + } + return NULL; +} + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +LinearLeastSquaresProblem* CreateLinearLeastSquaresProblemFromFile( + const string& filename) { + LinearLeastSquaresProblemProto problem_proto; + { + string serialized_proto; + ReadFileToStringOrDie(filename, &serialized_proto); + CHECK(problem_proto.ParseFromString(serialized_proto)); + } + + LinearLeastSquaresProblem* problem = new LinearLeastSquaresProblem; + const SparseMatrixProto& A = problem_proto.a(); + + if (A.has_block_matrix()) { + problem->A.reset(new BlockSparseMatrix(A)); + } else if (A.has_triplet_matrix()) { + problem->A.reset(new TripletSparseMatrix(A)); + } else { + problem->A.reset(new CompressedRowSparseMatrix(A)); + } + + if (problem_proto.b_size() > 0) { + problem->b.reset(new double[problem_proto.b_size()]); + for (int i = 0; i < problem_proto.b_size(); ++i) { + problem->b[i] = problem_proto.b(i); + } + } + + if (problem_proto.d_size() > 0) { + problem->D.reset(new double[problem_proto.d_size()]); + for (int i = 0; i < problem_proto.d_size(); ++i) { + problem->D[i] = problem_proto.d(i); + } + } + + if (problem_proto.d_size() > 0) { + if (problem_proto.x_size() > 0) { + problem->x_D.reset(new double[problem_proto.x_size()]); + for (int i = 0; i < problem_proto.x_size(); ++i) { + problem->x_D[i] = problem_proto.x(i); + } + } + } else { + if (problem_proto.x_size() > 0) { + problem->x.reset(new double[problem_proto.x_size()]); + for (int i = 0; i < problem_proto.x_size(); ++i) { + problem->x[i] = problem_proto.x(i); + } + } + } + + problem->num_eliminate_blocks = 0; + if (problem_proto.has_num_eliminate_blocks()) { + problem->num_eliminate_blocks = problem_proto.num_eliminate_blocks(); + } + + return problem; +} +#else +LinearLeastSquaresProblem* CreateLinearLeastSquaresProblemFromFile( + const string& filename) { + LOG(FATAL) + << "Loading a least squares problem from disk requires " + << "Ceres to be built with Protocol Buffers support."; + return NULL; +} +#endif // CERES_DONT_HAVE_PROTOCOL_BUFFERS + +/* +A = [1 2] + [3 4] + [6 -10] + +b = [ 8 + 18 + -18] + +x = [2 + 3] + +D = [1 + 2] + +x_D = [1.78448275; + 2.82327586;] + */ +LinearLeastSquaresProblem* LinearLeastSquaresProblem0() { + LinearLeastSquaresProblem* problem = new LinearLeastSquaresProblem; + + TripletSparseMatrix* A = new TripletSparseMatrix(3, 2, 6); + problem->b.reset(new double[3]); + problem->D.reset(new double[2]); + + problem->x.reset(new double[2]); + problem->x_D.reset(new double[2]); + + int* Ai = A->mutable_rows(); + int* Aj = A->mutable_cols(); + double* Ax = A->mutable_values(); + + int counter = 0; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j< 2; ++j) { + Ai[counter]=i; + Aj[counter]=j; + ++counter; + } + }; + + Ax[0] = 1.; + Ax[1] = 2.; + Ax[2] = 3.; + Ax[3] = 4.; + Ax[4] = 6; + Ax[5] = -10; + A->set_num_nonzeros(6); + problem->A.reset(A); + + problem->b[0] = 8; + problem->b[1] = 18; + problem->b[2] = -18; + + problem->x[0] = 2.0; + problem->x[1] = 3.0; + + problem->D[0] = 1; + problem->D[1] = 2; + + problem->x_D[0] = 1.78448275; + problem->x_D[1] = 2.82327586; + return problem; +} + + +/* + A = [1 0 | 2 0 0 + 3 0 | 0 4 0 + 0 5 | 0 0 6 + 0 7 | 8 0 0 + 0 9 | 1 0 0 + 0 0 | 1 1 1] + + b = [0 + 1 + 2 + 3 + 4 + 5] + + c = A'* b = [ 3 + 67 + 33 + 9 + 17] + + A'A = [10 0 2 12 0 + 0 155 65 0 30 + 2 65 70 1 1 + 12 0 1 17 1 + 0 30 1 1 37] + + S = [ 42.3419 -1.4000 -11.5806 + -1.4000 2.6000 1.0000 + 11.5806 1.0000 31.1935] + + r = [ 4.3032 + 5.4000 + 5.0323] + + S\r = [ 0.2102 + 2.1367 + 0.1388] + + A\b = [-2.3061 + 0.3172 + 0.2102 + 2.1367 + 0.1388] +*/ +// The following two functions create a TripletSparseMatrix and a +// BlockSparseMatrix version of this problem. + +// TripletSparseMatrix version. +LinearLeastSquaresProblem* LinearLeastSquaresProblem1() { + int num_rows = 6; + int num_cols = 5; + + LinearLeastSquaresProblem* problem = new LinearLeastSquaresProblem; + TripletSparseMatrix* A = new TripletSparseMatrix(num_rows, + num_cols, + num_rows * num_cols); + problem->b.reset(new double[num_rows]); + problem->D.reset(new double[num_cols]); + problem->num_eliminate_blocks = 2; + + int* rows = A->mutable_rows(); + int* cols = A->mutable_cols(); + double* values = A->mutable_values(); + + int nnz = 0; + + // Row 1 + { + rows[nnz] = 0; + cols[nnz] = 0; + values[nnz++] = 1; + + rows[nnz] = 0; + cols[nnz] = 2; + values[nnz++] = 2; + } + + // Row 2 + { + rows[nnz] = 1; + cols[nnz] = 0; + values[nnz++] = 3; + + rows[nnz] = 1; + cols[nnz] = 3; + values[nnz++] = 4; + } + + // Row 3 + { + rows[nnz] = 2; + cols[nnz] = 1; + values[nnz++] = 5; + + rows[nnz] = 2; + cols[nnz] = 4; + values[nnz++] = 6; + } + + // Row 4 + { + rows[nnz] = 3; + cols[nnz] = 1; + values[nnz++] = 7; + + rows[nnz] = 3; + cols[nnz] = 2; + values[nnz++] = 8; + } + + // Row 5 + { + rows[nnz] = 4; + cols[nnz] = 1; + values[nnz++] = 9; + + rows[nnz] = 4; + cols[nnz] = 2; + values[nnz++] = 1; + } + + // Row 6 + { + rows[nnz] = 5; + cols[nnz] = 2; + values[nnz++] = 1; + + rows[nnz] = 5; + cols[nnz] = 3; + values[nnz++] = 1; + + rows[nnz] = 5; + cols[nnz] = 4; + values[nnz++] = 1; + } + + A->set_num_nonzeros(nnz); + CHECK(A->IsValid()); + + problem->A.reset(A); + + for (int i = 0; i < num_cols; ++i) { + problem->D.get()[i] = 1; + } + + for (int i = 0; i < num_rows; ++i) { + problem->b.get()[i] = i; + } + + return problem; +} + +// BlockSparseMatrix version +LinearLeastSquaresProblem* LinearLeastSquaresProblem2() { + int num_rows = 6; + int num_cols = 5; + + LinearLeastSquaresProblem* problem = new LinearLeastSquaresProblem; + + problem->b.reset(new double[num_rows]); + problem->D.reset(new double[num_cols]); + problem->num_eliminate_blocks = 2; + + CompressedRowBlockStructure* bs = new CompressedRowBlockStructure; + scoped_array values(new double[num_rows * num_cols]); + + for (int c = 0; c < num_cols; ++c) { + bs->cols.push_back(Block()); + bs->cols.back().size = 1; + bs->cols.back().position = c; + } + + int nnz = 0; + + // Row 1 + { + values[nnz++] = 1; + values[nnz++] = 2; + + bs->rows.push_back(CompressedRow()); + CompressedRow& row = bs->rows.back(); + row.block.size = 1; + row.block.position = 0; + row.cells.push_back(Cell(0, 0)); + row.cells.push_back(Cell(2, 1)); + } + + // Row 2 + { + values[nnz++] = 3; + values[nnz++] = 4; + + bs->rows.push_back(CompressedRow()); + CompressedRow& row = bs->rows.back(); + row.block.size = 1; + row.block.position = 1; + row.cells.push_back(Cell(0, 2)); + row.cells.push_back(Cell(3, 3)); + } + + // Row 3 + { + values[nnz++] = 5; + values[nnz++] = 6; + + bs->rows.push_back(CompressedRow()); + CompressedRow& row = bs->rows.back(); + row.block.size = 1; + row.block.position = 2; + row.cells.push_back(Cell(1, 4)); + row.cells.push_back(Cell(4, 5)); + } + + // Row 4 + { + values[nnz++] = 7; + values[nnz++] = 8; + + bs->rows.push_back(CompressedRow()); + CompressedRow& row = bs->rows.back(); + row.block.size = 1; + row.block.position = 3; + row.cells.push_back(Cell(1, 6)); + row.cells.push_back(Cell(2, 7)); + } + + // Row 5 + { + values[nnz++] = 9; + values[nnz++] = 1; + + bs->rows.push_back(CompressedRow()); + CompressedRow& row = bs->rows.back(); + row.block.size = 1; + row.block.position = 4; + row.cells.push_back(Cell(1, 8)); + row.cells.push_back(Cell(2, 9)); + } + + // Row 6 + { + values[nnz++] = 1; + values[nnz++] = 1; + values[nnz++] = 1; + + bs->rows.push_back(CompressedRow()); + CompressedRow& row = bs->rows.back(); + row.block.size = 1; + row.block.position = 5; + row.cells.push_back(Cell(2, 10)); + row.cells.push_back(Cell(3, 11)); + row.cells.push_back(Cell(4, 12)); + } + + BlockSparseMatrix* A = new BlockSparseMatrix(bs); + memcpy(A->mutable_values(), values.get(), nnz * sizeof(*A->values())); + + for (int i = 0; i < num_cols; ++i) { + problem->D.get()[i] = 1; + } + + for (int i = 0; i < num_rows; ++i) { + problem->b.get()[i] = i; + } + + problem->A.reset(A); + + return problem; +} + + +/* + A = [1 0 + 3 0 + 0 5 + 0 7 + 0 9 + 0 0] + + b = [0 + 1 + 2 + 3 + 4 + 5] +*/ +// BlockSparseMatrix version +LinearLeastSquaresProblem* LinearLeastSquaresProblem3() { + int num_rows = 5; + int num_cols = 2; + + LinearLeastSquaresProblem* problem = new LinearLeastSquaresProblem; + + problem->b.reset(new double[num_rows]); + problem->D.reset(new double[num_cols]); + problem->num_eliminate_blocks = 2; + + CompressedRowBlockStructure* bs = new CompressedRowBlockStructure; + scoped_array values(new double[num_rows * num_cols]); + + for (int c = 0; c < num_cols; ++c) { + bs->cols.push_back(Block()); + bs->cols.back().size = 1; + bs->cols.back().position = c; + } + + int nnz = 0; + + // Row 1 + { + values[nnz++] = 1; + bs->rows.push_back(CompressedRow()); + CompressedRow& row = bs->rows.back(); + row.block.size = 1; + row.block.position = 0; + row.cells.push_back(Cell(0, 0)); + } + + // Row 2 + { + values[nnz++] = 3; + bs->rows.push_back(CompressedRow()); + CompressedRow& row = bs->rows.back(); + row.block.size = 1; + row.block.position = 1; + row.cells.push_back(Cell(0, 1)); + } + + // Row 3 + { + values[nnz++] = 5; + bs->rows.push_back(CompressedRow()); + CompressedRow& row = bs->rows.back(); + row.block.size = 1; + row.block.position = 2; + row.cells.push_back(Cell(1, 2)); + } + + // Row 4 + { + values[nnz++] = 7; + bs->rows.push_back(CompressedRow()); + CompressedRow& row = bs->rows.back(); + row.block.size = 1; + row.block.position = 3; + row.cells.push_back(Cell(1, 3)); + } + + // Row 5 + { + values[nnz++] = 9; + bs->rows.push_back(CompressedRow()); + CompressedRow& row = bs->rows.back(); + row.block.size = 1; + row.block.position = 4; + row.cells.push_back(Cell(1, 4)); + } + + BlockSparseMatrix* A = new BlockSparseMatrix(bs); + memcpy(A->mutable_values(), values.get(), nnz * sizeof(*A->values())); + + for (int i = 0; i < num_cols; ++i) { + problem->D.get()[i] = 1; + } + + for (int i = 0; i < num_rows; ++i) { + problem->b.get()[i] = i; + } + + problem->A.reset(A); + + return problem; +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h new file mode 100644 index 00000000000..46a624bd73f --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h @@ -0,0 +1,77 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_LINEAR_LEAST_SQUARES_PROBLEMS_H_ +#define CERES_INTERNAL_LINEAR_LEAST_SQUARES_PROBLEMS_H_ + +#include + +#include "ceres/sparse_matrix.h" +#include "ceres/internal/port.h" +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { + +// Structure defining a linear least squares problem and if possible +// ground truth solutions. To be used by various LinearSolver tests. +struct LinearLeastSquaresProblem { + LinearLeastSquaresProblem() + : A(NULL), b(NULL), D(NULL), num_eliminate_blocks(0), + x(NULL), x_D(NULL) { + } + + scoped_ptr A; + scoped_array b; + scoped_array D; + // If using the schur eliminator then how many of the variable + // blocks are e_type blocks. + int num_eliminate_blocks; + + // Solution to min_x |Ax - b|^2 + scoped_array x; + // Solution to min_x |Ax - b|^2 + |Dx|^2 + scoped_array x_D; +}; + +// Factories for linear least squares problem. +LinearLeastSquaresProblem* CreateLinearLeastSquaresProblemFromId(int id); +LinearLeastSquaresProblem* CreateLinearLeastSquaresProblemFromFile( + const string& filename); + +LinearLeastSquaresProblem* LinearLeastSquaresProblem0(); +LinearLeastSquaresProblem* LinearLeastSquaresProblem1(); +LinearLeastSquaresProblem* LinearLeastSquaresProblem2(); +LinearLeastSquaresProblem* LinearLeastSquaresProblem3(); + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_LINEAR_LEAST_SQUARES_PROBLEMS_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_operator.cc b/extern/libmv/third_party/ceres/internal/ceres/linear_operator.cc new file mode 100644 index 00000000000..4b59fa13009 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/linear_operator.cc @@ -0,0 +1,40 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/linear_operator.h" + +namespace ceres { +namespace internal { + +LinearOperator::~LinearOperator() { +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_operator.h b/extern/libmv/third_party/ceres/internal/ceres/linear_operator.h new file mode 100644 index 00000000000..d5c15cee6a9 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/linear_operator.h @@ -0,0 +1,59 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Base classes for access to an linear operator. + +#ifndef CERES_INTERNAL_LINEAR_OPERATOR_H_ +#define CERES_INTERNAL_LINEAR_OPERATOR_H_ + +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +// This is an abstract base class for linear operators. It supports +// access to size information and left and right multiply operators. +class LinearOperator { + public: + virtual ~LinearOperator(); + + // y = y + Ax; + virtual void RightMultiply(const double* x, double* y) const = 0; + // y = y + A'x; + virtual void LeftMultiply(const double* x, double* y) const = 0; + + virtual int num_rows() const = 0; + virtual int num_cols() const = 0; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_LINEAR_OPERATOR_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.cc new file mode 100644 index 00000000000..b2e3941eea1 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.cc @@ -0,0 +1,87 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/linear_solver.h" + +#include +#include "ceres/cgnr_solver.h" +#include "ceres/dense_qr_solver.h" +#include "ceres/iterative_schur_complement_solver.h" +#include "ceres/schur_complement_solver.h" +#include "ceres/sparse_normal_cholesky_solver.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +LinearSolver::~LinearSolver() { +} + +LinearSolver* LinearSolver::Create(const LinearSolver::Options& options) { + switch (options.type) { + case CGNR: + return new CgnrSolver(options); + + case SPARSE_NORMAL_CHOLESKY: +#ifndef CERES_NO_SUITESPARSE + return new SparseNormalCholeskySolver(options); +#else + LOG(WARNING) << "SPARSE_NORMAL_CHOLESKY is not available. Please " + << "build Ceres with SuiteSparse. Returning NULL."; + return NULL; +#endif // CERES_NO_SUITESPARSE + + case SPARSE_SCHUR: +#ifndef CERES_NO_SUITESPARSE + return new SparseSchurComplementSolver(options); +#else + LOG(WARNING) << "SPARSE_SCHUR is not available. Please " + << "build Ceres with SuiteSparse. Returning NULL."; + return NULL; +#endif // CERES_NO_SUITESPARSE + + case DENSE_SCHUR: + return new DenseSchurComplementSolver(options); + + case ITERATIVE_SCHUR: + return new IterativeSchurComplementSolver(options); + + case DENSE_QR: + return new DenseQRSolver(options); + + default: + LOG(FATAL) << "Unknown linear solver type :" + << options.type; + return NULL; // MSVC doesn't understand that LOG(FATAL) never returns. + } +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h new file mode 100644 index 00000000000..5860ecc8a77 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h @@ -0,0 +1,291 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Abstract interface for objects solving linear systems of various +// kinds. + +#ifndef CERES_INTERNAL_LINEAR_SOLVER_H_ +#define CERES_INTERNAL_LINEAR_SOLVER_H_ + +#include + +#include +#include "ceres/block_sparse_matrix.h" +#include "ceres/casts.h" +#include "ceres/compressed_row_sparse_matrix.h" +#include "ceres/dense_sparse_matrix.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +class LinearOperator; + +// Abstract base class for objects that implement algorithms for +// solving linear systems +// +// Ax = b +// +// It is expected that a single instance of a LinearSolver object +// maybe used multiple times for solving different linear +// systems. This allows them to cache and reuse information across +// solves if for example the sparsity of the linear system remains +// constant. +// +// Subclasses of LinearSolver use two structs to configure themselves. +// The Options struct configures the LinearSolver object for its +// lifetime. The PerSolveOptions struct is used to specify options for +// a particular Solve call. +class LinearSolver { + public: + struct Options { + Options() + : type(SPARSE_NORMAL_CHOLESKY), + preconditioner_type(JACOBI), + min_num_iterations(1), + max_num_iterations(1), + num_threads(1), + constant_sparsity(false), + num_eliminate_blocks(0), + residual_reset_period(10), + row_block_size(Dynamic), + e_block_size(Dynamic), + f_block_size(Dynamic) { + } + + LinearSolverType type; + + PreconditionerType preconditioner_type; + + // Number of internal iterations that the solver uses. This + // parameter only makes sense for iterative solvers like CG. + int min_num_iterations; + int max_num_iterations; + + // If possible, how many threads can the solver use. + int num_threads; + + // If possible cache and reuse the symbolic factorization across + // multiple calls. + bool constant_sparsity; + + // Eliminate 0 to num_eliminate_blocks - 1 from the Normal + // equations to form a schur complement. Only used by the Schur + // complement based solver. The most common use for this parameter + // is in the case of structure from motion problems where we have + // camera blocks and point blocks. Then setting the + // num_eliminate_blocks to the number of points allows the solver + // to use the Schur complement trick. For more details see the + // description of this parameter in solver.h. + int num_eliminate_blocks; + + // Iterative solvers, e.g. Preconditioned Conjugate Gradients + // maintain a cheap estimate of the residual which may become + // inaccurate over time. Thus for non-zero values of this + // parameter, the solver can be told to recalculate the value of + // the residual using a |b - Ax| evaluation. + int residual_reset_period; + + // If the block sizes in a BlockSparseMatrix are fixed, then in + // some cases the Schur complement based solvers can detect and + // specialize on them. + // + // It is expected that these parameters are set programmatically + // rather than manually. + // + // Please see explicit_schur_complement_solver_impl.h for more + // details. + int row_block_size; + int e_block_size; + int f_block_size; + }; + + // Options for the Solve method. + struct PerSolveOptions { + PerSolveOptions() + : D(NULL), + preconditioner(NULL), + r_tolerance(0.0), + q_tolerance(0.0) { + } + + // This option only makes sense for unsymmetric linear solvers + // that can solve rectangular linear systems. + // + // Given a matrix A, an optional diagonal matrix D as a vector, + // and a vector b, the linear solver will solve for + // + // | A | x = | b | + // | D | | 0 | + // + // If D is null, then it is treated as zero, and the solver returns + // the solution to + // + // A x = b + // + // In either case, x is the vector that solves the following + // optimization problem. + // + // arg min_x ||Ax - b||^2 + ||Dx||^2 + // + // Here A is a matrix of size m x n, with full column rank. If A + // does not have full column rank, the results returned by the + // solver cannot be relied on. D, if it is not null is an array of + // size n. b is an array of size m and x is an array of size n. + double * D; + + // This option only makes sense for iterative solvers. + // + // In general the performance of an iterative linear solver + // depends on the condition number of the matrix A. For example + // the convergence rate of the conjugate gradients algorithm + // is proportional to the square root of the condition number. + // + // One particularly useful technique for improving the + // conditioning of a linear system is to precondition it. In its + // simplest form a preconditioner is a matrix M such that instead + // of solving Ax = b, we solve the linear system AM^{-1} y = b + // instead, where M is such that the condition number k(AM^{-1}) + // is smaller than the conditioner k(A). Given the solution to + // this system, x = M^{-1} y. The iterative solver takes care of + // the mechanics of solving the preconditioned system and + // returning the corrected solution x. The user only needs to + // supply a linear operator. + // + // A null preconditioner is equivalent to an identity matrix being + // used a preconditioner. + LinearOperator* preconditioner; + + + // The following tolerance related options only makes sense for + // iterative solvers. Direct solvers ignore them. + + // Solver terminates when + // + // |Ax - b| <= r_tolerance * |b|. + // + // This is the most commonly used termination criterion for + // iterative solvers. + double r_tolerance; + + // For PSD matrices A, let + // + // Q(x) = x'Ax - 2b'x + // + // be the cost of the quadratic function defined by A and b. Then, + // the solver terminates at iteration i if + // + // i * (Q(x_i) - Q(x_i-1)) / Q(x_i) < q_tolerance. + // + // This termination criterion is more useful when using CG to + // solve the Newton step. This particular convergence test comes + // from Stephen Nash's work on truncated Newton + // methods. References: + // + // 1. Stephen G. Nash & Ariela Sofer, Assessing A Search + // Direction Within A Truncated Newton Method, Operation + // Research Letters 9(1990) 219-221. + // + // 2. Stephen G. Nash, A Survey of Truncated Newton Methods, + // Journal of Computational and Applied Mathematics, + // 124(1-2), 45-59, 2000. + // + double q_tolerance; + }; + + // Summary of a call to the Solve method. We should move away from + // the true/false method for determining solver success. We should + // let the summary object do the talking. + struct Summary { + Summary() + : residual_norm(0.0), + num_iterations(-1), + termination_type(FAILURE) { + } + + double residual_norm; + int num_iterations; + LinearSolverTerminationType termination_type; + }; + + virtual ~LinearSolver(); + + // Solve Ax = b. + virtual Summary Solve(LinearOperator* A, + const double* b, + const PerSolveOptions& per_solve_options, + double* x) = 0; + + static LinearSolver* Create(const Options& options); +}; + +// This templated subclass of LinearSolver serves as a base class for +// other linear solvers that depend on the particular matrix layout of +// the underlying linear operator. For example some linear solvers +// need low level access to the TripletSparseMatrix implementing the +// LinearOperator interface. This class hides those implementation +// details behind a private virtual method, and has the Solve method +// perform the necessary upcasting. +template +class TypedLinearSolver : public LinearSolver { + public: + virtual ~TypedLinearSolver() {} + virtual LinearSolver::Summary Solve( + LinearOperator* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double* x) { + CHECK_NOTNULL(A); + CHECK_NOTNULL(b); + CHECK_NOTNULL(x); + return SolveImpl(down_cast(A), b, per_solve_options, x); + } + + private: + virtual LinearSolver::Summary SolveImpl( + MatrixType* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double* x) = 0; +}; + +// Linear solvers that depend on acccess to the low level structure of +// a SparseMatrix. +typedef TypedLinearSolver BlockSparseMatrixSolver; // NOLINT +typedef TypedLinearSolver BlockSparseMatrixBaseSolver; // NOLINT +typedef TypedLinearSolver CompressedRowSparseMatrixSolver; // NOLINT +typedef TypedLinearSolver DenseSparseMatrixSolver; // NOLINT +typedef TypedLinearSolver TripletSparseMatrixSolver; // NOLINT + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_LINEAR_SOLVER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/local_parameterization.cc b/extern/libmv/third_party/ceres/internal/ceres/local_parameterization.cc new file mode 100644 index 00000000000..eeae74e3f95 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/local_parameterization.cc @@ -0,0 +1,140 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include +#include "ceres/internal/eigen.h" +#include "ceres/local_parameterization.h" +#include "ceres/rotation.h" + +namespace ceres { + +IdentityParameterization::IdentityParameterization(const int size) + : size_(size) { + CHECK_GT(size, 0); +} + +bool IdentityParameterization::Plus(const double* x, + const double* delta, + double* x_plus_delta) const { + VectorRef(x_plus_delta, size_) = + ConstVectorRef(x, size_) + ConstVectorRef(delta, size_); + return true; +} + +bool IdentityParameterization::ComputeJacobian(const double* x, + double* jacobian) const { + MatrixRef(jacobian, size_, size_) = Matrix::Identity(size_, size_); + return true; +} + +SubsetParameterization::SubsetParameterization( + int size, + const vector& constant_parameters) + : local_size_(size - constant_parameters.size()), + constancy_mask_(size, 0) { + CHECK_GT(constant_parameters.size(), 0) + << "The set of constant parameters should contain at least " + << "one element. If you do not wish to hold any parameters " + << "constant, then do not use a SubsetParameterization"; + + vector constant = constant_parameters; + sort(constant.begin(), constant.end()); + CHECK(unique(constant.begin(), constant.end()) == constant.end()) + << "The set of constant parameters cannot contain duplicates"; + CHECK_LT(constant_parameters.size(), size) + << "Number of parameters held constant should be less " + << "than the size of the parameter block. If you wish " + << "to hold the entire parameter block constant, then a " + << "efficient way is to directly mark it as constant " + << "instead of using a LocalParameterization to do so."; + CHECK_GE(*min_element(constant.begin(), constant.end()), 0); + CHECK_LT(*max_element(constant.begin(), constant.end()), size); + + for (int i = 0; i < constant_parameters.size(); ++i) { + constancy_mask_[constant_parameters[i]] = 1; + } +} + +bool SubsetParameterization::Plus(const double* x, + const double* delta, + double* x_plus_delta) const { + for (int i = 0, j = 0; i < constancy_mask_.size(); ++i) { + if (constancy_mask_[i]) { + x_plus_delta[i] = x[i]; + } else { + x_plus_delta[i] = x[i] + delta[j++]; + } + } + return true; +} + +bool SubsetParameterization::ComputeJacobian(const double* x, + double* jacobian) const { + MatrixRef m(jacobian, constancy_mask_.size(), local_size_); + m.setZero(); + for (int i = 0, j = 0; i < constancy_mask_.size(); ++i) { + if (!constancy_mask_[i]) { + m(i, j++) = 1.0; + } + } + return true; +} + +bool QuaternionParameterization::Plus(const double* x, + const double* delta, + double* x_plus_delta) const { + const double norm_delta = + sqrt(delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2]); + if (norm_delta > 0.0) { + const double sin_delta_by_delta = (sin(norm_delta) / norm_delta); + double q_delta[4]; + q_delta[0] = cos(norm_delta); + q_delta[1] = sin_delta_by_delta * delta[0]; + q_delta[2] = sin_delta_by_delta * delta[1]; + q_delta[3] = sin_delta_by_delta * delta[2]; + QuaternionProduct(q_delta, x, x_plus_delta); + } else { + for (int i = 0; i < 4; ++i) { + x_plus_delta[i] = x[i]; + } + } + return true; +} + +bool QuaternionParameterization::ComputeJacobian(const double* x, + double* jacobian) const { + jacobian[0] = -x[1]; jacobian[1] = -x[2]; jacobian[2] = -x[3]; // NOLINT + jacobian[3] = x[0]; jacobian[4] = x[3]; jacobian[5] = -x[2]; // NOLINT + jacobian[6] = -x[3]; jacobian[7] = x[0]; jacobian[8] = x[1]; // NOLINT + jacobian[9] = x[2]; jacobian[10] = -x[1]; jacobian[11] = x[0]; // NOLINT + return true; +} + +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/loss_function.cc b/extern/libmv/third_party/ceres/internal/ceres/loss_function.cc new file mode 100644 index 00000000000..00b2b184729 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/loss_function.cc @@ -0,0 +1,93 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Purpose: See .h file. + +#include "ceres/loss_function.h" + +#include +#include + +namespace ceres { + +void TrivialLoss::Evaluate(double s, double rho[3]) const { + rho[0] = s; + rho[1] = 1; + rho[2] = 0; +} + +void HuberLoss::Evaluate(double s, double rho[3]) const { + if (s > b_) { + // Outlier region. + // 'r' is always positive. + const double r = sqrt(s); + rho[0] = 2 * a_ * r - b_; + rho[1] = a_ / r; + rho[2] = - rho[1] / (2 * s); + } else { + // Inlier region. + rho[0] = s; + rho[1] = 1; + rho[2] = 0; + } +} + +void SoftLOneLoss::Evaluate(double s, double rho[3]) const { + const double sum = 1 + s * c_; + const double tmp = sqrt(sum); + // 'sum' and 'tmp' are always positive, assuming that 's' is. + rho[0] = 2 * b_ * (tmp - 1); + rho[1] = 1 / tmp; + rho[2] = - (c_ * rho[1]) / (2 * sum); +} + +void CauchyLoss::Evaluate(double s, double rho[3]) const { + const double sum = 1 + s * c_; + const double inv = 1 / sum; + // 'sum' and 'inv' are always positive, assuming that 's' is. + rho[0] = b_ * log(sum); + rho[1] = inv; + rho[2] = - c_ * (inv * inv); +} + +void ScaledLoss::Evaluate(double s, double rho[3]) const { + if (rho_.get() == NULL) { + rho[0] = a_ * s; + rho[1] = a_; + rho[2] = 0.0; + } else { + rho_->Evaluate(s, rho); + rho[0] *= a_; + rho[1] *= a_; + rho[2] *= a_; + } +} + +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/map_util.h b/extern/libmv/third_party/ceres/internal/ceres/map_util.h new file mode 100644 index 00000000000..ddf1252f674 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/map_util.h @@ -0,0 +1,129 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// Originally by Anton Carver + +#ifndef CERES_INTERNAL_MAP_UTIL_H_ +#define CERES_INTERNAL_MAP_UTIL_H_ + +#include +#include "ceres/internal/port.h" + +namespace ceres { + +// Perform a lookup in a map or hash_map, assuming that the key exists. +// Crash if it does not. +// +// This is intended as a replacement for operator[] as an rvalue (for reading) +// when the key is guaranteed to exist. +// +// operator[] is discouraged for several reasons: +// * It has a side-effect of inserting missing keys +// * It is not thread-safe (even when it is not inserting, it can still +// choose to resize the underlying storage) +// * It invalidates iterators (when it chooses to resize) +// * It default constructs a value object even if it doesn't need to +// +// This version assumes the key is printable, and includes it in the fatal log +// message. +template +const typename Collection::value_type::second_type& +FindOrDie(const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + CHECK(it != collection.end()) << "Map key not found: " << key; + return it->second; +} + +// Perform a lookup in a map or hash_map. +// If the key is present in the map then the value associated with that +// key is returned, otherwise the value passed as a default is returned. +template +const typename Collection::value_type::second_type& +FindWithDefault(const Collection& collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& value) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return value; + } + return it->second; +} + +// Insert a new key and value into a map or hash_map. +// If the key is not present in the map the key and value are +// inserted, otherwise nothing happens. True indicates that an insert +// took place, false indicates the key was already present. +template +bool InsertIfNotPresent( + Collection * const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& value) { + pair ret = + collection->insert(typename Collection::value_type(key, value)); + return ret.second; +} + +// Perform a lookup in a map or hash_map. +// Same as above but the returned pointer is not const and can be used to change +// the stored value. +template +typename Collection::value_type::second_type* +FindOrNull(Collection& collection, // NOLINT + const typename Collection::value_type::first_type& key) { + typename Collection::iterator it = collection.find(key); + if (it == collection.end()) { + return 0; + } + return &it->second; +} + +// Test to see if a set, map, hash_set or hash_map contains a particular key. +// Returns true if the key is in the collection. +template +bool ContainsKey(const Collection& collection, const Key& key) { + typename Collection::const_iterator it = collection.find(key); + return it != collection.end(); +} + +// Inserts a new key/value into a map or hash_map. +// Dies if the key is already present. +template +void InsertOrDie(Collection* const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& data) { + typedef typename Collection::value_type value_type; + CHECK(collection->insert(value_type(key, data)).second) + << "duplicate key: " << key; +} + +} // namespace ceres + +#endif // CERES_INTERNAL_MAP_UTIL_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/matrix_proto.h b/extern/libmv/third_party/ceres/internal/ceres/matrix_proto.h new file mode 100644 index 00000000000..b8a3a1a6de6 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/matrix_proto.h @@ -0,0 +1,40 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// A portability header to make optional protocol buffer support less intrusive. + +#ifndef CERES_INTERNAL_MATRIX_PROTO_H_ +#define CERES_INTERNAL_MATRIX_PROTO_H_ + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +#include "ceres/matrix.pb.h" +#endif + +#endif // CERES_INTERNAL_MATRIX_PROTO_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/minimizer.h b/extern/libmv/third_party/ceres/internal/ceres/minimizer.h new file mode 100644 index 00000000000..71163a8ea6f --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/minimizer.h @@ -0,0 +1,102 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_MINIMIZER_H_ +#define CERES_INTERNAL_MINIMIZER_H_ + +#include +#include "ceres/solver.h" +#include "ceres/iteration_callback.h" + +namespace ceres { +namespace internal { + +class Evaluator; +class LinearSolver; + +// Interface for non-linear least squares solvers. +class Minimizer { + public: + // Options struct to control the behaviour of the Minimizer. Please + // see solver.h for detailed information about the meaning and + // default values of each of these parameters. + struct Options { + explicit Options(const Solver::Options& options) { + max_num_iterations = options.max_num_iterations; + max_solver_time_sec = options.max_solver_time_sec; + gradient_tolerance = options.gradient_tolerance; + parameter_tolerance = options.parameter_tolerance; + function_tolerance = options.function_tolerance; + min_relative_decrease = options.min_relative_decrease; + eta = options.eta; + tau = options.tau; + jacobi_scaling = options.jacobi_scaling; + crash_and_dump_lsqp_on_failure = options.crash_and_dump_lsqp_on_failure; + lsqp_dump_format = options.lsqp_dump_format; + lsqp_iterations_to_dump = options.lsqp_iterations_to_dump; + num_eliminate_blocks = options.num_eliminate_blocks; + logging_type = options.logging_type; + } + + int max_num_iterations; + int max_solver_time_sec; + double gradient_tolerance; + double parameter_tolerance; + double function_tolerance; + double min_relative_decrease; + double eta; + double tau; + bool jacobi_scaling; + bool crash_and_dump_lsqp_on_failure; + string lsqp_dump_format; + vector lsqp_iterations_to_dump; + int num_eliminate_blocks; + LoggingType logging_type; + + // List of callbacks that are executed by the Minimizer at the end + // of each iteration. + // + // Client owns these pointers. + vector callbacks; + }; + + virtual ~Minimizer() {} + virtual void Minimize(const Options& options, + Evaluator* evaluator, + LinearSolver* linear_solver, + const double* initial_parameters, + double* final_parameters, + Solver::Summary* summary) = 0; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_MINIMIZER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/mutex.h b/extern/libmv/third_party/ceres/internal/ceres/mutex.h new file mode 100644 index 00000000000..6514b107041 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/mutex.h @@ -0,0 +1,312 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: Craig Silverstein. +// +// A simple mutex wrapper, supporting locks and read-write locks. +// You should assume the locks are *not* re-entrant. +// +// This class is meant to be internal-only and should be wrapped by an +// internal namespace. Before you use this module, please give the +// name of your internal namespace for this module. Or, if you want +// to expose it, you'll want to move it to the Google namespace. We +// cannot put this class in global namespace because there can be some +// problems when we have multiple versions of Mutex in each shared object. +// +// NOTE: by default, we have #ifdef'ed out the TryLock() method. +// This is for two reasons: +// 1) TryLock() under Windows is a bit annoying (it requires a +// #define to be defined very early). +// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG +// mode. +// If you need TryLock(), and either these two caveats are not a +// problem for you, or you're willing to work around them, then +// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs +// in the code below. +// +// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy: +// http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html +// Because of that, we might as well use windows locks for +// cygwin. They seem to be more reliable than the cygwin pthreads layer. +// +// TRICKY IMPLEMENTATION NOTE: +// This class is designed to be safe to use during +// dynamic-initialization -- that is, by global constructors that are +// run before main() starts. The issue in this case is that +// dynamic-initialization happens in an unpredictable order, and it +// could be that someone else's dynamic initializer could call a +// function that tries to acquire this mutex -- but that all happens +// before this mutex's constructor has run. (This can happen even if +// the mutex and the function that uses the mutex are in the same .cc +// file.) Basically, because Mutex does non-trivial work in its +// constructor, it's not, in the naive implementation, safe to use +// before dynamic initialization has run on it. +// +// The solution used here is to pair the actual mutex primitive with a +// bool that is set to true when the mutex is dynamically initialized. +// (Before that it's false.) Then we modify all mutex routines to +// look at the bool, and not try to lock/unlock until the bool makes +// it to true (which happens after the Mutex constructor has run.) +// +// This works because before main() starts -- particularly, during +// dynamic initialization -- there are no threads, so a) it's ok that +// the mutex operations are a no-op, since we don't need locking then +// anyway; and b) we can be quite confident our bool won't change +// state between a call to Lock() and a call to Unlock() (that would +// require a global constructor in one translation unit to call Lock() +// and another global constructor in another translation unit to call +// Unlock() later, which is pretty perverse). +// +// That said, it's tricky, and can conceivably fail; it's safest to +// avoid trying to acquire a mutex in a global constructor, if you +// can. One way it can fail is that a really smart compiler might +// initialize the bool to true at static-initialization time (too +// early) rather than at dynamic-initialization time. To discourage +// that, we set is_safe_ to true in code (not the constructor +// colon-initializer) and set it to true via a function that always +// evaluates to true, but that the compiler can't know always +// evaluates to true. This should be good enough. + +#ifndef CERES_INTERNAL_MUTEX_H_ +#define CERES_INTERNAL_MUTEX_H_ + +#if defined(NO_THREADS) + typedef int MutexType; // to keep a lock-count +#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) +# define WIN32_LEAN_AND_MEAN // We only need minimal includes +# ifdef GMUTEX_TRYLOCK + // We need Windows NT or later for TryEnterCriticalSection(). If you + // don't need that functionality, you can remove these _WIN32_WINNT + // lines, and change TryLock() to assert(0) or something. +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +# endif +# endif +// To avoid macro definition of ERROR. +# define NOGDI +// To avoid macro definition of min/max. +# define NOMINMAX +# include + typedef CRITICAL_SECTION MutexType; +#elif defined(CERES_HAVE_PTHREAD) && defined(CERES_HAVE_RWLOCK) + // Needed for pthread_rwlock_*. If it causes problems, you could take it + // out, but then you'd have to unset CERES_HAVE_RWLOCK (at least on linux -- + // it *does* cause problems for FreeBSD, or MacOSX, but isn't needed for + // locking there.) +# if defined(__linux__) && !defined(_XOPEN_SOURCE) +# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls +# endif +# include + typedef pthread_rwlock_t MutexType; +#elif defined(CERES_HAVE_PTHREAD) +# include + typedef pthread_mutex_t MutexType; +#else +# error Need to implement mutex.h for your architecture, or #define NO_THREADS +#endif + +// We need to include these header files after defining _XOPEN_SOURCE +// as they may define the _XOPEN_SOURCE macro. +#include +#include // for abort() + +namespace ceres { +namespace internal { + +class Mutex { + public: + // Create a Mutex that is not held by anybody. This constructor is + // typically used for Mutexes allocated on the heap or the stack. + // See below for a recommendation for constructing global Mutex + // objects. + inline Mutex(); + + // Destructor + inline ~Mutex(); + + inline void Lock(); // Block if needed until free then acquire exclusively + inline void Unlock(); // Release a lock acquired via Lock() +#ifdef GMUTEX_TRYLOCK + inline bool TryLock(); // If free, Lock() and return true, else return false +#endif + // Note that on systems that don't support read-write locks, these may + // be implemented as synonyms to Lock() and Unlock(). So you can use + // these for efficiency, but don't use them anyplace where being able + // to do shared reads is necessary to avoid deadlock. + inline void ReaderLock(); // Block until free or shared then acquire a share + inline void ReaderUnlock(); // Release a read share of this Mutex + inline void WriterLock() { Lock(); } // Acquire an exclusive lock + inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock() + + // TODO(hamaji): Do nothing, implement correctly. + inline void AssertHeld() {} + + private: + MutexType mutex_; + // We want to make sure that the compiler sets is_safe_ to true only + // when we tell it to, and never makes assumptions is_safe_ is + // always true. volatile is the most reliable way to do that. + volatile bool is_safe_; + + inline void SetIsSafe() { is_safe_ = true; } + + // Catch the error of writing Mutex when intending MutexLock. + Mutex(Mutex* /*ignored*/) {} + // Disallow "evil" constructors + Mutex(const Mutex&); + void operator=(const Mutex&); +}; + +// Now the implementation of Mutex for various systems +#if defined(NO_THREADS) + +// When we don't have threads, we can be either reading or writing, +// but not both. We can have lots of readers at once (in no-threads +// mode, that's most likely to happen in recursive function calls), +// but only one writer. We represent this by having mutex_ be -1 when +// writing and a number > 0 when reading (and 0 when no lock is held). +// +// In debug mode, we assert these invariants, while in non-debug mode +// we do nothing, for efficiency. That's why everything is in an +// assert. + +Mutex::Mutex() : mutex_(0) { } +Mutex::~Mutex() { assert(mutex_ == 0); } +void Mutex::Lock() { assert(--mutex_ == -1); } +void Mutex::Unlock() { assert(mutex_++ == -1); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; } +#endif +void Mutex::ReaderLock() { assert(++mutex_ > 0); } +void Mutex::ReaderUnlock() { assert(mutex_-- > 0); } + +#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) + +Mutex::Mutex() { InitializeCriticalSection(&mutex_); SetIsSafe(); } +Mutex::~Mutex() { DeleteCriticalSection(&mutex_); } +void Mutex::Lock() { if (is_safe_) EnterCriticalSection(&mutex_); } +void Mutex::Unlock() { if (is_safe_) LeaveCriticalSection(&mutex_); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { return is_safe_ ? + TryEnterCriticalSection(&mutex_) != 0 : true; } +#endif +void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks +void Mutex::ReaderUnlock() { Unlock(); } + +#elif defined(CERES_HAVE_PTHREAD) && defined(CERES_HAVE_RWLOCK) + +#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ + if (is_safe_ && fncall(&mutex_) != 0) abort(); \ +} while (0) + +Mutex::Mutex() { + SetIsSafe(); + if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort(); +} +Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); } +void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); } +void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { return is_safe_ ? + pthread_rwlock_trywrlock(&mutex_) == 0 : + true; } +#endif +void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); } +void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } +#undef SAFE_PTHREAD + +#elif defined(CERES_HAVE_PTHREAD) + +#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ + if (is_safe_ && fncall(&mutex_) != 0) abort(); \ +} while (0) + +Mutex::Mutex() { + SetIsSafe(); + if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort(); +} +Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); } +void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); } +void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { return is_safe_ ? + pthread_mutex_trylock(&mutex_) == 0 : true; } +#endif +void Mutex::ReaderLock() { Lock(); } +void Mutex::ReaderUnlock() { Unlock(); } +#undef SAFE_PTHREAD + +#endif + +// -------------------------------------------------------------------------- +// Some helper classes + +// MutexLock(mu) acquires mu when constructed and releases it when destroyed. +class MutexLock { + public: + explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); } + ~MutexLock() { mu_->Unlock(); } + private: + Mutex * const mu_; + // Disallow "evil" constructors + MutexLock(const MutexLock&); + void operator=(const MutexLock&); +}; + +// ReaderMutexLock and WriterMutexLock do the same, for rwlocks +class ReaderMutexLock { + public: + explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); } + ~ReaderMutexLock() { mu_->ReaderUnlock(); } + private: + Mutex * const mu_; + // Disallow "evil" constructors + ReaderMutexLock(const ReaderMutexLock&); + void operator=(const ReaderMutexLock&); +}; + +class WriterMutexLock { + public: + explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); } + ~WriterMutexLock() { mu_->WriterUnlock(); } + private: + Mutex * const mu_; + // Disallow "evil" constructors + WriterMutexLock(const WriterMutexLock&); + void operator=(const WriterMutexLock&); +}; + +// Catch bug where variable name is omitted, e.g. MutexLock (&mu); +#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name) +#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name) +#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name) + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_MUTEX_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/normal_prior.cc b/extern/libmv/third_party/ceres/internal/ceres/normal_prior.cc new file mode 100644 index 00000000000..f30bbc8b46b --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/normal_prior.cc @@ -0,0 +1,67 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/normal_prior.h" + +#include +#include + +#include +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { + +NormalPrior::NormalPrior(const Matrix& A, const Vector& b) + : A_(A), b_(b) { + CHECK_GT(b_.rows(), 0); + CHECK_GT(A_.rows(), 0); + CHECK_EQ(b_.rows(), A.cols()); + set_num_residuals(A_.rows()); + mutable_parameter_block_sizes()->push_back(b_.rows()); +} + +bool NormalPrior::Evaluate(double const* const* parameters, + double* residuals, + double** jacobians) const { + ConstVectorRef p(parameters[0], parameter_block_sizes()[0]); + VectorRef r(residuals, num_residuals()); + // The following line should read + // r = A_ * (p - b_); + // The extra eval is to get around a bug in the eigen library. + r = A_ * (p - b_).eval(); + if ((jacobians != NULL) && (jacobians[0] != NULL)) { + MatrixRef(jacobians[0], num_residuals(), parameter_block_sizes()[0]) = A_; + } + return true; +} + +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/parameter_block.h b/extern/libmv/third_party/ceres/internal/ceres/parameter_block.h new file mode 100644 index 00000000000..4bac1a85828 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/parameter_block.h @@ -0,0 +1,256 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#ifndef CERES_INTERNAL_PARAMETER_BLOCK_H_ +#define CERES_INTERNAL_PARAMETER_BLOCK_H_ + +#include +#include "ceres/integral_types.h" +#include +#include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/local_parameterization.h" +#include "ceres/residual_block_utils.h" + +namespace ceres { +namespace internal { + +class ProblemImpl; + +// The parameter block encodes the location of the user's original value, and +// also the "current state" of the parameter. The evaluator uses whatever is in +// the current state of the parameter when evaluating. This is inlined since the +// methods are performance sensitive. +// +// The class is not thread-safe, unless only const methods are called. The +// parameter block may also hold a pointer to a local parameterization; the +// parameter block does not take ownership of this pointer, so the user is +// responsible for the proper disposal of the local parameterization. +class ParameterBlock { + public: + ParameterBlock(double* user_state, int size) { + Init(user_state, size, NULL); + } + ParameterBlock(double* user_state, + int size, + LocalParameterization* local_parameterization) { + Init(user_state, size, local_parameterization); + } + + // The size of the parameter block. + int Size() const { return size_; } + + // Manipulate the parameter state. + bool SetState(const double* x) { + CHECK(x != NULL) + << "Tried to set the state of constant parameter " + << "with user location " << user_state_; + CHECK(!is_constant_) + << "Tried to set the state of constant parameter " + << "with user location " << user_state_; + + state_ = x; + return UpdateLocalParameterizationJacobian(); + } + + // Copy the current parameter state out to x. This is "GetState()" rather than + // simply "state()" since it is actively copying the data into the passed + // pointer. + void GetState(double *x) const { + if (x != state_) { + memcpy(x, state_, sizeof(*state_) * size_); + } + } + + // Direct pointers to the current state. + const double* state() const { return state_; } + const double* user_state() const { return user_state_; } + double* mutable_user_state() { return user_state_; } + LocalParameterization* local_parameterization() const { + return local_parameterization_; + } + LocalParameterization* mutable_local_parameterization() { + return local_parameterization_; + } + + // Set this parameter block to vary or not. + void SetConstant() { is_constant_ = true; } + void SetVarying() { is_constant_ = false; } + bool IsConstant() const { return is_constant_; } + + // This parameter block's index in an array. + int index() const { return index_; } + void set_index(int index) { index_ = index; } + + // This parameter offset inside a larger state vector. + int state_offset() const { return state_offset_; } + void set_state_offset(int state_offset) { state_offset_ = state_offset; } + + // This parameter offset inside a larger delta vector. + int delta_offset() const { return delta_offset_; } + void set_delta_offset(int delta_offset) { delta_offset_ = delta_offset; } + + // Methods relating to the parameter block's parameterization. + + // The local to global jacobian. Returns NULL if there is no local + // parameterization for this parameter block. The returned matrix is row-major + // and has Size() rows and LocalSize() columns. + const double* LocalParameterizationJacobian() const { + return local_parameterization_jacobian_.get(); + } + + int LocalSize() const { + return (local_parameterization_ == NULL) + ? size_ + : local_parameterization_->LocalSize(); + } + + // Set the parameterization. The parameterization can be set exactly once; + // multiple calls to set the parameterization to different values will crash. + // It is an error to pass NULL for the parameterization. The parameter block + // does not take ownership of the parameterization. + void SetParameterization(LocalParameterization* new_parameterization) { + CHECK(new_parameterization != NULL) << "NULL parameterization invalid."; + CHECK(new_parameterization->GlobalSize() == size_) + << "Invalid parameterization for parameter block. The parameter block " + << "has size " << size_ << " while the parameterization has a global " + << "size of " << new_parameterization->GlobalSize() << ". Did you " + << "accidentally use the wrong parameter block or parameterization?"; + if (new_parameterization != local_parameterization_) { + CHECK(local_parameterization_ == NULL) + << "Can't re-set the local parameterization; it leads to " + << "ambiguous ownership."; + local_parameterization_ = new_parameterization; + local_parameterization_jacobian_.reset( + new double[local_parameterization_->GlobalSize() * + local_parameterization_->LocalSize()]); + CHECK(UpdateLocalParameterizationJacobian()) + "Local parameterization Jacobian computation failed" + "for x: " << ConstVectorRef(state_, Size()).transpose(); + } else { + // Ignore the case that the parameterizations match. + } + } + + // Generalization of the addition operation. This is the same as + // LocalParameterization::Plus() but uses the parameter's current state + // instead of operating on a passed in pointer. + bool Plus(const double *x, const double* delta, double* x_plus_delta) { + if (local_parameterization_ == NULL) { + VectorRef(x_plus_delta, size_) = ConstVectorRef(x, size_) + + ConstVectorRef(delta, size_); + return true; + } + return local_parameterization_->Plus(x, delta, x_plus_delta); + } + + private: + void Init(double* user_state, + int size, + LocalParameterization* local_parameterization) { + user_state_ = user_state; + size_ = size; + is_constant_ = false; + state_ = user_state_; + + local_parameterization_ = NULL; + if (local_parameterization != NULL) { + SetParameterization(local_parameterization); + } + + index_ = -1; + state_offset_ = -1; + delta_offset_ = -1; + } + + bool UpdateLocalParameterizationJacobian() { + if (local_parameterization_ == NULL) { + return true; + } + + // Update the local to global Jacobian. In some cases this is + // wasted effort; if this is a bottleneck, we will find a solution + // at that time. + + const int jacobian_size = Size() * LocalSize(); + InvalidateArray(jacobian_size, + local_parameterization_jacobian_.get()); + if (!local_parameterization_->ComputeJacobian( + state_, + local_parameterization_jacobian_.get())) { + LOG(WARNING) << "Local parameterization Jacobian computation failed" + "for x: " << ConstVectorRef(state_, Size()).transpose(); + return false; + } + + if (!IsArrayValid(jacobian_size, local_parameterization_jacobian_.get())) { + LOG(WARNING) << "Local parameterization Jacobian computation returned" + << "an invalid matrix for x: " + << ConstVectorRef(state_, Size()).transpose() + << "\n Jacobian matrix : " + << ConstMatrixRef(local_parameterization_jacobian_.get(), + Size(), + LocalSize()); + return false; + } + return true; + } + + double* user_state_; + int size_; + bool is_constant_; + LocalParameterization* local_parameterization_; + + // The "state" of the parameter. These fields are only needed while the + // solver is running. While at first glance using mutable is a bad idea, this + // ends up simplifying the internals of Ceres enough to justify the potential + // pitfalls of using "mutable." + mutable const double* state_; + mutable scoped_array local_parameterization_jacobian_; + + // The index of the parameter. This is used by various other parts of Ceres to + // permit switching from a ParameterBlock* to an index in another array. + int32 index_; + + // The offset of this parameter block inside a larger state vector. + int32 state_offset_; + + // The offset of this parameter block inside a larger delta vector. + int32 delta_offset_; + + // Necessary so ProblemImpl can clean up the parameterizations. + friend class ProblemImpl; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_PARAMETER_BLOCK_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.cc b/extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.cc new file mode 100644 index 00000000000..fcf8fd53aed --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.cc @@ -0,0 +1,315 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 10 + +#include "ceres/partitioned_matrix_view.h" + +#include +#include +#include +#include +#include "ceres/block_sparse_matrix.h" +#include "ceres/block_structure.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +PartitionedMatrixView::PartitionedMatrixView( + const BlockSparseMatrixBase& matrix, + int num_col_blocks_a) + : matrix_(matrix), + num_col_blocks_e_(num_col_blocks_a) { + const CompressedRowBlockStructure* bs = matrix_.block_structure(); + CHECK_NOTNULL(bs); + + num_col_blocks_f_ = bs->cols.size() - num_col_blocks_a; + + // Compute the number of row blocks in E. The number of row blocks + // in E maybe less than the number of row blocks in the input matrix + // as some of the row blocks at the bottom may not have any + // e_blocks. For a definition of what an e_block is, please see + // explicit_schur_complement_solver.h + num_row_blocks_e_ = 0; + for (int r = 0; r < bs->rows.size(); ++r) { + const vector& cells = bs->rows[r].cells; + if (cells[0].block_id < num_col_blocks_a) { + ++num_row_blocks_e_; + } + } + + // Compute the number of columns in E and F. + num_cols_e_ = 0; + num_cols_f_ = 0; + + for (int c = 0; c < bs->cols.size(); ++c) { + const Block& block = bs->cols[c]; + if (c < num_col_blocks_a) { + num_cols_e_ += block.size; + } else { + num_cols_f_ += block.size; + } + } + + CHECK_EQ(num_cols_e_ + num_cols_f_, matrix_.num_cols()); +} + +PartitionedMatrixView::~PartitionedMatrixView() { +} + +// The next four methods don't seem to be particularly cache +// friendly. This is an artifact of how the BlockStructure of the +// input matrix is constructed. These methods will benefit from +// multithreading as well as improved data layout. + +void PartitionedMatrixView::RightMultiplyE(const double* x, double* y) const { + const CompressedRowBlockStructure* bs = matrix_.block_structure(); + + // Iterate over the first num_row_blocks_e_ row blocks, and multiply + // by the first cell in each row block. + for (int r = 0; r < num_row_blocks_e_; ++r) { + const double* row_values = matrix_.RowBlockValues(r); + const Cell& cell = bs->rows[r].cells[0]; + const int row_block_pos = bs->rows[r].block.position; + const int row_block_size = bs->rows[r].block.size; + const int col_block_id = cell.block_id; + const int col_block_pos = bs->cols[col_block_id].position; + const int col_block_size = bs->cols[col_block_id].size; + + ConstVectorRef xref(x + col_block_pos, col_block_size); + VectorRef yref(y + row_block_pos, row_block_size); + ConstMatrixRef m(row_values + cell.position, + row_block_size, + col_block_size); + yref += m.lazyProduct(xref); + } +} + +void PartitionedMatrixView::RightMultiplyF(const double* x, double* y) const { + const CompressedRowBlockStructure* bs = matrix_.block_structure(); + + // Iterate over row blocks, and if the row block is in E, then + // multiply by all the cells except the first one which is of type + // E. If the row block is not in E (i.e its in the bottom + // num_row_blocks - num_row_blocks_e row blocks), then all the cells + // are of type F and multiply by them all. + for (int r = 0; r < bs->rows.size(); ++r) { + const int row_block_pos = bs->rows[r].block.position; + const int row_block_size = bs->rows[r].block.size; + VectorRef yref(y + row_block_pos, row_block_size); + const vector& cells = bs->rows[r].cells; + for (int c = (r < num_row_blocks_e_) ? 1 : 0; c < cells.size(); ++c) { + const double* row_values = matrix_.RowBlockValues(r); + const int col_block_id = cells[c].block_id; + const int col_block_pos = bs->cols[col_block_id].position; + const int col_block_size = bs->cols[col_block_id].size; + + ConstVectorRef xref(x + col_block_pos - num_cols_e(), + col_block_size); + ConstMatrixRef m(row_values + cells[c].position, + row_block_size, + col_block_size); + yref += m.lazyProduct(xref); + } + } +} + +void PartitionedMatrixView::LeftMultiplyE(const double* x, double* y) const { + const CompressedRowBlockStructure* bs = matrix_.block_structure(); + + // Iterate over the first num_row_blocks_e_ row blocks, and multiply + // by the first cell in each row block. + for (int r = 0; r < num_row_blocks_e_; ++r) { + const Cell& cell = bs->rows[r].cells[0]; + const double* row_values = matrix_.RowBlockValues(r); + const int row_block_pos = bs->rows[r].block.position; + const int row_block_size = bs->rows[r].block.size; + const int col_block_id = cell.block_id; + const int col_block_pos = bs->cols[col_block_id].position; + const int col_block_size = bs->cols[col_block_id].size; + + ConstVectorRef xref(x + row_block_pos, row_block_size); + VectorRef yref(y + col_block_pos, col_block_size); + ConstMatrixRef m(row_values + cell.position, + row_block_size, + col_block_size); + yref += m.transpose().lazyProduct(xref); + } +} + +void PartitionedMatrixView::LeftMultiplyF(const double* x, double* y) const { + const CompressedRowBlockStructure* bs = matrix_.block_structure(); + + // Iterate over row blocks, and if the row block is in E, then + // multiply by all the cells except the first one which is of type + // E. If the row block is not in E (i.e its in the bottom + // num_row_blocks - num_row_blocks_e row blocks), then all the cells + // are of type F and multiply by them all. + for (int r = 0; r < bs->rows.size(); ++r) { + const int row_block_pos = bs->rows[r].block.position; + const int row_block_size = bs->rows[r].block.size; + ConstVectorRef xref(x + row_block_pos, row_block_size); + const vector& cells = bs->rows[r].cells; + for (int c = (r < num_row_blocks_e_) ? 1 : 0; c < cells.size(); ++c) { + const double* row_values = matrix_.RowBlockValues(r); + const int col_block_id = cells[c].block_id; + const int col_block_pos = bs->cols[col_block_id].position; + const int col_block_size = bs->cols[col_block_id].size; + + VectorRef yref(y + col_block_pos - num_cols_e(), col_block_size); + ConstMatrixRef m(row_values + cells[c].position, + row_block_size, + col_block_size); + yref += m.transpose().lazyProduct(xref); + } + } +} + +// Given a range of columns blocks of a matrix m, compute the block +// structure of the block diagonal of the matrix m(:, +// start_col_block:end_col_block)'m(:, start_col_block:end_col_block) +// and return a BlockSparseMatrix with the this block structure. The +// caller owns the result. +BlockSparseMatrix* PartitionedMatrixView::CreateBlockDiagonalMatrixLayout( + int start_col_block, int end_col_block) const { + const CompressedRowBlockStructure* bs = matrix_.block_structure(); + CompressedRowBlockStructure* block_diagonal_structure = + new CompressedRowBlockStructure; + + int block_position = 0; + int diagonal_cell_position = 0; + + // Iterate over the column blocks, creating a new diagonal block for + // each column block. + for (int c = start_col_block; c < end_col_block; ++c) { + const Block& block = bs->cols[c]; + block_diagonal_structure->cols.push_back(Block()); + Block& diagonal_block = block_diagonal_structure->cols.back(); + diagonal_block.size = block.size; + diagonal_block.position = block_position; + + block_diagonal_structure->rows.push_back(CompressedRow()); + CompressedRow& row = block_diagonal_structure->rows.back(); + row.block = diagonal_block; + + row.cells.push_back(Cell()); + Cell& cell = row.cells.back(); + cell.block_id = c - start_col_block; + cell.position = diagonal_cell_position; + + block_position += block.size; + diagonal_cell_position += block.size * block.size; + } + + // Build a BlockSparseMatrix with the just computed block + // structure. + return new BlockSparseMatrix(block_diagonal_structure); +} + +BlockSparseMatrix* PartitionedMatrixView::CreateBlockDiagonalEtE() const { + BlockSparseMatrix* block_diagonal = + CreateBlockDiagonalMatrixLayout(0, num_col_blocks_e_); + UpdateBlockDiagonalEtE(block_diagonal); + return block_diagonal; +} + +BlockSparseMatrix* PartitionedMatrixView::CreateBlockDiagonalFtF() const { + BlockSparseMatrix* block_diagonal = + CreateBlockDiagonalMatrixLayout( + num_col_blocks_e_, num_col_blocks_e_ + num_col_blocks_f_); + UpdateBlockDiagonalFtF(block_diagonal); + return block_diagonal; +} + +// Similar to the code in RightMultiplyE, except instead of the matrix +// vector multiply its an outer product. +// +// block_diagonal = block_diagonal(E'E) +void PartitionedMatrixView::UpdateBlockDiagonalEtE( + BlockSparseMatrix* block_diagonal) const { + const CompressedRowBlockStructure* bs = matrix_.block_structure(); + const CompressedRowBlockStructure* block_diagonal_structure = + block_diagonal->block_structure(); + + block_diagonal->SetZero(); + + for (int r = 0; r < num_row_blocks_e_ ; ++r) { + const double* row_values = matrix_.RowBlockValues(r); + const Cell& cell = bs->rows[r].cells[0]; + const int row_block_size = bs->rows[r].block.size; + const int block_id = cell.block_id; + const int col_block_size = bs->cols[block_id].size; + ConstMatrixRef m(row_values + cell.position, + row_block_size, + col_block_size); + + const int cell_position = + block_diagonal_structure->rows[block_id].cells[0].position; + + MatrixRef(block_diagonal->mutable_values() + cell_position, + col_block_size, col_block_size).noalias() += m.transpose() * m; + } +} + +// Similar to the code in RightMultiplyF, except instead of the matrix +// vector multiply its an outer product. +// +// block_diagonal = block_diagonal(F'F) +// +void PartitionedMatrixView::UpdateBlockDiagonalFtF( + BlockSparseMatrix* block_diagonal) const { + const CompressedRowBlockStructure* bs = matrix_.block_structure(); + const CompressedRowBlockStructure* block_diagonal_structure = + block_diagonal->block_structure(); + + block_diagonal->SetZero(); + for (int r = 0; r < bs->rows.size(); ++r) { + const int row_block_size = bs->rows[r].block.size; + const vector& cells = bs->rows[r].cells; + const double* row_values = matrix_.RowBlockValues(r); + for (int c = (r < num_row_blocks_e_) ? 1 : 0; c < cells.size(); ++c) { + const int col_block_id = cells[c].block_id; + const int col_block_size = bs->cols[col_block_id].size; + ConstMatrixRef m(row_values + cells[c].position, + row_block_size, + col_block_size); + const int diagonal_block_id = col_block_id - num_col_blocks_e_; + const int cell_position = + block_diagonal_structure->rows[diagonal_block_id].cells[0].position; + + MatrixRef(block_diagonal->mutable_values() + cell_position, + col_block_size, col_block_size).noalias() += m.transpose() * m; + } + } +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.h b/extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.h new file mode 100644 index 00000000000..cfe4de5b436 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.h @@ -0,0 +1,121 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// For generalized bi-partite Jacobian matrices that arise in +// Structure from Motion related problems, it is sometimes useful to +// have access to the two parts of the matrix as linear operators +// themselves. This class provides that functionality. + +#ifndef CERES_INTERNAL_PARTITIONED_MATRIX_VIEW_H_ +#define CERES_INTERNAL_PARTITIONED_MATRIX_VIEW_H_ + +#include "ceres/block_sparse_matrix.h" + +namespace ceres { +namespace internal { + +// Given generalized bi-partite matrix A = [E F], with the same block +// structure as required by the Schur complement based solver, found +// in explicit_schur_complement_solver.h, provide access to the +// matrices E and F and their outer products E'E and F'F with +// themselves. +// +// Lack of BlockStructure object will result in a crash and if the +// block structure of the matrix does not satisfy the requirements of +// the Schur complement solver it will result in unpredictable and +// wrong output. +// +// This class lives in the internal name space as its a utility class +// to be used by the IterativeSchurComplementSolver class, found in +// iterative_schur_complement_solver.h, and is not meant for general +// consumption. +class PartitionedMatrixView { + public: + // matrix = [E F], where the matrix E contains the first + // num_col_blocks_a column blocks. + PartitionedMatrixView(const BlockSparseMatrixBase& matrix, + int num_col_blocks_a); + ~PartitionedMatrixView(); + + // y += E'x + void LeftMultiplyE(const double* x, double* y) const; + + // y += F'x + void LeftMultiplyF(const double* x, double* y) const; + + // y += Ex + void RightMultiplyE(const double* x, double* y) const; + + // y += Fx + void RightMultiplyF(const double* x, double* y) const; + + // Create and return the block diagonal of the matrix E'E. + BlockSparseMatrix* CreateBlockDiagonalEtE() const; + + // Create and return the block diagonal of the matrix F'F. + BlockSparseMatrix* CreateBlockDiagonalFtF() const; + + // Compute the block diagonal of the matrix E'E and store it in + // block_diagonal. The matrix block_diagonal is expected to have a + // BlockStructure (preferably created using + // CreateBlockDiagonalMatrixEtE) which is has the same structure as + // the block diagonal of E'E. + void UpdateBlockDiagonalEtE(BlockSparseMatrix* block_diagonal) const; + + // Compute the block diagonal of the matrix F'F and store it in + // block_diagonal. The matrix block_diagonal is expected to have a + // BlockStructure (preferably created using + // CreateBlockDiagonalMatrixFtF) which is has the same structure as + // the block diagonal of F'F. + void UpdateBlockDiagonalFtF(BlockSparseMatrix* block_diagonal) const; + + int num_col_blocks_e() const { return num_col_blocks_e_; } + int num_col_blocks_f() const { return num_col_blocks_f_; } + int num_cols_e() const { return num_cols_e_; } + int num_cols_f() const { return num_cols_f_; } + int num_rows() const { return matrix_.num_rows(); } + int num_cols() const { return matrix_.num_cols(); } + + private: + BlockSparseMatrix* CreateBlockDiagonalMatrixLayout(int start_col_block, + int end_col_block) const; + + const BlockSparseMatrixBase& matrix_; + int num_row_blocks_e_; + int num_col_blocks_e_; + int num_col_blocks_f_; + int num_cols_e_; + int num_cols_f_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_PARTITIONED_MATRIX_VIEW_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/problem.cc b/extern/libmv/third_party/ceres/internal/ceres/problem.cc new file mode 100644 index 00000000000..b8c25d9db84 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/problem.cc @@ -0,0 +1,149 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// keir@google.com (Keir Mierle) + +#include "ceres/problem.h" + +#include +#include "ceres/problem_impl.h" + +namespace ceres { + +class ResidualBlock; + +Problem::Problem() : problem_impl_(new internal::ProblemImpl) {} +Problem::Problem(const Problem::Options& options) + : problem_impl_(new internal::ProblemImpl(options)) {} +Problem::~Problem() {} + +ResidualBlockId Problem::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + const vector& parameter_blocks) { + return problem_impl_->AddResidualBlock(cost_function, + loss_function, + parameter_blocks); +} + +ResidualBlockId Problem::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0) { + return problem_impl_->AddResidualBlock(cost_function, + loss_function, + x0); +} + +ResidualBlockId Problem::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1) { + return problem_impl_->AddResidualBlock(cost_function, + loss_function, + x0, x1); +} + +ResidualBlockId Problem::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2) { + return problem_impl_->AddResidualBlock(cost_function, + loss_function, + x0, x1, x2); +} + +ResidualBlockId Problem::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, double* x3) { + return problem_impl_->AddResidualBlock(cost_function, + loss_function, + x0, x1, x2, x3); +} + +ResidualBlockId Problem::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, double* x3, double* x4) { + return problem_impl_->AddResidualBlock(cost_function, + loss_function, + x0, x1, x2, x3, x4); +} + +ResidualBlockId Problem::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, double* x3, double* x4, double* x5) { + return problem_impl_->AddResidualBlock(cost_function, + loss_function, + x0, x1, x2, x3, x4, x5); +} + +void Problem::AddParameterBlock(double* values, int size) { + problem_impl_->AddParameterBlock(values, size); +} + +void Problem::AddParameterBlock(double* values, + int size, + LocalParameterization* local_parameterization) { + problem_impl_->AddParameterBlock(values, size, local_parameterization); +} + +void Problem::SetParameterBlockConstant(double* values) { + problem_impl_->SetParameterBlockConstant(values); +} + +void Problem::SetParameterBlockVariable(double* values) { + problem_impl_->SetParameterBlockVariable(values); +} + +void Problem::SetParameterization( + double* values, + LocalParameterization* local_parameterization) { + problem_impl_->SetParameterization(values, local_parameterization); +} + +int Problem::NumParameterBlocks() const { + return problem_impl_->NumParameterBlocks(); +} + +int Problem::NumParameters() const { + return problem_impl_->NumParameters(); +} + +int Problem::NumResidualBlocks() const { + return problem_impl_->NumResidualBlocks(); +} + +int Problem::NumResiduals() const { + return problem_impl_->NumResiduals(); +} + +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc new file mode 100644 index 00000000000..68242477d6f --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc @@ -0,0 +1,359 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// keir@google.com (Keir Mierle) + +#include "ceres/problem_impl.h" + +#include +#include +#include +#include +#include +#include + +#include +#include "ceres/parameter_block.h" +#include "ceres/program.h" +#include "ceres/residual_block.h" +#include "ceres/stl_util.h" +#include "ceres/map_util.h" +#include "ceres/stringprintf.h" +#include "ceres/cost_function.h" +#include "ceres/loss_function.h" + +namespace ceres { +namespace internal { + +typedef map ParameterMap; + +// Returns true if two regions of memory, a and b, with sizes size_a and size_b +// respectively, overlap. +static bool RegionsAlias(const double* a, int size_a, + const double* b, int size_b) { + return (a < b) ? b < (a + size_a) + : a < (b + size_b); +} + +static void CheckForNoAliasing(double* existing_block, + int existing_block_size, + double* new_block, + int new_block_size) { + CHECK(!RegionsAlias(existing_block, existing_block_size, + new_block, new_block_size)) + << "Aliasing detected between existing parameter block at memory " + << "location " << existing_block + << " and has size " << existing_block_size << " with new parameter " + << "block that has memory adderss " << new_block << " and would have " + << "size " << new_block_size << "."; +} + +static ParameterBlock* InternalAddParameterBlock( + double* values, + int size, + ParameterMap* parameter_map, + vector* parameter_blocks) { + CHECK(values) << "Null pointer passed to AddParameterBlock for a parameter " + << "with size " << size; + + // Ignore the request if there is a block for the given pointer already. + ParameterMap::iterator it = parameter_map->find(values); + if (it != parameter_map->end()) { + int existing_size = it->second->Size(); + CHECK(size == existing_size) + << "Tried adding a parameter block with the same double pointer, " + << values << ", twice, but with different block sizes. Original " + << "size was " << existing_size << " but new size is " + << size; + return it->second; + } + // Before adding the parameter block, also check that it doesn't alias any + // other parameter blocks. + if (!parameter_map->empty()) { + ParameterMap::iterator lb = parameter_map->lower_bound(values); + + // If lb is not the first block, check the previous block for aliasing. + if (lb != parameter_map->begin()) { + ParameterMap::iterator previous = lb; + --previous; + CheckForNoAliasing(previous->first, + previous->second->Size(), + values, + size); + } + + // If lb is not off the end, check lb for aliasing. + if (lb != parameter_map->end()) { + CheckForNoAliasing(lb->first, + lb->second->Size(), + values, + size); + } + } + ParameterBlock* new_parameter_block = new ParameterBlock(values, size); + (*parameter_map)[values] = new_parameter_block; + parameter_blocks->push_back(new_parameter_block); + return new_parameter_block; +} + +ProblemImpl::ProblemImpl() : program_(new internal::Program) {} +ProblemImpl::ProblemImpl(const Problem::Options& options) + : options_(options), + program_(new internal::Program) {} + +ProblemImpl::~ProblemImpl() { + // Collect the unique cost/loss functions and delete the residuals. + set cost_functions; + set loss_functions; + for (int i = 0; i < program_->residual_blocks_.size(); ++i) { + ResidualBlock* residual_block = program_->residual_blocks_[i]; + + // The const casts here are legit, since ResidualBlock holds these + // pointers as const pointers but we have ownership of them and + // have the right to destroy them when the destructor is called. + if (options_.cost_function_ownership == TAKE_OWNERSHIP) { + cost_functions.insert( + const_cast(residual_block->cost_function())); + } + if (options_.loss_function_ownership == TAKE_OWNERSHIP) { + loss_functions.insert( + const_cast(residual_block->loss_function())); + } + + delete residual_block; + } + + // Collect the unique parameterizations and delete the parameters. + set local_parameterizations; + for (int i = 0; i < program_->parameter_blocks_.size(); ++i) { + ParameterBlock* parameter_block = program_->parameter_blocks_[i]; + + if (options_.local_parameterization_ownership == TAKE_OWNERSHIP) { + local_parameterizations.insert(parameter_block->local_parameterization_); + } + + delete parameter_block; + } + + // Delete the owned cost/loss functions and parameterizations. + STLDeleteContainerPointers(local_parameterizations.begin(), + local_parameterizations.end()); + STLDeleteContainerPointers(cost_functions.begin(), + cost_functions.end()); + STLDeleteContainerPointers(loss_functions.begin(), + loss_functions.end()); +} + +const ResidualBlock* ProblemImpl::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + const vector& parameter_blocks) { + CHECK_NOTNULL(cost_function); + CHECK_EQ(parameter_blocks.size(), + cost_function->parameter_block_sizes().size()); + + // Check the sizes match. + const vector& parameter_block_sizes = + cost_function->parameter_block_sizes(); + CHECK_EQ(parameter_block_sizes.size(), parameter_blocks.size()) + << "Number of blocks input is different than the number of blocks " + << "that the cost function expects."; + + // Check for duplicate parameter blocks. + vector sorted_parameter_blocks(parameter_blocks); + sort(sorted_parameter_blocks.begin(), sorted_parameter_blocks.end()); + vector::const_iterator duplicate_items = + unique(sorted_parameter_blocks.begin(), + sorted_parameter_blocks.end()); + if (duplicate_items != sorted_parameter_blocks.end()) { + string blocks; + for (int i = 0; i < parameter_blocks.size(); ++i) { + blocks += internal::StringPrintf(" %p ", parameter_blocks[i]); + } + + LOG(FATAL) << "Duplicate parameter blocks in a residual parameter " + << "are not allowed. Parameter block pointers: [" + << blocks << "]"; + } + + // Add parameter blocks and convert the double*'s to parameter blocks. + vector parameter_block_ptrs(parameter_blocks.size()); + for (int i = 0; i < parameter_blocks.size(); ++i) { + parameter_block_ptrs[i] = + InternalAddParameterBlock(parameter_blocks[i], + parameter_block_sizes[i], + ¶meter_block_map_, + &program_->parameter_blocks_); + } + + // Check that the block sizes match the block sizes expected by the + // cost_function. + for (int i = 0; i < parameter_block_ptrs.size(); ++i) { + CHECK_EQ(cost_function->parameter_block_sizes()[i], + parameter_block_ptrs[i]->Size()) + << "The cost function expects parameter block " << i + << " of size " << cost_function->parameter_block_sizes()[i] + << " but was given a block of size " + << parameter_block_ptrs[i]->Size(); + } + + ResidualBlock* new_residual_block = + new ResidualBlock(cost_function, + loss_function, + parameter_block_ptrs); + program_->residual_blocks_.push_back(new_residual_block); + return new_residual_block; +} + +// Unfortunately, macros don't help much to reduce this code, and var args don't +// work because of the ambiguous case that there is no loss function. +const ResidualBlock* ProblemImpl::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0) { + vector residual_parameters; + residual_parameters.push_back(x0); + return AddResidualBlock(cost_function, loss_function, residual_parameters); +} + +const ResidualBlock* ProblemImpl::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1) { + vector residual_parameters; + residual_parameters.push_back(x0); + residual_parameters.push_back(x1); + return AddResidualBlock(cost_function, loss_function, residual_parameters); +} + +const ResidualBlock* ProblemImpl::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2) { + vector residual_parameters; + residual_parameters.push_back(x0); + residual_parameters.push_back(x1); + residual_parameters.push_back(x2); + return AddResidualBlock(cost_function, loss_function, residual_parameters); +} + +const ResidualBlock* ProblemImpl::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, double* x3) { + vector residual_parameters; + residual_parameters.push_back(x0); + residual_parameters.push_back(x1); + residual_parameters.push_back(x2); + residual_parameters.push_back(x3); + return AddResidualBlock(cost_function, loss_function, residual_parameters); +} + +const ResidualBlock* ProblemImpl::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, double* x3, double* x4) { + vector residual_parameters; + residual_parameters.push_back(x0); + residual_parameters.push_back(x1); + residual_parameters.push_back(x2); + residual_parameters.push_back(x3); + residual_parameters.push_back(x4); + return AddResidualBlock(cost_function, loss_function, residual_parameters); +} + +const ResidualBlock* ProblemImpl::AddResidualBlock( + CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, double* x3, double* x4, double* x5) { + vector residual_parameters; + residual_parameters.push_back(x0); + residual_parameters.push_back(x1); + residual_parameters.push_back(x2); + residual_parameters.push_back(x3); + residual_parameters.push_back(x4); + residual_parameters.push_back(x5); + return AddResidualBlock(cost_function, loss_function, residual_parameters); +} + + +void ProblemImpl::AddParameterBlock(double* values, int size) { + InternalAddParameterBlock(values, + size, + ¶meter_block_map_, + &program_->parameter_blocks_); +} + +void ProblemImpl::AddParameterBlock( + double* values, + int size, + LocalParameterization* local_parameterization) { + ParameterBlock* parameter_block = + InternalAddParameterBlock(values, + size, + ¶meter_block_map_, + &program_->parameter_blocks_); + if (local_parameterization != NULL) { + parameter_block->SetParameterization(local_parameterization); + } +} + +void ProblemImpl::SetParameterBlockConstant(double* values) { + FindOrDie(parameter_block_map_, values)->SetConstant(); +} + +void ProblemImpl::SetParameterBlockVariable(double* values) { + FindOrDie(parameter_block_map_, values)->SetVarying(); +} + +void ProblemImpl::SetParameterization( + double* values, + LocalParameterization* local_parameterization) { + FindOrDie(parameter_block_map_, values) + ->SetParameterization(local_parameterization); +} + +int ProblemImpl::NumParameterBlocks() const { + return program_->NumParameterBlocks(); +} + +int ProblemImpl::NumParameters() const { + return program_->NumParameters(); +} + +int ProblemImpl::NumResidualBlocks() const { + return program_->NumResidualBlocks(); +} + +int ProblemImpl::NumResiduals() const { + return program_->NumResiduals(); +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.h b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.h new file mode 100644 index 00000000000..523860e652a --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.h @@ -0,0 +1,127 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// This is the implementation of the public Problem API. The pointer to +// implementation (PIMPL) idiom makes it possible for Ceres internal code to +// refer to the private data members without needing to exposing it to the +// world. An alternative to PIMPL is to have a factory which returns instances +// of a virtual base class; while that approach would work, it requires clients +// to always put a Problem object into a scoped pointer; this needlessly muddies +// client code for little benefit. Therefore, the PIMPL comprise was chosen. + +#ifndef CERES_PUBLIC_PROBLEM_IMPL_H_ +#define CERES_PUBLIC_PROBLEM_IMPL_H_ + +#include +#include + +#include "ceres/internal/macros.h" +#include "ceres/internal/port.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/problem.h" +#include "ceres/types.h" + +namespace ceres { + +class CostFunction; +class LossFunction; +class LocalParameterization; + +namespace internal { + +class Program; +class ResidualBlock; + +class ProblemImpl { + public: + typedef map ParameterMap; + + ProblemImpl(); + explicit ProblemImpl(const Problem::Options& options); + + ~ProblemImpl(); + + // See the public problem.h file for description of these methods. + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + const vector& parameter_blocks); + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0); + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1); + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2); + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, + double* x3); + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, + double* x3, double* x4); + ResidualBlockId AddResidualBlock(CostFunction* cost_function, + LossFunction* loss_function, + double* x0, double* x1, double* x2, + double* x3, double* x4, double* x5); + void AddParameterBlock(double* values, int size); + void AddParameterBlock(double* values, + int size, + LocalParameterization* local_parameterization); + void SetParameterBlockConstant(double* values); + void SetParameterBlockVariable(double* values); + void SetParameterization(double* values, + LocalParameterization* local_parameterization); + int NumParameterBlocks() const; + int NumParameters() const; + int NumResidualBlocks() const; + int NumResiduals() const; + + const Program& program() const { return *program_; } + Program* mutable_program() { return program_.get(); } + + const ParameterMap& parameter_map() const { return parameter_block_map_; } + + private: + const Problem::Options options_; + + // The mapping from user pointers to parameter blocks. + map parameter_block_map_; + + internal::scoped_ptr program_; + DISALLOW_COPY_AND_ASSIGN(ProblemImpl); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_PUBLIC_PROBLEM_IMPL_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/program.cc b/extern/libmv/third_party/ceres/internal/ceres/program.cc new file mode 100644 index 00000000000..444b1020253 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/program.cc @@ -0,0 +1,233 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include "ceres/program.h" + +#include +#include +#include "ceres/parameter_block.h" +#include "ceres/residual_block.h" +#include "ceres/stl_util.h" +#include "ceres/map_util.h" +#include "ceres/problem.h" +#include "ceres/cost_function.h" +#include "ceres/loss_function.h" +#include "ceres/local_parameterization.h" + +namespace ceres { +namespace internal { + +Program::Program() {} + +Program::Program(const Program& program) + : parameter_blocks_(program.parameter_blocks_), + residual_blocks_(program.residual_blocks_) { +} + +const vector& Program::parameter_blocks() const { + return parameter_blocks_; +} + +const vector& Program::residual_blocks() const { + return residual_blocks_; +} + +vector* Program::mutable_parameter_blocks() { + return ¶meter_blocks_; +} + +vector* Program::mutable_residual_blocks() { + return &residual_blocks_; +} + +bool Program::StateVectorToParameterBlocks(const double *state) { + for (int i = 0; i < parameter_blocks_.size(); ++i) { + if (!parameter_blocks_[i]->SetState(state)) { + return false; + } + state += parameter_blocks_[i]->Size(); + } + return true; +} + +void Program::ParameterBlocksToStateVector(double *state) const { + for (int i = 0; i < parameter_blocks_.size(); ++i) { + parameter_blocks_[i]->GetState(state); + state += parameter_blocks_[i]->Size(); + } +} + +void Program::CopyParameterBlockStateToUserState() { + for (int i = 0; i < parameter_blocks_.size(); ++i) { + parameter_blocks_[i]->GetState( + parameter_blocks_[i]->mutable_user_state()); + } +} + +bool Program::Plus(const double* state, + const double* delta, + double* state_plus_delta) const { + for (int i = 0; i < parameter_blocks_.size(); ++i) { + if (!parameter_blocks_[i]->Plus(state, delta, state_plus_delta)) { + return false; + } + state += parameter_blocks_[i]->Size(); + delta += parameter_blocks_[i]->LocalSize(); + state_plus_delta += parameter_blocks_[i]->Size(); + } + return true; +} + +void Program::SetParameterOffsetsAndIndex() { + // Set positions for all parameters appearing as arguments to residuals to one + // past the end of the parameter block array. + for (int i = 0; i < residual_blocks_.size(); ++i) { + ResidualBlock* residual_block = residual_blocks_[i]; + for (int j = 0; j < residual_block->NumParameterBlocks(); ++j) { + residual_block->parameter_blocks()[j]->set_index(-1); + } + } + // For parameters that appear in the program, set their position and offset. + int state_offset = 0; + int delta_offset = 0; + for (int i = 0; i < parameter_blocks_.size(); ++i) { + parameter_blocks_[i]->set_index(i); + parameter_blocks_[i]->set_state_offset(state_offset); + parameter_blocks_[i]->set_delta_offset(delta_offset); + state_offset += parameter_blocks_[i]->Size(); + delta_offset += parameter_blocks_[i]->LocalSize(); + } +} + +int Program::NumResidualBlocks() const { + return residual_blocks_.size(); +} + +int Program::NumParameterBlocks() const { + return parameter_blocks_.size(); +} + +int Program::NumResiduals() const { + int num_residuals = 0; + for (int i = 0; i < residual_blocks_.size(); ++i) { + num_residuals += residual_blocks_[i]->NumResiduals(); + } + return num_residuals; +} + +int Program::NumParameters() const { + int num_parameters = 0; + for (int i = 0; i < parameter_blocks_.size(); ++i) { + num_parameters += parameter_blocks_[i]->Size(); + } + return num_parameters; +} + +int Program::NumEffectiveParameters() const { + int num_parameters = 0; + for (int i = 0; i < parameter_blocks_.size(); ++i) { + num_parameters += parameter_blocks_[i]->LocalSize(); + } + return num_parameters; +} + +int Program::MaxScratchDoublesNeededForEvaluate() const { + // Compute the scratch space needed for evaluate. + int max_scratch_bytes_for_evaluate = 0; + for (int i = 0; i < residual_blocks_.size(); ++i) { + max_scratch_bytes_for_evaluate = + max(max_scratch_bytes_for_evaluate, + residual_blocks_[i]->NumScratchDoublesForEvaluate()); + } + return max_scratch_bytes_for_evaluate; +} + +int Program::MaxDerivativesPerResidualBlock() const { + int max_derivatives = 0; + for (int i = 0; i < residual_blocks_.size(); ++i) { + int derivatives = 0; + ResidualBlock* residual_block = residual_blocks_[i]; + int num_parameters = residual_block->NumParameterBlocks(); + for (int j = 0; j < num_parameters; ++j) { + derivatives += residual_block->NumResiduals() * + residual_block->parameter_blocks()[j]->LocalSize(); + } + max_derivatives = max(max_derivatives, derivatives); + } + return max_derivatives; +} + +int Program::MaxParametersPerResidualBlock() const { + int max_parameters = 0; + for (int i = 0; i < residual_blocks_.size(); ++i) { + max_parameters = max(max_parameters, + residual_blocks_[i]->NumParameterBlocks()); + } + return max_parameters; +} + +bool Program::Evaluate(double* cost, double* residuals) { + *cost = 0.0; + + // Scratch space is only needed if residuals is NULL. + scoped_array scratch; + if (residuals == NULL) { + scratch.reset(new double[MaxScratchDoublesNeededForEvaluate()]); + } else { + // TODO(keir): Is this needed? Check by removing the equivalent statement in + // dense_evaluator.cc and running the tests. + VectorRef(residuals, NumResiduals()).setZero(); + } + + for (int i = 0; i < residual_blocks_.size(); ++i) { + ResidualBlock* residual_block = residual_blocks_[i]; + + // Evaluate the cost function for this residual. + double residual_cost; + if (!residual_block->Evaluate(&residual_cost, + residuals, + NULL, // No jacobian. + scratch.get())) { + return false; + } + + // Accumulate residual cost into the total cost. + *cost += residual_cost; + + // Update the residuals cursor. + if (residuals != NULL) { + residuals += residual_block->NumResiduals(); + } + } + return true; +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/program.h b/extern/libmv/third_party/ceres/internal/ceres/program.h new file mode 100644 index 00000000000..113d352d562 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/program.h @@ -0,0 +1,128 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#ifndef CERES_INTERNAL_PROGRAM_H_ +#define CERES_INTERNAL_PROGRAM_H_ + +#include +#include "ceres/internal/port.h" + +namespace ceres { +namespace internal { + +class ParameterBlock; +class ProblemImpl; +class ResidualBlock; + +// A nonlinear least squares optimization problem. This is different from the +// similarly-named "Problem" object, which offers a mutation interface for +// adding and modifying parameters and residuals. The Program contains the core +// part of the Problem, which is the parameters and the residuals, stored in a +// particular ordering. The ordering is critical, since it defines the mapping +// between (residual, parameter) pairs and a position in the jacobian of the +// objective function. Various parts of Ceres transform one Program into +// another; for example, the first stage of solving involves stripping all +// constant parameters and residuals. This is in contrast with Problem, which is +// not built for transformation. +class Program { + public: + Program(); + explicit Program(const Program& program); + + // The ordered parameter and residual blocks for the program. + const vector& parameter_blocks() const; + const vector& residual_blocks() const; + vector* mutable_parameter_blocks(); + vector* mutable_residual_blocks(); + + // Serialize to/from the program and update states. + // + // NOTE: Setting the state of a parameter block can trigger the + // computation of the Jacobian of its local parameterization. If + // this computation fails for some reason, then this method returns + // false and the state of the parameter blocks cannot be trusted. + bool StateVectorToParameterBlocks(const double *state); + void ParameterBlocksToStateVector(double *state) const; + + // Copy internal state out to the user's parameters. + void CopyParameterBlockStateToUserState(); + + // Update a state vector for the program given a delta. + bool Plus(const double* state, + const double* delta, + double* state_plus_delta) const; + + // Set the parameter indices and offsets. This permits mapping backward + // from a ParameterBlock* to an index in the parameter_blocks() vector. For + // any parameter block p, after calling SetParameterOffsetsAndIndex(), it + // is true that + // + // parameter_blocks()[p->index()] == p + // + // If a parameter appears in a residual but not in the parameter block, then + // it will have an index of -1. + // + // This also updates p->state_offset() and p->delta_offset(), which are the + // position of the parameter in the state and delta vector respectively. + void SetParameterOffsetsAndIndex(); + + // See problem.h for what these do. + int NumParameterBlocks() const; + int NumParameters() const; + int NumEffectiveParameters() const; + int NumResidualBlocks() const; + int NumResiduals() const; + + int MaxScratchDoublesNeededForEvaluate() const; + int MaxDerivativesPerResidualBlock() const; + int MaxParametersPerResidualBlock() const; + + // Evaluate the cost and maybe the residuals for the program. If residuals is + // NULL, then residuals are not calculated. If the jacobian is needed, instead + // use the various evaluators (e.g. dense_evaluator.h). + // + // This is a trivial implementation of evaluate not intended for use in the + // core solving loop. The other evaluators, which support constructing the + // jacobian in addition to the cost and residuals, are considerably + // complicated by the need to construct the jacobian. + bool Evaluate(double* cost, double* residuals); + + private: + // The Program does not own the ParameterBlock or ResidualBlock objects. + vector parameter_blocks_; + vector residual_blocks_; + + friend class ProblemImpl; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_PROGRAM_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h b/extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h new file mode 100644 index 00000000000..7ec74b1b269 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h @@ -0,0 +1,279 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// The ProgramEvaluator runs the cost functions contained in each residual block +// and stores the result into a jacobian. The particular type of jacobian is +// abstracted out using two template parameters: +// +// - An "EvaluatePreparer" that is responsible for creating the array with +// pointers to the jacobian blocks where the cost function evaluates to. +// - A "JacobianWriter" that is responsible for storing the resulting +// jacobian blocks in the passed sparse matrix. +// +// This abstraction affords an efficient evaluator implementation while still +// supporting writing to multiple sparse matrix formats. For example, when the +// ProgramEvaluator is parameterized for writing to block sparse matrices, the +// residual jacobians are written directly into their final position in the +// block sparse matrix by the user's CostFunction; there is no copying. +// +// The evaluation is threaded with OpenMP. +// +// The EvaluatePreparer and JacobianWriter interfaces are as follows: +// +// class EvaluatePreparer { +// // Prepare the jacobians array for use as the destination of a call to +// // a cost function's evaluate method. +// void Prepare(const ResidualBlock* residual_block, +// int residual_block_index, +// SparseMatrix* jacobian, +// double** jacobians); +// } +// +// class JacobianWriter { +// // Create a jacobian that this writer can write. Same as +// // Evaluator::CreateJacobian. +// SparseMatrix* CreateJacobian() const; +// +// // Create num_threads evaluate preparers. Caller owns result which must +// // be freed with delete[]. Resulting preparers are valid while *this is. +// EvaluatePreparer* CreateEvaluatePreparers(int num_threads); +// +// // Write the block jacobians from a residual block evaluation to the +// // larger sparse jacobian. +// void Write(int residual_id, +// int residual_offset, +// double** jacobians, +// SparseMatrix* jacobian); +// } +// +// Note: The ProgramEvaluator is not thread safe, since internally it maintains +// some per-thread scratch space. + +#ifndef CERES_INTERNAL_PROGRAM_EVALUATOR_H_ +#define CERES_INTERNAL_PROGRAM_EVALUATOR_H_ + +#ifdef CERES_USE_OPENMP +#include +#endif + +#include "ceres/parameter_block.h" +#include "ceres/program.h" +#include "ceres/residual_block.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { + +template +class ProgramEvaluator : public Evaluator { + public: + ProgramEvaluator(const Evaluator::Options &options, Program* program) + : options_(options), + program_(program), + jacobian_writer_(options, program), + evaluate_preparers_( + jacobian_writer_.CreateEvaluatePreparers(options.num_threads)) { +#ifndef CERES_USE_OPENMP + CHECK_EQ(1, options_.num_threads) + << "OpenMP support is not compiled into this binary; " + << "only options.num_threads=1 is supported."; +#endif + + BuildResidualLayout(*program, &residual_layout_); + evaluate_scratch_.reset(CreateEvaluatorScratch(*program, + options.num_threads)); + } + + // Implementation of Evaluator interface. + SparseMatrix* CreateJacobian() const { + return jacobian_writer_.CreateJacobian(); + } + + bool Evaluate(const double* state, + double* cost, + double* residuals, + SparseMatrix* jacobian) { + // The parameters are stateful, so set the state before evaluating. + if (!program_->StateVectorToParameterBlocks(state)) { + return false; + } + + if (jacobian) { + jacobian->SetZero(); + } + + // Each thread gets it's own cost and evaluate scratch space. + for (int i = 0; i < options_.num_threads; ++i) { + evaluate_scratch_[i].cost = 0.0; + } + + // This bool is used to disable the loop if an error is encountered + // without breaking out of it. The remaining loop iterations are still run, + // but with an empty body, and so will finish quickly. + bool abort = false; + int num_residual_blocks = program_->NumResidualBlocks(); +#pragma omp parallel for num_threads(options_.num_threads) + for (int i = 0; i < num_residual_blocks; ++i) { +// Disable the loop instead of breaking, as required by OpenMP. +#pragma omp flush(abort) + if (abort) { + continue; + } + +#ifdef CERES_USE_OPENMP + int thread_id = omp_get_thread_num(); +#else + int thread_id = 0; +#endif + EvaluatePreparer* preparer = &evaluate_preparers_[thread_id]; + EvaluateScratch* scratch = &evaluate_scratch_[thread_id]; + + // Prepare block residuals if requested. + const ResidualBlock* residual_block = program_->residual_blocks()[i]; + double* block_residuals = (residuals != NULL) + ? (residuals + residual_layout_[i]) + : NULL; + + // Prepare block jacobians if requested. + double** block_jacobians = NULL; + if (jacobian != NULL) { + preparer->Prepare(residual_block, + i, + jacobian, + scratch->jacobian_block_ptrs.get()); + block_jacobians = scratch->jacobian_block_ptrs.get(); + } + + // Evaluate the cost, residuals, and jacobians. + double block_cost; + if (!residual_block->Evaluate(&block_cost, + block_residuals, + block_jacobians, + scratch->scratch.get())) { + abort = true; +// This ensures that the OpenMP threads have a consistent view of 'abort'. Do +// the flush inside the failure case so that there is usually only one +// synchronization point per loop iteration instead of two. +#pragma omp flush(abort) + continue; + } + + scratch->cost += block_cost; + + if (jacobian != NULL) { + jacobian_writer_.Write(i, + residual_layout_[i], + block_jacobians, + jacobian); + } + } + + if (!abort) { + // Sum the cost from each thread. + (*cost) = 0.0; + for (int i = 0; i < options_.num_threads; ++i) { + (*cost) += evaluate_scratch_[i].cost; + } + } + return !abort; + } + + bool Plus(const double* state, + const double* delta, + double* state_plus_delta) const { + return program_->Plus(state, delta, state_plus_delta); + } + + int NumParameters() const { + return program_->NumParameters(); + } + int NumEffectiveParameters() const { + return program_->NumEffectiveParameters(); + } + + int NumResiduals() const { + return program_->NumResiduals(); + } + + private: + struct EvaluateScratch { + void Init(int max_parameters_per_residual_block, + int max_scratch_doubles_needed_for_evaluate) { + jacobian_block_ptrs.reset( + new double*[max_parameters_per_residual_block]); + scratch.reset(new double[max_scratch_doubles_needed_for_evaluate]); + } + + double cost; + scoped_array scratch; + scoped_array jacobian_block_ptrs; + }; + + static void BuildResidualLayout(const Program& program, + vector* residual_layout) { + const vector& residual_blocks = program.residual_blocks(); + residual_layout->resize(program.NumResidualBlocks()); + int residual_pos = 0; + for (int i = 0; i < residual_blocks.size(); ++i) { + const int num_residuals = residual_blocks[i]->NumResiduals(); + (*residual_layout)[i] = residual_pos; + residual_pos += num_residuals; + } + } + + // Create scratch space for each thread evaluating the program. + static EvaluateScratch* CreateEvaluatorScratch(const Program& program, + int num_threads) { + int max_parameters_per_residual_block = + program.MaxParametersPerResidualBlock(); + int max_scratch_doubles_needed_for_evaluate = + program.MaxScratchDoublesNeededForEvaluate(); + + EvaluateScratch* evaluate_scratch = new EvaluateScratch[num_threads]; + for (int i = 0; i < num_threads; i++) { + evaluate_scratch[i].Init(max_parameters_per_residual_block, + max_scratch_doubles_needed_for_evaluate); + } + return evaluate_scratch; + } + + Evaluator::Options options_; + Program* program_; + JacobianWriter jacobian_writer_; + scoped_array evaluate_preparers_; + scoped_array evaluate_scratch_; + vector residual_layout_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_PROGRAM_EVALUATOR_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/random.h b/extern/libmv/third_party/ceres/internal/ceres/random.h new file mode 100644 index 00000000000..769e0b4dd27 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/random.h @@ -0,0 +1,47 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#ifndef CERES_INTERNAL_RANDOM_H_ +#define CERES_INTERNAL_RANDOM_H_ + +namespace ceres { + +inline double RandDouble() { + double r = rand(); + return r / RAND_MAX; +} + +inline int Uniform(int n) { + return rand() % n; +} + +} // namespace ceres + +#endif // CERES_INTERNAL_RANDOM_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/residual_block.cc b/extern/libmv/third_party/ceres/internal/ceres/residual_block.cc new file mode 100644 index 00000000000..03867891dba --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/residual_block.cc @@ -0,0 +1,212 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/residual_block.h" + +#include +#include +#include + +#include "ceres/corrector.h" +#include "ceres/parameter_block.h" +#include "ceres/residual_block_utils.h" +#include "ceres/cost_function.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/fixed_array.h" +#include "ceres/local_parameterization.h" +#include "ceres/loss_function.h" + +namespace ceres { +namespace internal { + +ResidualBlock::ResidualBlock(const CostFunction* cost_function, + const LossFunction* loss_function, + const vector& parameter_blocks) + : cost_function_(cost_function), + loss_function_(loss_function), + parameter_blocks_( + new ParameterBlock* [ + cost_function->parameter_block_sizes().size()]) { + std::copy(parameter_blocks.begin(), + parameter_blocks.end(), + parameter_blocks_.get()); +} + +bool ResidualBlock::Evaluate(double* cost, + double* residuals, + double** jacobians, + double* scratch) const { + const int num_parameter_blocks = NumParameterBlocks(); + const int num_residuals = cost_function_->num_residuals(); + + // Collect the parameters from their blocks. This will rarely allocate, since + // residuals taking more than 8 parameter block arguments are rare. + FixedArray parameters(num_parameter_blocks); + for (int i = 0; i < num_parameter_blocks; ++i) { + parameters[i] = parameter_blocks_[i]->state(); + } + + // Put pointers into the scratch space into global_jacobians as appropriate. + FixedArray global_jacobians(num_parameter_blocks); + if (jacobians != NULL) { + for (int i = 0; i < num_parameter_blocks; ++i) { + const ParameterBlock* parameter_block = parameter_blocks_[i]; + if (jacobians[i] != NULL && + parameter_block->LocalParameterizationJacobian() != NULL) { + global_jacobians[i] = scratch; + scratch += num_residuals * parameter_block->Size(); + } else { + global_jacobians[i] = jacobians[i]; + } + } + } + + // If the caller didn't request residuals, use the scratch space for them. + bool outputting_residuals = (residuals != NULL); + if (!outputting_residuals) { + residuals = scratch; + } + + // Invalidate the evaluation buffers so that we can check them after + // the CostFunction::Evaluate call, to see if all the return values + // that were required were written to and that they are finite. + double** eval_jacobians = (jacobians != NULL) ? global_jacobians.get() : NULL; + + InvalidateEvaluation(*this, cost, residuals, eval_jacobians); + + if (!cost_function_->Evaluate(parameters.get(), residuals, eval_jacobians) || + !IsEvaluationValid(*this, + parameters.get(), + cost, + residuals, + eval_jacobians)) { + string message = + "\n\n" + "Error in evaluating the ResidualBlock.\n\n" + "There are two possible reasons. Either the CostFunction did not evaluate and fill all \n" // NOLINT + "residual and jacobians that were requested or there was a non-finite value (nan/infinite)\n" // NOLINT + "generated during the or jacobian computation. \n\n" + + EvaluationToString(*this, + parameters.get(), + cost, + residuals, + eval_jacobians); + LOG(WARNING) << message; + return false; + } + + double squared_norm = VectorRef(residuals, num_residuals).squaredNorm(); + + // Update the jacobians with the local parameterizations. + if (jacobians != NULL) { + for (int i = 0; i < num_parameter_blocks; ++i) { + if (jacobians[i] != NULL) { + const ParameterBlock* parameter_block = parameter_blocks_[i]; + + // Apply local reparameterization to the jacobians. + if (parameter_block->LocalParameterizationJacobian() != NULL) { + ConstMatrixRef local_to_global( + parameter_block->LocalParameterizationJacobian(), + parameter_block->Size(), + parameter_block->LocalSize()); + MatrixRef global_jacobian(global_jacobians[i], + num_residuals, + parameter_block->Size()); + MatrixRef local_jacobian(jacobians[i], + num_residuals, + parameter_block->LocalSize()); + local_jacobian.noalias() = global_jacobian * local_to_global; + } + } + } + } + + if (loss_function_ == NULL) { + *cost = 0.5 * squared_norm; + return true; + } + + double rho[3]; + loss_function_->Evaluate(squared_norm, rho); + *cost = 0.5 * rho[0]; + + // No jacobians and not outputting residuals? All done. Doing an early exit + // here avoids constructing the "Corrector" object below in a common case. + if (jacobians == NULL && !outputting_residuals) { + return true; + } + + // Correct for the effects of the loss function. The jacobians need to be + // corrected before the residuals, since they use the uncorrected residuals. + Corrector correct(squared_norm, rho); + if (jacobians != NULL) { + for (int i = 0; i < num_parameter_blocks; ++i) { + if (jacobians[i] != NULL) { + const ParameterBlock* parameter_block = parameter_blocks_[i]; + + // Correct the jacobians for the loss function. + correct.CorrectJacobian(num_residuals, + parameter_block->LocalSize(), + residuals, + jacobians[i]); + } + } + } + + // Correct the residuals with the loss function. + if (outputting_residuals) { + correct.CorrectResiduals(num_residuals, residuals); + } + return true; +} + +int ResidualBlock::NumScratchDoublesForEvaluate() const { + // Compute the amount of scratch space needed to store the full-sized + // jacobians. For parameters that have no local parameterization no storage + // is needed and the passed-in jacobian array is used directly. Also include + // space to store the residuals, which is needed for cost-only evaluations. + // This is slightly pessimistic, since both won't be needed all the time, but + // the amount of excess should not cause problems for the caller. + int num_parameters = NumParameterBlocks(); + int scratch_doubles = 1; + for (int i = 0; i < num_parameters; ++i) { + const ParameterBlock* parameter_block = parameter_blocks_[i]; + if (!parameter_block->IsConstant() && + parameter_block->LocalParameterizationJacobian() != NULL) { + scratch_doubles += parameter_block->Size(); + } + } + scratch_doubles *= NumResiduals(); + return scratch_doubles; +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/residual_block.h b/extern/libmv/third_party/ceres/internal/ceres/residual_block.h new file mode 100644 index 00000000000..e0a06e78958 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/residual_block.h @@ -0,0 +1,124 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// keir@google.com (Keir Mierle) +// +// Purpose : Class and struct definitions for parameter and residual blocks. + +#ifndef CERES_INTERNAL_RESIDUAL_BLOCK_H_ +#define CERES_INTERNAL_RESIDUAL_BLOCK_H_ + +#include + +#include "ceres/cost_function.h" +#include "ceres/internal/port.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { + +class LossFunction; + +namespace internal { + +class ParameterBlock; + +// A term in the least squares problem. The mathematical form of each term in +// the overall least-squares cost function is: +// +// 1 +// --- loss_function( || cost_function(block1, block2, ...) ||^2 ), +// 2 +// +// Storing the cost function and the loss function separately permits optimizing +// the problem with standard non-linear least techniques, without requiring a +// more general non-linear solver. +// +// The residual block stores pointers to but does not own the cost functions, +// loss functions, and parameter blocks. +class ResidualBlock { + public: + ResidualBlock(const CostFunction* cost_function, + const LossFunction* loss_function, + const vector& parameter_blocks); + + // Evaluates the residual term, storing the scalar cost in *cost, the residual + // components in *residuals, and the jacobians between the parameters and + // residuals in jacobians[i], in row-major order. If residuals is NULL, the + // residuals are not computed. If jacobians is NULL, no jacobians are + // computed. If jacobians[i] is NULL, then the jacobian for that parameter is + // not computed. + // + // Evaluate needs scratch space which must be supplied by the caller via + // scratch. The array should have at least NumScratchDoublesForEvaluate() + // space available. + // + // The return value indicates the success or failure. If the function returns + // false, the caller should expect the the output memory locations to have + // been modified. + // + // The returned cost and jacobians have had robustification and local + // parameterizations applied already; for example, the jacobian for a + // 4-dimensional quaternion parameter using the "QuaternionParameterization" + // is num_residuals by 3 instead of num_residuals by 4. + bool Evaluate(double* cost, + double* residuals, + double** jacobians, + double* scratch) const; + + const CostFunction* cost_function() const { return cost_function_; } + const LossFunction* loss_function() const { return loss_function_; } + + // Access the parameter blocks for this residual. The array has size + // NumParameterBlocks(). + ParameterBlock* const* parameter_blocks() const { + return parameter_blocks_.get(); + } + + // Number of variable blocks that this residual term depends on. + int NumParameterBlocks() const { + return cost_function_->parameter_block_sizes().size(); + } + + // The size of the residual vector returned by this residual function. + int NumResiduals() const { return cost_function_->num_residuals(); } + + // The minimum amount of scratch space needed to pass to Evaluate(). + int NumScratchDoublesForEvaluate() const; + + private: + const CostFunction* cost_function_; + const LossFunction* loss_function_; + scoped_array parameter_blocks_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_RESIDUAL_BLOCK_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.cc b/extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.cc new file mode 100644 index 00000000000..28e03130844 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.cc @@ -0,0 +1,185 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/residual_block_utils.h" + +#include +#include +#include +#include +#include "ceres/residual_block.h" +#include "ceres/parameter_block.h" +#include "ceres/stringprintf.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" + +#ifdef _MSC_VER +# define isfinite _finite +#endif + +namespace ceres { +namespace internal { + +// It is a near impossibility that user code generates this exact +// value in normal operation, thus we will use it to fill arrays +// before passing them to user code. If on return an element of the +// array still contains this value, we will assume that the user code +// did not write to that memory location. +static const double kImpossibleValue = 1e302; + +bool IsArrayValid(const int size, const double* x) { + if (x != NULL) { + for (int i = 0; i < size; ++i) { + if (!isfinite(x[i]) || (x[i] == kImpossibleValue)) { + return false; + } + } + } + return true; +} + +void InvalidateArray(const int size, double* x) { + if (x != NULL) { + for (int i = 0; i < size; ++i) { + x[i] = kImpossibleValue; + } + } +} + +void InvalidateEvaluation(const ResidualBlock& block, + double* cost, + double* residuals, + double** jacobians) { + const int num_parameter_blocks = block.NumParameterBlocks(); + const int num_residuals = block.NumResiduals(); + + InvalidateArray(1, cost); + InvalidateArray(num_residuals, residuals); + if (jacobians != NULL) { + for (int i = 0; i < num_parameter_blocks; ++i) { + const int parameter_block_size = block.parameter_blocks()[i]->Size(); + InvalidateArray(num_residuals * parameter_block_size, jacobians[i]); + } + } +} + +// Utility routine to print an array of doubles to a string. If the +// array pointer is NULL, it is treated as an array of zeros. +void AppendArrayToString(const int size, const double* x, string* result) { + for (int i = 0; i < size; ++i) { + if (x == NULL) { + StringAppendF(result, "Not Computed "); + } else { + if (x[i] == kImpossibleValue) { + StringAppendF(result, "Uninitialized "); + } else { + StringAppendF(result, "%12g ", x[i]); + } + } + } +} + +string EvaluationToString(const ResidualBlock& block, + double const* const* parameters, + double* cost, + double* residuals, + double** jacobians) { + CHECK_NOTNULL(cost); + CHECK_NOTNULL(residuals); + + const int num_parameter_blocks = block.NumParameterBlocks(); + const int num_residuals = block.NumResiduals(); + string result = ""; + + StringAppendF(&result, + "Residual Block size: %d parameter blocks x %d residuals\n\n", + num_parameter_blocks, num_residuals); + result += + "For each parameter block, the value of the parameters are printed in the first column \n" // NOLINT + "and the value of the jacobian under the corresponding residual. If a ParameterBlock was \n" // NOLINT + "held constant then the corresponding jacobian is printed as 'Not Computed'. If an entry \n" // NOLINT + "of the Jacobian/residual array was requested but was not written to by user code, it is \n" // NOLINT + "indicated by 'Uninitialized'. This is an error. Residuals or Jacobian values evaluating \n" // NOLINT + "to Inf or NaN is also an error. \n\n"; // NOLINT + + string space = "Residuals: "; + result += space; + AppendArrayToString(num_residuals, residuals, &result); + StringAppendF(&result, "\n\n"); + + for (int i = 0; i < num_parameter_blocks; ++i) { + const int parameter_block_size = block.parameter_blocks()[i]->Size(); + StringAppendF( + &result, "Parameter Block %d, size: %d\n", i, parameter_block_size); + StringAppendF(&result, "\n"); + for (int j = 0; j < parameter_block_size; ++j) { + AppendArrayToString(1, parameters[i] + j, &result); + StringAppendF(&result, "| "); + for (int k = 0; k < num_residuals; ++k) { + AppendArrayToString(1, + (jacobians != NULL && jacobians[i] != NULL) + ? jacobians[i] + k * parameter_block_size + j + : NULL, + &result); + } + StringAppendF(&result, "\n"); + } + StringAppendF(&result, "\n"); + } + StringAppendF(&result, "\n"); + return result; +} + +bool IsEvaluationValid(const ResidualBlock& block, + double const* const* parameters, + double* cost, + double* residuals, + double** jacobians) { + const int num_parameter_blocks = block.NumParameterBlocks(); + const int num_residuals = block.NumResiduals(); + + if (!IsArrayValid(num_residuals, residuals)) { + return false; + } + + if (jacobians != NULL) { + for (int i = 0; i < num_parameter_blocks; ++i) { + const int parameter_block_size = block.parameter_blocks()[i]->Size(); + if (!IsArrayValid(num_residuals * parameter_block_size, jacobians[i])) { + return false; + } + } + } + + return true; +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.h b/extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.h new file mode 100644 index 00000000000..228867cc60c --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.h @@ -0,0 +1,89 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Utility routines for ResidualBlock evaluation. +// +// These are useful for detecting two common class of errors. +// +// 1. Uninitialized memory - where the user for some reason did not +// compute part of a cost/residual/jacobian. +// +// 2. Numerical failure while computing the cost/residual/jacobian, +// e.g. NaN, infinities etc. This is particularly useful since the +// automatic differentiation code does computations that are not +// evident to the user and can silently generate hard to debug errors. + +#ifndef CERES_INTERNAL_RESIDUAL_BLOCK_UTILS_H_ +#define CERES_INTERNAL_RESIDUAL_BLOCK_UTILS_H_ + +#include +#include "ceres/internal/port.h" + +namespace ceres { +namespace internal { + +class ResidualBlock; + +// Fill the array x with an impossible value that the user code is +// never expected to compute. +void InvalidateArray(int size, double* x); + +// Check if all the entries of the array x are valid, i.e. all the +// values in the array should be finite and none of them should be +// equal to the "impossible" value used by InvalidateArray. +bool IsArrayValid(int size, const double* x); + +// Invalidate cost, resdual and jacobian arrays (if not NULL). +void InvalidateEvaluation(const ResidualBlock& block, + double* cost, + double* residuals, + double** jacobians); + +// Check if any of the arrays cost, residuals or jacobians contains an +// NaN, return true if it does. +bool IsEvaluationValid(const ResidualBlock& block, + double const* const* parameters, + double* cost, + double* residuals, + double** jacobians); + +// Create a string representation of the Residual block containing the +// value of the parameters, residuals and jacobians if present. +// Useful for debugging output. +string EvaluationToString(const ResidualBlock& block, + double const* const* parameters, + double* cost, + double* residuals, + double** jacobians); + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_RESIDUAL_BLOCK_UTILS_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/runtime_numeric_diff_cost_function.cc b/extern/libmv/third_party/ceres/internal/ceres/runtime_numeric_diff_cost_function.cc new file mode 100644 index 00000000000..ac6d8aa279a --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/runtime_numeric_diff_cost_function.cc @@ -0,0 +1,218 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// Based on the templated version in public/numeric_diff_cost_function.h. + +#include "ceres/runtime_numeric_diff_cost_function.h" + +#include +#include +#include + +#include +#include "Eigen/Dense" +#include "ceres/cost_function.h" +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { +namespace { + +bool EvaluateJacobianForParameterBlock(const CostFunction* function, + int parameter_block_size, + int parameter_block, + RuntimeNumericDiffMethod method, + double relative_step_size, + double const* residuals_at_eval_point, + double** parameters, + double** jacobians) { + using Eigen::Map; + using Eigen::Matrix; + using Eigen::Dynamic; + using Eigen::RowMajor; + + typedef Matrix ResidualVector; + typedef Matrix ParameterVector; + typedef Matrix JacobianMatrix; + + int num_residuals = function->num_residuals(); + + Map parameter_jacobian(jacobians[parameter_block], + num_residuals, + parameter_block_size); + + // Mutate one element at a time and then restore. + Map x_plus_delta(parameters[parameter_block], + parameter_block_size); + ParameterVector x(x_plus_delta); + ParameterVector step_size = x.array().abs() * relative_step_size; + + // To handle cases where a paremeter is exactly zero, instead use the mean + // step_size for the other dimensions. + double fallback_step_size = step_size.sum() / step_size.rows(); + if (fallback_step_size == 0.0) { + // If all the parameters are zero, there's no good answer. Use the given + // relative step_size as absolute step_size and hope for the best. + fallback_step_size = relative_step_size; + } + + // For each parameter in the parameter block, use finite differences to + // compute the derivative for that parameter. + for (int j = 0; j < parameter_block_size; ++j) { + if (step_size(j) == 0.0) { + // The parameter is exactly zero, so compromise and use the mean step_size + // from the other parameters. This can break in many cases, but it's hard + // to pick a good number without problem specific knowledge. + step_size(j) = fallback_step_size; + } + x_plus_delta(j) = x(j) + step_size(j); + + ResidualVector residuals(num_residuals); + if (!function->Evaluate(parameters, &residuals[0], NULL)) { + // Something went wrong; bail. + return false; + } + + // Compute this column of the jacobian in 3 steps: + // 1. Store residuals for the forward part. + // 2. Subtract residuals for the backward (or 0) part. + // 3. Divide out the run. + parameter_jacobian.col(j) = residuals; + + double one_over_h = 1 / step_size(j); + if (method == CENTRAL) { + // Compute the function on the other side of x(j). + x_plus_delta(j) = x(j) - step_size(j); + + if (!function->Evaluate(parameters, &residuals[0], NULL)) { + // Something went wrong; bail. + return false; + } + parameter_jacobian.col(j) -= residuals; + one_over_h /= 2; + } else { + // Forward difference only; reuse existing residuals evaluation. + parameter_jacobian.col(j) -= + Map(residuals_at_eval_point, num_residuals); + } + x_plus_delta(j) = x(j); // Restore x_plus_delta. + + // Divide out the run to get slope. + parameter_jacobian.col(j) *= one_over_h; + } + return true; +} + +class RuntimeNumericDiffCostFunction : public CostFunction { + public: + RuntimeNumericDiffCostFunction(const CostFunction* function, + RuntimeNumericDiffMethod method, + double relative_step_size) + : function_(function), + method_(method), + relative_step_size_(relative_step_size) { + *mutable_parameter_block_sizes() = function->parameter_block_sizes(); + set_num_residuals(function->num_residuals()); + } + + virtual ~RuntimeNumericDiffCostFunction() { } + + virtual bool Evaluate(double const* const* parameters, + double* residuals, + double** jacobians) const { + // Get the function value (residuals) at the the point to evaluate. + bool success = function_->Evaluate(parameters, residuals, NULL); + if (!success) { + // Something went wrong; ignore the jacobian. + return false; + } + if (!jacobians) { + // Nothing to do; just forward. + return true; + } + + const vector& block_sizes = function_->parameter_block_sizes(); + CHECK(!block_sizes.empty()); + + // Create local space for a copy of the parameters which will get mutated. + int parameters_size = accumulate(block_sizes.begin(), block_sizes.end(), 0); + vector parameters_copy(parameters_size); + vector parameters_references_copy(block_sizes.size()); + parameters_references_copy[0] = ¶meters_copy[0]; + for (int block = 1; block < block_sizes.size(); ++block) { + parameters_references_copy[block] = parameters_references_copy[block - 1] + + block_sizes[block - 1]; + } + + // Copy the parameters into the local temp space. + for (int block = 0; block < block_sizes.size(); ++block) { + memcpy(parameters_references_copy[block], + parameters[block], + block_sizes[block] * sizeof(*parameters[block])); + } + + for (int block = 0; block < block_sizes.size(); ++block) { + if (!jacobians[block]) { + // No jacobian requested for this parameter / residual pair. + continue; + } + if (!EvaluateJacobianForParameterBlock(function_, + block_sizes[block], + block, + method_, + relative_step_size_, + residuals, + ¶meters_references_copy[0], + jacobians)) { + return false; + } + } + return true; + } + + private: + const CostFunction* function_; + RuntimeNumericDiffMethod method_; + double relative_step_size_; +}; + +} // namespace + +CostFunction* CreateRuntimeNumericDiffCostFunction( + const CostFunction* cost_function, + RuntimeNumericDiffMethod method, + double relative_step_size) { + return new RuntimeNumericDiffCostFunction(cost_function, + method, + relative_step_size); +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/runtime_numeric_diff_cost_function.h b/extern/libmv/third_party/ceres/internal/ceres/runtime_numeric_diff_cost_function.h new file mode 100644 index 00000000000..01b57f92ef3 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/runtime_numeric_diff_cost_function.h @@ -0,0 +1,87 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// Create CostFunctions as needed by the least squares framework with jacobians +// computed via numeric differentiation. +// +// To get a numerically differentiated cost function, define a subclass of +// CostFunction such that the Evaluate() function ignores the jacobian +// parameter. The numeric differentiation wrapper will fill in the jacobian +// parameter if nececssary by repeatedly calling the Evaluate() function with +// small changes to the appropriate parameters, and computing the slope. This +// implementation is not templated (hence the "Runtime" prefix), which is a bit +// slower than but is more convenient than the templated version in +// numeric_diff_cost_function.h +// +// The numerically differentiated version of a cost function for a cost function +// can be constructed as follows: +// +// CostFunction* cost_function = +// CreateRuntimeNumericDiffCostFunction(new MyCostFunction(...), +// CENTRAL, +// TAKE_OWNERSHIP); +// +// The central difference method is considerably more accurate; consider using +// to start and only after that works, trying forward difference. +// +// TODO(keir): Characterize accuracy; mention pitfalls; provide alternatives. + +#ifndef CERES_INTERNAL_RUNTIME_NUMERIC_DIFF_COST_FUNCTION_H_ +#define CERES_INTERNAL_RUNTIME_NUMERIC_DIFF_COST_FUNCTION_H_ + +#include "ceres/cost_function.h" + +namespace ceres { +namespace internal { + +enum RuntimeNumericDiffMethod { + CENTRAL, + FORWARD, +}; + +// Create a cost function that evaluates the derivative with finite differences. +// The base cost_function's implementation of Evaluate() only needs to fill in +// the "residuals" argument and not the "jacobians". Any data written to the +// jacobians by the base cost_function is overwritten. +// +// Forward difference or central difference is selected with CENTRAL or FORWARD. +// The relative eps, which determines the step size for forward and central +// differencing, is set with relative eps. Caller owns the resulting cost +// function, and the resulting cost function does not own the base cost +// function. +CostFunction *CreateRuntimeNumericDiffCostFunction( + const CostFunction *cost_function, + RuntimeNumericDiffMethod method, + double relative_eps); + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_RUNTIME_NUMERIC_DIFF_COST_FUNCTION_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc new file mode 100644 index 00000000000..2bc8cdd6bec --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc @@ -0,0 +1,285 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include +#include +#include +#include +#include "Eigen/Dense" +#include "ceres/block_random_access_dense_matrix.h" +#include "ceres/block_random_access_matrix.h" +#include "ceres/block_random_access_sparse_matrix.h" +#include "ceres/block_sparse_matrix.h" +#include "ceres/block_structure.h" +#include "ceres/detect_structure.h" +#include "ceres/linear_solver.h" +#include "ceres/schur_complement_solver.h" +#include "ceres/suitesparse.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +LinearSolver::Summary SchurComplementSolver::SolveImpl( + BlockSparseMatrixBase* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double* x) { + const time_t start_time = time(NULL); + if (!options_.constant_sparsity || (eliminator_.get() == NULL)) { + InitStorage(A->block_structure()); + DetectStructure(*A->block_structure(), + options_.num_eliminate_blocks, + &options_.row_block_size, + &options_.e_block_size, + &options_.f_block_size); + eliminator_.reset(CHECK_NOTNULL(SchurEliminatorBase::Create(options_))); + eliminator_->Init(options_.num_eliminate_blocks, A->block_structure()); + }; + const time_t init_time = time(NULL); + fill(x, x + A->num_cols(), 0.0); + + LinearSolver::Summary summary; + summary.num_iterations = 1; + summary.termination_type = FAILURE; + eliminator_->Eliminate(A, b, per_solve_options.D, lhs_.get(), rhs_.get()); + const time_t eliminate_time = time(NULL); + + double* reduced_solution = x + A->num_cols() - lhs_->num_cols(); + const bool status = SolveReducedLinearSystem(reduced_solution); + const time_t solve_time = time(NULL); + + if (!status) { + return summary; + } + + eliminator_->BackSubstitute(A, b, per_solve_options.D, reduced_solution, x); + const time_t backsubstitute_time = time(NULL); + summary.termination_type = TOLERANCE; + + VLOG(2) << "time (sec) total: " << backsubstitute_time - start_time + << " init: " << init_time - start_time + << " eliminate: " << eliminate_time - init_time + << " solve: " << solve_time - eliminate_time + << " backsubstitute: " << backsubstitute_time - solve_time; + return summary; +} + +// Initialize a BlockRandomAccessDenseMatrix to store the Schur +// complement. +void DenseSchurComplementSolver::InitStorage( + const CompressedRowBlockStructure* bs) { + const int num_eliminate_blocks = options().num_eliminate_blocks; + const int num_col_blocks = bs->cols.size(); + + vector blocks(num_col_blocks - num_eliminate_blocks, 0); + for (int i = num_eliminate_blocks, j = 0; + i < num_col_blocks; + ++i, ++j) { + blocks[j] = bs->cols[i].size; + } + + set_lhs(new BlockRandomAccessDenseMatrix(blocks)); + set_rhs(new double[lhs()->num_rows()]); +} + +// Solve the system Sx = r, assuming that the matrix S is stored in a +// BlockRandomAccessDenseMatrix. The linear system is solved using +// Eigen's Cholesky factorization. +bool DenseSchurComplementSolver::SolveReducedLinearSystem(double* solution) { + const BlockRandomAccessDenseMatrix* m = + down_cast(lhs()); + const int num_rows = m->num_rows(); + + // The case where there are no f blocks, and the system is block + // diagonal. + if (num_rows == 0) { + return true; + } + + // TODO(sameeragarwal): Add proper error handling; this completely ignores + // the quality of the solution to the solve. + VectorRef(solution, num_rows) = + ConstMatrixRef(m->values(), num_rows, num_rows) + .selfadjointView() + .ldlt() + .solve(ConstVectorRef(rhs(), num_rows)); + + return true; +} + +#ifndef CERES_NO_SUITESPARSE +SparseSchurComplementSolver::SparseSchurComplementSolver( + const LinearSolver::Options& options) + : SchurComplementSolver(options), + symbolic_factor_(NULL) { +} + +SparseSchurComplementSolver::~SparseSchurComplementSolver() { + if (symbolic_factor_ != NULL) { + ss_.Free(symbolic_factor_); + symbolic_factor_ = NULL; + } +} + +// Determine the non-zero blocks in the Schur Complement matrix, and +// initialize a BlockRandomAccessSparseMatrix object. +void SparseSchurComplementSolver::InitStorage( + const CompressedRowBlockStructure* bs) { + const int num_eliminate_blocks = options().num_eliminate_blocks; + const int num_col_blocks = bs->cols.size(); + const int num_row_blocks = bs->rows.size(); + + vector blocks(num_col_blocks - num_eliminate_blocks, 0); + for (int i = num_eliminate_blocks; i < num_col_blocks; ++i) { + blocks[i - num_eliminate_blocks] = bs->cols[i].size; + } + + set > block_pairs; + for (int i = 0; i < blocks.size(); ++i) { + block_pairs.insert(make_pair(i, i)); + } + + int r = 0; + while (r < num_row_blocks) { + int e_block_id = bs->rows[r].cells.front().block_id; + if (e_block_id >= num_eliminate_blocks) { + break; + } + vector f_blocks; + + // Add to the chunk until the first block in the row is + // different than the one in the first row for the chunk. + for (; r < num_row_blocks; ++r) { + const CompressedRow& row = bs->rows[r]; + if (row.cells.front().block_id != e_block_id) { + break; + } + + // Iterate over the blocks in the row, ignoring the first + // block since it is the one to be eliminated. + for (int c = 1; c < row.cells.size(); ++c) { + const Cell& cell = row.cells[c]; + f_blocks.push_back(cell.block_id - num_eliminate_blocks); + } + } + + sort(f_blocks.begin(), f_blocks.end()); + f_blocks.erase(unique(f_blocks.begin(), f_blocks.end()), f_blocks.end()); + for (int i = 0; i < f_blocks.size(); ++i) { + for (int j = i + 1; j < f_blocks.size(); ++j) { + block_pairs.insert(make_pair(f_blocks[i], f_blocks[j])); + } + } + } + + // Remaing rows do not contribute to the chunks and directly go + // into the schur complement via an outer product. + for (; r < num_row_blocks; ++r) { + const CompressedRow& row = bs->rows[r]; + CHECK_GE(row.cells.front().block_id, num_eliminate_blocks); + for (int i = 0; i < row.cells.size(); ++i) { + int r_block1_id = row.cells[i].block_id - num_eliminate_blocks; + for (int j = 0; j < row.cells.size(); ++j) { + int r_block2_id = row.cells[j].block_id - num_eliminate_blocks; + if (r_block1_id <= r_block2_id) { + block_pairs.insert(make_pair(r_block1_id, r_block2_id)); + } + } + } + } + + set_lhs(new BlockRandomAccessSparseMatrix(blocks, block_pairs)); + set_rhs(new double[lhs()->num_rows()]); +} + +// Solve the system Sx = r, assuming that the matrix S is stored in a +// BlockRandomAccessSparseMatrix. The linear system is solved using +// CHOLMOD's sparse cholesky factorization routines. +bool SparseSchurComplementSolver::SolveReducedLinearSystem(double* solution) { + // Extract the TripletSparseMatrix that is used for actually storing S. + TripletSparseMatrix* tsm = + const_cast( + down_cast(lhs())->matrix()); + + const int num_rows = tsm->num_rows(); + + // The case where there are no f blocks, and the system is block + // diagonal. + if (num_rows == 0) { + return true; + } + + cholmod_sparse* cholmod_lhs = ss_.CreateSparseMatrix(tsm); + // The matrix is symmetric, and the upper triangular part of the + // matrix contains the values. + cholmod_lhs->stype = 1; + + cholmod_dense* cholmod_rhs = + ss_.CreateDenseVector(const_cast(rhs()), num_rows, num_rows); + + // Symbolic factorization is computed if we don't already have one handy. + if (symbolic_factor_ == NULL) { + symbolic_factor_ = ss_.AnalyzeCholesky(cholmod_lhs); + } + + cholmod_dense* cholmod_solution = + ss_.SolveCholesky(cholmod_lhs, symbolic_factor_, cholmod_rhs); + + ss_.Free(cholmod_lhs); + cholmod_lhs = NULL; + ss_.Free(cholmod_rhs); + cholmod_rhs = NULL; + + // If sparsity is not constant across calls, then reset the symbolic + // factorization. + if (!options().constant_sparsity) { + ss_.Free(symbolic_factor_); + symbolic_factor_ = NULL; + } + + if (cholmod_solution == NULL) { + LOG(ERROR) << "CHOLMOD solve failed."; + return false; + } + + VectorRef(solution, num_rows) + = VectorRef(static_cast(cholmod_solution->x), num_rows); + ss_.Free(cholmod_solution); + return true; +} +#endif // CERES_NO_SUITESPARSE + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h new file mode 100644 index 00000000000..039bc09e3ce --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h @@ -0,0 +1,182 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_SCHUR_COMPLEMENT_SOLVER_H_ +#define CERES_INTERNAL_SCHUR_COMPLEMENT_SOLVER_H_ + +#include "ceres/block_random_access_matrix.h" +#include "ceres/block_sparse_matrix.h" +#include "ceres/block_structure.h" +#include "ceres/linear_solver.h" +#include "ceres/schur_eliminator.h" +#include "ceres/suitesparse.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +class BlockSparseMatrixBase; + +// Base class for Schur complement based linear least squares +// solvers. It assumes that the input linear system Ax = b can be +// partitioned into +// +// E y + F z = b +// +// Where x = [y;z] is a partition of the variables. The paritioning +// of the variables is such that, E'E is a block diagonal +// matrix. Further, the rows of A are ordered so that for every +// variable block in y, all the rows containing that variable block +// occur as a vertically contiguous block. i.e the matrix A looks like +// +// E F +// A = [ y1 0 0 0 | z1 0 0 0 z5] +// [ y1 0 0 0 | z1 z2 0 0 0] +// [ 0 y2 0 0 | 0 0 z3 0 0] +// [ 0 0 y3 0 | z1 z2 z3 z4 z5] +// [ 0 0 y3 0 | z1 0 0 0 z5] +// [ 0 0 0 y4 | 0 0 0 0 z5] +// [ 0 0 0 y4 | 0 z2 0 0 0] +// [ 0 0 0 y4 | 0 0 0 0 0] +// [ 0 0 0 0 | z1 0 0 0 0] +// [ 0 0 0 0 | 0 0 z3 z4 z5] +// +// This structure should be reflected in the corresponding +// CompressedRowBlockStructure object associated with A. The linear +// system Ax = b should either be well posed or the array D below +// should be non-null and the diagonal matrix corresponding to it +// should be non-singular. +// +// SchurComplementSolver has two sub-classes. +// +// DenseSchurComplementSolver: For problems where the Schur complement +// matrix is small and dense, or if CHOLMOD/SuiteSparse is not +// installed. For structure from motion problems, this is solver can +// be used for problems with upto a few hundred cameras. +// +// SparseSchurComplementSolver: For problems where the Schur +// complement matrix is large and sparse. It requires that +// CHOLMOD/SuiteSparse be installed, as it uses CHOLMOD to find a +// sparse Cholesky factorization of the Schur complement. This solver +// can be used for solving structure from motion problems with tens of +// thousands of cameras, though depending on the exact sparsity +// structure, it maybe better to use an iterative solver. +// +// The two solvers can be instantiated by calling +// LinearSolver::CreateLinearSolver with LinearSolver::Options::type +// set to DENSE_SCHUR and SPARSE_SCHUR +// respectively. LinearSolver::Options::num_eliminate_blocks should be +// at least 1. +class SchurComplementSolver : public BlockSparseMatrixBaseSolver { + public: + explicit SchurComplementSolver(const LinearSolver::Options& options) + : options_(options) { + CHECK_GT(options.num_eliminate_blocks, 0); + } + + // LinearSolver methods + virtual ~SchurComplementSolver() {} + virtual LinearSolver::Summary SolveImpl( + BlockSparseMatrixBase* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double* x); + + protected: + const LinearSolver::Options& options() const { return options_; } + + const BlockRandomAccessMatrix* lhs() const { return lhs_.get(); } + void set_lhs(BlockRandomAccessMatrix* lhs) { lhs_.reset(lhs); } + const double* rhs() const { return rhs_.get(); } + void set_rhs(double* rhs) { rhs_.reset(rhs); } + + private: + virtual void InitStorage(const CompressedRowBlockStructure* bs) = 0; + virtual bool SolveReducedLinearSystem(double* solution) = 0; + + LinearSolver::Options options_; + + scoped_ptr eliminator_; + scoped_ptr lhs_; + scoped_array rhs_; + + DISALLOW_COPY_AND_ASSIGN(SchurComplementSolver); +}; + +// Dense Cholesky factorization based solver. +class DenseSchurComplementSolver : public SchurComplementSolver { + public: + explicit DenseSchurComplementSolver(const LinearSolver::Options& options) + : SchurComplementSolver(options) {} + virtual ~DenseSchurComplementSolver() {} + + private: + virtual void InitStorage(const CompressedRowBlockStructure* bs); + virtual bool SolveReducedLinearSystem(double* solution); + + DISALLOW_COPY_AND_ASSIGN(DenseSchurComplementSolver); +}; + +#ifndef CERES_NO_SUITESPARSE +// Sparse Cholesky factorization based solver. +class SparseSchurComplementSolver : public SchurComplementSolver { + public: + explicit SparseSchurComplementSolver(const LinearSolver::Options& options); + virtual ~SparseSchurComplementSolver(); + + private: + virtual void InitStorage(const CompressedRowBlockStructure* bs); + virtual bool SolveReducedLinearSystem(double* solution); + + + SuiteSparse ss_; + // Symbolic factorization of the reduced linear system. Precomputed + // once and reused if constant_sparsity_ is true. + cholmod_factor* symbolic_factor_; + DISALLOW_COPY_AND_ASSIGN(SparseSchurComplementSolver); +}; +#else // CERES_NO_SUITESPARSE +class SparseSchurComplementSolver : public SchurComplementSolver { + public: + explicit SparseSchurComplementSolver(const LinearSolver::Options& options) + : SchurComplementSolver(options) { + LOG(FATAL) << "SPARSE_SCHUR is not available. Please " + "build Ceres with SuiteSparse."; + } + + virtual ~SparseSchurComplementSolver() {} +}; +#endif // CERES_NO_SUITESPARSE + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_SCHUR_COMPLEMENT_SOLVER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.cc b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.cc new file mode 100644 index 00000000000..44f5be3b4e9 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.cc @@ -0,0 +1,141 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// ======================================== +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +// THIS FILE IS AUTOGENERATED. DO NOT EDIT. +//========================================= +// +// This file is generated using generate_template_specializations.py. +// Editing it manually is not recommended. + +#include "ceres/linear_solver.h" +#include "ceres/schur_eliminator.h" +#include "ceres/internal/eigen.h" + +namespace ceres { +namespace internal { + +SchurEliminatorBase* +SchurEliminatorBase::Create(const LinearSolver::Options& options) { +#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION + if ((options.row_block_size == 2) && + (options.e_block_size == 2) && + (options.f_block_size == 2)) { + return new SchurEliminator<2, 2, 2>(options); + } + if ((options.row_block_size == 2) && + (options.e_block_size == 2) && + (options.f_block_size == 3)) { + return new SchurEliminator<2, 2, 3>(options); + } + if ((options.row_block_size == 2) && + (options.e_block_size == 2) && + (options.f_block_size == 4)) { + return new SchurEliminator<2, 2, 4>(options); + } + if ((options.row_block_size == 2) && + (options.e_block_size == 2) && + (options.f_block_size == Dynamic)) { + return new SchurEliminator<2, 2, Dynamic>(options); + } + if ((options.row_block_size == 2) && + (options.e_block_size == 3) && + (options.f_block_size == 3)) { + return new SchurEliminator<2, 3, 3>(options); + } + if ((options.row_block_size == 2) && + (options.e_block_size == 3) && + (options.f_block_size == 4)) { + return new SchurEliminator<2, 3, 4>(options); + } + if ((options.row_block_size == 2) && + (options.e_block_size == 3) && + (options.f_block_size == 9)) { + return new SchurEliminator<2, 3, 9>(options); + } + if ((options.row_block_size == 2) && + (options.e_block_size == 3) && + (options.f_block_size == Dynamic)) { + return new SchurEliminator<2, 3, Dynamic>(options); + } + if ((options.row_block_size == 2) && + (options.e_block_size == 4) && + (options.f_block_size == 3)) { + return new SchurEliminator<2, 4, 3>(options); + } + if ((options.row_block_size == 2) && + (options.e_block_size == 4) && + (options.f_block_size == 4)) { + return new SchurEliminator<2, 4, 4>(options); + } + if ((options.row_block_size == 2) && + (options.e_block_size == 4) && + (options.f_block_size == Dynamic)) { + return new SchurEliminator<2, 4, Dynamic>(options); + } + if ((options.row_block_size == 4) && + (options.e_block_size == 4) && + (options.f_block_size == 2)) { + return new SchurEliminator<4, 4, 2>(options); + } + if ((options.row_block_size == 4) && + (options.e_block_size == 4) && + (options.f_block_size == 3)) { + return new SchurEliminator<4, 4, 3>(options); + } + if ((options.row_block_size == 4) && + (options.e_block_size == 4) && + (options.f_block_size == 4)) { + return new SchurEliminator<4, 4, 4>(options); + } + if ((options.row_block_size == 4) && + (options.e_block_size == 4) && + (options.f_block_size == Dynamic)) { + return new SchurEliminator<4, 4, Dynamic>(options); + } + if ((options.row_block_size == Dynamic) && + (options.e_block_size == Dynamic) && + (options.f_block_size == Dynamic)) { + return new SchurEliminator(options); + } + +#endif + VLOG(1) << "Template specializations not found for <" + << options.row_block_size << "," + << options.e_block_size << "," + << options.f_block_size << ">"; + return new SchurEliminator(options); +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h new file mode 100644 index 00000000000..c24fe435f54 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h @@ -0,0 +1,339 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_SCHUR_ELIMINATOR_H_ +#define CERES_INTERNAL_SCHUR_ELIMINATOR_H_ + +#include +#include +#include "ceres/mutex.h" +#include "ceres/block_random_access_matrix.h" +#include "ceres/block_sparse_matrix.h" +#include "ceres/block_structure.h" +#include "ceres/linear_solver.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { + +// Classes implementing the SchurEliminatorBase interface implement +// variable elimination for linear least squares problems. Assuming +// that the input linear system Ax = b can be partitioned into +// +// E y + F z = b +// +// Where x = [y;z] is a partition of the variables. The paritioning +// of the variables is such that, E'E is a block diagonal matrix. Or +// in other words, the parameter blocks in E form an independent set +// of the of the graph implied by the block matrix A'A. Then, this +// class provides the functionality to compute the Schur complement +// system +// +// S z = r +// +// where +// +// S = F'F - F'E (E'E)^{-1} E'F and r = F'b - F'E(E'E)^(-1) E'b +// +// This is the Eliminate operation, i.e., construct the linear system +// obtained by eliminating the variables in E. +// +// The eliminator also provides the reverse functionality, i.e. given +// values for z it can back substitute for the values of y, by solving the +// linear system +// +// Ey = b - F z +// +// which is done by observing that +// +// y = (E'E)^(-1) [E'b - E'F z] +// +// The eliminator has a number of requirements. +// +// The rows of A are ordered so that for every variable block in y, +// all the rows containing that variable block occur as a vertically +// contiguous block. i.e the matrix A looks like +// +// E F chunk +// A = [ y1 0 0 0 | z1 0 0 0 z5] 1 +// [ y1 0 0 0 | z1 z2 0 0 0] 1 +// [ 0 y2 0 0 | 0 0 z3 0 0] 2 +// [ 0 0 y3 0 | z1 z2 z3 z4 z5] 3 +// [ 0 0 y3 0 | z1 0 0 0 z5] 3 +// [ 0 0 0 y4 | 0 0 0 0 z5] 4 +// [ 0 0 0 y4 | 0 z2 0 0 0] 4 +// [ 0 0 0 y4 | 0 0 0 0 0] 4 +// [ 0 0 0 0 | z1 0 0 0 0] non chunk blocks +// [ 0 0 0 0 | 0 0 z3 z4 z5] non chunk blocks +// +// This structure should be reflected in the corresponding +// CompressedRowBlockStructure object associated with A. The linear +// system Ax = b should either be well posed or the array D below +// should be non-null and the diagonal matrix corresponding to it +// should be non-singular. For simplicity of exposition only the case +// with a null D is described. +// +// The usual way to do the elimination is as follows. Starting with +// +// E y + F z = b +// +// we can form the normal equations, +// +// E'E y + E'F z = E'b +// F'E y + F'F z = F'b +// +// multiplying both sides of the first equation by (E'E)^(-1) and then +// by F'E we get +// +// F'E y + F'E (E'E)^(-1) E'F z = F'E (E'E)^(-1) E'b +// F'E y + F'F z = F'b +// +// now subtracting the two equations we get +// +// [FF' - F'E (E'E)^(-1) E'F] z = F'b - F'E(E'E)^(-1) E'b +// +// Instead of forming the normal equations and operating on them as +// general sparse matrices, the algorithm here deals with one +// parameter block in y at a time. The rows corresponding to a single +// parameter block yi are known as a chunk, and the algorithm operates +// on one chunk at a time. The mathematics remains the same since the +// reduced linear system can be shown to be the sum of the reduced +// linear systems for each chunk. This can be seen by observing two +// things. +// +// 1. E'E is a block diagonal matrix. +// +// 2. When E'F is computed, only the terms within a single chunk +// interact, i.e for y1 column blocks when transposed and multiplied +// with F, the only non-zero contribution comes from the blocks in +// chunk1. +// +// Thus, the reduced linear system +// +// FF' - F'E (E'E)^(-1) E'F +// +// can be re-written as +// +// sum_k F_k F_k' - F_k'E_k (E_k'E_k)^(-1) E_k' F_k +// +// Where the sum is over chunks and E_k'E_k is dense matrix of size y1 +// x y1. +// +// Advanced usage. Uptil now it has been assumed that the user would +// be interested in all of the Schur Complement S. However, it is also +// possible to use this eliminator to obtain an arbitrary submatrix of +// the full Schur complement. When the eliminator is generating the +// blocks of S, it asks the RandomAccessBlockMatrix instance passed to +// it if it has storage for that block. If it does, the eliminator +// computes/updates it, if not it is skipped. This is useful when one +// is interested in constructing a preconditioner based on the Schur +// Complement, e.g., computing the block diagonal of S so that it can +// be used as a preconditioner for an Iterative Substructuring based +// solver [See Agarwal et al, Bundle Adjustment in the Large, ECCV +// 2008 for an example of such use]. +// +// Example usage: Please see schur_complement_solver.cc +class SchurEliminatorBase { + public: + virtual ~SchurEliminatorBase() {} + + // Initialize the eliminator. It is the user's responsibilty to call + // this function before calling Eliminate or BackSubstitute. It is + // also the caller's responsibilty to ensure that the + // CompressedRowBlockStructure object passed to this method is the + // same one (or is equivalent to) the one associated with the + // BlockSparseMatrixBase objects below. + virtual void Init(int num_eliminate_blocks, + const CompressedRowBlockStructure* bs) = 0; + + // Compute the Schur complement system from the augmented linear + // least squares problem [A;D] x = [b;0]. The left hand side and the + // right hand side of the reduced linear system are returned in lhs + // and rhs respectively. + // + // It is the caller's responsibility to construct and initialize + // lhs. Depending upon the structure of the lhs object passed here, + // the full or a submatrix of the Schur complement will be computed. + // + // Since the Schur complement is a symmetric matrix, only the upper + // triangular part of the Schur complement is computed. + virtual void Eliminate(const BlockSparseMatrixBase* A, + const double* b, + const double* D, + BlockRandomAccessMatrix* lhs, + double* rhs) = 0; + + // Given values for the variables z in the F block of A, solve for + // the optimal values of the variables y corresponding to the E + // block in A. + virtual void BackSubstitute(const BlockSparseMatrixBase* A, + const double* b, + const double* D, + const double* z, + double* y) = 0; + // Factory + static SchurEliminatorBase* Create(const LinearSolver::Options& options); +}; + +// Templated implementation of the SchurEliminatorBase interface. The +// templating is on the sizes of the row, e and f blocks sizes in the +// input matrix. In many problems, the sizes of one or more of these +// blocks are constant, in that case, its worth passing these +// parameters as template arguments so that they are visible to the +// compiler and can be used for compile time optimization of the low +// level linear algebra routines. +// +// This implementation is mulithreaded using OpenMP. The level of +// parallelism is controlled by LinearSolver::Options::num_threads. +template +class SchurEliminator : public SchurEliminatorBase { + public: + explicit SchurEliminator(const LinearSolver::Options& options) + : num_threads_(options.num_threads) { + } + + // SchurEliminatorBase Interface + virtual ~SchurEliminator(); + virtual void Init(int num_eliminate_blocks, + const CompressedRowBlockStructure* bs); + virtual void Eliminate(const BlockSparseMatrixBase* A, + const double* b, + const double* D, + BlockRandomAccessMatrix* lhs, + double* rhs); + virtual void BackSubstitute(const BlockSparseMatrixBase* A, + const double* b, + const double* D, + const double* z, + double* y); + + private: + // Chunk objects store combinatorial information needed to + // efficiently eliminate a whole chunk out of the least squares + // problem. Consider the first chunk in the example matrix above. + // + // [ y1 0 0 0 | z1 0 0 0 z5] + // [ y1 0 0 0 | z1 z2 0 0 0] + // + // One of the intermediate quantities that needs to be calculated is + // for each row the product of the y block transposed with the + // non-zero z block, and the sum of these blocks across rows. A + // temporary array "buffer_" is used for computing and storing them + // and the buffer_layout maps the indices of the z-blocks to + // position in the buffer_ array. The size of the chunk is the + // number of row blocks/residual blocks for the particular y block + // being considered. + // + // For the example chunk shown above, + // + // size = 2 + // + // The entries of buffer_layout will be filled in the following order. + // + // buffer_layout[z1] = 0 + // buffer_layout[z5] = y1 * z1 + // buffer_layout[z2] = y1 * z1 + y1 * z5 + typedef map BufferLayoutType; + struct Chunk { + Chunk() : size(0) {} + int size; + int start; + BufferLayoutType buffer_layout; + }; + + void ChunkDiagonalBlockAndGradient( + const Chunk& chunk, + const BlockSparseMatrixBase* A, + const double* b, + int row_block_counter, + typename EigenTypes::Matrix* eet, + typename EigenTypes::Vector* g, + double* buffer, + BlockRandomAccessMatrix* lhs); + + void UpdateRhs(const Chunk& chunk, + const BlockSparseMatrixBase* A, + const double* b, + int row_block_counter, + const Vector& inverse_ete_g, + double* rhs); + + void ChunkOuterProduct(const CompressedRowBlockStructure* bs, + const Matrix& inverse_eet, + const double* buffer, + const BufferLayoutType& buffer_layout, + BlockRandomAccessMatrix* lhs); + void EBlockRowOuterProduct(const BlockSparseMatrixBase* A, + int row_block_index, + BlockRandomAccessMatrix* lhs); + + + void NoEBlockRowsUpdate(const BlockSparseMatrixBase* A, + const double* b, + int row_block_counter, + BlockRandomAccessMatrix* lhs, + double* rhs); + + void NoEBlockRowOuterProduct(const BlockSparseMatrixBase* A, + int row_block_index, + BlockRandomAccessMatrix* lhs); + + int num_eliminate_blocks_; + + // Block layout of the columns of the reduced linear system. Since + // the f blocks can be of varying size, this vector stores the + // position of each f block in the row/col of the reduced linear + // system. Thus lhs_row_layout_[i] is the row/col position of the + // i^th f block. + vector lhs_row_layout_; + + // Combinatorial structure of the chunks in A. For more information + // see the documentation of the Chunk object above. + vector chunks_; + + // Buffer to store the products of the y and z blocks generated + // during the elimination phase. + scoped_array buffer_; + int buffer_size_; + int num_threads_; + int uneliminated_row_begins_; + + // Locks for the blocks in the right hand side of the reduced linear + // system. + vector rhs_locks_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_SCHUR_ELIMINATOR_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h new file mode 100644 index 00000000000..a388d005424 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h @@ -0,0 +1,702 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// TODO(sameeragarwal): row_block_counter can perhaps be replaced by +// Chunk::start ? + +#ifndef CERES_INTERNAL_SCHUR_ELIMINATOR_IMPL_H_ +#define CERES_INTERNAL_SCHUR_ELIMINATOR_IMPL_H_ + +#ifdef CERES_USE_OPENMP +#include +#endif + +// Eigen has an internal threshold switching between different matrix +// multiplication algorithms. In particular for matrices larger than +// EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD it uses a cache friendly +// matrix matrix product algorithm that has a higher setup cost. For +// matrix sizes close to this threshold, especially when the matrices +// are thin and long, the default choice may not be optimal. This is +// the case for us, as the default choice causes a 30% performance +// regression when we moved from Eigen2 to Eigen3. +#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 10 + +#include +#include +#include +#include "Eigen/Dense" +#include "ceres/block_random_access_matrix.h" +#include "ceres/block_sparse_matrix.h" +#include "ceres/block_structure.h" +#include "ceres/map_util.h" +#include "ceres/schur_eliminator.h" +#include "ceres/stl_util.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { + +template +SchurEliminator::~SchurEliminator() { + STLDeleteElements(&rhs_locks_); +} + +template +void +SchurEliminator:: +Init(int num_eliminate_blocks, const CompressedRowBlockStructure* bs) { + CHECK_GT(num_eliminate_blocks, 0) + << "SchurComplementSolver cannot be initialized with " + << "num_eliminate_blocks = 0."; + + num_eliminate_blocks_ = num_eliminate_blocks; + + const int num_col_blocks = bs->cols.size(); + const int num_row_blocks = bs->rows.size(); + + buffer_size_ = 1; + chunks_.clear(); + lhs_row_layout_.clear(); + + int lhs_num_rows = 0; + // Add a map object for each block in the reduced linear system + // and build the row/column block structure of the reduced linear + // system. + lhs_row_layout_.resize(num_col_blocks - num_eliminate_blocks_); + for (int i = num_eliminate_blocks_; i < num_col_blocks; ++i) { + lhs_row_layout_[i - num_eliminate_blocks_] = lhs_num_rows; + lhs_num_rows += bs->cols[i].size; + } + + int r = 0; + // Iterate over the row blocks of A, and detect the chunks. The + // matrix should already have been ordered so that all rows + // containing the same y block are vertically contiguous. Along + // the way also compute the amount of space each chunk will need + // to perform the elimination. + while (r < num_row_blocks) { + const int chunk_block_id = bs->rows[r].cells.front().block_id; + if (chunk_block_id >= num_eliminate_blocks_) { + break; + } + + chunks_.push_back(Chunk()); + Chunk& chunk = chunks_.back(); + chunk.size = 0; + chunk.start = r; + int buffer_size = 0; + const int e_block_size = bs->cols[chunk_block_id].size; + + // Add to the chunk until the first block in the row is + // different than the one in the first row for the chunk. + while (r + chunk.size < num_row_blocks) { + const CompressedRow& row = bs->rows[r + chunk.size]; + if (row.cells.front().block_id != chunk_block_id) { + break; + } + + // Iterate over the blocks in the row, ignoring the first + // block since it is the one to be eliminated. + for (int c = 1; c < row.cells.size(); ++c) { + const Cell& cell = row.cells[c]; + if (InsertIfNotPresent( + &(chunk.buffer_layout), cell.block_id, buffer_size)) { + buffer_size += e_block_size * bs->cols[cell.block_id].size; + } + } + + buffer_size_ = max(buffer_size, buffer_size_); + ++chunk.size; + } + + CHECK_GT(chunk.size, 0); + r += chunk.size; + } + const Chunk& chunk = chunks_.back(); + + uneliminated_row_begins_ = chunk.start + chunk.size; + if (num_threads_ > 1) { + random_shuffle(chunks_.begin(), chunks_.end()); + } + + buffer_.reset(new double[buffer_size_ * num_threads_]); + + STLDeleteElements(&rhs_locks_); + rhs_locks_.resize(num_col_blocks - num_eliminate_blocks_); + for (int i = 0; i < num_col_blocks - num_eliminate_blocks_; ++i) { + rhs_locks_[i] = new Mutex; + } + + VLOG(1) << "Eliminator threads: " << num_threads_; +} + +template +void +SchurEliminator:: +Eliminate(const BlockSparseMatrixBase* A, + const double* b, + const double* D, + BlockRandomAccessMatrix* lhs, + double* rhs) { + if (lhs->num_rows() > 0) { + lhs->SetZero(); + VectorRef(rhs, lhs->num_rows()).setZero(); + } + + const CompressedRowBlockStructure* bs = A->block_structure(); + const int num_col_blocks = bs->cols.size(); + + // Add the diagonal to the schur complement. + if (D != NULL) { +#pragma omp parallel for num_threads(num_threads_) schedule(dynamic) + for (int i = num_eliminate_blocks_; i < num_col_blocks; ++i) { + const int block_id = i - num_eliminate_blocks_; + int r, c, row_stride, col_stride; + CellInfo* cell_info = lhs->GetCell(block_id, block_id, + &r, &c, + &row_stride, &col_stride); + if (cell_info != NULL) { + const int block_size = bs->cols[i].size; + typename EigenTypes::ConstVectorRef + diag(D + bs->cols[i].position, block_size); + + MutexLock l(&cell_info->m); + MatrixRef m(cell_info->values, row_stride, col_stride); + m.block(r, c, block_size, block_size).diagonal() + += diag.array().square().matrix(); + } + } + } + + // Eliminate y blocks one chunk at a time. For each chunk,x3 + // compute the entries of the normal equations and the gradient + // vector block corresponding to the y block and then apply + // Gaussian elimination to them. The matrix ete stores the normal + // matrix corresponding to the block being eliminated and array + // buffer_ contains the non-zero blocks in the row corresponding + // to this y block in the normal equations. This computation is + // done in ChunkDiagonalBlockAndGradient. UpdateRhs then applies + // gaussian elimination to the rhs of the normal equations, + // updating the rhs of the reduced linear system by modifying rhs + // blocks for all the z blocks that share a row block/residual + // term with the y block. EliminateRowOuterProduct does the + // corresponding operation for the lhs of the reduced linear + // system. +#pragma omp parallel for num_threads(num_threads_) schedule(dynamic) + for (int i = 0; i < chunks_.size(); ++i) { +#ifdef CERES_USE_OPENMP + int thread_id = omp_get_thread_num(); +#else + int thread_id = 0; +#endif + double* buffer = buffer_.get() + thread_id * buffer_size_; + const Chunk& chunk = chunks_[i]; + const int e_block_id = bs->rows[chunk.start].cells.front().block_id; + const int e_block_size = bs->cols[e_block_id].size; + + VectorRef(buffer, buffer_size_).setZero(); + + typename EigenTypes::Matrix + ete(e_block_size, e_block_size); + + if (D != NULL) { + const typename EigenTypes::ConstVectorRef + diag(D + bs->cols[e_block_id].position, e_block_size); + ete = diag.array().square().matrix().asDiagonal(); + } else { + ete.setZero(); + } + + typename EigenTypes::Vector g(e_block_size); + g.setZero(); + + // We are going to be computing + // + // S += F'F - F'E(E'E)^{-1}E'F + // + // for each Chunk. The computation is broken down into a number of + // function calls as below. + + // Compute the outer product of the e_blocks with themselves (ete + // = E'E). Compute the product of the e_blocks with the + // corresonding f_blocks (buffer = E'F), the gradient of the terms + // in this chunk (g) and add the outer product of the f_blocks to + // Schur complement (S += F'F). + ChunkDiagonalBlockAndGradient( + chunk, A, b, chunk.start, &ete, &g, buffer, lhs); + + // Normally one wouldn't compute the inverse explicitly, but + // e_block_size will typically be a small number like 3, in + // which case its much faster to compute the inverse once and + // use it to multiply other matrices/vectors instead of doing a + // Solve call over and over again. + typename EigenTypes::Matrix inverse_ete = + ete + .template selfadjointView() + .ldlt() + .solve(Matrix::Identity(e_block_size, e_block_size)); + + // For the current chunk compute and update the rhs of the reduced + // linear system. + // + // rhs = F'b - F'E(E'E)^(-1) E'b + UpdateRhs(chunk, A, b, chunk.start, inverse_ete * g, rhs); + + // S -= F'E(E'E)^{-1}E'F + ChunkOuterProduct(bs, inverse_ete, buffer, chunk.buffer_layout, lhs); + } + + // For rows with no e_blocks, the schur complement update reduces to + // S += F'F. + NoEBlockRowsUpdate(A, b, uneliminated_row_begins_, lhs, rhs); +} + +template +void +SchurEliminator:: +BackSubstitute(const BlockSparseMatrixBase* A, + const double* b, + const double* D, + const double* z, + double* y) { + const CompressedRowBlockStructure* bs = A->block_structure(); +#pragma omp parallel for num_threads(num_threads_) schedule(dynamic) + for (int i = 0; i < chunks_.size(); ++i) { + const Chunk& chunk = chunks_[i]; + const int e_block_id = bs->rows[chunk.start].cells.front().block_id; + const int e_block_size = bs->cols[e_block_id].size; + + typename EigenTypes::VectorRef y_block( + y + bs->cols[e_block_id].position, e_block_size); + + typename EigenTypes::Matrix + ete(e_block_size, e_block_size); + if (D != NULL) { + const typename EigenTypes::ConstVectorRef + diag(D + bs->cols[e_block_id].position, e_block_size); + ete = diag.array().square().matrix().asDiagonal(); + } else { + ete.setZero(); + } + + for (int j = 0; j < chunk.size; ++j) { + const CompressedRow& row = bs->rows[chunk.start + j]; + const double* row_values = A->RowBlockValues(chunk.start + j); + const Cell& e_cell = row.cells.front(); + DCHECK_EQ(e_block_id, e_cell.block_id); + const typename EigenTypes::ConstMatrixRef + e_block(row_values + e_cell.position, + row.block.size, + e_block_size); + + typename EigenTypes::Vector + sj = + typename EigenTypes::ConstVectorRef + (b + bs->rows[chunk.start + j].block.position, + row.block.size); + + for (int c = 1; c < row.cells.size(); ++c) { + const int f_block_id = row.cells[c].block_id; + const int f_block_size = bs->cols[f_block_id].size; + const typename EigenTypes::ConstMatrixRef + f_block(row_values + row.cells[c].position, + row.block.size, f_block_size); + const int r_block = f_block_id - num_eliminate_blocks_; + + sj -= f_block * + typename EigenTypes::ConstVectorRef + (z + lhs_row_layout_[r_block], f_block_size); + } + + y_block += e_block.transpose() * sj; + ete.template selfadjointView() + .rankUpdate(e_block.transpose(), 1.0); + } + + y_block = + ete + .template selfadjointView() + .ldlt() + .solve(y_block); + } +} + +// Update the rhs of the reduced linear system. Compute +// +// F'b - F'E(E'E)^(-1) E'b +template +void +SchurEliminator:: +UpdateRhs(const Chunk& chunk, + const BlockSparseMatrixBase* A, + const double* b, + int row_block_counter, + const Vector& inverse_ete_g, + double* rhs) { + const CompressedRowBlockStructure* bs = A->block_structure(); + const int e_block_size = inverse_ete_g.rows(); + int b_pos = bs->rows[row_block_counter].block.position; + for (int j = 0; j < chunk.size; ++j) { + const CompressedRow& row = bs->rows[row_block_counter + j]; + const double *row_values = A->RowBlockValues(row_block_counter + j); + const Cell& e_cell = row.cells.front(); + + const typename EigenTypes::ConstMatrixRef + e_block(row_values + e_cell.position, + row.block.size, + e_block_size); + + const typename EigenTypes::Vector + sj = + typename EigenTypes::ConstVectorRef + (b + b_pos, row.block.size) - e_block * (inverse_ete_g); + + for (int c = 1; c < row.cells.size(); ++c) { + const int block_id = row.cells[c].block_id; + const int block_size = bs->cols[block_id].size; + const typename EigenTypes::ConstMatrixRef + b(row_values + row.cells[c].position, + row.block.size, block_size); + + const int block = block_id - num_eliminate_blocks_; + MutexLock l(rhs_locks_[block]); + typename EigenTypes::VectorRef + (rhs + lhs_row_layout_[block], block_size).noalias() + += b.transpose() * sj; + } + b_pos += row.block.size; + } +} + +// Given a Chunk - set of rows with the same e_block, e.g. in the +// following Chunk with two rows. +// +// E F +// [ y11 0 0 0 | z11 0 0 0 z51] +// [ y12 0 0 0 | z12 z22 0 0 0] +// +// this function computes twp matrices. The diagonal block matrix +// +// ete = y11 * y11' + y12 * y12' +// +// and the off diagonal blocks in the Guass Newton Hessian. +// +// buffer = [y11'(z11 + z12), y12' * z22, y11' * z51] +// +// which are zero compressed versions of the block sparse matrices E'E +// and E'F. +// +// and the gradient of the e_block, E'b. +template +void +SchurEliminator:: +ChunkDiagonalBlockAndGradient( + const Chunk& chunk, + const BlockSparseMatrixBase* A, + const double* b, + int row_block_counter, + typename EigenTypes::Matrix* ete, + typename EigenTypes::Vector* g, + double* buffer, + BlockRandomAccessMatrix* lhs) { + const CompressedRowBlockStructure* bs = A->block_structure(); + + int b_pos = bs->rows[row_block_counter].block.position; + const int e_block_size = ete->rows(); + + // Iterate over the rows in this chunk, for each row, compute the + // contribution of its F blocks to the Schur complement, the + // contribution of its E block to the matrix EE' (ete), and the + // corresponding block in the gradient vector. + for (int j = 0; j < chunk.size; ++j) { + const CompressedRow& row = bs->rows[row_block_counter + j]; + const double *row_values = A->RowBlockValues(row_block_counter + j); + + if (row.cells.size() > 1) { + EBlockRowOuterProduct(A, row_block_counter + j, lhs); + } + + // Extract the e_block, ETE += E_i' E_i + const Cell& e_cell = row.cells.front(); + const typename EigenTypes::ConstMatrixRef + e_block(row_values + e_cell.position, + row.block.size, + e_block_size); + + ete->template selfadjointView() + .rankUpdate(e_block.transpose(), 1.0); + + // g += E_i' b_i + g->noalias() += e_block.transpose() * + typename EigenTypes::ConstVectorRef + (b + b_pos, row.block.size); + + // buffer = E'F. This computation is done by iterating over the + // f_blocks for each row in the chunk. + for (int c = 1; c < row.cells.size(); ++c) { + const int f_block_id = row.cells[c].block_id; + const int f_block_size = bs->cols[f_block_id].size; + const typename EigenTypes::ConstMatrixRef + f_block(row_values + row.cells[c].position, + row.block.size, f_block_size); + + double* buffer_ptr = + buffer + FindOrDie(chunk.buffer_layout, f_block_id); + + typename EigenTypes::MatrixRef + (buffer_ptr, e_block_size, f_block_size).noalias() + += e_block.transpose() * f_block; + } + b_pos += row.block.size; + } +} + +// Compute the outer product F'E(E'E)^{-1}E'F and subtract it from the +// Schur complement matrix, i.e +// +// S -= F'E(E'E)^{-1}E'F. +template +void +SchurEliminator:: +ChunkOuterProduct(const CompressedRowBlockStructure* bs, + const Matrix& inverse_ete, + const double* buffer, + const BufferLayoutType& buffer_layout, + BlockRandomAccessMatrix* lhs) { + // This is the most computationally expensive part of this + // code. Profiling experiments reveal that the bottleneck is not the + // computation of the right-hand matrix product, but memory + // references to the left hand side. + const int e_block_size = inverse_ete.rows(); + BufferLayoutType::const_iterator it1 = buffer_layout.begin(); + // S(i,j) -= bi' * ete^{-1} b_j + for (; it1 != buffer_layout.end(); ++it1) { + const int block1 = it1->first - num_eliminate_blocks_; + const int block1_size = bs->cols[it1->first].size; + + const typename EigenTypes::ConstMatrixRef + b1(buffer + it1->second, e_block_size, block1_size); + const typename EigenTypes::Matrix + b1_transpose_inverse_ete = b1.transpose() * inverse_ete; + + BufferLayoutType::const_iterator it2 = it1; + for (; it2 != buffer_layout.end(); ++it2) { + const int block2 = it2->first - num_eliminate_blocks_; + + int r, c, row_stride, col_stride; + CellInfo* cell_info = lhs->GetCell(block1, block2, + &r, &c, + &row_stride, &col_stride); + if (cell_info == NULL) { + continue; + } + + const int block2_size = bs->cols[it2->first].size; + const typename EigenTypes::ConstMatrixRef + b2(buffer + it2->second, e_block_size, block2_size); + + MutexLock l(&cell_info->m); + MatrixRef m(cell_info->values, row_stride, col_stride); + + // We explicitly construct a block object here instead of using + // m.block(), as m.block() variant of the constructor does not + // allow mixing of template sizing and runtime sizing parameters + // like the Matrix class does. + Eigen::Block + block(m, r, c, block1_size, block2_size); + block.noalias() -= b1_transpose_inverse_ete * b2; + } + } +} + +// For rows with no e_blocks, the schur complement update reduces to S +// += F'F. This function iterates over the rows of A with no e_block, +// and calls NoEBlockRowOuterProduct on each row. +template +void +SchurEliminator:: +NoEBlockRowsUpdate(const BlockSparseMatrixBase* A, + const double* b, + int row_block_counter, + BlockRandomAccessMatrix* lhs, + double* rhs) { + const CompressedRowBlockStructure* bs = A->block_structure(); + for (; row_block_counter < bs->rows.size(); ++row_block_counter) { + const CompressedRow& row = bs->rows[row_block_counter]; + const double *row_values = A->RowBlockValues(row_block_counter); + for (int c = 0; c < row.cells.size(); ++c) { + const int block_id = row.cells[c].block_id; + const int block_size = bs->cols[block_id].size; + const int block = block_id - num_eliminate_blocks_; + VectorRef(rhs + lhs_row_layout_[block], block_size).noalias() + += (ConstMatrixRef(row_values + row.cells[c].position, + row.block.size, block_size).transpose() * + ConstVectorRef(b + row.block.position, row.block.size)); + } + NoEBlockRowOuterProduct(A, row_block_counter, lhs); + } +} + + +// A row r of A, which has no e_blocks gets added to the Schur +// Complement as S += r r'. This function is responsible for computing +// the contribution of a single row r to the Schur complement. It is +// very similar in structure to EBlockRowOuterProduct except for +// one difference. It does not use any of the template +// parameters. This is because the algorithm used for detecting the +// static structure of the matrix A only pays attention to rows with +// e_blocks. This is becase rows without e_blocks are rare and +// typically arise from regularization terms in the original +// optimization problem, and have a very different structure than the +// rows with e_blocks. Including them in the static structure +// detection will lead to most template parameters being set to +// dynamic. Since the number of rows without e_blocks is small, the +// lack of templating is not an issue. +template +void +SchurEliminator:: +NoEBlockRowOuterProduct(const BlockSparseMatrixBase* A, + int row_block_index, + BlockRandomAccessMatrix* lhs) { + const CompressedRowBlockStructure* bs = A->block_structure(); + const CompressedRow& row = bs->rows[row_block_index]; + const double *row_values = A->RowBlockValues(row_block_index); + for (int i = 0; i < row.cells.size(); ++i) { + const int block1 = row.cells[i].block_id - num_eliminate_blocks_; + DCHECK_GE(block1, 0); + + const int block1_size = bs->cols[row.cells[i].block_id].size; + const ConstMatrixRef b1(row_values + row.cells[i].position, + row.block.size, block1_size); + int r, c, row_stride, col_stride; + CellInfo* cell_info = lhs->GetCell(block1, block1, + &r, &c, + &row_stride, &col_stride); + if (cell_info != NULL) { + MutexLock l(&cell_info->m); + MatrixRef m(cell_info->values, row_stride, col_stride); + m.block(r, c, block1_size, block1_size) + .selfadjointView() + .rankUpdate(b1.transpose(), 1.0); + } + + for (int j = i + 1; j < row.cells.size(); ++j) { + const int block2 = row.cells[j].block_id - num_eliminate_blocks_; + DCHECK_GE(block2, 0); + DCHECK_LT(block1, block2); + int r, c, row_stride, col_stride; + CellInfo* cell_info = lhs->GetCell(block1, block2, + &r, &c, + &row_stride, &col_stride); + if (cell_info == NULL) { + continue; + } + + const int block2_size = bs->cols[row.cells[j].block_id].size; + MutexLock l(&cell_info->m); + MatrixRef m(cell_info->values, row_stride, col_stride); + m.block(r, c, block1_size, block2_size).noalias() += + b1.transpose() * ConstMatrixRef(row_values + row.cells[j].position, + row.block.size, + block2_size); + } + } +} + +// For a row with an e_block, compute the contribition S += F'F. This +// function has the same structure as NoEBlockRowOuterProduct, except +// that this function uses the template parameters. +template +void +SchurEliminator:: +EBlockRowOuterProduct(const BlockSparseMatrixBase* A, + int row_block_index, + BlockRandomAccessMatrix* lhs) { + const CompressedRowBlockStructure* bs = A->block_structure(); + const CompressedRow& row = bs->rows[row_block_index]; + const double *row_values = A->RowBlockValues(row_block_index); + for (int i = 1; i < row.cells.size(); ++i) { + const int block1 = row.cells[i].block_id - num_eliminate_blocks_; + DCHECK_GE(block1, 0); + + const int block1_size = bs->cols[row.cells[i].block_id].size; + const typename EigenTypes::ConstMatrixRef + b1(row_values + row.cells[i].position, + row.block.size, block1_size); + { + int r, c, row_stride, col_stride; + CellInfo* cell_info = lhs->GetCell(block1, block1, + &r, &c, + &row_stride, &col_stride); + if (cell_info == NULL) { + continue; + } + + MutexLock l(&cell_info->m); + MatrixRef m(cell_info->values, row_stride, col_stride); + + Eigen::Block + block(m, r, c, block1_size, block1_size); + block.template selfadjointView() + .rankUpdate(b1.transpose(), 1.0); + } + + for (int j = i + 1; j < row.cells.size(); ++j) { + const int block2 = row.cells[j].block_id - num_eliminate_blocks_; + DCHECK_GE(block2, 0); + DCHECK_LT(block1, block2); + const int block2_size = bs->cols[row.cells[j].block_id].size; + int r, c, row_stride, col_stride; + CellInfo* cell_info = lhs->GetCell(block1, block2, + &r, &c, + &row_stride, &col_stride); + if (cell_info == NULL) { + continue; + } + + const typename EigenTypes::ConstMatrixRef + b2(row_values + row.cells[j].position, + row.block.size, + block2_size); + + MutexLock l(&cell_info->m); + MatrixRef m(cell_info->values, row_stride, col_stride); + Eigen::Block + block(m, r, c, block1_size, block2_size); + block.noalias() += b1.transpose() * b2; + } + } +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_SCHUR_ELIMINATOR_IMPL_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_ordering.cc b/extern/libmv/third_party/ceres/internal/ceres/schur_ordering.cc new file mode 100644 index 00000000000..c4fc1da3c2f --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/schur_ordering.cc @@ -0,0 +1,113 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/schur_ordering.h" + +#include +#include "ceres/graph.h" +#include "ceres/graph_algorithms.h" +#include "ceres/map_util.h" +#include "ceres/parameter_block.h" +#include "ceres/program.h" +#include "ceres/residual_block.h" +#include "ceres/internal/scoped_ptr.h" + +CERES_HASH_NAMESPACE_START + +// Allow us to hash pointers as if they were int's +template<> struct hash< ::ceres::internal::ParameterBlock*> { + size_t operator()(::ceres::internal::ParameterBlock* x) const { + return reinterpret_cast(x); + } +}; + +CERES_HASH_NAMESPACE_END + +namespace ceres { +namespace internal { + +int ComputeSchurOrdering(const Program& program, + vector* ordering) { + CHECK_NOTNULL(ordering)->clear(); + + scoped_ptr > graph( + CHECK_NOTNULL(CreateHessianGraph(program))); + int independent_set_size = + IndependentSetOrdering(*graph, ordering); + const vector& parameter_blocks = program.parameter_blocks(); + + // Add the excluded blocks to back of the ordering vector. + for (int i = 0; i < parameter_blocks.size(); ++i) { + ParameterBlock* parameter_block = parameter_blocks[i]; + if (parameter_block->IsConstant()) { + ordering->push_back(parameter_block); + } + } + + return independent_set_size; +} + +Graph* +CreateHessianGraph(const Program& program) { + Graph* graph = new Graph; + const vector& parameter_blocks = program.parameter_blocks(); + for (int i = 0; i < parameter_blocks.size(); ++i) { + ParameterBlock* parameter_block = parameter_blocks[i]; + if (!parameter_block->IsConstant()) { + graph->AddVertex(parameter_block); + } + } + + const vector& residual_blocks = program.residual_blocks(); + for (int i = 0; i < residual_blocks.size(); ++i) { + const ResidualBlock* residual_block = residual_blocks[i]; + const int num_parameter_blocks = residual_block->NumParameterBlocks(); + ParameterBlock* const* parameter_blocks = + residual_block->parameter_blocks(); + for (int j = 0; j < num_parameter_blocks; ++j) { + if (parameter_blocks[j]->IsConstant()) { + continue; + } + + for (int k = j + 1; k < num_parameter_blocks; ++k) { + if (parameter_blocks[k]->IsConstant()) { + continue; + } + + graph->AddEdge(parameter_blocks[j], parameter_blocks[k]); + } + } + } + + return graph; +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_ordering.h b/extern/libmv/third_party/ceres/internal/ceres/schur_ordering.h new file mode 100644 index 00000000000..1f9a4ff354f --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/schur_ordering.h @@ -0,0 +1,74 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Compute a parameter block ordering for use with the Schur +// complement based algorithms. + +#ifndef CERES_INTERNAL_SCHUR_ORDERING_H_ +#define CERES_INTERNAL_SCHUR_ORDERING_H_ + +#include +#include "ceres/graph.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +class Program; +class ParameterBlock; + +// Uses an approximate independent set ordering to order the parameter +// blocks of a problem so that it is suitable for use with Schur +// complement based solvers. The output variable ordering contains an +// ordering of the parameter blocks and the return value is size of +// the independent set or the number of e_blocks (see +// schur_complement_solver.h for an explanation). Constant parameters +// are added to the end. +// +// The ordering vector has the structure +// +// ordering = [independent set, +// complement of the independent set, +// fixed blocks] +int ComputeSchurOrdering(const Program& program, + vector* ordering); + + +// Builds a graph on the parameter blocks of a Problem, whose +// structure reflects the sparsity structure of the Hessian. Each +// vertex corresponds to a parameter block in the Problem except for +// parameter blocks that are marked constant. An edge connects two +// parameter blocks, if they co-occur in a residual block. +Graph* CreateHessianGraph(const Program& program); + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_SCHUR_ORDERING_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/scratch_evaluate_preparer.cc b/extern/libmv/third_party/ceres/internal/ceres/scratch_evaluate_preparer.cc new file mode 100644 index 00000000000..6f0ceefd87d --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/scratch_evaluate_preparer.cc @@ -0,0 +1,78 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include "ceres/scratch_evaluate_preparer.h" + +#include "ceres/parameter_block.h" +#include "ceres/program.h" +#include "ceres/residual_block.h" + +namespace ceres { +namespace internal { + +ScratchEvaluatePreparer* ScratchEvaluatePreparer::Create( + const Program &program, + int num_threads) { + ScratchEvaluatePreparer* preparers = new ScratchEvaluatePreparer[num_threads]; + int max_derivatives_per_residual_block = + program.MaxDerivativesPerResidualBlock(); + for (int i = 0; i < num_threads; i++) { + preparers[i].Init(max_derivatives_per_residual_block); + } + return preparers; +} + +void ScratchEvaluatePreparer::Init(int max_derivatives_per_residual_block) { + jacobian_scratch_.reset( + new double[max_derivatives_per_residual_block]); +} + +// Point the jacobian blocks into the scratch area of this evaluate preparer. +void ScratchEvaluatePreparer::Prepare(const ResidualBlock* residual_block, + int /* residual_block_index */, + SparseMatrix* /* jacobian */, + double** jacobians) { + double* jacobian_block_cursor = jacobian_scratch_.get(); + int num_residuals = residual_block->NumResiduals(); + int num_parameter_blocks = residual_block->NumParameterBlocks(); + for (int j = 0; j < num_parameter_blocks; ++j) { + const ParameterBlock* parameter_block = + residual_block->parameter_blocks()[j]; + if (parameter_block->IsConstant()) { + jacobians[j] = NULL; + } else { + jacobians[j] = jacobian_block_cursor; + jacobian_block_cursor += num_residuals * parameter_block->LocalSize(); + } + } +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/scratch_evaluate_preparer.h b/extern/libmv/third_party/ceres/internal/ceres/scratch_evaluate_preparer.h new file mode 100644 index 00000000000..6b127081976 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/scratch_evaluate_preparer.h @@ -0,0 +1,69 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// +// A scratch evaluate preparer provides temporary storage for the jacobians that +// are created when running user-provided cost functions. The evaluator takes +// care to avoid evaluating the jacobian for fixed parameters. + +#ifndef CERES_INTERNAL_SCRATCH_EVALUATE_PREPARER_H_ +#define CERES_INTERNAL_SCRATCH_EVALUATE_PREPARER_H_ + +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { + +class Program; +class ResidualBlock; +class SparseMatrix; + +class ScratchEvaluatePreparer { + public: + // Create num_threads ScratchEvaluatePreparers. + static ScratchEvaluatePreparer* Create(const Program &program, + int num_threads); + + // EvaluatePreparer interface + void Init(int max_derivatives_per_residual_block); + void Prepare(const ResidualBlock* residual_block, + int residual_block_index, + SparseMatrix* jacobian, + double** jacobians); + + private: + // Scratch space for the jacobians; each jacobian is packed one after another. + // There is enough scratch to hold all the jacobians for the largest residual. + scoped_array jacobian_scratch_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_SCRATCH_EVALUATE_PREPARER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver.cc b/extern/libmv/third_party/ceres/internal/ceres/solver.cc new file mode 100644 index 00000000000..77f04d1d918 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/solver.cc @@ -0,0 +1,230 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) +// sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/solver.h" + +#include +#include "ceres/levenberg_marquardt.h" +#include "ceres/program.h" +#include "ceres/solver_impl.h" +#include "ceres/stringprintf.h" +#include "ceres/problem.h" + +namespace ceres { + +Solver::~Solver() {} + +// TODO(sameeragarwal): The timing code here should use a sub-second +// timer. +void Solver::Solve(const Solver::Options& options, + Problem* problem, + Solver::Summary* summary) { + time_t start_time_seconds = time(NULL); + internal::SolverImpl::Solve(options, problem, summary); + summary->total_time_in_seconds = time(NULL) - start_time_seconds; + summary->preprocessor_time_in_seconds = + summary->total_time_in_seconds - summary->minimizer_time_in_seconds; +} + +void Solve(const Solver::Options& options, + Problem* problem, + Solver::Summary* summary) { + time_t start_time_seconds = time(NULL); + internal::SolverImpl::Solve(options, problem, summary); + summary->total_time_in_seconds = time(NULL) - start_time_seconds; + summary->preprocessor_time_in_seconds = + summary->total_time_in_seconds - summary->minimizer_time_in_seconds; +} + +Solver::Summary::Summary() + // Invalid values for most fields, to ensure that we are not + // accidentally reporting default values. + : termination_type(DID_NOT_RUN), + initial_cost(-1.0), + final_cost(-1.0), + fixed_cost(-1.0), + num_successful_steps(-1), + num_unsuccessful_steps(-1), + preprocessor_time_in_seconds(-1.0), + minimizer_time_in_seconds(-1.0), + total_time_in_seconds(-1.0), + num_parameter_blocks(-1), + num_parameters(-1), + num_residual_blocks(-1), + num_residuals(-1), + num_parameter_blocks_reduced(-1), + num_parameters_reduced(-1), + num_residual_blocks_reduced(-1), + num_residuals_reduced(-1), + num_eliminate_blocks_given(-1), + num_eliminate_blocks_used(-1), + num_threads_given(-1), + num_threads_used(-1), + num_linear_solver_threads_given(-1), + num_linear_solver_threads_used(-1), + linear_solver_type_given(SPARSE_NORMAL_CHOLESKY), + linear_solver_type_used(SPARSE_NORMAL_CHOLESKY), + preconditioner_type(IDENTITY), + ordering_type(NATURAL) { +} + +string Solver::Summary::BriefReport() const { + string report = "Ceres Solver Report: "; + if (termination_type == DID_NOT_RUN) { + CHECK(!error.empty()) + << "Solver terminated with DID_NOT_RUN but the solver did not " + << "return a reason. This is a Ceres error. Please report this " + << "to the Ceres team"; + return report + "Termination: DID_NOT_RUN, because " + error; + } + + internal::StringAppendF(&report, "Iterations: %d", + num_successful_steps + num_unsuccessful_steps); + internal::StringAppendF(&report, ", Initial cost: %e", initial_cost); + + // If the solver failed or was aborted, then the final_cost has no + // meaning. + if (termination_type != NUMERICAL_FAILURE && + termination_type != USER_ABORT) { + internal::StringAppendF(&report, ", Final cost: %e", final_cost); + } + + internal::StringAppendF(&report, ", Termination: %s.", + SolverTerminationTypeToString(termination_type)); + return report; +}; + +string Solver::Summary::FullReport() const { + string report = + "\n" + "Ceres Solver Report\n" + "-------------------\n"; + + if (termination_type == DID_NOT_RUN) { + internal::StringAppendF(&report, " Original\n"); + internal::StringAppendF(&report, "Parameter blocks % 10d\n", + num_parameter_blocks); + internal::StringAppendF(&report, "Parameters % 10d\n", + num_parameters); + internal::StringAppendF(&report, "Residual blocks % 10d\n", + num_residual_blocks); + internal::StringAppendF(&report, "Residual % 10d\n\n", + num_residuals); + } else { + internal::StringAppendF(&report, "%45s %21s\n", "Original", "Reduced"); + internal::StringAppendF(&report, "Parameter blocks % 25d% 25d\n", + num_parameter_blocks, num_parameter_blocks_reduced); + internal::StringAppendF(&report, "Parameters % 25d% 25d\n", + num_parameters, num_parameters_reduced); + internal::StringAppendF(&report, "Residual blocks % 25d% 25d\n", + num_residual_blocks, num_residual_blocks_reduced); + internal::StringAppendF(&report, "Residual % 25d% 25d\n\n", + num_residuals, num_residuals_reduced); + } + + internal::StringAppendF(&report, "%45s %21s\n", "Given", "Used"); + internal::StringAppendF(&report, "Linear solver %25s%25s\n", + LinearSolverTypeToString(linear_solver_type_given), + LinearSolverTypeToString(linear_solver_type_used)); + + if (linear_solver_type_given == CGNR || + linear_solver_type_given == ITERATIVE_SCHUR) { + internal::StringAppendF(&report, "Preconditioner %25s%25s\n", + PreconditionerTypeToString(preconditioner_type), + PreconditionerTypeToString(preconditioner_type)); + } else { + internal::StringAppendF(&report, "Preconditioner %25s%25s\n", + "N/A", "N/A"); + } + + internal::StringAppendF(&report, "Ordering %25s%25s\n", + OrderingTypeToString(ordering_type), + OrderingTypeToString(ordering_type)); + + if (IsSchurType(linear_solver_type_given)) { + if (ordering_type == SCHUR) { + internal::StringAppendF(&report, "num_eliminate_blocks%25s% 25d\n", + "N/A", + num_eliminate_blocks_used); + } else { + internal::StringAppendF(&report, "num_eliminate_blocks% 25d% 25d\n", + num_eliminate_blocks_given, + num_eliminate_blocks_used); + } + } + + internal::StringAppendF(&report, "Threads: % 25d% 25d\n", + num_threads_given, num_threads_used); + internal::StringAppendF(&report, "Linear Solver Threads:% 23d% 25d\n", + num_linear_solver_threads_given, + num_linear_solver_threads_used); + + + if (termination_type == DID_NOT_RUN) { + CHECK(!error.empty()) + << "Solver terminated with DID_NOT_RUN but the solver did not " + << "return a reason. This is a Ceres error. Please report this " + << "to the Ceres team"; + internal::StringAppendF(&report, "Termination: %20s\n", + "DID_NOT_RUN"); + internal::StringAppendF(&report, "Reason: %s\n", error.c_str()); + return report; + } + + internal::StringAppendF(&report, "\nCost:\n"); + internal::StringAppendF(&report, "Initial % 30e\n", initial_cost); + if (termination_type != NUMERICAL_FAILURE && termination_type != USER_ABORT) { + internal::StringAppendF(&report, "Final % 30e\n", final_cost); + internal::StringAppendF(&report, "Change % 30e\n", + initial_cost - final_cost); + } + + internal::StringAppendF(&report, "\nNumber of iterations:\n"); + internal::StringAppendF(&report, "Successful % 20d\n", + num_successful_steps); + internal::StringAppendF(&report, "Unsuccessful % 20d\n", + num_unsuccessful_steps); + internal::StringAppendF(&report, "Total % 20d\n", + num_successful_steps + num_unsuccessful_steps); + internal::StringAppendF(&report, "\nTime (in seconds):\n"); + internal::StringAppendF(&report, "Preprocessor % 25e\n", + preprocessor_time_in_seconds); + internal::StringAppendF(&report, "Minimizer % 25e\n", + minimizer_time_in_seconds); + internal::StringAppendF(&report, "Total % 25e\n", + total_time_in_seconds); + + internal::StringAppendF(&report, "Termination: %25s\n", + SolverTerminationTypeToString(termination_type)); + return report; +}; + +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc new file mode 100644 index 00000000000..ed07d9dc6d7 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc @@ -0,0 +1,693 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include "ceres/solver_impl.h" + +#include // NOLINT +#include +#include "ceres/evaluator.h" +#include "ceres/gradient_checking_cost_function.h" +#include "ceres/levenberg_marquardt.h" +#include "ceres/linear_solver.h" +#include "ceres/map_util.h" +#include "ceres/minimizer.h" +#include "ceres/parameter_block.h" +#include "ceres/problem_impl.h" +#include "ceres/program.h" +#include "ceres/residual_block.h" +#include "ceres/schur_ordering.h" +#include "ceres/stringprintf.h" +#include "ceres/iteration_callback.h" +#include "ceres/problem.h" + +namespace ceres { +namespace internal { +namespace { + +void EvaluateCostAndResiduals(ProblemImpl* problem_impl, + double* cost, + vector* residuals) { + CHECK_NOTNULL(cost); + Program* program = CHECK_NOTNULL(problem_impl)->mutable_program(); + if (residuals != NULL) { + residuals->resize(program->NumResiduals()); + program->Evaluate(cost, &(*residuals)[0]); + } else { + program->Evaluate(cost, NULL); + } +} + +// Callback for updating the user's parameter blocks. Updates are only +// done if the step is successful. +class StateUpdatingCallback : public IterationCallback { + public: + StateUpdatingCallback(Program* program, double* parameters) + : program_(program), parameters_(parameters) {} + + CallbackReturnType operator()(const IterationSummary& summary) { + if (summary.step_is_successful) { + program_->StateVectorToParameterBlocks(parameters_); + program_->CopyParameterBlockStateToUserState(); + } + return SOLVER_CONTINUE; + } + + private: + Program* program_; + double* parameters_; +}; + +// Callback for logging the state of the minimizer to STDERR or STDOUT +// depending on the user's preferences and logging level. +class LoggingCallback : public IterationCallback { + public: + explicit LoggingCallback(bool log_to_stdout) + : log_to_stdout_(log_to_stdout) {} + + ~LoggingCallback() {} + + CallbackReturnType operator()(const IterationSummary& summary) { + const char* kReportRowFormat = + "% 4d: f:% 8e d:% 3.2e g:% 3.2e h:% 3.2e " + "rho:% 3.2e mu:% 3.2e li:% 3d"; + string output = StringPrintf(kReportRowFormat, + summary.iteration, + summary.cost, + summary.cost_change, + summary.gradient_max_norm, + summary.step_norm, + summary.relative_decrease, + summary.mu, + summary.linear_solver_iterations); + if (log_to_stdout_) { + cout << output << endl; + } else { + VLOG(1) << output; + } + return SOLVER_CONTINUE; + } + + private: + const bool log_to_stdout_; +}; + +} // namespace + +void SolverImpl::Minimize(const Solver::Options& options, + Program* program, + Evaluator* evaluator, + LinearSolver* linear_solver, + double* initial_parameters, + double* final_parameters, + Solver::Summary* summary) { + Minimizer::Options minimizer_options(options); + + LoggingCallback logging_callback(options.minimizer_progress_to_stdout); + if (options.logging_type != SILENT) { + minimizer_options.callbacks.push_back(&logging_callback); + } + + StateUpdatingCallback updating_callback(program, initial_parameters); + if (options.update_state_every_iteration) { + minimizer_options.callbacks.push_back(&updating_callback); + } + + LevenbergMarquardt levenberg_marquardt; + + time_t start_minimizer_time_seconds = time(NULL); + levenberg_marquardt.Minimize(minimizer_options, + evaluator, + linear_solver, + initial_parameters, + final_parameters, + summary); + summary->minimizer_time_in_seconds = + time(NULL) - start_minimizer_time_seconds; +} + +void SolverImpl::Solve(const Solver::Options& original_options, + Problem* problem, + Solver::Summary* summary) { + Solver::Options options(original_options); + +#ifndef CERES_USE_OPENMP + if (options.num_threads > 1) { + LOG(WARNING) + << "OpenMP support is not compiled into this binary; " + << "only options.num_threads=1 is supported. Switching" + << "to single threaded mode."; + options.num_threads = 1; + } + if (options.num_linear_solver_threads > 1) { + LOG(WARNING) + << "OpenMP support is not compiled into this binary; " + << "only options.num_linear_solver_threads=1 is supported. Switching" + << "to single threaded mode."; + options.num_linear_solver_threads = 1; + } +#endif + + // Reset the summary object to its default values; + *CHECK_NOTNULL(summary) = Solver::Summary(); + summary->linear_solver_type_given = options.linear_solver_type; + summary->num_eliminate_blocks_given = original_options.num_eliminate_blocks; + summary->num_threads_given = original_options.num_threads; + summary->num_linear_solver_threads_given = + original_options.num_linear_solver_threads; + summary->ordering_type = original_options.ordering_type; + + ProblemImpl* problem_impl = CHECK_NOTNULL(problem)->problem_impl_.get(); + + summary->num_parameter_blocks = problem_impl->NumParameterBlocks(); + summary->num_parameters = problem_impl->NumParameters(); + summary->num_residual_blocks = problem_impl->NumResidualBlocks(); + summary->num_residuals = problem_impl->NumResiduals(); + + summary->num_threads_used = options.num_threads; + + // Evaluate the initial cost and residual vector (if needed). The + // initial cost needs to be computed on the original unpreprocessed + // problem, as it is used to determine the value of the "fixed" part + // of the objective function after the problem has undergone + // reduction. Also the initial residuals are in the order in which + // the user added the ResidualBlocks to the optimization problem. + EvaluateCostAndResiduals(problem_impl, + &summary->initial_cost, + options.return_initial_residuals + ? &summary->initial_residuals + : NULL); + + // If the user requests gradient checking, construct a new + // ProblemImpl by wrapping the CostFunctions of problem_impl inside + // GradientCheckingCostFunction and replacing problem_impl with + // gradient_checking_problem_impl. + scoped_ptr gradient_checking_problem_impl; + if (options.check_gradients) { + VLOG(1) << "Checking Gradients"; + gradient_checking_problem_impl.reset( + CreateGradientCheckingProblemImpl( + problem_impl, + options.numeric_derivative_relative_step_size, + options.gradient_check_relative_precision)); + + // From here on, problem_impl will point to the GradientChecking version. + problem_impl = gradient_checking_problem_impl.get(); + } + + // Create the three objects needed to minimize: the transformed program, the + // evaluator, and the linear solver. + + scoped_ptr reduced_program( + CreateReducedProgram(&options, problem_impl, &summary->error)); + if (reduced_program == NULL) { + return; + } + + summary->num_parameter_blocks_reduced = reduced_program->NumParameterBlocks(); + summary->num_parameters_reduced = reduced_program->NumParameters(); + summary->num_residual_blocks_reduced = reduced_program->NumResidualBlocks(); + summary->num_residuals_reduced = reduced_program->NumResiduals(); + + scoped_ptr + linear_solver(CreateLinearSolver(&options, &summary->error)); + summary->linear_solver_type_used = options.linear_solver_type; + summary->preconditioner_type = options.preconditioner_type; + summary->num_eliminate_blocks_used = options.num_eliminate_blocks; + summary->num_linear_solver_threads_used = options.num_linear_solver_threads; + + if (linear_solver == NULL) { + return; + } + + if (!MaybeReorderResidualBlocks(options, + reduced_program.get(), + &summary->error)) { + return; + } + + scoped_ptr evaluator( + CreateEvaluator(options, reduced_program.get(), &summary->error)); + if (evaluator == NULL) { + return; + } + + // The optimizer works on contiguous parameter vectors; allocate some. + Vector initial_parameters(reduced_program->NumParameters()); + Vector optimized_parameters(reduced_program->NumParameters()); + + // Collect the discontiguous parameters into a contiguous state vector. + reduced_program->ParameterBlocksToStateVector(&initial_parameters[0]); + + // Run the optimization. + Minimize(options, + reduced_program.get(), + evaluator.get(), + linear_solver.get(), + initial_parameters.data(), + optimized_parameters.data(), + summary); + + // If the user aborted mid-optimization or the optimization + // terminated because of a numerical failure, then return without + // updating user state. + if (summary->termination_type == USER_ABORT || + summary->termination_type == NUMERICAL_FAILURE) { + return; + } + + // Push the contiguous optimized parameters back to the user's parameters. + reduced_program->StateVectorToParameterBlocks(&optimized_parameters[0]); + reduced_program->CopyParameterBlockStateToUserState(); + + // Return the final cost and residuals for the original problem. + EvaluateCostAndResiduals(problem->problem_impl_.get(), + &summary->final_cost, + options.return_final_residuals + ? &summary->final_residuals + : NULL); + + // Stick a fork in it, we're done. + return; +} + +// Strips varying parameters and residuals, maintaining order, and updating +// num_eliminate_blocks. +bool SolverImpl::RemoveFixedBlocksFromProgram(Program* program, + int* num_eliminate_blocks, + string* error) { + int original_num_eliminate_blocks = *num_eliminate_blocks; + vector* parameter_blocks = + program->mutable_parameter_blocks(); + + // Mark all the parameters as unused. Abuse the index member of the parameter + // blocks for the marking. + for (int i = 0; i < parameter_blocks->size(); ++i) { + (*parameter_blocks)[i]->set_index(-1); + } + + // Filter out residual that have all-constant parameters, and mark all the + // parameter blocks that appear in residuals. + { + vector* residual_blocks = + program->mutable_residual_blocks(); + int j = 0; + for (int i = 0; i < residual_blocks->size(); ++i) { + ResidualBlock* residual_block = (*residual_blocks)[i]; + int num_parameter_blocks = residual_block->NumParameterBlocks(); + + // Determine if the residual block is fixed, and also mark varying + // parameters that appear in the residual block. + bool all_constant = true; + for (int k = 0; k < num_parameter_blocks; k++) { + ParameterBlock* parameter_block = residual_block->parameter_blocks()[k]; + if (!parameter_block->IsConstant()) { + all_constant = false; + parameter_block->set_index(1); + } + } + + if (!all_constant) { + (*residual_blocks)[j++] = (*residual_blocks)[i]; + } + } + residual_blocks->resize(j); + } + + // Filter out unused or fixed parameter blocks, and update + // num_eliminate_blocks as necessary. + { + vector* parameter_blocks = + program->mutable_parameter_blocks(); + int j = 0; + for (int i = 0; i < parameter_blocks->size(); ++i) { + ParameterBlock* parameter_block = (*parameter_blocks)[i]; + if (parameter_block->index() == 1) { + (*parameter_blocks)[j++] = parameter_block; + } else if (i < original_num_eliminate_blocks) { + (*num_eliminate_blocks)--; + } + } + parameter_blocks->resize(j); + } + + CHECK(((program->NumResidualBlocks() == 0) && + (program->NumParameterBlocks() == 0)) || + ((program->NumResidualBlocks() != 0) && + (program->NumParameterBlocks() != 0))) + << "Congratulations, you found a bug in Ceres. Please report it."; + return true; +} + +Program* SolverImpl::CreateReducedProgram(Solver::Options* options, + ProblemImpl* problem_impl, + string* error) { + Program* original_program = problem_impl->mutable_program(); + scoped_ptr transformed_program(new Program(*original_program)); + + if (options->ordering_type == USER && + !ApplyUserOrdering(*problem_impl, + options->ordering, + transformed_program.get(), + error)) { + return NULL; + } + + if (options->ordering_type == SCHUR && options->num_eliminate_blocks != 0) { + *error = "Can't specify SCHUR ordering and num_eliminate_blocks " + "at the same time; SCHUR ordering determines " + "num_eliminate_blocks automatically."; + return NULL; + } + + if (options->ordering_type == SCHUR && options->ordering.size() != 0) { + *error = "Can't specify SCHUR ordering type and the ordering " + "vector at the same time; SCHUR ordering determines " + "a suitable parameter ordering automatically."; + return NULL; + } + + int num_eliminate_blocks = options->num_eliminate_blocks; + + if (!RemoveFixedBlocksFromProgram(transformed_program.get(), + &num_eliminate_blocks, + error)) { + return NULL; + } + + if (transformed_program->NumParameterBlocks() == 0) { + LOG(WARNING) << "No varying parameter blocks to optimize; " + << "bailing early."; + return transformed_program.release(); + } + + if (options->ordering_type == SCHUR) { + vector schur_ordering; + num_eliminate_blocks = ComputeSchurOrdering(*transformed_program, + &schur_ordering); + CHECK_EQ(schur_ordering.size(), transformed_program->NumParameterBlocks()) + << "Congratulations, you found a Ceres bug! Please report this error " + << "to the developers."; + + // Replace the transformed program's ordering with the schur ordering. + swap(*transformed_program->mutable_parameter_blocks(), schur_ordering); + } + options->num_eliminate_blocks = num_eliminate_blocks; + CHECK_GE(options->num_eliminate_blocks, 0) + << "Congratulations, you found a Ceres bug! Please report this error " + << "to the developers."; + + // Since the transformed program is the "active" program, and it is mutated, + // update the parameter offsets and indices. + transformed_program->SetParameterOffsetsAndIndex(); + return transformed_program.release(); +} + +LinearSolver* SolverImpl::CreateLinearSolver(Solver::Options* options, + string* error) { +#ifdef CERES_NO_SUITESPARSE + if (options->linear_solver_type == SPARSE_NORMAL_CHOLESKY) { + *error = "Can't use SPARSE_NORMAL_CHOLESKY because SuiteSparse was not " + "enabled when Ceres was built."; + return NULL; + } +#endif // CERES_NO_SUITESPARSE + + if (options->linear_solver_max_num_iterations <= 0) { + *error = "Solver::Options::linear_solver_max_num_iterations is 0."; + return NULL; + } + if (options->linear_solver_min_num_iterations <= 0) { + *error = "Solver::Options::linear_solver_min_num_iterations is 0."; + return NULL; + } + if (options->linear_solver_min_num_iterations > + options->linear_solver_max_num_iterations) { + *error = "Solver::Options::linear_solver_min_num_iterations > " + "Solver::Options::linear_solver_max_num_iterations."; + return NULL; + } + + LinearSolver::Options linear_solver_options; + linear_solver_options.constant_sparsity = true; + linear_solver_options.min_num_iterations = + options->linear_solver_min_num_iterations; + linear_solver_options.max_num_iterations = + options->linear_solver_max_num_iterations; + linear_solver_options.type = options->linear_solver_type; + linear_solver_options.preconditioner_type = options->preconditioner_type; + +#ifdef CERES_NO_SUITESPARSE + if (linear_solver_options.preconditioner_type == SCHUR_JACOBI) { + *error = "SCHUR_JACOBI preconditioner not suppored. Please build Ceres " + "with SuiteSparse support"; + return NULL; + } + + if (linear_solver_options.preconditioner_type == CLUSTER_JACOBI) { + *error = "CLUSTER_JACOBI preconditioner not suppored. Please build Ceres " + "with SuiteSparse support"; + return NULL; + } + + if (linear_solver_options.preconditioner_type == CLUSTER_TRIDIAGONAL) { + *error = "CLUSTER_TRIDIAGONAL preconditioner not suppored. Please build " + "Ceres with SuiteSparse support"; + return NULL; + } +#endif + + linear_solver_options.num_threads = options->num_linear_solver_threads; + linear_solver_options.num_eliminate_blocks = + options->num_eliminate_blocks; + + if ((linear_solver_options.num_eliminate_blocks == 0) && + IsSchurType(linear_solver_options.type)) { +#ifndef CERES_NO_SUITESPARSE + LOG(INFO) << "No elimination block remaining " + << "switching to SPARSE_NORMAL_CHOLESKY."; + linear_solver_options.type = SPARSE_NORMAL_CHOLESKY; +#else + LOG(INFO) << "No elimination block remaining switching to DENSE_QR."; + linear_solver_options.type = DENSE_QR; +#endif // CERES_NO_SUITESPARSE + } + +#ifdef CERES_NO_SUITESPARSE + if (linear_solver_options.type == SPARSE_SCHUR) { + *error = "Can't use SPARSE_SCHUR because SuiteSparse was not " + "enabled when Ceres was built."; + return NULL; + } +#endif // CERES_NO_SUITESPARSE + + // The matrix used for storing the dense Schur complement has a + // single lock guarding the whole matrix. Running the + // SchurComplementSolver with multiple threads leads to maximum + // contention and slowdown. If the problem is large enough to + // benefit from a multithreaded schur eliminator, you should be + // using a SPARSE_SCHUR solver anyways. + if ((linear_solver_options.num_threads > 1) && + (linear_solver_options.type == DENSE_SCHUR)) { + LOG(WARNING) << "Warning: Solver::Options::num_linear_solver_threads = " + << options->num_linear_solver_threads + << " with DENSE_SCHUR will result in poor performance; " + << "switching to single-threaded."; + linear_solver_options.num_threads = 1; + } + + options->linear_solver_type = linear_solver_options.type; + options->num_linear_solver_threads = linear_solver_options.num_threads; + + return LinearSolver::Create(linear_solver_options); +} + +bool SolverImpl::ApplyUserOrdering(const ProblemImpl& problem_impl, + vector& ordering, + Program* program, + string* error) { + if (ordering.size() != program->NumParameterBlocks()) { + *error = StringPrintf("User specified ordering does not have the same " + "number of parameters as the problem. The problem" + "has %d blocks while the ordering has %ld blocks.", + program->NumParameterBlocks(), + ordering.size()); + return false; + } + + // Ensure that there are no duplicates in the user's ordering. + { + vector ordering_copy(ordering); + sort(ordering_copy.begin(), ordering_copy.end()); + if (unique(ordering_copy.begin(), ordering_copy.end()) + != ordering_copy.end()) { + *error = "User specified ordering contains duplicates."; + return false; + } + } + + vector* parameter_blocks = + program->mutable_parameter_blocks(); + + fill(parameter_blocks->begin(), + parameter_blocks->end(), + static_cast(NULL)); + + const ProblemImpl::ParameterMap& parameter_map = problem_impl.parameter_map(); + for (int i = 0; i < ordering.size(); ++i) { + ProblemImpl::ParameterMap::const_iterator it = + parameter_map.find(ordering[i]); + if (it == parameter_map.end()) { + *error = StringPrintf("User specified ordering contains a pointer " + "to a double that is not a parameter block in the " + "problem. The invalid double is at position %d " + " in options.ordering.", i); + return false; + } + (*parameter_blocks)[i] = it->second; + } + return true; +} + +// Find the minimum index of any parameter block to the given residual. +// Parameter blocks that have indices greater than num_eliminate_blocks are +// considered to have an index equal to num_eliminate_blocks. +int MinParameterBlock(const ResidualBlock* residual_block, + int num_eliminate_blocks) { + int min_parameter_block_position = num_eliminate_blocks; + for (int i = 0; i < residual_block->NumParameterBlocks(); ++i) { + ParameterBlock* parameter_block = residual_block->parameter_blocks()[i]; + DCHECK_NE(parameter_block->index(), -1) + << "Did you forget to call Program::SetParameterOffsetsAndIndex()?"; + min_parameter_block_position = std::min(parameter_block->index(), + min_parameter_block_position); + } + return min_parameter_block_position; +} + +// Reorder the residuals for program, if necessary, so that the residuals +// involving each E block occur together. This is a necessary condition for the +// Schur eliminator, which works on these "row blocks" in the jacobian. +bool SolverImpl::MaybeReorderResidualBlocks(const Solver::Options& options, + Program* program, + string* error) { + // Only Schur types require the lexicographic reordering. + if (!IsSchurType(options.linear_solver_type)) { + return true; + } + + CHECK_NE(0, options.num_eliminate_blocks) + << "Congratulations, you found a Ceres bug! Please report this error " + << "to the developers."; + + // Create a histogram of the number of residuals for each E block. There is an + // extra bucket at the end to catch all non-eliminated F blocks. + vector residual_blocks_per_e_block(options.num_eliminate_blocks + 1); + vector* residual_blocks = program->mutable_residual_blocks(); + vector min_position_per_residual(residual_blocks->size()); + for (int i = 0; i < residual_blocks->size(); ++i) { + ResidualBlock* residual_block = (*residual_blocks)[i]; + int position = MinParameterBlock(residual_block, + options.num_eliminate_blocks); + min_position_per_residual[i] = position; + DCHECK_LE(position, options.num_eliminate_blocks); + residual_blocks_per_e_block[position]++; + } + + // Run a cumulative sum on the histogram, to obtain offsets to the start of + // each histogram bucket (where each bucket is for the residuals for that + // E-block). + vector offsets(options.num_eliminate_blocks + 1); + std::partial_sum(residual_blocks_per_e_block.begin(), + residual_blocks_per_e_block.end(), + offsets.begin()); + CHECK_EQ(offsets.back(), residual_blocks->size()) + << "Congratulations, you found a Ceres bug! Please report this error " + << "to the developers."; + + CHECK(find(residual_blocks_per_e_block.begin(), + residual_blocks_per_e_block.end() - 1, 0) != + residual_blocks_per_e_block.end()) + << "Congratulations, you found a Ceres bug! Please report this error " + << "to the developers."; + + // Fill in each bucket with the residual blocks for its corresponding E block. + // Each bucket is individually filled from the back of the bucket to the front + // of the bucket. The filling order among the buckets is dictated by the + // residual blocks. This loop uses the offsets as counters; subtracting one + // from each offset as a residual block is placed in the bucket. When the + // filling is finished, the offset pointerts should have shifted down one + // entry (this is verified below). + vector reordered_residual_blocks( + (*residual_blocks).size(), static_cast(NULL)); + for (int i = 0; i < residual_blocks->size(); ++i) { + int bucket = min_position_per_residual[i]; + + // Decrement the cursor, which should now point at the next empty position. + offsets[bucket]--; + + // Sanity. + CHECK(reordered_residual_blocks[offsets[bucket]] == NULL) + << "Congratulations, you found a Ceres bug! Please report this error " + << "to the developers."; + + reordered_residual_blocks[offsets[bucket]] = (*residual_blocks)[i]; + } + + // Sanity check #1: The difference in bucket offsets should match the + // histogram sizes. + for (int i = 0; i < options.num_eliminate_blocks; ++i) { + CHECK_EQ(residual_blocks_per_e_block[i], offsets[i + 1] - offsets[i]) + << "Congratulations, you found a Ceres bug! Please report this error " + << "to the developers."; + } + // Sanity check #2: No NULL's left behind. + for (int i = 0; i < reordered_residual_blocks.size(); ++i) { + CHECK(reordered_residual_blocks[i] != NULL) + << "Congratulations, you found a Ceres bug! Please report this error " + << "to the developers."; + } + + // Now that the residuals are collected by E block, swap them in place. + swap(*program->mutable_residual_blocks(), reordered_residual_blocks); + return true; +} + +Evaluator* SolverImpl::CreateEvaluator(const Solver::Options& options, + Program* program, + string* error) { + Evaluator::Options evaluator_options; + evaluator_options.linear_solver_type = options.linear_solver_type; + evaluator_options.num_eliminate_blocks = options.num_eliminate_blocks; + evaluator_options.num_threads = options.num_threads; + return Evaluator::Create(evaluator_options, program, error); +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.h b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.h new file mode 100644 index 00000000000..957ebcc65df --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.h @@ -0,0 +1,111 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#ifndef CERES_INTERNAL_SOLVER_IMPL_H_ +#define CERES_INTERNAL_SOLVER_IMPL_H_ + +#include "ceres/solver.h" + +namespace ceres { +namespace internal { + +class Evaluator; +class LinearSolver; +class ProblemImpl; +class Program; + +class SolverImpl { + public: + // Mirrors the interface in solver.h, but exposes implementation + // details for testing internally. + static void Solve(const Solver::Options& options, + Problem* problem, + Solver::Summary* summary); + + // Create the transformed Program, which has all the fixed blocks + // and residuals eliminated, and in the case of automatic schur + // ordering, has the E blocks first in the resulting program, with + // options.num_eliminate_blocks set appropriately. + static Program* CreateReducedProgram(Solver::Options* options, + ProblemImpl* problem_impl, + string* error); + + // Create the appropriate linear solver, taking into account any + // config changes decided by CreateTransformedProgram(). The + // selected linear solver, which may be different from what the user + // selected; consider the case that the remaining elimininated + // blocks is zero after removing fixed blocks. + static LinearSolver* CreateLinearSolver(Solver::Options* options, + string* error); + + // Reorder the parameter blocks in program using the vector + // ordering. A return value of true indicates success and false + // indicates an error was encountered whose cause is logged to + // LOG(ERROR). + static bool ApplyUserOrdering(const ProblemImpl& problem_impl, + vector& ordering, + Program* program, + string* error); + + // Reorder the residuals for program, if necessary, so that the + // residuals involving each E block occur together. This is a + // necessary condition for the Schur eliminator, which works on + // these "row blocks" in the jacobian. + static bool MaybeReorderResidualBlocks(const Solver::Options& options, + Program* program, + string* error); + + // Create the appropriate evaluator for the transformed program. + static Evaluator* CreateEvaluator(const Solver::Options& options, + Program* program, + string* error); + + // Run the minimization for the given evaluator and configuration. + static void Minimize(const Solver::Options &options, + Program* program, + Evaluator* evaluator, + LinearSolver* linear_solver, + double* initial_parameters, + double* final_parameters, + Solver::Summary* summary); + + // Remove the fixed or unused parameter blocks and residuals + // depending only on fixed parameters from the problem. Also updates + // num_eliminate_blocks, since removed parameters changes the point + // at which the eliminated blocks is valid. + static bool RemoveFixedBlocksFromProgram(Program* program, + int* num_eliminate_blocks, + string* error); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_SOLVER_IMPL_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.cc new file mode 100644 index 00000000000..55336fd3130 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.cc @@ -0,0 +1,40 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/sparse_matrix.h" + +namespace ceres { +namespace internal { + +SparseMatrix::~SparseMatrix() { +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.h new file mode 100644 index 00000000000..962b803dd87 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.h @@ -0,0 +1,108 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Interface definition for sparse matrices. + +#ifndef CERES_INTERNAL_SPARSE_MATRIX_H_ +#define CERES_INTERNAL_SPARSE_MATRIX_H_ + +#include "ceres/linear_operator.h" +#include "ceres/internal/eigen.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +class SparseMatrixProto; + +// This class defines the interface for storing and manipulating +// sparse matrices. The key property that differentiates different +// sparse matrices is how they are organized in memory and how the +// information about the sparsity structure of the matrix is +// stored. This has significant implications for linear solvers +// operating on these matrices. +// +// To deal with the different kinds of layouts, we will assume that a +// sparse matrix will have a two part representation. A values array +// that will be used to store the entries of the sparse matrix and +// some sort of a layout object that tells the user the sparsity +// structure and layout of the values array. For example in case of +// the TripletSparseMatrix, this information is carried in the rows +// and cols arrays and for the BlockSparseMatrix, this information is +// carried in the CompressedRowBlockStructure object. +// +// This interface deliberately does not contain any information about +// the structure of the sparse matrix as that seems to be highly +// matrix type dependent and we are at this stage unable to come up +// with an efficient high level interface that spans multiple sparse +// matrix types. +class SparseMatrix : public LinearOperator { + public: + virtual ~SparseMatrix(); + + // y += Ax; + virtual void RightMultiply(const double* x, double* y) const = 0; + // y += A'x; + virtual void LeftMultiply(const double* x, double* y) const = 0; + + // In MATLAB notation sum(A.*A, 1) + virtual void SquaredColumnNorm(double* x) const = 0; + // A = A * diag(scale) + virtual void ScaleColumns(const double* scale) = 0; + + // A = 0. A->num_nonzeros() == 0 is true after this call. The + // sparsity pattern is preserved. + virtual void SetZero() = 0; + + // Resize and populate dense_matrix with a dense version of the + // sparse matrix. + virtual void ToDenseMatrix(Matrix* dense_matrix) const = 0; + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS + // Dump the sparse matrix to a proto. Destroys the contents of proto. + virtual void ToProto(SparseMatrixProto *proto) const = 0; +#endif + + // Accessors for the values array that stores the entries of the + // sparse matrix. The exact interpreptation of the values of this + // array depends on the particular kind of SparseMatrix being + // accessed. + virtual double* mutable_values() = 0; + virtual const double* values() const = 0; + + virtual int num_rows() const = 0; + virtual int num_cols() const = 0; + virtual int num_nonzeros() const = 0; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_SPARSE_MATRIX_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc new file mode 100644 index 00000000000..59222dc374d --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc @@ -0,0 +1,129 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_NO_SUITESPARSE + +#include "ceres/sparse_normal_cholesky_solver.h" + +#include +#include +#include +#include "ceres/compressed_row_sparse_matrix.h" +#include "ceres/linear_solver.h" +#include "ceres/suitesparse.h" +#include "ceres/triplet_sparse_matrix.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +SparseNormalCholeskySolver::SparseNormalCholeskySolver( + const LinearSolver::Options& options) + : options_(options), symbolic_factor_(NULL) {} + +SparseNormalCholeskySolver::~SparseNormalCholeskySolver() { + if (symbolic_factor_ != NULL) { + ss_.Free(symbolic_factor_); + symbolic_factor_ = NULL; + } +} + +LinearSolver::Summary SparseNormalCholeskySolver::SolveImpl( + CompressedRowSparseMatrix* A, + const double* b, + const LinearSolver::PerSolveOptions& per_solve_options, + double * x) { + const time_t start_time = time(NULL); + const int num_cols = A->num_cols(); + + LinearSolver::Summary summary; + Vector Atb = Vector::Zero(num_cols); + A->LeftMultiply(b, Atb.data()); + + if (per_solve_options.D != NULL) { + // Temporarily append a diagonal block to the A matrix, but undo it before + // returning the matrix to the user. + CompressedRowSparseMatrix D(per_solve_options.D, num_cols); + A->AppendRows(D); + } + + VectorRef(x, num_cols).setZero(); + + scoped_ptr lhs(ss_.CreateSparseMatrixTransposeView(A)); + CHECK_NOTNULL(lhs.get()); + + cholmod_dense* rhs = ss_.CreateDenseVector(Atb.data(), num_cols, num_cols); + const time_t init_time = time(NULL); + + if (symbolic_factor_ == NULL) { + symbolic_factor_ = CHECK_NOTNULL(ss_.AnalyzeCholesky(lhs.get())); + } + + const time_t symbolic_time = time(NULL); + + cholmod_dense* sol = ss_.SolveCholesky(lhs.get(), symbolic_factor_, rhs); + const time_t solve_time = time(NULL); + + ss_.Free(rhs); + rhs = NULL; + + if (per_solve_options.D != NULL) { + A->DeleteRows(num_cols); + } + + if (!options_.constant_sparsity) { + ss_.Free(symbolic_factor_); + symbolic_factor_ = NULL; + } + + summary.num_iterations = 1; + if (sol != NULL) { + memcpy(x, sol->x, num_cols * sizeof(*x)); + + ss_.Free(sol); + sol = NULL; + summary.termination_type = TOLERANCE; + } + + const time_t cleanup_time = time(NULL); + VLOG(2) << "time (sec) total: " << cleanup_time - start_time + << " init: " << init_time - start_time + << " symbolic: " << symbolic_time - init_time + << " solve: " << solve_time - symbolic_time + << " cleanup: " << cleanup_time - solve_time; + return summary; +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_SUITESPARSE diff --git a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h new file mode 100644 index 00000000000..ce1d6d285be --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h @@ -0,0 +1,77 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// A solver for sparse linear least squares problem based on solving +// the normal equations via a sparse cholesky factorization. + +#ifndef CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_ +#define CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_ + +#ifndef CERES_NO_SUITESPARSE + +#include "cholmod.h" +#include "cholmod_core.h" +#include "ceres/linear_solver.h" +#include "ceres/suitesparse.h" +#include "ceres/internal/macros.h" + +namespace ceres { +namespace internal { + +class CompressedRowSparseMatrix; + +// Solves the normal equations (A'A + D'D) x = A'b, using the CHOLMOD sparse +// cholesky solver. +class SparseNormalCholeskySolver : public CompressedRowSparseMatrixSolver { + public: + explicit SparseNormalCholeskySolver(const LinearSolver::Options& options); + virtual ~SparseNormalCholeskySolver(); + + private: + virtual LinearSolver::Summary SolveImpl( + CompressedRowSparseMatrix* A, + const double* b, + const LinearSolver::PerSolveOptions& options, + double* x); + + const LinearSolver::Options options_; + SuiteSparse ss_; + + // Cached factorization + cholmod_factor* symbolic_factor_; + DISALLOW_COPY_AND_ASSIGN(SparseNormalCholeskySolver); +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_SUITESPARSE + +#endif // CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/split.cc b/extern/libmv/third_party/ceres/internal/ceres/split.cc new file mode 100644 index 00000000000..4fa1bd468b9 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/split.cc @@ -0,0 +1,115 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include +#include +#include +#include "ceres/internal/port.h" + +namespace ceres { + +// If we know how much to allocate for a vector of strings, we can allocate the +// vector only once and directly to the right size. This saves in +// between 33-66 % of memory space needed for the result, and runs faster in the +// microbenchmarks. +// +// The reserve is only implemented for the single character delim. +// +// The implementation for counting is cut-and-pasted from +// SplitStringToIteratorUsing. I could have written my own counting iterator, +// and use the existing template function, but probably this is more clear and +// more sure to get optimized to reasonable code. +static int CalculateReserveForVector(const string& full, const char* delim) { + int count = 0; + if (delim[0] != '\0' && delim[1] == '\0') { + // Optimize the common case where delim is a single character. + char c = delim[0]; + const char* p = full.data(); + const char* end = p + full.size(); + while (p != end) { + if (*p == c) { // This could be optimized with hasless(v,1) trick. + ++p; + } else { + while (++p != end && *p != c) { + // Skip to the next occurence of the delimiter. + } + ++count; + } + } + } + return count; +} + +template +static inline +void SplitStringToIteratorUsing(const StringType& full, + const char* delim, + ITR& result) { + // Optimize the common case where delim is a single character. + if (delim[0] != '\0' && delim[1] == '\0') { + char c = delim[0]; + const char* p = full.data(); + const char* end = p + full.size(); + while (p != end) { + if (*p == c) { + ++p; + } else { + const char* start = p; + while (++p != end && *p != c) { + // Skip to the next occurence of the delimiter. + } + *result++ = StringType(start, p - start); + } + } + return; + } + + string::size_type begin_index, end_index; + begin_index = full.find_first_not_of(delim); + while (begin_index != string::npos) { + end_index = full.find_first_of(delim, begin_index); + if (end_index == string::npos) { + *result++ = full.substr(begin_index); + return; + } + *result++ = full.substr(begin_index, (end_index - begin_index)); + begin_index = full.find_first_not_of(delim, end_index); + } +} + +void SplitStringUsing(const string& full, + const char* delim, + vector* result) { + result->reserve(result->size() + CalculateReserveForVector(full, delim)); + back_insert_iterator< vector > it(*result); + SplitStringToIteratorUsing(full, delim, it); +} + +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/stl_util.h b/extern/libmv/third_party/ceres/internal/ceres/stl_util.h new file mode 100644 index 00000000000..a1a19e8b3ce --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/stl_util.h @@ -0,0 +1,75 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#ifndef CERES_INTERNAL_STL_UTIL_H_ +#define CERES_INTERNAL_STL_UTIL_H_ + +namespace ceres { + +// STLDeleteContainerPointers() +// For a range within a container of pointers, calls delete +// (non-array version) on these pointers. +// NOTE: for these three functions, we could just implement a DeleteObject +// functor and then call for_each() on the range and functor, but this +// requires us to pull in all of algorithm.h, which seems expensive. +// For hash_[multi]set, it is important that this deletes behind the iterator +// because the hash_set may call the hash function on the iterator when it is +// advanced, which could result in the hash function trying to deference a +// stale pointer. +template +void STLDeleteContainerPointers(ForwardIterator begin, + ForwardIterator end) { + while (begin != end) { + ForwardIterator temp = begin; + ++begin; + delete *temp; + } +} + +// STLDeleteElements() deletes all the elements in an STL container and clears +// the container. This function is suitable for use with a vector, set, +// hash_set, or any other STL container which defines sensible begin(), end(), +// and clear() methods. +// +// If container is NULL, this function is a no-op. +// +// As an alternative to calling STLDeleteElements() directly, consider +// ElementDeleter (defined below), which ensures that your container's elements +// are deleted when the ElementDeleter goes out of scope. +template +void STLDeleteElements(T *container) { + if (!container) return; + STLDeleteContainerPointers(container->begin(), container->end()); + container->clear(); +} + +} // namespace ceres + +#endif // CERES_INTERNAL_STL_UTIL_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/stringprintf.cc b/extern/libmv/third_party/ceres/internal/ceres/stringprintf.cc new file mode 100644 index 00000000000..c0f35225bc3 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/stringprintf.cc @@ -0,0 +1,126 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: Sanjay Ghemawat + +#include +#include // For va_list and related operations +#include // MSVC requires this for _vsnprintf +#include +#include + +#include "ceres/internal/port.h" + +namespace ceres { +namespace internal { + +#ifdef _MSC_VER +enum { IS_COMPILER_MSVC = 1 }; +#define va_copy(d,s) ((d) = (s)) +#else +enum { IS_COMPILER_MSVC = 0 }; +#endif + +void StringAppendV(string* dst, const char* format, va_list ap) { + // First try with a small fixed size buffer + char space[1024]; + + // It's possible for methods that use a va_list to invalidate + // the data in it upon use. The fix is to make a copy + // of the structure before using it and use that copy instead. + va_list backup_ap; + va_copy(backup_ap, ap); + int result = vsnprintf(space, sizeof(space), format, backup_ap); + va_end(backup_ap); + + if (result < sizeof(space)) { + if (result >= 0) { + // Normal case -- everything fit. + dst->append(space, result); + return; + } + + if (IS_COMPILER_MSVC) { + // Error or MSVC running out of space. MSVC 8.0 and higher + // can be asked about space needed with the special idiom below: + va_copy(backup_ap, ap); + result = vsnprintf(NULL, 0, format, backup_ap); + va_end(backup_ap); + } + + if (result < 0) { + // Just an error. + return; + } + } + + // Increase the buffer size to the size requested by vsnprintf, + // plus one for the closing \0. + int length = result+1; + char* buf = new char[length]; + + // Restore the va_list before we use it again + va_copy(backup_ap, ap); + result = vsnprintf(buf, length, format, backup_ap); + va_end(backup_ap); + + if (result >= 0 && result < length) { + // It fit + dst->append(buf, result); + } + delete[] buf; +} + + +string StringPrintf(const char* format, ...) { + va_list ap; + va_start(ap, format); + string result; + StringAppendV(&result, format, ap); + va_end(ap); + return result; +} + +const string& SStringPrintf(string* dst, const char* format, ...) { + va_list ap; + va_start(ap, format); + dst->clear(); + StringAppendV(dst, format, ap); + va_end(ap); + return *dst; +} + +void StringAppendF(string* dst, const char* format, ...) { + va_list ap; + va_start(ap, format); + StringAppendV(dst, format, ap); + va_end(ap); +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/stringprintf.h b/extern/libmv/third_party/ceres/internal/ceres/stringprintf.h new file mode 100644 index 00000000000..30b974e7ae5 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/stringprintf.h @@ -0,0 +1,89 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: Sanjay Ghemawat +// +// Printf variants that place their output in a C++ string. +// +// Usage: +// string result = StringPrintf("%d %s\n", 10, "hello"); +// SStringPrintf(&result, "%d %s\n", 10, "hello"); +// StringAppendF(&result, "%d %s\n", 20, "there"); + +#ifndef CERES_INTERNAL_STRINGPRINTF_H_ +#define CERES_INTERNAL_STRINGPRINTF_H_ + +#include +#include + +#include "ceres/internal/port.h" + +namespace ceres { +namespace internal { + +#if (defined(__GNUC__) || defined(__clang__)) +// Tell the compiler to do printf format string checking if the compiler +// supports it; see the 'format' attribute in +// . +// +// N.B.: As the GCC manual states, "[s]ince non-static C++ methods +// have an implicit 'this' argument, the arguments of such methods +// should be counted from two, not one." +#define PRINTF_ATTRIBUTE(string_index, first_to_check) \ + __attribute__((__format__ (__printf__, string_index, first_to_check))) +#define SCANF_ATTRIBUTE(string_index, first_to_check) \ + __attribute__((__format__ (__scanf__, string_index, first_to_check))) +#else +#define PRINTF_ATTRIBUTE(string_index, first_to_check) +#endif + +// Return a C++ string. +extern string StringPrintf(const char* format, ...) + // Tell the compiler to do printf format string checking. + PRINTF_ATTRIBUTE(1,2); + +// Store result into a supplied string and return it. +extern const string& SStringPrintf(string* dst, const char* format, ...) + // Tell the compiler to do printf format string checking. + PRINTF_ATTRIBUTE(2,3); + +// Append result to a supplied string. +extern void StringAppendF(string* dst, const char* format, ...) + // Tell the compiler to do printf format string checking. + PRINTF_ATTRIBUTE(2,3); + +// Lower-level routine that takes a va_list and appends to a specified string. +// All other routines are just convenience wrappers around it. +extern void StringAppendV(string* dst, const char* format, va_list ap); + +#undef PRINTF_ATTRIBUTE + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_STRINGPRINTF_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc new file mode 100644 index 00000000000..1cf6a7496a7 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc @@ -0,0 +1,193 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_NO_SUITESPARSE + +#include "ceres/suitesparse.h" + +#include "cholmod.h" +#include "ceres/compressed_row_sparse_matrix.h" +#include "ceres/triplet_sparse_matrix.h" +namespace ceres { +namespace internal { + +cholmod_sparse* SuiteSparse::CreateSparseMatrix(TripletSparseMatrix* A) { + cholmod_triplet triplet; + + triplet.nrow = A->num_rows(); + triplet.ncol = A->num_cols(); + triplet.nzmax = A->max_num_nonzeros(); + triplet.nnz = A->num_nonzeros(); + triplet.i = reinterpret_cast(A->mutable_rows()); + triplet.j = reinterpret_cast(A->mutable_cols()); + triplet.x = reinterpret_cast(A->mutable_values()); + triplet.stype = 0; // Matrix is not symmetric. + triplet.itype = CHOLMOD_INT; + triplet.xtype = CHOLMOD_REAL; + triplet.dtype = CHOLMOD_DOUBLE; + + return cholmod_triplet_to_sparse(&triplet, triplet.nnz, &cc_); +} + + +cholmod_sparse* SuiteSparse::CreateSparseMatrixTranspose( + TripletSparseMatrix* A) { + cholmod_triplet triplet; + + triplet.ncol = A->num_rows(); // swap row and columns + triplet.nrow = A->num_cols(); + triplet.nzmax = A->max_num_nonzeros(); + triplet.nnz = A->num_nonzeros(); + + // swap rows and columns + triplet.j = reinterpret_cast(A->mutable_rows()); + triplet.i = reinterpret_cast(A->mutable_cols()); + triplet.x = reinterpret_cast(A->mutable_values()); + triplet.stype = 0; // Matrix is not symmetric. + triplet.itype = CHOLMOD_INT; + triplet.xtype = CHOLMOD_REAL; + triplet.dtype = CHOLMOD_DOUBLE; + + return cholmod_triplet_to_sparse(&triplet, triplet.nnz, &cc_); +} + +cholmod_sparse* SuiteSparse::CreateSparseMatrixTransposeView( + CompressedRowSparseMatrix* A) { + cholmod_sparse* m = new cholmod_sparse_struct; + m->nrow = A->num_cols(); + m->ncol = A->num_rows(); + m->nzmax = A->num_nonzeros(); + + m->p = reinterpret_cast(A->mutable_rows()); + m->i = reinterpret_cast(A->mutable_cols()); + m->x = reinterpret_cast(A->mutable_values()); + + m->stype = 0; // Matrix is not symmetric. + m->itype = CHOLMOD_INT; + m->xtype = CHOLMOD_REAL; + m->dtype = CHOLMOD_DOUBLE; + m->sorted = 1; + m->packed = 1; + + return m; +} + +cholmod_dense* SuiteSparse::CreateDenseVector(const double* x, + int in_size, + int out_size) { + CHECK_LE(in_size, out_size); + cholmod_dense* v = cholmod_zeros(out_size, 1, CHOLMOD_REAL, &cc_); + if (x != NULL) { + memcpy(v->x, x, in_size*sizeof(*x)); + } + return v; +} + +cholmod_factor* SuiteSparse::AnalyzeCholesky(cholmod_sparse* A) { + cholmod_factor* factor = cholmod_analyze(A, &cc_); + CHECK_EQ(cc_.status, CHOLMOD_OK) + << "Cholmod symbolic analysis failed " << cc_.status; + CHECK_NOTNULL(factor); + return factor; +} + +bool SuiteSparse::Cholesky(cholmod_sparse* A, cholmod_factor* L) { + CHECK_NOTNULL(A); + CHECK_NOTNULL(L); + + cc_.quick_return_if_not_posdef = 1; + int status = cholmod_factorize(A, L, &cc_); + switch (cc_.status) { + case CHOLMOD_NOT_INSTALLED: + LOG(WARNING) << "Cholmod failure: method not installed."; + return false; + case CHOLMOD_OUT_OF_MEMORY: + LOG(WARNING) << "Cholmod failure: out of memory."; + return false; + case CHOLMOD_TOO_LARGE: + LOG(WARNING) << "Cholmod failure: integer overflow occured."; + return false; + case CHOLMOD_INVALID: + LOG(WARNING) << "Cholmod failure: invalid input."; + return false; + case CHOLMOD_NOT_POSDEF: + // TODO(sameeragarwal): These two warnings require more + // sophisticated handling going forward. For now we will be + // strict and treat them as failures. + LOG(WARNING) << "Cholmod warning: matrix not positive definite."; + return false; + case CHOLMOD_DSMALL: + LOG(WARNING) << "Cholmod warning: D for LDL' or diag(L) or " + << "LL' has tiny absolute value."; + return false; + case CHOLMOD_OK: + if (status != 0) { + return true; + } + LOG(WARNING) << "Cholmod failure: cholmod_factorize returned zero " + << "but cholmod_common::status is CHOLMOD_OK." + << "Please report this to ceres-solver@googlegroups.com."; + return false; + default: + LOG(WARNING) << "Unknown cholmod return code. " + << "Please report this to ceres-solver@googlegroups.com."; + return false; + } + return false; +} + +cholmod_dense* SuiteSparse::Solve(cholmod_factor* L, + cholmod_dense* b) { + if (cc_.status != CHOLMOD_OK) { + LOG(WARNING) << "CHOLMOD status NOT OK"; + return NULL; + } + + return cholmod_solve(CHOLMOD_A, L, b, &cc_); +} + +cholmod_dense* SuiteSparse::SolveCholesky(cholmod_sparse* A, + cholmod_factor* L, + cholmod_dense* b) { + CHECK_NOTNULL(A); + CHECK_NOTNULL(L); + CHECK_NOTNULL(b); + + if (Cholesky(A, L)) { + return Solve(L, b); + } + + return NULL; +} + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_SUITESPARSE diff --git a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h new file mode 100644 index 00000000000..091e67a69a9 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h @@ -0,0 +1,159 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// A simple C++ interface to the SuiteSparse and CHOLMOD libraries. + +#ifndef CERES_INTERNAL_SUITESPARSE_H_ +#define CERES_INTERNAL_SUITESPARSE_H_ + +#ifndef CERES_NO_SUITESPARSE + +#include +#include + +#include +#include "cholmod.h" +#include "ceres/internal/port.h" + +namespace ceres { +namespace internal { + +class CompressedRowSparseMatrix; +class TripletSparseMatrix; + +// The raw CHOLMOD and SuiteSparseQR libraries have a slightly +// cumbersome c like calling format. This object abstracts it away and +// provides the user with a simpler interface. The methods here cannot +// be static as a cholmod_common object serves as a global variable +// for all cholmod function calls. +class SuiteSparse { + public: + SuiteSparse() { cholmod_start(&cc_); } + ~SuiteSparse() { cholmod_finish(&cc_); } + + // Functions for building cholmod_sparse objects from sparse + // matrices stored in triplet form. The matrix A is not + // modifed. Called owns the result. + cholmod_sparse* CreateSparseMatrix(TripletSparseMatrix* A); + + // This function works like CreateSparseMatrix, except that the + // return value corresponds to A' rather than A. + cholmod_sparse* CreateSparseMatrixTranspose(TripletSparseMatrix* A); + + // Create a cholmod_sparse wrapper around the contents of A. This is + // a shallow object, which refers to the contents of A and does not + // use the SuiteSparse machinery to allocate memory, this object + // should be disposed off with a delete and not a call to Free as is + // the case for objects returned by CreateSparseMatrixTranspose. + cholmod_sparse* CreateSparseMatrixTransposeView(CompressedRowSparseMatrix* A); + + // Given a vector x, build a cholmod_dense vector of size out_size + // with the first in_size entries copied from x. If x is NULL, then + // an all zeros vector is returned. Caller owns the result. + cholmod_dense* CreateDenseVector(const double* x, int in_size, int out_size); + + // The matrix A is scaled using the matrix whose diagonal is the + // vector scale. mode describes how scaling is applied. Possible + // values are CHOLMOD_ROW for row scaling - diag(scale) * A, + // CHOLMOD_COL for column scaling - A * diag(scale) and CHOLMOD_SYM + // for symmetric scaling which scales both the rows and the columns + // - diag(scale) * A * diag(scale). + void Scale(cholmod_dense* scale, int mode, cholmod_sparse* A) { + cholmod_scale(scale, mode, A, &cc_); + } + + // Create and return a matrix m = A * A'. Caller owns the + // result. The matrix A is not modified. + cholmod_sparse* AATranspose(cholmod_sparse* A) { + cholmod_sparse*m = cholmod_aat(A, NULL, A->nrow, 1, &cc_); + m->stype = 1; // Pay attention to the upper triangular part. + return m; + } + + // y = alpha * A * x + beta * y. Only y is modified. + void SparseDenseMultiply(cholmod_sparse* A, double alpha, double beta, + cholmod_dense* x, cholmod_dense* y) { + double alpha_[2] = {alpha, 0}; + double beta_[2] = {beta, 0}; + cholmod_sdmult(A, 0, alpha_, beta_, x, y, &cc_); + } + + // Analyze the sparsity structure of the matrix A compute the + // symbolic factorization of A. A is not modified, only the pattern + // of non-zeros of A is used, the actual numerical values in A are + // of no consequence. Caller owns the result. + cholmod_factor* AnalyzeCholesky(cholmod_sparse* A); + + // Use the symbolic factorization in L, to find the numerical + // factorization for the matrix A or AA^T. Return true if + // successful, false otherwise. L contains the numeric factorization + // on return. + bool Cholesky(cholmod_sparse* A, cholmod_factor* L); + + // Given a Cholesky factorization of a matrix A = LL^T, solve the + // linear system Ax = b, and return the result. If the Solve fails + // NULL is returned. Caller owns the result. + cholmod_dense* Solve(cholmod_factor* L, cholmod_dense* b); + + // Combine the calls to Cholesky and Solve into a single call. If + // the cholesky factorization or the solve fails, return + // NULL. Caller owns the result. + cholmod_dense* SolveCholesky(cholmod_sparse* A, + cholmod_factor* L, + cholmod_dense* b); + + void Free(cholmod_sparse* m) { cholmod_free_sparse(&m, &cc_); } + void Free(cholmod_dense* m) { cholmod_free_dense(&m, &cc_); } + void Free(cholmod_factor* m) { cholmod_free_factor(&m, &cc_); } + + void Print(cholmod_sparse* m, const string& name) { + cholmod_print_sparse(m, const_cast(name.c_str()), &cc_); + } + + void Print(cholmod_dense* m, const string& name) { + cholmod_print_dense(m, const_cast(name.c_str()), &cc_); + } + + void Print(cholmod_triplet* m, const string& name) { + cholmod_print_triplet(m, const_cast(name.c_str()), &cc_); + } + + cholmod_common* mutable_cc() { return &cc_; } + + private: + cholmod_common cc_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_NO_SUITESPARSE + +#endif // CERES_INTERNAL_SUITESPARSE_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc new file mode 100644 index 00000000000..7d7c3df9960 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc @@ -0,0 +1,299 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/triplet_sparse_matrix.h" + +#include +#include +#include +#include "ceres/matrix_proto.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/port.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +TripletSparseMatrix::TripletSparseMatrix() + : num_rows_(0), + num_cols_(0), + max_num_nonzeros_(0), + num_nonzeros_(0), + rows_(NULL), + cols_(NULL), + values_(NULL) {} + +TripletSparseMatrix::~TripletSparseMatrix() {} + +TripletSparseMatrix::TripletSparseMatrix(int num_rows, + int num_cols, + int max_num_nonzeros) + : num_rows_(num_rows), + num_cols_(num_cols), + max_num_nonzeros_(max_num_nonzeros), + num_nonzeros_(0), + rows_(NULL), + cols_(NULL), + values_(NULL) { + // All the sizes should at least be zero + CHECK_GE(num_rows, 0); + CHECK_GE(num_cols, 0); + CHECK_GE(max_num_nonzeros, 0); + AllocateMemory(); +} + +TripletSparseMatrix::TripletSparseMatrix(const TripletSparseMatrix& orig) + : num_rows_(orig.num_rows_), + num_cols_(orig.num_cols_), + max_num_nonzeros_(orig.max_num_nonzeros_), + num_nonzeros_(orig.num_nonzeros_), + rows_(NULL), + cols_(NULL), + values_(NULL) { + AllocateMemory(); + CopyData(orig); +} + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +TripletSparseMatrix::TripletSparseMatrix(const SparseMatrixProto& outer_proto) { + CHECK(outer_proto.has_triplet_matrix()); + + const TripletSparseMatrixProto& proto = outer_proto.triplet_matrix(); + CHECK(proto.has_num_rows()); + CHECK(proto.has_num_cols()); + CHECK_EQ(proto.rows_size(), proto.cols_size()); + CHECK_EQ(proto.cols_size(), proto.values_size()); + + // Initialize the matrix with the appropriate size and capacity. + max_num_nonzeros_ = 0; + set_num_nonzeros(0); + Reserve(proto.num_nonzeros()); + Resize(proto.num_rows(), proto.num_cols()); + set_num_nonzeros(proto.num_nonzeros()); + + // Copy the entries in. + for (int i = 0; i < proto.num_nonzeros(); ++i) { + rows_[i] = proto.rows(i); + cols_[i] = proto.cols(i); + values_[i] = proto.values(i); + } +} +#endif + +TripletSparseMatrix& TripletSparseMatrix::operator=( + const TripletSparseMatrix& rhs) { + num_rows_ = rhs.num_rows_; + num_cols_ = rhs.num_cols_; + num_nonzeros_ = rhs.num_nonzeros_; + max_num_nonzeros_ = rhs.max_num_nonzeros_; + AllocateMemory(); + CopyData(rhs); + return *this; +} + +bool TripletSparseMatrix::AllTripletsWithinBounds() const { + for (int i = 0; i < num_nonzeros_; ++i) { + if ((rows_[i] < 0) || (rows_[i] >= num_rows_) || + (cols_[i] < 0) || (cols_[i] >= num_cols_)) + return false; + } + return true; +} + +void TripletSparseMatrix::Reserve(int new_max_num_nonzeros) { + CHECK_LE(num_nonzeros_, new_max_num_nonzeros) + << "Reallocation will cause data loss"; + + // Nothing to do if we have enough space already. + if (new_max_num_nonzeros <= max_num_nonzeros_) + return; + + int* new_rows = new int[new_max_num_nonzeros]; + int* new_cols = new int[new_max_num_nonzeros]; + double* new_values = new double[new_max_num_nonzeros]; + + for (int i = 0; i < num_nonzeros_; ++i) { + new_rows[i] = rows_[i]; + new_cols[i] = cols_[i]; + new_values[i] = values_[i]; + } + + rows_.reset(new_rows); + cols_.reset(new_cols); + values_.reset(new_values); + + max_num_nonzeros_ = new_max_num_nonzeros; +} + +void TripletSparseMatrix::SetZero() { + fill(values_.get(), values_.get() + max_num_nonzeros_, 0.0); + num_nonzeros_ = 0; +} + +void TripletSparseMatrix::set_num_nonzeros(int num_nonzeros) { + CHECK_GE(num_nonzeros, 0); + CHECK_LE(num_nonzeros, max_num_nonzeros_); + num_nonzeros_ = num_nonzeros; +}; + +void TripletSparseMatrix::AllocateMemory() { + rows_.reset(new int[max_num_nonzeros_]); + cols_.reset(new int[max_num_nonzeros_]); + values_.reset(new double[max_num_nonzeros_]); +} + +void TripletSparseMatrix::CopyData(const TripletSparseMatrix& orig) { + for (int i = 0; i < num_nonzeros_; ++i) { + rows_[i] = orig.rows_[i]; + cols_[i] = orig.cols_[i]; + values_[i] = orig.values_[i]; + } +} + +void TripletSparseMatrix::RightMultiply(const double* x, double* y) const { + for (int i = 0; i < num_nonzeros_; ++i) { + y[rows_[i]] += values_[i]*x[cols_[i]]; + } +} + +void TripletSparseMatrix::LeftMultiply(const double* x, double* y) const { + for (int i = 0; i < num_nonzeros_; ++i) { + y[cols_[i]] += values_[i]*x[rows_[i]]; + } +} + +void TripletSparseMatrix::SquaredColumnNorm(double* x) const { + CHECK_NOTNULL(x); + VectorRef(x, num_cols_).setZero(); + for (int i = 0; i < num_nonzeros_; ++i) { + x[cols_[i]] += values_[i] * values_[i]; + } +} + +void TripletSparseMatrix::ScaleColumns(const double* scale) { + CHECK_NOTNULL(scale); + for (int i = 0; i < num_nonzeros_; ++i) { + values_[i] = values_[i] * scale[cols_[i]]; + } +} + +void TripletSparseMatrix::ToDenseMatrix(Matrix* dense_matrix) const { + dense_matrix->resize(num_rows_, num_cols_); + dense_matrix->setZero(); + Matrix& m = *dense_matrix; + for (int i = 0; i < num_nonzeros_; ++i) { + m(rows_[i], cols_[i]) += values_[i]; + } +} + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +void TripletSparseMatrix::ToProto(SparseMatrixProto *proto) const { + proto->Clear(); + + TripletSparseMatrixProto* tsm_proto = proto->mutable_triplet_matrix(); + tsm_proto->set_num_rows(num_rows_); + tsm_proto->set_num_cols(num_cols_); + tsm_proto->set_num_nonzeros(num_nonzeros_); + for (int i = 0; i < num_nonzeros_; ++i) { + tsm_proto->add_rows(rows_[i]); + tsm_proto->add_cols(cols_[i]); + tsm_proto->add_values(values_[i]); + } +} +#endif + +void TripletSparseMatrix::AppendRows(const TripletSparseMatrix& B) { + CHECK_EQ(B.num_cols(), num_cols_); + Reserve(num_nonzeros_ + B.num_nonzeros_); + for (int i = 0; i < B.num_nonzeros_; ++i) { + rows_.get()[num_nonzeros_] = B.rows()[i] + num_rows_; + cols_.get()[num_nonzeros_] = B.cols()[i]; + values_.get()[num_nonzeros_++] = B.values()[i]; + } + num_rows_ = num_rows_ + B.num_rows(); +} + +void TripletSparseMatrix::AppendCols(const TripletSparseMatrix& B) { + CHECK_EQ(B.num_rows(), num_rows_); + Reserve(num_nonzeros_ + B.num_nonzeros_); + for (int i = 0; i < B.num_nonzeros_; ++i, ++num_nonzeros_) { + rows_.get()[num_nonzeros_] = B.rows()[i]; + cols_.get()[num_nonzeros_] = B.cols()[i] + num_cols_; + values_.get()[num_nonzeros_] = B.values()[i]; + } + num_cols_ = num_cols_ + B.num_cols(); +} + + +void TripletSparseMatrix::Resize(int new_num_rows, int new_num_cols) { + if ((new_num_rows >= num_rows_) && (new_num_cols >= num_cols_)) { + num_rows_ = new_num_rows; + num_cols_ = new_num_cols; + return; + } + + num_rows_ = new_num_rows; + num_cols_ = new_num_cols; + + int* r_ptr = rows_.get(); + int* c_ptr = cols_.get(); + double* v_ptr = values_.get(); + + int dropped_terms = 0; + for (int i = 0; i < num_nonzeros_; ++i) { + if ((r_ptr[i] < num_rows_) && (c_ptr[i] < num_cols_)) { + if (dropped_terms) { + r_ptr[i-dropped_terms] = r_ptr[i]; + c_ptr[i-dropped_terms] = c_ptr[i]; + v_ptr[i-dropped_terms] = v_ptr[i]; + } + } else { + ++dropped_terms; + } + } + num_nonzeros_ -= dropped_terms; +} + +TripletSparseMatrix* TripletSparseMatrix::CreateSparseDiagonalMatrix( + const double* values, int num_rows) { + TripletSparseMatrix* m = + new TripletSparseMatrix(num_rows, num_rows, num_rows); + for (int i = 0; i < num_rows; ++i) { + m->mutable_rows()[i] = i; + m->mutable_cols()[i] = i; + m->mutable_values()[i] = values[i]; + } + m->set_num_nonzeros(num_rows); + return m; +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.h new file mode 100644 index 00000000000..3c90a62fd20 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.h @@ -0,0 +1,136 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#ifndef CERES_INTERNAL_TRIPLET_SPARSE_MATRIX_H_ +#define CERES_INTERNAL_TRIPLET_SPARSE_MATRIX_H_ + +#include "ceres/sparse_matrix.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" +#include "ceres/types.h" + +namespace ceres { +namespace internal { + +class SparseMatrixProto; + +// An implementation of the SparseMatrix interface to store and +// manipulate sparse matrices in triplet (i,j,s) form. This object is +// inspired by the design of the cholmod_triplet struct used in the +// SuiteSparse package and is memory layout compatible with it. +class TripletSparseMatrix : public SparseMatrix { + public: + TripletSparseMatrix(); + TripletSparseMatrix(int num_rows, int num_cols, int max_num_nonzeros); + explicit TripletSparseMatrix(const TripletSparseMatrix& orig); +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS + explicit TripletSparseMatrix(const SparseMatrixProto& proto); +#endif + + TripletSparseMatrix& operator=(const TripletSparseMatrix& rhs); + + ~TripletSparseMatrix(); + + // Implementation of the SparseMatrix interface. + virtual void SetZero(); + virtual void RightMultiply(const double* x, double* y) const; + virtual void LeftMultiply(const double* x, double* y) const; + virtual void SquaredColumnNorm(double* x) const; + virtual void ScaleColumns(const double* scale); + virtual void ToDenseMatrix(Matrix* dense_matrix) const; +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS + virtual void ToProto(SparseMatrixProto *proto) const; +#endif + virtual int num_rows() const { return num_rows_; } + virtual int num_cols() const { return num_cols_; } + virtual int num_nonzeros() const { return num_nonzeros_; } + virtual const double* values() const { return values_.get(); } + virtual double* mutable_values() { return values_.get(); } + virtual void set_num_nonzeros(int num_nonzeros); + + // Increase max_num_nonzeros and correspondingly increase the size + // of rows_, cols_ and values_. If new_max_num_nonzeros is smaller + // than max_num_nonzeros_, then num_non_zeros should be less than or + // equal to new_max_num_nonzeros, otherwise data loss is possible + // and the method crashes. + void Reserve(int new_max_num_nonzeros); + + // Append the matrix B at the bottom of this matrix. B should have + // the same number of columns as num_cols_. + void AppendRows(const TripletSparseMatrix& B); + + // Append the matrix B at the right of this matrix. B should have + // the same number of rows as num_rows_; + void AppendCols(const TripletSparseMatrix& B); + + // Resize the matrix. Entries which fall outside the new matrix + // bounds are dropped and the num_non_zeros changed accordingly. + void Resize(int new_num_rows, int new_num_cols); + + int max_num_nonzeros() const { return max_num_nonzeros_; } + const int* rows() const { return rows_.get(); } + const int* cols() const { return cols_.get(); } + int* mutable_rows() { return rows_.get(); } + int* mutable_cols() { return cols_.get(); } + + // Returns true if the entries of the matrix obey the row, column, + // and column size bounds and false otherwise. + bool AllTripletsWithinBounds() const; + + bool IsValid() const { return AllTripletsWithinBounds(); } + + // Build a sparse diagonal matrix of size num_rows x num_rows from + // the array values. Entries of the values array are copied into the + // sparse matrix. + static TripletSparseMatrix* CreateSparseDiagonalMatrix(const double* values, + int num_rows); + + private: + void AllocateMemory(); + void CopyData(const TripletSparseMatrix& orig); + + int num_rows_; + int num_cols_; + int max_num_nonzeros_; + int num_nonzeros_; + + // The data is stored as three arrays. For each i, values_[i] is + // stored at the location (rows_[i], cols_[i]). If the there are + // multiple entries with the same (rows_[i], cols_[i]), the values_ + // entries corresponding to them are summed up. + scoped_array rows_; + scoped_array cols_; + scoped_array values_; +}; + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_TRIPLET_SPARSE_MATRIX_H__ diff --git a/extern/libmv/third_party/ceres/internal/ceres/types.cc b/extern/libmv/third_party/ceres/internal/ceres/types.cc new file mode 100644 index 00000000000..860f8a43f37 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/types.cc @@ -0,0 +1,98 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include +#include "ceres/types.h" + +namespace ceres { + +#define CASESTR(x) case x: return #x + +const char* LinearSolverTypeToString(LinearSolverType solver_type) { + switch (solver_type) { + CASESTR(SPARSE_NORMAL_CHOLESKY); + CASESTR(DENSE_QR); + CASESTR(DENSE_SCHUR); + CASESTR(SPARSE_SCHUR); + CASESTR(ITERATIVE_SCHUR); + CASESTR(CGNR); + default: + return "UNKNOWN"; + } +} + +const char* PreconditionerTypeToString( + PreconditionerType preconditioner_type) { + switch (preconditioner_type) { + CASESTR(IDENTITY); + CASESTR(JACOBI); + CASESTR(SCHUR_JACOBI); + CASESTR(CLUSTER_JACOBI); + CASESTR(CLUSTER_TRIDIAGONAL); + default: + return "UNKNOWN"; + } +} + +const char* OrderingTypeToString(OrderingType ordering_type) { + switch (ordering_type) { + CASESTR(NATURAL); + CASESTR(USER); + CASESTR(SCHUR); + default: + return "UNKNOWN"; + } +} + +const char* SolverTerminationTypeToString( + SolverTerminationType termination_type) { + switch (termination_type) { + CASESTR(NO_CONVERGENCE); + CASESTR(FUNCTION_TOLERANCE); + CASESTR(GRADIENT_TOLERANCE); + CASESTR(PARAMETER_TOLERANCE); + CASESTR(NUMERICAL_FAILURE); + CASESTR(USER_ABORT); + CASESTR(USER_SUCCESS); + CASESTR(DID_NOT_RUN); + default: + return "UNKNOWN"; + } +} + +#undef CASESTR + +bool IsSchurType(LinearSolverType type) { + return ((type == SPARSE_SCHUR) || + (type == DENSE_SCHUR) || + (type == ITERATIVE_SCHUR)); +} + +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility.cc b/extern/libmv/third_party/ceres/internal/ceres/visibility.cc new file mode 100644 index 00000000000..fd41648a7af --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/visibility.cc @@ -0,0 +1,150 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: kushalav@google.com (Avanish Kushal) + +#include +#include +#include +#include +#include +#include + +#include +#include "ceres/block_structure.h" +#include "ceres/collections_port.h" +#include "ceres/graph.h" + +namespace ceres { +namespace internal { + +void ComputeVisibility(const CompressedRowBlockStructure& block_structure, + const int num_eliminate_blocks, + vector< set >* visibility) { + CHECK_NOTNULL(visibility); + + // Clear the visibility vector and resize it to hold a + // vector for each camera. + visibility->resize(0); + visibility->resize(block_structure.cols.size() - num_eliminate_blocks); + + for (int i = 0; i < block_structure.rows.size(); ++i) { + const vector& cells = block_structure.rows[i].cells; + int block_id = cells[0].block_id; + // If the first block is not an e_block, then skip this row block. + if (block_id >= num_eliminate_blocks) { + continue; + } + + for (int j = 1; j < cells.size(); ++j) { + int camera_block_id = cells[j].block_id - num_eliminate_blocks; + DCHECK_GE(camera_block_id, 0); + DCHECK_LT(camera_block_id, visibility->size()); + (*visibility)[camera_block_id].insert(block_id); + } + } +} + +Graph* CreateSchurComplementGraph(const vector >& visibility) { + const time_t start_time = time(NULL); + // Compute the number of e_blocks/point blocks. Since the visibility + // set for each e_block/camera contains the set of e_blocks/points + // visible to it, we find the maximum across all visibility sets. + int num_points = 0; + for (int i = 0; i < visibility.size(); i++) { + if (visibility[i].size() > 0) { + num_points = max(num_points, (*visibility[i].rbegin()) + 1); + } + } + + // Invert the visibility. The input is a camera->point mapping, + // which tells us which points are visible in which + // cameras. However, to compute the sparsity structure of the Schur + // Complement efficiently, its better to have the point->camera + // mapping. + vector > inverse_visibility(num_points); + for (int i = 0; i < visibility.size(); i++) { + const set& visibility_set = visibility[i]; + for (set::const_iterator it = visibility_set.begin(); + it != visibility_set.end(); + ++it) { + inverse_visibility[*it].insert(i); + } + } + + // Map from camera pairs to number of points visible to both cameras + // in the pair. + HashMap, int > camera_pairs; + + // Count the number of points visible to each camera/f_block pair. + for (vector >::const_iterator it = inverse_visibility.begin(); + it != inverse_visibility.end(); + ++it) { + const set& inverse_visibility_set = *it; + for (set::const_iterator camera1 = inverse_visibility_set.begin(); + camera1 != inverse_visibility_set.end(); + ++camera1) { + set::const_iterator camera2 = camera1; + for (++camera2; camera2 != inverse_visibility_set.end(); ++camera2) { + ++(camera_pairs[make_pair(*camera1, *camera2)]); + } + } + } + + Graph* graph = new Graph(); + + // Add vertices and initialize the pairs for self edges so that self + // edges are guaranteed. This is needed for the Canonical views + // algorithm to work correctly. + static const double kSelfEdgeWeight = 1.0; + for (int i = 0; i < visibility.size(); ++i) { + graph->AddVertex(i); + graph->AddEdge(i, i, kSelfEdgeWeight); + } + + // Add an edge for each camera pair. + for (HashMap, int>::const_iterator it = camera_pairs.begin(); + it != camera_pairs.end(); + ++it) { + const int camera1 = it->first.first; + const int camera2 = it->first.second; + CHECK_NE(camera1, camera2); + + const int count = it->second; + // Static cast necessary for Windows. + const double weight = static_cast(count) / + (sqrt(static_cast(visibility[camera1].size() * visibility[camera2].size()))); + graph->AddEdge(camera1, camera2, weight); + } + + VLOG(2) << "Schur complement graph time: " << (time(NULL) - start_time); + return graph; +} + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility.h b/extern/libmv/third_party/ceres/internal/ceres/visibility.h new file mode 100644 index 00000000000..692dd87201e --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/visibility.h @@ -0,0 +1,77 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: kushalav@google.com (Avanish Kushal) +// sameeragarwal@google.com (Sameer Agarwal) +// +// Functions to manipulate visibility information from the block +// structure of sparse matrices. + +#ifndef CERES_INTERNAL_VISIBILITY_H_ +#define CERES_INTERNAL_VISIBILITY_H_ + +#include +#include +#include "ceres/graph.h" + +namespace ceres { +namespace internal { + +class CompressedRowBlockStructure; + +// Given a compressed row block structure, computes the set of +// e_blocks "visible" to each f_block. If an e_block co-occurs with an +// f_block in a residual block, it is visible to the f_block. The +// first num_eliminate_blocks columns blocks are e_blocks and the rest +// f_blocks. +// +// In a structure from motion problem, e_blocks correspond to 3D +// points and f_blocks correspond to cameras. +void ComputeVisibility(const CompressedRowBlockStructure& block_structure, + int num_eliminate_blocks, + vector >* visibility); + +// Given f_block visibility as computed by the ComputeVisibility +// function above, construct and return a graph whose vertices are +// f_blocks and an edge connects two vertices if they have atleast one +// e_block in common. The weight of this edge is normalized dot +// product between the visibility vectors of the two +// vertices/f_blocks. +// +// This graph reflects the sparsity structure of reduced camera +// matrix/Schur complement matrix obtained by eliminating the e_blocks +// from the normal equations. +// +// Caller acquires ownership of the returned Graph pointer +// (heap-allocated). +Graph* CreateSchurComplementGraph(const vector >& visibility); + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_VISIBILITY_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc new file mode 100644 index 00000000000..aca77528215 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc @@ -0,0 +1,611 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) + +#include "ceres/visibility_based_preconditioner.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Eigen/Dense" +#include "ceres/block_random_access_sparse_matrix.h" +#include "ceres/block_sparse_matrix.h" +#include "ceres/canonical_views_clustering.h" +#include "ceres/collections_port.h" +#include "ceres/detect_structure.h" +#include "ceres/graph.h" +#include "ceres/graph_algorithms.h" +#include "ceres/linear_solver.h" +#include "ceres/schur_eliminator.h" +#include "ceres/visibility.h" +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { + +// TODO(sameeragarwal): Currently these are magic weights for the +// preconditioner construction. Move these higher up into the Options +// struct and provide some guidelines for choosing them. +// +// This will require some more work on the clustering algorithm and +// possibly some more refactoring of the code. +static const double kSizePenaltyWeight = 3.0; +static const double kSimilarityPenaltyWeight = 0.0; + +#ifndef CERES_NO_SUITESPARSE +VisibilityBasedPreconditioner::VisibilityBasedPreconditioner( + const CompressedRowBlockStructure& bs, + const LinearSolver::Options& options) + : options_(options), + num_blocks_(0), + num_clusters_(0), + factor_(NULL) { + CHECK_GT(options_.num_eliminate_blocks, 0); + CHECK(options_.preconditioner_type == SCHUR_JACOBI || + options_.preconditioner_type == CLUSTER_JACOBI || + options_.preconditioner_type == CLUSTER_TRIDIAGONAL) + << "Unknown preconditioner type: " << options_.preconditioner_type; + num_blocks_ = bs.cols.size() - options_.num_eliminate_blocks; + CHECK_GT(num_blocks_, 0) + << "Jacobian should have atleast 1 f_block for " + << "visibility based preconditioning."; + + // Vector of camera block sizes + block_size_.resize(num_blocks_); + for (int i = 0; i < num_blocks_; ++i) { + block_size_[i] = bs.cols[i + options_.num_eliminate_blocks].size; + } + + const time_t start_time = time(NULL); + switch (options_.preconditioner_type) { + case SCHUR_JACOBI: + ComputeSchurJacobiSparsity(bs); + break; + case CLUSTER_JACOBI: + ComputeClusterJacobiSparsity(bs); + break; + case CLUSTER_TRIDIAGONAL: + ComputeClusterTridiagonalSparsity(bs); + break; + default: + LOG(FATAL) << "Unknown preconditioner type"; + } + const time_t structure_time = time(NULL); + InitStorage(bs); + const time_t storage_time = time(NULL); + InitEliminator(bs); + const time_t eliminator_time = time(NULL); + + // Allocate temporary storage for a vector used during + // RightMultiply. + tmp_rhs_ = CHECK_NOTNULL(ss_.CreateDenseVector(NULL, + m_->num_rows(), + m_->num_rows())); + const time_t init_time = time(NULL); + VLOG(2) << "init time: " + << init_time - start_time + << " structure time: " << structure_time - start_time + << " storage time:" << storage_time - structure_time + << " eliminator time: " << eliminator_time - storage_time; +} + +VisibilityBasedPreconditioner::~VisibilityBasedPreconditioner() { + if (factor_ != NULL) { + ss_.Free(factor_); + factor_ = NULL; + } + if (tmp_rhs_ != NULL) { + ss_.Free(tmp_rhs_); + tmp_rhs_ = NULL; + } +} + +// Determine the sparsity structure of the SCHUR_JACOBI +// preconditioner. SCHUR_JACOBI is an extreme case of a visibility +// based preconditioner where each camera block corresponds to a +// cluster and there is no interaction between clusters. +void VisibilityBasedPreconditioner::ComputeSchurJacobiSparsity( + const CompressedRowBlockStructure& bs) { + num_clusters_ = num_blocks_; + cluster_membership_.resize(num_blocks_); + cluster_pairs_.clear(); + + // Each camea block is a member of its own cluster and the only + // cluster pairs are the self edges (i,i). + for (int i = 0; i < num_clusters_; ++i) { + cluster_membership_[i] = i; + cluster_pairs_.insert(make_pair(i, i)); + } +} + +// Determine the sparsity structure of the CLUSTER_JACOBI +// preconditioner. It clusters cameras using their scene +// visibility. The clusters form the diagonal blocks of the +// preconditioner matrix. +void VisibilityBasedPreconditioner::ComputeClusterJacobiSparsity( + const CompressedRowBlockStructure& bs) { + vector > visibility; + ComputeVisibility(bs, options_.num_eliminate_blocks, &visibility); + CHECK_EQ(num_blocks_, visibility.size()); + ClusterCameras(visibility); + cluster_pairs_.clear(); + for (int i = 0; i < num_clusters_; ++i) { + cluster_pairs_.insert(make_pair(i, i)); + } +} + +// Determine the sparsity structure of the CLUSTER_TRIDIAGONAL +// preconditioner. It clusters cameras using using the scene +// visibility and then finds the strongly interacting pairs of +// clusters by constructing another graph with the clusters as +// vertices and approximating it with a degree-2 maximum spanning +// forest. The set of edges in this forest are the cluster pairs. +void VisibilityBasedPreconditioner::ComputeClusterTridiagonalSparsity( + const CompressedRowBlockStructure& bs) { + vector > visibility; + ComputeVisibility(bs, options_.num_eliminate_blocks, &visibility); + CHECK_EQ(num_blocks_, visibility.size()); + ClusterCameras(visibility); + + // Construct a weighted graph on the set of clusters, where the + // edges are the number of 3D points/e_blocks visible in both the + // clusters at the ends of the edge. Return an approximate degree-2 + // maximum spanning forest of this graph. + vector > cluster_visibility; + ComputeClusterVisibility(visibility, &cluster_visibility); + scoped_ptr > cluster_graph( + CHECK_NOTNULL(CreateClusterGraph(cluster_visibility))); + scoped_ptr > forest( + CHECK_NOTNULL(Degree2MaximumSpanningForest(*cluster_graph))); + ForestToClusterPairs(*forest, &cluster_pairs_); +} + +// Allocate storage for the preconditioner matrix. +void VisibilityBasedPreconditioner::InitStorage( + const CompressedRowBlockStructure& bs) { + ComputeBlockPairsInPreconditioner(bs); + m_.reset(new BlockRandomAccessSparseMatrix(block_size_, block_pairs_)); +} + +// Call the canonical views algorithm and cluster the cameras based on +// their visibility sets. The visibility set of a camera is the set of +// e_blocks/3D points in the scene that are seen by it. +// +// The cluster_membership_ vector is updated to indicate cluster +// memberships for each camera block. +void VisibilityBasedPreconditioner::ClusterCameras( + const vector >& visibility) { + scoped_ptr > schur_complement_graph( + CHECK_NOTNULL(CreateSchurComplementGraph(visibility))); + + CanonicalViewsClusteringOptions options; + options.size_penalty_weight = kSizePenaltyWeight; + options.similarity_penalty_weight = kSimilarityPenaltyWeight; + + vector centers; + HashMap membership; + ComputeCanonicalViewsClustering(*schur_complement_graph, + options, + ¢ers, + &membership); + num_clusters_ = centers.size(); + CHECK_GT(num_clusters_, 0); + VLOG(2) << "num_clusters: " << num_clusters_; + FlattenMembershipMap(membership, &cluster_membership_); +} + +// Compute the block sparsity structure of the Schur complement +// matrix. For each pair of cameras contributing a non-zero cell to +// the schur complement, determine if that cell is present in the +// preconditioner or not. +// +// A pair of cameras contribute a cell to the preconditioner if they +// are part of the same cluster or if the the two clusters that they +// belong have an edge connecting them in the degree-2 maximum +// spanning forest. +// +// For example, a camera pair (i,j) where i belonges to cluster1 and +// j belongs to cluster2 (assume that cluster1 < cluster2). +// +// The cell corresponding to (i,j) is present in the preconditioner +// if cluster1 == cluster2 or the pair (cluster1, cluster2) were +// connected by an edge in the degree-2 maximum spanning forest. +// +// Since we have already expanded the forest into a set of camera +// pairs/edges, including self edges, the check can be reduced to +// checking membership of (cluster1, cluster2) in cluster_pairs_. +void VisibilityBasedPreconditioner::ComputeBlockPairsInPreconditioner( + const CompressedRowBlockStructure& bs) { + block_pairs_.clear(); + for (int i = 0; i < num_blocks_; ++i) { + block_pairs_.insert(make_pair(i, i)); + } + + int r = 0; + set > skipped_pairs; + const int num_row_blocks = bs.rows.size(); + const int num_eliminate_blocks = options_.num_eliminate_blocks; + + // Iterate over each row of the matrix. The block structure of the + // matrix is assumed to be sorted in order of the e_blocks/point + // blocks. Thus all row blocks containing an e_block/point occur + // contiguously. Further, if present, an e_block is always the first + // parameter block in each row block. These structural assumptions + // are common to all Schur complement based solvers in Ceres. + // + // For each e_block/point block we identify the set of cameras + // seeing it. The cross product of this set with itself is the set + // of non-zero cells contibuted by this e_block. + // + // The time complexity of this is O(nm^2) where, n is the number of + // 3d points and m is the maximum number of cameras seeing any + // point, which for most scenes is a fairly small number. + while (r < num_row_blocks) { + int e_block_id = bs.rows[r].cells.front().block_id; + if (e_block_id >= num_eliminate_blocks) { + // Skip the rows whose first block is an f_block. + break; + } + + set f_blocks; + for (; r < num_row_blocks; ++r) { + const CompressedRow& row = bs.rows[r]; + if (row.cells.front().block_id != e_block_id) { + break; + } + + // Iterate over the blocks in the row, ignoring the first block + // since it is the one to be eliminated and adding the rest to + // the list of f_blocks associated with this e_block. + for (int c = 1; c < row.cells.size(); ++c) { + const Cell& cell = row.cells[c]; + const int f_block_id = cell.block_id - num_eliminate_blocks; + CHECK_GE(f_block_id, 0); + f_blocks.insert(f_block_id); + } + } + + for (set::const_iterator block1 = f_blocks.begin(); + block1 != f_blocks.end(); + ++block1) { + set::const_iterator block2 = block1; + ++block2; + for (; block2 != f_blocks.end(); ++block2) { + if (IsBlockPairInPreconditioner(*block1, *block2)) { + block_pairs_.insert(make_pair(*block1, *block2)); + } else { + skipped_pairs.insert(make_pair(*block1, *block2)); + } + } + } + } + + // The remaining rows which do not contain any e_blocks. + for (; r < num_row_blocks; ++r) { + const CompressedRow& row = bs.rows[r]; + CHECK_GE(row.cells.front().block_id, num_eliminate_blocks); + for (int i = 0; i < row.cells.size(); ++i) { + const int block1 = row.cells[i].block_id - num_eliminate_blocks; + for (int j = 0; j < row.cells.size(); ++j) { + const int block2 = row.cells[j].block_id - num_eliminate_blocks; + if (block1 <= block2) { + if (IsBlockPairInPreconditioner(block1, block2)) { + block_pairs_.insert(make_pair(block1, block2)); + } else { + skipped_pairs.insert(make_pair(block1, block2)); + } + } + } + } + } + + VLOG(1) << "Block pair stats: " + << block_pairs_.size() << " included " + << skipped_pairs.size() << " excluded"; +} + +// Initialize the SchurEliminator. +void VisibilityBasedPreconditioner::InitEliminator( + const CompressedRowBlockStructure& bs) { + LinearSolver::Options eliminator_options; + eliminator_options.num_eliminate_blocks = options_.num_eliminate_blocks; + eliminator_options.num_threads = options_.num_threads; + eliminator_options.constant_sparsity = true; + + DetectStructure(bs, options_.num_eliminate_blocks, + &eliminator_options.row_block_size, + &eliminator_options.e_block_size, + &eliminator_options.f_block_size); + + eliminator_.reset(SchurEliminatorBase::Create(eliminator_options)); + eliminator_->Init(options_.num_eliminate_blocks, &bs); +} + +// Compute the values of the preconditioner matrix and factorize it. +bool VisibilityBasedPreconditioner::Compute(const BlockSparseMatrixBase& A, + const double* D) { + const time_t start_time = time(NULL); + const int num_rows = m_->num_rows(); + CHECK_GT(num_rows, 0); + + // We need a dummy rhs vector and a dummy b vector since the Schur + // eliminator combines the computation of the reduced camera matrix + // with the computation of the right hand side of that linear + // system. + // + // TODO(sameeragarwal): Perhaps its worth refactoring the + // SchurEliminator::Eliminate function to allow NULL for the rhs. As + // of now it does not seem to be worth the effort. + Vector rhs = Vector::Zero(m_->num_rows()); + Vector b = Vector::Zero(A.num_rows()); + + // Compute a subset of the entries of the Schur complement. + eliminator_->Eliminate(&A, b.data(), D, m_.get(), rhs.data()); + + // Try factorizing the matrix. For SCHUR_JACOBI and CLUSTER_JACOBI, + // this should always succeed modulo some numerical/conditioning + // problems. For CLUSTER_TRIDIAGONAL, in general the preconditioner + // matrix as constructed is not positive definite. However, we will + // go ahead and try factorizing it. If it works, great, otherwise we + // scale all the cells in the preconditioner corresponding to the + // edges in the degree-2 forest and that guarantees positive + // definiteness. The proof of this fact can be found in Lemma 1 in + // "Visibility Based Preconditioning for Bundle Adjustment". + // + // Doing the factorization like this saves us matrix mass when + // scaling is not needed, which is quite often in our experience. + bool status = Factorize(); + + // The scaling only affects the tri-diagonal case, since + // ScaleOffDiagonalBlocks only pays attenion to the cells that + // belong to the edges of the degree-2 forest. In the SCHUR_JACOBI + // and the CLUSTER_JACOBI cases, the preconditioner is guaranteed to + // be positive semidefinite. + if (!status && options_.preconditioner_type == CLUSTER_TRIDIAGONAL) { + VLOG(1) << "Unscaled factorization failed. Retrying with off-diagonal " + << "scaling"; + ScaleOffDiagonalCells(); + status = Factorize(); + } + + VLOG(2) << "Compute time: " << time(NULL) - start_time; + return status; +} + +// Consider the preconditioner matrix as meta-block matrix, whose +// blocks correspond to the clusters. Then cluster pairs corresponding +// to edges in the degree-2 forest are off diagonal entries of this +// matrix. Scaling these off-diagonal entries by 1/2 forces this +// matrix to be positive definite. +void VisibilityBasedPreconditioner::ScaleOffDiagonalCells() { + for (set< pair >::const_iterator it = block_pairs_.begin(); + it != block_pairs_.end(); + ++it) { + const int block1 = it->first; + const int block2 = it->second; + if (!IsBlockPairOffDiagonal(block1, block2)) { + continue; + } + + int r, c, row_stride, col_stride; + CellInfo* cell_info = m_->GetCell(block1, block2, + &r, &c, + &row_stride, &col_stride); + CHECK(cell_info != NULL) + << "Cell missing for block pair (" << block1 << "," << block2 << ")" + << " cluster pair (" << cluster_membership_[block1] + << " " << cluster_membership_[block2] << ")"; + + // Ah the magic of tri-diagonal matrices and diagonal + // dominance. See Lemma 1 in "Visibility Based Preconditioning + // For Bundle Adjustment". + MatrixRef m(cell_info->values, row_stride, col_stride); + m.block(r, c, block_size_[block1], block_size_[block2]) *= 0.5; + } +} + +// Compute the sparse Cholesky factorization of the preconditioner +// matrix. +bool VisibilityBasedPreconditioner::Factorize() { + // Extract the TripletSparseMatrix that is used for actually storing + // S and convert it into a cholmod_sparse object. + cholmod_sparse* lhs = ss_.CreateSparseMatrix( + down_cast( + m_.get())->mutable_matrix()); + + // The matrix is symmetric, and the upper triangular part of the + // matrix contains the values. + lhs->stype = 1; + + // Symbolic factorization is computed if we don't already have one + // handy. + if (factor_ == NULL) { + factor_ = ss_.AnalyzeCholesky(lhs); + } + + bool status = ss_.Cholesky(lhs, factor_); + ss_.Free(lhs); + return status; +} + +void VisibilityBasedPreconditioner::RightMultiply(const double* x, + double* y) const { + CHECK_NOTNULL(x); + CHECK_NOTNULL(y); + SuiteSparse* ss = const_cast(&ss_); + + const int num_rows = m_->num_rows(); + memcpy(CHECK_NOTNULL(tmp_rhs_)->x, x, m_->num_rows() * sizeof(*x)); + cholmod_dense* solution = CHECK_NOTNULL(ss->Solve(factor_, tmp_rhs_)); + memcpy(y, solution->x, sizeof(*y) * num_rows); + ss->Free(solution); +} + +int VisibilityBasedPreconditioner::num_rows() const { + return m_->num_rows(); +} + +// Classify camera/f_block pairs as in and out of the preconditioner, +// based on whether the cluster pair that they belong to is in the +// preconditioner or not. +bool VisibilityBasedPreconditioner::IsBlockPairInPreconditioner( + const int block1, + const int block2) const { + int cluster1 = cluster_membership_[block1]; + int cluster2 = cluster_membership_[block2]; + if (cluster1 > cluster2) { + std::swap(cluster1, cluster2); + } + return (cluster_pairs_.count(make_pair(cluster1, cluster2)) > 0); +} + +bool VisibilityBasedPreconditioner::IsBlockPairOffDiagonal( + const int block1, + const int block2) const { + return (cluster_membership_[block1] != cluster_membership_[block2]); +} + +// Convert a graph into a list of edges that includes self edges for +// each vertex. +void VisibilityBasedPreconditioner::ForestToClusterPairs( + const Graph& forest, + HashSet >* cluster_pairs) const { + CHECK_NOTNULL(cluster_pairs)->clear(); + const HashSet& vertices = forest.vertices(); + CHECK_EQ(vertices.size(), num_clusters_); + + // Add all the cluster pairs corresponding to the edges in the + // forest. + for (HashSet::const_iterator it1 = vertices.begin(); + it1 != vertices.end(); + ++it1) { + const int cluster1 = *it1; + cluster_pairs->insert(make_pair(cluster1, cluster1)); + const HashSet& neighbors = forest.Neighbors(cluster1); + for (HashSet::const_iterator it2 = neighbors.begin(); + it2 != neighbors.end(); + ++it2) { + const int cluster2 = *it2; + if (cluster1 < cluster2) { + cluster_pairs->insert(make_pair(cluster1, cluster2)); + } + } + } +} + +// The visibilty set of a cluster is the union of the visibilty sets +// of all its cameras. In other words, the set of points visible to +// any camera in the cluster. +void VisibilityBasedPreconditioner::ComputeClusterVisibility( + const vector >& visibility, + vector >* cluster_visibility) const { + CHECK_NOTNULL(cluster_visibility)->resize(0); + cluster_visibility->resize(num_clusters_); + for (int i = 0; i < num_blocks_; ++i) { + const int cluster_id = cluster_membership_[i]; + (*cluster_visibility)[cluster_id].insert(visibility[i].begin(), + visibility[i].end()); + } +} + +// Construct a graph whose vertices are the clusters, and the edge +// weights are the number of 3D points visible to cameras in both the +// vertices. +Graph* VisibilityBasedPreconditioner::CreateClusterGraph( + const vector >& cluster_visibility) const { + Graph* cluster_graph = new Graph; + + for (int i = 0; i < num_clusters_; ++i) { + cluster_graph->AddVertex(i); + } + + for (int i = 0; i < num_clusters_; ++i) { + const set& cluster_i = cluster_visibility[i]; + for (int j = i+1; j < num_clusters_; ++j) { + vector intersection; + const set& cluster_j = cluster_visibility[j]; + set_intersection(cluster_i.begin(), cluster_i.end(), + cluster_j.begin(), cluster_j.end(), + back_inserter(intersection)); + + if (intersection.size() > 0) { + // Clusters interact strongly when they share a large number + // of 3D points. The degree-2 maximum spanning forest + // alorithm, iterates on the edges in decreasing order of + // their weight, which is the number of points shared by the + // two cameras that it connects. + cluster_graph->AddEdge(i, j, intersection.size()); + } + } + } + return cluster_graph; +} + +// Canonical views clustering returns a HashMap from vertices to +// cluster ids. Convert this into a flat array for quick lookup. It is +// possible that some of the vertices may not be associated with any +// cluster. In that case, randomly assign them to one of the clusters. +void VisibilityBasedPreconditioner::FlattenMembershipMap( + const HashMap& membership_map, + vector* membership_vector) const { + CHECK_NOTNULL(membership_vector)->resize(0); + membership_vector->resize(num_blocks_, -1); + // Iterate over the cluster membership map and update the + // cluster_membership_ vector assigning arbitrary cluster ids to + // the few cameras that have not been clustered. + for (HashMap::const_iterator it = membership_map.begin(); + it != membership_map.end(); + ++it) { + const int camera_id = it->first; + int cluster_id = it->second; + + // If the view was not clustered, randomly assign it to one of the + // clusters. This preserves the mathematical correctness of the + // preconditioner. If there are too many views which are not + // clustered, it may lead to some quality degradation though. + // + // TODO(sameeragarwal): Check if a large number of views have not + // been clustered and deal with it? + if (cluster_id == -1) { + cluster_id = camera_id % num_clusters_; + } + + membership_vector->at(camera_id) = cluster_id; + } +} + +#endif // CERES_NO_SUITESPARSE + +} // namespace internal +} // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h new file mode 100644 index 00000000000..fa095ca1dd8 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h @@ -0,0 +1,273 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Preconditioners for linear systems that arise in Structure from +// Motion problems. VisibilityBasedPreconditioner implements three +// preconditioners: +// +// SCHUR_JACOBI +// CLUSTER_JACOBI +// CLUSTER_TRIDIAGONAL +// +// Detailed descriptions of these preconditions beyond what is +// documented here can be found in +// +// Bundle Adjustment in the Large +// S. Agarwal, N. Snavely, S. Seitz & R. Szeliski, ECCV 2010 +// http://www.cs.washington.edu/homes/sagarwal/bal.pdf +// +// Visibility Based Preconditioning for Bundle Adjustment +// A. Kushal & S. Agarwal, submitted to CVPR 2012 +// http://www.cs.washington.edu/homes/sagarwal/vbp.pdf +// +// The three preconditioners share enough code that its most efficient +// to implement them as part of the same code base. + +#ifndef CERES_INTERNAL_VISIBILITY_BASED_PRECONDITIONER_H_ +#define CERES_INTERNAL_VISIBILITY_BASED_PRECONDITIONER_H_ + +#include +#include +#include +#include "ceres/collections_port.h" +#include "ceres/graph.h" +#include "ceres/linear_solver.h" +#include "ceres/linear_operator.h" +#include "ceres/suitesparse.h" +#include "ceres/internal/macros.h" +#include "ceres/internal/scoped_ptr.h" + +namespace ceres { +namespace internal { + +class BlockRandomAccessSparseMatrix; +class BlockSparseMatrixBase; +class CompressedRowBlockStructure; +class SchurEliminatorBase; + +// This class implements three preconditioners for Structure from +// Motion/Bundle Adjustment problems. The name +// VisibilityBasedPreconditioner comes from the fact that the sparsity +// structure of the preconditioner matrix is determined by analyzing +// the visibility structure of the scene, i.e. which cameras see which +// points. +// +// Strictly speaking, SCHUR_JACOBI is not a visibility based +// preconditioner but it is an extreme case of CLUSTER_JACOBI, where +// every cluster contains exactly one camera block. Treating it as a +// special case of CLUSTER_JACOBI makes it easy to implement as part +// of the same code base with no significant loss of performance. +// +// In the following, we will only discuss CLUSTER_JACOBI and +// CLUSTER_TRIDIAGONAL. +// +// The key idea of visibility based preconditioning is to identify +// cameras that we expect have strong interactions, and then using the +// entries in the Schur complement matrix corresponding to these +// camera pairs as an approximation to the full Schur complement. +// +// CLUSTER_JACOBI identifies these camera pairs by clustering cameras, +// and considering all non-zero camera pairs within each cluster. The +// clustering in the current implementation is done using the +// Canonical Views algorithm of Simon et al. (see +// canonical_views_clustering.h). For the purposes of clustering, the +// similarity or the degree of interaction between a pair of cameras +// is measured by counting the number of points visible in both the +// cameras. Thus the name VisibilityBasedPreconditioner. Further, if we +// were to permute the parameter blocks such that all the cameras in +// the same cluster occur contiguously, the preconditioner matrix will +// be a block diagonal matrix with blocks corresponding to the +// clusters. Thus in analogy with the Jacobi preconditioner we refer +// to this as the CLUSTER_JACOBI preconditioner. +// +// CLUSTER_TRIDIAGONAL adds more mass to the CLUSTER_JACOBI +// preconditioner by considering the interaction between clusters and +// identifying strong interactions between cluster pairs. This is done +// by constructing a weighted graph on the clusters, with the weight +// on the edges connecting two clusters proportional to the number of +// 3D points visible to cameras in both the clusters. A degree-2 +// maximum spanning forest is identified in this graph and the camera +// pairs contained in the edges of this forest are added to the +// preconditioner. The detailed reasoning for this construction is +// explained in the paper mentioned above. +// +// Degree-2 spanning trees and forests have the property that they +// correspond to tri-diagonal matrices. Thus there exist a permutation +// of the camera blocks under which the CLUSTER_TRIDIAGONAL +// preconditioner matrix is a block tridiagonal matrix, and thus the +// name for the preconditioner. +// +// Thread Safety: This class is NOT thread safe. +// +// Example usage: +// +// LinearSolver::Options options; +// options.preconditioner_type = CLUSTER_JACOBI; +// options.num_eliminate_blocks = num_points; +// VisibilityBasedPreconditioner preconditioner( +// *A.block_structure(), options); +// preconditioner.Compute(A, NULL); +// preconditioner.RightMultiply(x, y); +// + +#ifndef CERES_NO_SUITESPARSE +class VisibilityBasedPreconditioner : public LinearOperator { + public: + // Initialize the symbolic structure of the preconditioner. bs is + // the block structure of the linear system to be solved. It is used + // to determine the sparsity structure of the preconditioner matrix. + // + // It has the same structural requirement as other Schur complement + // based solvers. Please see schur_eliminator.h for more details. + // + // LinearSolver::Options::num_eliminate_blocks should be set to the + // number of e_blocks in the block structure. + // + // TODO(sameeragarwal): The use of LinearSolver::Options should + // ultimately be replaced with Preconditioner::Options and some sort + // of preconditioner factory along the lines of + // LinearSolver::CreateLinearSolver. I will wait to do this till I + // create a general purpose block Jacobi preconditioner for general + // sparse problems along with a CGLS solver. + VisibilityBasedPreconditioner(const CompressedRowBlockStructure& bs, + const LinearSolver::Options& options); + virtual ~VisibilityBasedPreconditioner(); + + // Compute the numerical value of the preconditioner for the linear + // system: + // + // | A | x = |b| + // |diag(D)| |0| + // + // for some vector b. It is important that the matrix A have the + // same block structure as the one used to construct this object. + // + // D can be NULL, in which case its interpreted as a diagonal matrix + // of size zero. + bool Compute(const BlockSparseMatrixBase& A, + const double* D); + + // LinearOperator interface. Since the operator is symmetric, + // LeftMultiply and num_cols are just calls to RightMultiply and + // num_rows respectively. Compute() must be called before + // RightMultiply can be called. + virtual void RightMultiply(const double* x, double* y) const; + virtual void LeftMultiply(const double* x, double* y) const { + RightMultiply(x, y); + } + virtual int num_rows() const; + virtual int num_cols() const { return num_rows(); } + + friend class VisibilityBasedPreconditionerTest; + private: + void ComputeSchurJacobiSparsity(const CompressedRowBlockStructure& bs); + void ComputeClusterJacobiSparsity(const CompressedRowBlockStructure& bs); + void ComputeClusterTridiagonalSparsity(const CompressedRowBlockStructure& bs); + void InitStorage(const CompressedRowBlockStructure& bs); + void InitEliminator(const CompressedRowBlockStructure& bs); + bool Factorize(); + void ScaleOffDiagonalCells(); + + void ClusterCameras(const vector< set >& visibility); + void FlattenMembershipMap(const HashMap& membership_map, + vector* membership_vector) const; + void ComputeClusterVisibility(const vector >& visibility, + vector >* cluster_visibility) const; + Graph* CreateClusterGraph(const vector >& visibility) const; + void ForestToClusterPairs(const Graph& forest, + HashSet >* cluster_pairs) const; + void ComputeBlockPairsInPreconditioner(const CompressedRowBlockStructure& bs); + bool IsBlockPairInPreconditioner(int block1, int block2) const; + bool IsBlockPairOffDiagonal(int block1, int block2) const; + + LinearSolver::Options options_; + + // Number of parameter blocks in the schur complement. + int num_blocks_; + int num_clusters_; + + // Sizes of the blocks in the schur complement. + vector block_size_; + + // Mapping from cameras to clusters. + vector cluster_membership_; + + // Non-zero camera pairs from the schur complement matrix that are + // present in the preconditioner, sorted by row (first element of + // each pair), then column (second). + set > block_pairs_; + + // Set of cluster pairs (including self pairs (i,i)) in the + // preconditioner. + HashSet > cluster_pairs_; + scoped_ptr eliminator_; + + // Preconditioner matrix. + scoped_ptr m_; + + // RightMultiply is a const method for LinearOperators. It is + // implemented using CHOLMOD's sparse triangular matrix solve + // function. This however requires non-const access to the + // SuiteSparse context object, even though it does not result in any + // of the state of the preconditioner being modified. + SuiteSparse ss_; + + // Symbolic and numeric factorization of the preconditioner. + cholmod_factor* factor_; + + // Temporary vector used by RightMultiply. + cholmod_dense* tmp_rhs_; + DISALLOW_COPY_AND_ASSIGN(VisibilityBasedPreconditioner); +}; +#else // SuiteSparse +// If SuiteSparse is not compiled in, the preconditioner is not +// available. +class VisibilityBasedPreconditioner : public LinearOperator { + public: + VisibilityBasedPreconditioner(const CompressedRowBlockStructure& bs, + const LinearSolver::Options& options) { + LOG(FATAL) << "Visibility based preconditioning is not available. Please " + "build Ceres with SuiteSparse."; + } + virtual ~VisibilityBasedPreconditioner() {} + virtual void RightMultiply(const double* x, double* y) const {} + virtual void LeftMultiply(const double* x, double* y) const {} + virtual int num_rows() const { return -1; } + virtual int num_cols() const { return -1; } + bool Compute(const BlockSparseMatrixBase& A, const double* D) { + return false; + } +}; +#endif // CERES_NO_SUITESPARSE + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_VISIBILITY_BASED_PRECONDITIONER_H_ diff --git a/extern/libmv/third_party/ceres/mkfiles.sh b/extern/libmv/third_party/ceres/mkfiles.sh new file mode 100755 index 00000000000..d335829aa2c --- /dev/null +++ b/extern/libmv/third_party/ceres/mkfiles.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +find ./include/ -type f | sed -r 's/^\.\///' | sort > files.txt +find ./internal/ -type f | sed -r 's/^\.\///' | sort >> files.txt diff --git a/extern/libmv/third_party/ceres/patches/series b/extern/libmv/third_party/ceres/patches/series new file mode 100644 index 00000000000..dbe955ae61e --- /dev/null +++ b/extern/libmv/third_party/ceres/patches/series @@ -0,0 +1 @@ +msvc_isfinite.patch diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index 70354c0a2ec..dcd4d78d19a 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -171,6 +171,7 @@ endif() if(WITH_LIBMV) list(APPEND BLENDER_SORTED_LIBS extern_libmv) + list(APPEND BLENDER_SORTED_LIBS extern_ceres) endif() list(APPEND BLENDER_SORTED_LIBS extern_colamd) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 5f0386dc28b..5524b50cdf7 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -909,6 +909,7 @@ endif() if(WITH_LIBMV) list(APPEND BLENDER_SORTED_LIBS extern_libmv) + list(APPEND BLENDER_SORTED_LIBS extern_ceres) endif() if(WITH_MOD_CLOTH_ELTOPO) From 7ca990f2a9053175fab1d38250d6c180b024ffd0 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 10 May 2012 10:17:59 +0000 Subject: [PATCH 028/360] Tomato: re-integrate ceres library with updates needed for tracking improvement Also commit missed patch. --- extern/libmv/third_party/ceres/CMakeLists.txt | 10 +- extern/libmv/third_party/ceres/ChangeLog | 97 ++++++++++ .../include/ceres/autodiff_cost_function.h | 67 +++++-- .../ceres/include/ceres/internal/autodiff.h | 52 +++--- .../ceres/include/ceres/sized_cost_function.h | 14 +- .../third_party/ceres/include/ceres/solver.h | 11 +- .../third_party/ceres/include/ceres/types.h | 34 ++++ .../internal/ceres/block_sparse_matrix.cc | 23 +++ .../internal/ceres/block_sparse_matrix.h | 2 + .../ceres/compressed_row_sparse_matrix.cc | 9 + .../ceres/compressed_row_sparse_matrix.h | 2 +- .../internal/ceres/dense_sparse_matrix.cc | 13 ++ .../internal/ceres/dense_sparse_matrix.h | 1 + .../internal/ceres/levenberg_marquardt.cc | 116 ++++-------- .../ceres/linear_least_squares_problems.cc | 170 ++++++++++++++++++ .../ceres/linear_least_squares_problems.h | 12 +- .../ceres/internal/ceres/minimizer.h | 6 +- .../ceres/internal/ceres/sparse_matrix.h | 8 +- .../internal/ceres/triplet_sparse_matrix.cc | 7 + .../internal/ceres/triplet_sparse_matrix.h | 1 + .../ceres/patches/msvc_isfinite.patch | 15 ++ 21 files changed, 527 insertions(+), 143 deletions(-) create mode 100644 extern/libmv/third_party/ceres/patches/msvc_isfinite.patch diff --git a/extern/libmv/third_party/ceres/CMakeLists.txt b/extern/libmv/third_party/ceres/CMakeLists.txt index 19158dcfebb..5207bddec12 100644 --- a/extern/libmv/third_party/ceres/CMakeLists.txt +++ b/extern/libmv/third_party/ceres/CMakeLists.txt @@ -208,11 +208,11 @@ else() endif() add_definitions( - -DCERES_HAVE_PTHREAD - -D"CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {" - -D"CERES_HASH_NAMESPACE_END=}}" - -DCERES_NO_SUITESPARSE - -DCERES_DONT_HAVE_PROTOCOL_BUFFERS + -DCERES_HAVE_PTHREAD + -D"CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {" + -D"CERES_HASH_NAMESPACE_END=}}" + -DCERES_NO_SUITESPARSE + -DCERES_DONT_HAVE_PROTOCOL_BUFFERS ) blender_add_lib(extern_ceres "${SRC}" "${INC}" "${INC_SYS}") diff --git a/extern/libmv/third_party/ceres/ChangeLog b/extern/libmv/third_party/ceres/ChangeLog index c652a73c0c1..6e919658f13 100644 --- a/extern/libmv/third_party/ceres/ChangeLog +++ b/extern/libmv/third_party/ceres/ChangeLog @@ -1,3 +1,100 @@ +commit ca72152362ae1f4b9928c012e74b4d49d094a4ca +Merge: d297f8d 0a04199 +Author: Keir Mierle +Date: Wed May 9 13:10:59 2012 -0700 + + Merge branch 'master' into windows + +commit 0a04199ef279cc9ea97f665fed8e7fae717813c3 +Merge: fdeb577 f2571f1 +Author: Keir Mierle +Date: Wed May 9 12:54:56 2012 -0700 + + Merge branch 'master' of https://code.google.com/p/ceres-solver + +commit fdeb5772cc5eeebca4d776d220d80cc91b6d0f74 +Author: Keir Mierle +Date: Wed May 9 07:38:07 2012 -0700 + + Support varying numbers of residuals in autodiff. + + This commit modifies the only function in autodiff that takes a + templated number of outputs (i.e. residuals) and makes that + template parameter a normal parameter. With that change, it + is a trivial matter to support a dynamic number of residuals. + + The API for dynamic residuals is to pass a fake number of + residuals as the second template argument to + AutoDiffCostFunction, and to pass the real number of + parameters as a second constructor argument. + +commit da3e0563cc12e08e7b3e0fbf11d9cc8cfe9658aa +Author: Sameer Agarwal +Date: Wed May 9 11:57:47 2012 -0700 + + Typo corrections in the documentation from Bing + +commit aa9526d8e8fb34c23d63e3af5bf9239b0c4ea603 +Author: Sameer Agarwal +Date: Tue May 8 21:22:09 2012 -0700 + + Share search paths across various library searches. + Fix typos in glog search. + Split the error messages for include and lib. + Enable building of tests by default. + Made building on homebrew installations a bit better. + Remove temporary variables for glog and gflags. + +commit f2571f186850ed3dd316236ac4be488979df7d30 +Author: Sameer Agarwal +Date: Wed May 9 11:57:47 2012 -0700 + + Typo corrections in the documentation from Bing + +commit 8f7f11ff7d07737435428a2620c52419cf99f98e +Merge: e6c17c4 eaccbb3 +Author: Sameer Agarwal +Date: Wed May 9 11:34:15 2012 -0700 + + Merge branch 'master' of https://code.google.com/p/ceres-solver + +commit e6c17c4c9d9307218f6f739cea39bc2d87733d4d +Author: Sameer Agarwal +Date: Tue May 8 21:22:09 2012 -0700 + + Share search paths across various library searches. + Fix typos in glog search. + Split the error messages for include and lib. + Enable building of tests by default. + Made building on homebrew installations a bit better. + Remove temporary variables for glog and gflags. + +commit eaccbb345614c0d24c5e21fa931f470cfda874df +Author: Keir Mierle +Date: Wed May 9 05:31:29 2012 -0700 + + Remove unused template parameter from VariadicEvaluate. + +commit 82f4b88c34b0b2cf85064e5fc20e374e978b2e3b +Author: Sameer Agarwal +Date: Sun May 6 21:05:28 2012 -0700 + + Extend support writing linear least squares problems to disk. + + 1. Make the mechanism for writing problems to disk, generic and + controllable using an enum DumpType visible in the API. + + 2. Instead of single file containing protocol buffers, now matrices can + be written in a matlab/octave friendly format. This is now the default. + + 3. The support for writing problems to disk is moved into + linear_least_squares_problem.cc/h + + 4. SparseMatrix now has a ToTextFile virtual method which is + implemented by each of its subclasses to write a (i,j,s) triplets. + + 5. Minor changes to simple_bundle_adjuster to enable logging at startup. + commit d297f8d3d3f5025c24752f0f4c1ec2469a769f99 Merge: 7e74d81 f8bd7fa Author: Keir Mierle diff --git a/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h index 0ac6240dfab..da9ee2c7993 100644 --- a/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h +++ b/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h @@ -93,6 +93,20 @@ // "MyScalarCostFunction", "1, 2, 2", describe the functor as computing a // 1-dimensional output from two arguments, both 2-dimensional. // +// The autodiff cost function also supports cost functions with a +// runtime-determined number of residuals. For example: +// +// CostFunction* cost_function +// = new AutoDiffCostFunction( +// new CostFunctionWithDynamicNumResiduals(1.0), ^ ^ ^ +// runtime_number_of_residuals); <----+ | | | +// | | | | +// | | | | +// Actual number of residuals ------+ | | | +// Indicate dynamic number of residuals ---------+ | | +// Dimension of x -------------------------------------+ | +// Dimension of y ----------------------------------------+ +// // The framework can currently accommodate cost functions of up to 6 independent // variables, and there is no limit on the dimensionality of each of them. // @@ -115,18 +129,26 @@ #include "ceres/internal/autodiff.h" #include "ceres/internal/scoped_ptr.h" #include "ceres/sized_cost_function.h" +#include "ceres/types.h" namespace ceres { -// A cost function which computes the derivative of the cost with respect to the -// parameters (a.k.a. the jacobian) using an autodifferentiation framework. The -// first template argument is the functor object, described in the header -// comment. The second argument is the dimension of the residual, and subsequent +// A cost function which computes the derivative of the cost with respect to +// the parameters (a.k.a. the jacobian) using an autodifferentiation framework. +// The first template argument is the functor object, described in the header +// comment. The second argument is the dimension of the residual (or +// ceres::DYNAMIC to indicate it will be set at runtime), and subsequent // arguments describe the size of the Nth parameter, one per parameter. // -// The constructor, which takes a cost functor, takes ownership of the functor. +// The constructors take ownership of the cost functor. +// +// If the number of residuals (argument "M" below) is ceres::DYNAMIC, then the +// two-argument constructor must be used. The second constructor takes a number +// of residuals (in addition to the templated number of residuals). This allows +// for varying the number of residuals for a single autodiff cost function at +// runtime. template { public: - // Takes ownership of functor. - explicit AutoDiffCostFunction(CostFunctor* functor) : functor_(functor) {} + // Takes ownership of functor. Uses the template-provided value for the + // number of residuals ("M"). + explicit AutoDiffCostFunction(CostFunctor* functor) + : functor_(functor) { + CHECK_NE(M, DYNAMIC) << "Can't run the fixed-size constructor if the " + << "number of residuals is set to ceres::DYNAMIC."; + } + + // Takes ownership of functor. Ignores the template-provided number of + // residuals ("M") in favor of the "num_residuals" argument provided. + // + // This allows for having autodiff cost functions which return varying + // numbers of residuals at runtime. + AutoDiffCostFunction(CostFunctor* functor, int num_residuals) + : functor_(functor) { + CHECK_EQ(M, DYNAMIC) << "Can't run the dynamic-size constructor if the " + << "number of residuals is not ceres::DYNAMIC."; + SizedCostFunction::set_num_residuals(num_residuals); + } virtual ~AutoDiffCostFunction() {} @@ -151,14 +190,16 @@ class AutoDiffCostFunction : double** jacobians) const { if (!jacobians) { return internal::VariadicEvaluate< - CostFunctor, double, M, N0, N1, N2, N3, N4, N5> + CostFunctor, double, N0, N1, N2, N3, N4, N5> ::Call(*functor_, parameters, residuals); } return internal::AutoDiff::Differentiate(*functor_, - parameters, - residuals, - jacobians); + N0, N1, N2, N3, N4, N5>::Differentiate( + *functor_, + parameters, + SizedCostFunction::num_residuals(), + residuals, + jacobians); } private: diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h b/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h index 1a9d396c9ef..4f5081f8f66 100644 --- a/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h +++ b/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h @@ -144,6 +144,7 @@ #include #include "ceres/jet.h" +#include "ceres/internal/eigen.h" #include "ceres/internal/fixed_array.h" namespace ceres { @@ -185,18 +186,12 @@ inline void Take0thOrderPart(int M, const JetT *src, T dst) { // Takes N 1st order parts, starting at index N0, and puts them in the M x N // matrix 'dst'. This is used to pick out the "matrix" parts of the extended y. -template -inline void Take1stOrderPart(const JetT *src, T *dst) { +template +inline void Take1stOrderPart(const int M, const JetT *src, T *dst) { DCHECK(src); DCHECK(dst); - // TODO(keir): Change Jet to use a single array, where v[0] is the - // non-infinitesimal part rather than "a". That way it's possible to use a - // single memcpy or eigen operation, rather than the explicit loop. The loop - // doesn't exploit any SSE or other intrinsics. for (int i = 0; i < M; ++i) { - for (int j = 0; j < N; ++j) { - dst[N * i + j] = src[i].v[N0 + j]; - } + Eigen::Map >(dst + N * i, N) = src[i].v.template segment(N0); } } @@ -208,7 +203,7 @@ inline void Take1stOrderPart(const JetT *src, T *dst) { // Supporting variadic functions is the primary source of complexity in the // autodiff implementation. -template struct VariadicEvaluate { static bool Call(const Functor& functor, T const *const *input, T* output) { @@ -222,9 +217,9 @@ struct VariadicEvaluate { } }; -template -struct VariadicEvaluate { +struct VariadicEvaluate { static bool Call(const Functor& functor, T const *const *input, T* output) { return functor(input[0], input[1], @@ -235,9 +230,9 @@ struct VariadicEvaluate { } }; -template -struct VariadicEvaluate { +struct VariadicEvaluate { static bool Call(const Functor& functor, T const *const *input, T* output) { return functor(input[0], input[1], @@ -247,9 +242,9 @@ struct VariadicEvaluate { } }; -template -struct VariadicEvaluate { +struct VariadicEvaluate { static bool Call(const Functor& functor, T const *const *input, T* output) { return functor(input[0], input[1], @@ -258,9 +253,9 @@ struct VariadicEvaluate { } }; -template -struct VariadicEvaluate { +struct VariadicEvaluate { static bool Call(const Functor& functor, T const *const *input, T* output) { return functor(input[0], input[1], @@ -268,8 +263,8 @@ struct VariadicEvaluate { } }; -template -struct VariadicEvaluate { +template +struct VariadicEvaluate { static bool Call(const Functor& functor, T const *const *input, T* output) { return functor(input[0], output); @@ -279,11 +274,12 @@ struct VariadicEvaluate { // This is in a struct because default template parameters on a function are not // supported in C++03 (though it is available in C++0x). N0 through N5 are the // dimension of the input arguments to the user supplied functor. -template struct AutoDiff { static bool Differentiate(const Functor& functor, T const *const *parameters, + int num_outputs, T *function_value, T **jacobians) { typedef Jet JetT; @@ -300,10 +296,10 @@ struct AutoDiff { << "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", " << N3 << ", " << N4 << ", " << N5; - DCHECK_GT(kNumOutputs, 0); + DCHECK_GT(num_outputs, 0); FixedArray x( - N0 + N1 + N2 + N3 + N4 + N5 + kNumOutputs); + N0 + N1 + N2 + N3 + N4 + N5 + num_outputs); // It's ugly, but it works. const int jet0 = 0; @@ -339,22 +335,22 @@ struct AutoDiff { CERES_MAKE_1ST_ORDER_PERTURBATION(5); #undef CERES_MAKE_1ST_ORDER_PERTURBATION - if (!VariadicEvaluate::Call( functor, unpacked_parameters, output)) { return false; } - internal::Take0thOrderPart(kNumOutputs, output, function_value); + internal::Take0thOrderPart(num_outputs, output, function_value); #define CERES_TAKE_1ST_ORDER_PERTURBATION(i) \ if (N ## i) { \ if (jacobians[i]) { \ internal::Take1stOrderPart(output, \ - jacobians[i]); \ + N ## i>(num_outputs, \ + output, \ + jacobians[i]); \ } \ } CERES_TAKE_1ST_ORDER_PERTURBATION(0); diff --git a/extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h index 968285b8f1e..2894a9fba5c 100644 --- a/extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h +++ b/extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h @@ -30,11 +30,16 @@ // // A convenience class for cost functions which are statically sized. // Compared to the dynamically-sized base class, this reduces boilerplate. +// +// The kNumResiduals template parameter can be a constant such as 2 or 5, or it +// can be ceres::DYNAMIC. If kNumResiduals is ceres::DYNAMIC, then subclasses +// are responsible for calling set_num_residuals() at runtime. #ifndef CERES_PUBLIC_SIZED_COST_FUNCTION_H_ #define CERES_PUBLIC_SIZED_COST_FUNCTION_H_ #include +#include "ceres/types.h" #include "ceres/cost_function.h" namespace ceres { @@ -45,11 +50,12 @@ class SizedCostFunction : public CostFunction { public: SizedCostFunction() { // Sanity checking. - DCHECK_GT(kNumResiduals, 0) << "Cost functions must have at least " - << "one residual block."; - DCHECK_GT(N0, 0) + CHECK(kNumResiduals > 0 || kNumResiduals == DYNAMIC) + << "Cost functions must have at least one residual block."; + + CHECK_GT(N0, 0) << "Cost functions must have at least one parameter block."; - DCHECK((!N1 && !N2 && !N3 && !N4 && !N5) || + CHECK((!N1 && !N2 && !N3 && !N4 && !N5) || ((N1 > 0) && !N2 && !N3 && !N4 && !N5) || ((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5) || ((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5) || diff --git a/extern/libmv/third_party/ceres/include/ceres/solver.h b/extern/libmv/third_party/ceres/include/ceres/solver.h index 15fd7332d21..bd669272023 100644 --- a/extern/libmv/third_party/ceres/include/ceres/solver.h +++ b/extern/libmv/third_party/ceres/include/ceres/solver.h @@ -83,7 +83,8 @@ class Solver { minimizer_progress_to_stdout = false; return_initial_residuals = false; return_final_residuals = false; - lsqp_dump_format = "lm_iteration_%03d.lsqp"; + lsqp_dump_directory = "/tmp"; + lsqp_dump_format_type = TEXTFILE; crash_and_dump_lsqp_on_failure = false; check_gradients = false; gradient_check_relative_precision = 1e-8; @@ -213,12 +214,8 @@ class Solver { // // This is ignored if protocol buffers are disabled. vector lsqp_iterations_to_dump; - - // Format string for the file name used for dumping the least - // squares problem to disk. If the format is 'ascii', then the - // problem is logged to the screen; don't try this with large - // problems or expect a frozen terminal. - string lsqp_dump_format; + string lsqp_dump_directory; + DumpFormatType lsqp_dump_format_type; // Dump the linear least squares problem to disk if the minimizer // fails due to NUMERICAL_FAILURE and crash the process. This flag diff --git a/extern/libmv/third_party/ceres/include/ceres/types.h b/extern/libmv/third_party/ceres/include/ceres/types.h index b83a266d1ba..a30c79029ac 100644 --- a/extern/libmv/third_party/ceres/include/ceres/types.h +++ b/extern/libmv/third_party/ceres/include/ceres/types.h @@ -210,6 +210,40 @@ enum CallbackReturnType { SOLVER_TERMINATE_SUCCESSFULLY }; +// The format in which linear least squares problems should be logged +// when Solver::Options::lsqp_iterations_to_dump is non-empty. +enum DumpFormatType { + // Print the linear least squares problem in a human readable format + // to stderr. The Jacobian is printed as a dense matrix. The vectors + // D, x and f are printed as dense vectors. This should only be used + // for small problems. + CONSOLE, + + // Write out the linear least squares problem to the directory + // pointed to by Solver::Options::lsqp_dump_directory as a protocol + // buffer. linear_least_squares_problems.h/cc contains routines for + // loading these problems. For details on the on disk format used, + // see matrix.proto. The files are named lm_iteration_???.lsqp. + PROTOBUF, + + // Write out the linear least squares problem to the directory + // pointed to by Solver::Options::lsqp_dump_directory as text files + // which can be read into MATLAB/Octave. The Jacobian is dumped as a + // text file containing (i,j,s) triplets, the vectors D, x and f are + // dumped as text files containing a list of their values. + // + // A MATLAB/octave script called lm_iteration_???.m is also output, + // which can be used to parse and load the problem into memory. + TEXTFILE +}; + +// For SizedCostFunction and AutoDiffCostFunction, DYNAMIC can be specified for +// the number of residuals. If specified, then the number of residuas for that +// cost function can vary at runtime. +enum DimensionType { + DYNAMIC = -1 +}; + const char* LinearSolverTypeToString(LinearSolverType type); const char* PreconditionerTypeToString(PreconditionerType type); const char* LinearSolverTerminationTypeToString( diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc index c1be9402b78..7dd395e2975 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc @@ -259,5 +259,28 @@ void BlockSparseMatrix::ToProto(SparseMatrixProto* outer_proto) const { } #endif +void BlockSparseMatrix::ToTextFile(FILE* file) const { + CHECK_NOTNULL(file); + for (int i = 0; i < block_structure_->rows.size(); ++i) { + const int row_block_pos = block_structure_->rows[i].block.position; + const int row_block_size = block_structure_->rows[i].block.size; + const vector& cells = block_structure_->rows[i].cells; + for (int j = 0; j < cells.size(); ++j) { + const int col_block_id = cells[j].block_id; + const int col_block_size = block_structure_->cols[col_block_id].size; + const int col_block_pos = block_structure_->cols[col_block_id].position; + int jac_pos = cells[j].position; + for (int r = 0; r < row_block_size; ++r) { + for (int c = 0; c < col_block_size; ++c) { + fprintf(file, "% 10d % 10d %17f\n", + row_block_pos + r, + col_block_pos + c, + values_[jac_pos++]); + } + } + } + } +} + } // namespace internal } // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.h index b151dd0e248..f71446e8f58 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.h +++ b/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.h @@ -113,6 +113,8 @@ class BlockSparseMatrix : public BlockSparseMatrixBase { #ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS virtual void ToProto(SparseMatrixProto* proto) const; #endif + virtual void ToTextFile(FILE* file) const; + virtual int num_rows() const { return num_rows_; } virtual int num_cols() const { return num_cols_; } virtual int num_nonzeros() const { return num_nonzeros_; } diff --git a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.cc index 8fd568ffcc3..95edf5396af 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.cc @@ -321,5 +321,14 @@ void CompressedRowSparseMatrix::AppendRows(const CompressedRowSparseMatrix& m) { num_rows_ += m.num_rows(); } +void CompressedRowSparseMatrix::ToTextFile(FILE* file) const { + CHECK_NOTNULL(file); + for (int r = 0; r < num_rows_; ++r) { + for (int idx = rows_[r]; idx < rows_[r + 1]; ++idx) { + fprintf(file, "% 10d % 10d %17f\n", r, cols_[idx], values_[idx]); + } + } +} + } // namespace internal } // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h index 43712a86640..9a39d28e111 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h +++ b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h @@ -88,7 +88,7 @@ class CompressedRowSparseMatrix : public SparseMatrix { #ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS virtual void ToProto(SparseMatrixProto* proto) const; #endif - + virtual void ToTextFile(FILE* file) const; virtual int num_rows() const { return num_rows_; } virtual int num_cols() const { return num_cols_; } virtual int num_nonzeros() const { return rows_[num_rows_]; } diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc index ffbfab61de1..5d392ba6c3b 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc @@ -179,6 +179,19 @@ AlignedMatrixRef DenseSparseMatrix::mutable_matrix() { return AlignedMatrixRef(m_.data(), m_.rows(), m_.cols()); } +void DenseSparseMatrix::ToTextFile(FILE* file) const { + CHECK_NOTNULL(file); + const int active_rows = + (has_diagonal_reserved_ && !has_diagonal_appended_) + ? (m_.rows() - m_.cols()) + : m_.rows(); + + for (int r = 0; r < active_rows; ++r) { + for (int c = 0; c < m_.cols(); ++c) { + fprintf(file, "% 10d % 10d %17f\n", r, c, m_(r, c)); + } + } +} } // namespace internal } // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h index 5ce29eef51b..416c2143c2c 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h +++ b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h @@ -70,6 +70,7 @@ class DenseSparseMatrix : public SparseMatrix { #ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS virtual void ToProto(SparseMatrixProto* proto) const; #endif + virtual void ToTextFile(FILE* file) const; virtual int num_rows() const; virtual int num_cols() const; virtual int num_nonzeros() const; diff --git a/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.cc b/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.cc index 3ad359e63e4..b40a5162adc 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.cc @@ -58,6 +58,7 @@ #include "Eigen/Core" #include "ceres/evaluator.h" #include "ceres/file.h" +#include "ceres/linear_least_squares_problems.h" #include "ceres/linear_solver.h" #include "ceres/matrix_proto.h" #include "ceres/sparse_matrix.h" @@ -107,62 +108,6 @@ void LevenbergMarquardtDiagonal(const SparseMatrix& jacobian, } } -string DumpLinearSolverProblem( - int iteration, - const SparseMatrix* A, - const double* D, - const double* b, - const double* x, - const Minimizer::Options& solver_options) { - if (solver_options.lsqp_dump_format == "ascii") { - // Dump to the screen instead of to file. Useful for debugging. - Matrix AA; - A->ToDenseMatrix(&AA); - LOG(INFO) << "A^T: \n" << AA.transpose(); - if (D) { - LOG(INFO) << "A's appended diagonal:\n" - << ConstVectorRef(D, A->num_cols()); - } - LOG(INFO) << "b: \n" << ConstVectorRef(b, A->num_rows()); - LOG(INFO) << "x: \n" << ConstVectorRef(x, A->num_cols()); - return ""; - } -#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS - LinearLeastSquaresProblemProto lsqp; - A->ToProto(lsqp.mutable_a()); - for (int i = 0; i < A->num_rows(); ++i) { - lsqp.add_b(b[i]); - } - if (D) { - for (int i = 0; i < A->num_cols(); ++i) { - lsqp.add_d(D[i]); - } - } - if (x) { - for (int i = 0; i < A->num_cols(); ++i) { - lsqp.add_x(x[i]); - } - } - - lsqp.set_num_eliminate_blocks(solver_options.num_eliminate_blocks); - - CHECK(solver_options.lsqp_dump_format.size()); - string filename = - StringPrintf(solver_options.lsqp_dump_format.c_str(), // NOLINT - iteration); - VLOG(1) << "Dumping least squares problem for iteration " << iteration - << " to disk. File: " << filename; - WriteStringToFileOrDie(lsqp.SerializeAsString(), filename); - VLOG(2) << "Done dumping to disk"; - return filename; -#else - LOG(ERROR) << "Dumping least squares problems is only " - << "supported when Ceres is compiled with " - << "protocol buffer support."; - return ""; -#endif -} - bool RunCallback(IterationCallback* callback, const IterationSummary& iteration_summary, Solver::Summary* summary) { @@ -380,12 +325,17 @@ void LevenbergMarquardt::Minimize(const Minimizer::Options& options, if (binary_search(iterations_to_dump.begin(), iterations_to_dump.end(), iteration)) { - DumpLinearSolverProblem(iteration, - jacobian.get(), - muD.data(), - f.data(), - lm_step.data(), - options); + CHECK(DumpLinearLeastSquaresProblem(options.lsqp_dump_directory, + iteration, + options.lsqp_dump_format_type, + jacobian.get(), + muD.data(), + f.data(), + lm_step.data(), + options.num_eliminate_blocks)) + << "Tried writing linear least squares problem: " + << options.lsqp_dump_directory + << " but failed."; } // We ignore the case where the linear solver did not converge, @@ -413,7 +363,7 @@ void LevenbergMarquardt::Minimize(const Minimizer::Options& options, (x_norm + options.parameter_tolerance)) { summary->termination_type = PARAMETER_TOLERANCE; VLOG(1) << "Terminating on PARAMETER_TOLERANCE." - << "Relative step size: " << step_norm / step_size_tolerance + << "Relative step size: " << step_norm / step_size_tolerance << " <= " << options.parameter_tolerance; return; } @@ -545,33 +495,37 @@ void LevenbergMarquardt::Minimize(const Minimizer::Options& options, } if (num_consecutive_insane_steps == kMaxLinearSolverRetries) { - VLOG(1) << "Too many consecutive retries; ending with numerical fail."; summary->termination_type = NUMERICAL_FAILURE; + VLOG(1) << "Too many consecutive retries; ending with numerical fail."; if (!options.crash_and_dump_lsqp_on_failure) { return; } // Dump debugging information to disk. - CHECK(!options.lsqp_dump_format.empty()) + CHECK(options.lsqp_dump_format_type == TEXTFILE || + options.lsqp_dump_format_type == PROTOBUF) << "Dumping the linear least squares problem on crash " - << "requires Solver::Options::lsqp_dump_format set a " - << "filename"; - CHECK_NE(options.lsqp_dump_format, "ascii") - << "Dumping the linear least squares problem on crash " - << "requires Solver::Options::lsqp_dump_format set a " - << "filename"; + << "requires Solver::Options::lsqp_dump_format_type to be " + << "PROTOBUF or TEXTFILE."; - const string filename = DumpLinearSolverProblem(iteration, - jacobian.get(), - muD.data(), - f.data(), - lm_step.data(), - options); - LOG(FATAL) << "Linear least squares problem saved to " << filename - << " please provide this to the Ceres developers for " - << " debugging along with the v=2 log."; - return; + if (DumpLinearLeastSquaresProblem(options.lsqp_dump_directory, + iteration, + options.lsqp_dump_format_type, + jacobian.get(), + muD.data(), + f.data(), + lm_step.data(), + options.num_eliminate_blocks)) { + LOG(FATAL) << "Linear least squares problem saved to: " + << options.lsqp_dump_directory + << ". Please provide this to the Ceres developers for " + << " debugging along with the v=2 log."; + } else { + LOG(FATAL) << "Tried writing linear least squares problem: " + << options.lsqp_dump_directory + << " but failed."; + } } if (!step_is_successful) { diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc index 9fc5ff8a1c7..cca9f442fe7 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc @@ -30,15 +30,18 @@ #include "ceres/linear_least_squares_problems.h" +#include #include #include #include #include "ceres/block_sparse_matrix.h" #include "ceres/block_structure.h" +#include "ceres/casts.h" #include "ceres/compressed_row_sparse_matrix.h" #include "ceres/file.h" #include "ceres/matrix_proto.h" #include "ceres/triplet_sparse_matrix.h" +#include "ceres/stringprintf.h" #include "ceres/internal/scoped_ptr.h" #include "ceres/types.h" @@ -570,5 +573,172 @@ LinearLeastSquaresProblem* LinearLeastSquaresProblem3() { return problem; } +bool DumpLinearLeastSquaresProblemToConsole(const string& directory, + int iteration, + const SparseMatrix* A, + const double* D, + const double* b, + const double* x, + int num_eliminate_blocks) { + CHECK_NOTNULL(A); + Matrix AA; + A->ToDenseMatrix(&AA); + LOG(INFO) << "A^T: \n" << AA.transpose(); + + if (D != NULL) { + LOG(INFO) << "A's appended diagonal:\n" + << ConstVectorRef(D, A->num_cols()); + } + + if (b != NULL) { + LOG(INFO) << "b: \n" << ConstVectorRef(b, A->num_rows()); + } + + if (x != NULL) { + LOG(INFO) << "x: \n" << ConstVectorRef(x, A->num_cols()); + } + return true; +}; + +#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS +bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory, + int iteration, + const SparseMatrix* A, + const double* D, + const double* b, + const double* x, + int num_eliminate_blocks) { + CHECK_NOTNULL(A); + LinearLeastSquaresProblemProto lsqp; + A->ToProto(lsqp.mutable_a()); + + if (D != NULL) { + for (int i = 0; i < A->num_cols(); ++i) { + lsqp.add_d(D[i]); + } + } + + if (b != NULL) { + for (int i = 0; i < A->num_rows(); ++i) { + lsqp.add_b(b[i]); + } + } + + if (x != NULL) { + for (int i = 0; i < A->num_cols(); ++i) { + lsqp.add_x(x[i]); + } + } + + lsqp.set_num_eliminate_blocks(num_eliminate_blocks); + string format_string = JoinPath(directory, + "lm_iteration_%03d.lsqp"); + string filename = + StringPrintf(format_string.c_str(), iteration); + LOG(INFO) << "Dumping least squares problem for iteration " << iteration + << " to disk. File: " << filename; + WriteStringToFileOrDie(lsqp.SerializeAsString(), filename); + return true; +} +#else +bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory, + int iteration, + const SparseMatrix* A, + const double* D, + const double* b, + const double* x, + int num_eliminate_blocks) { + LOG(ERROR) << "Dumping least squares problems is only " + << "supported when Ceres is compiled with " + << "protocol buffer support."; + return false; +} +#endif + +void WriteArrayToFileOrDie(const string& filename, + const double* x, + const int size) { + CHECK_NOTNULL(x); + VLOG(2) << "Writing array to: " << filename; + FILE* fptr = fopen(filename.c_str(), "w"); + CHECK_NOTNULL(fptr); + for (int i = 0; i < size; ++i) { + fprintf(fptr, "%17f\n", x[i]); + } + fclose(fptr); +} + +bool DumpLinearLeastSquaresProblemToTextFile(const string& directory, + int iteration, + const SparseMatrix* A, + const double* D, + const double* b, + const double* x, + int num_eliminate_blocks) { + CHECK_NOTNULL(A); + string format_string = JoinPath(directory, + "lm_iteration_%03d"); + string filename_prefix = + StringPrintf(format_string.c_str(), iteration); + + { + string filename = filename_prefix + "_A.txt"; + LOG(INFO) << "writing to: " << filename; + FILE* fptr = fopen(filename.c_str(), "w"); + CHECK_NOTNULL(fptr); + A->ToTextFile(fptr); + fclose(fptr); + } + + if (D != NULL) { + string filename = filename_prefix + "_D.txt"; + WriteArrayToFileOrDie(filename, D, A->num_cols()); + } + + if (b != NULL) { + string filename = filename_prefix + "_b.txt"; + WriteArrayToFileOrDie(filename, b, A->num_rows()); + } + + if (x != NULL) { + string filename = filename_prefix + "_x.txt"; + WriteArrayToFileOrDie(filename, x, A->num_cols()); + } + + return true; +} + +bool DumpLinearLeastSquaresProblem(const string& directory, + int iteration, + DumpFormatType dump_format_type, + const SparseMatrix* A, + const double* D, + const double* b, + const double* x, + int num_eliminate_blocks) { + switch (dump_format_type) { + case (CONSOLE): + return DumpLinearLeastSquaresProblemToConsole(directory, + iteration, + A, D, b, x, + num_eliminate_blocks); + case (PROTOBUF): + return DumpLinearLeastSquaresProblemToProtocolBuffer( + directory, + iteration, + A, D, b, x, + num_eliminate_blocks); + case (TEXTFILE): + return DumpLinearLeastSquaresProblemToTextFile(directory, + iteration, + A, D, b, x, + num_eliminate_blocks); + default: + LOG(FATAL) << "Unknown DumpFormatType " << dump_format_type; + }; + + return true; +} + } // namespace internal } // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h index 46a624bd73f..553cc0d3db3 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h +++ b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h @@ -32,7 +32,7 @@ #define CERES_INTERNAL_LINEAR_LEAST_SQUARES_PROBLEMS_H_ #include - +#include #include "ceres/sparse_matrix.h" #include "ceres/internal/port.h" #include "ceres/internal/scoped_ptr.h" @@ -71,6 +71,16 @@ LinearLeastSquaresProblem* LinearLeastSquaresProblem1(); LinearLeastSquaresProblem* LinearLeastSquaresProblem2(); LinearLeastSquaresProblem* LinearLeastSquaresProblem3(); +// Write the linear least squares problem to disk. The exact format +// depends on dump_format_type. +bool DumpLinearLeastSquaresProblem(const string& directory, + int iteration, + DumpFormatType dump_format_type, + const SparseMatrix* A, + const double* D, + const double* b, + const double* x, + int num_eliminate_blocks); } // namespace internal } // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/minimizer.h b/extern/libmv/third_party/ceres/internal/ceres/minimizer.h index 71163a8ea6f..77cb00cb6b4 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/minimizer.h +++ b/extern/libmv/third_party/ceres/internal/ceres/minimizer.h @@ -59,8 +59,9 @@ class Minimizer { tau = options.tau; jacobi_scaling = options.jacobi_scaling; crash_and_dump_lsqp_on_failure = options.crash_and_dump_lsqp_on_failure; - lsqp_dump_format = options.lsqp_dump_format; + lsqp_dump_directory = options.lsqp_dump_directory; lsqp_iterations_to_dump = options.lsqp_iterations_to_dump; + lsqp_dump_format_type = options.lsqp_dump_format_type; num_eliminate_blocks = options.num_eliminate_blocks; logging_type = options.logging_type; } @@ -75,8 +76,9 @@ class Minimizer { double tau; bool jacobi_scaling; bool crash_and_dump_lsqp_on_failure; - string lsqp_dump_format; vector lsqp_iterations_to_dump; + DumpFormatType lsqp_dump_format_type; + string lsqp_dump_directory; int num_eliminate_blocks; LoggingType logging_type; diff --git a/extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.h index 962b803dd87..562210dfec8 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.h +++ b/extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.h @@ -33,6 +33,7 @@ #ifndef CERES_INTERNAL_SPARSE_MATRIX_H_ #define CERES_INTERNAL_SPARSE_MATRIX_H_ +#include #include "ceres/linear_operator.h" #include "ceres/internal/eigen.h" #include "ceres/types.h" @@ -87,9 +88,14 @@ class SparseMatrix : public LinearOperator { #ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS // Dump the sparse matrix to a proto. Destroys the contents of proto. - virtual void ToProto(SparseMatrixProto *proto) const = 0; + virtual void ToProto(SparseMatrixProto* proto) const = 0; #endif + // Write out the matrix as a sequence of (i,j,s) triplets. This + // format is useful for loading the matrix into MATLAB/octave as a + // sparse matrix. + virtual void ToTextFile(FILE* file) const = 0; + // Accessors for the values array that stores the entries of the // sparse matrix. The exact interpreptation of the values of this // array depends on the particular kind of SparseMatrix being diff --git a/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc index 7d7c3df9960..247ab2e697b 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc @@ -295,5 +295,12 @@ TripletSparseMatrix* TripletSparseMatrix::CreateSparseDiagonalMatrix( return m; } +void TripletSparseMatrix::ToTextFile(FILE* file) const { + CHECK_NOTNULL(file); + for (int i = 0; i < num_nonzeros_; ++i) { + fprintf(file, "% 10d % 10d %17f\n", rows_[i], cols_[i], values_[i]); + } +} + } // namespace internal } // namespace ceres diff --git a/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.h index 3c90a62fd20..300e74d0bbc 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.h +++ b/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.h @@ -68,6 +68,7 @@ class TripletSparseMatrix : public SparseMatrix { #ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS virtual void ToProto(SparseMatrixProto *proto) const; #endif + virtual void ToTextFile(FILE* file) const; virtual int num_rows() const { return num_rows_; } virtual int num_cols() const { return num_cols_; } virtual int num_nonzeros() const { return num_nonzeros_; } diff --git a/extern/libmv/third_party/ceres/patches/msvc_isfinite.patch b/extern/libmv/third_party/ceres/patches/msvc_isfinite.patch new file mode 100644 index 00000000000..c3129d8e02b --- /dev/null +++ b/extern/libmv/third_party/ceres/patches/msvc_isfinite.patch @@ -0,0 +1,15 @@ +diff --git a/internal/ceres/residual_block_utils.cc b/internal/ceres/residual_block_utils.cc +index ed3499b..28e0313 100644 +--- a/internal/ceres/residual_block_utils.cc ++++ b/internal/ceres/residual_block_utils.cc +@@ -40,6 +40,10 @@ + #include "ceres/internal/eigen.h" + #include "ceres/internal/port.h" + ++#ifdef _MSC_VER ++# define isfinite _finite ++#endif ++ + namespace ceres { + namespace internal { + From 39e81b468da264e1650fdbb634853126571e55c2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 10 May 2012 11:39:08 +0000 Subject: [PATCH 029/360] Tomato: ceres bundling script now works on svn checkout --- extern/libmv/third_party/ceres/bundle.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/extern/libmv/third_party/ceres/bundle.sh b/extern/libmv/third_party/ceres/bundle.sh index d7602f7c171..f54342180db 100755 --- a/extern/libmv/third_party/ceres/bundle.sh +++ b/extern/libmv/third_party/ceres/bundle.sh @@ -1,7 +1,9 @@ #!/bin/sh -if [ -d ./.svn ]; then - echo "This script is supposed to work only when using git-svn" +if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then + echo Proceeding as requested by command line ... +else + echo "*** Please run again with --i-really-know-what-im-doing ..." exit 1 fi @@ -24,8 +26,8 @@ for p in `cat ./patches/series`; do cat ./patches/$p | patch -d $tmp/ceres -p1 done -rm -rf include -rm -rf internal +find include -type f -not -iwholename '*.svn*' -exec rm -rf {} \; +find internal -type f -not -iwholename '*.svn*' -exec rm -rf {} \; cat "files.txt" | while read f; do mkdir -p `dirname $f` From e345a232d8dcb2838be54ddc074bd91bfee58a3d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 11 May 2012 05:21:04 +0000 Subject: [PATCH 030/360] Tomato: fixed invalid float suffix. --- source/blender/editors/mask/mask_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 0fedc2b34dc..acfd633a811 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -94,7 +94,7 @@ static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, fl float u = -1.0f, du = 1.0f / N, u1 = start_u, u2 = start_u; float ang = -1.0f; - while (u1 > 0.0f || u2 < 1.0d) { + while (u1 > 0.0f || u2 < 1.0f) { float n1[2], n2[2], co1[2], co2[2]; float v1[2], v2[2]; float ang1, ang2; From b3c1c03ba4f3f93f0df4e62d277995a3e5794646 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 13 May 2012 16:24:42 +0000 Subject: [PATCH 031/360] style cleanup: mask files --- source/blender/blenkernel/BKE_mask.h | 26 ++++++++++--------- source/blender/blenkernel/intern/mask.c | 25 +++++++++--------- .../composite/nodes/node_composite_mask.c | 8 +++--- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 268b7df0247..b39e15b4d32 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -53,20 +53,22 @@ struct MaskSpline *BKE_mask_spline_add(struct MaskShape *shape); int BKE_mask_spline_resolution(struct MaskSpline *spline); float *BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point); float *BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, float aspx, - float aspy, int *tot_feather_point); + float aspy, int *tot_feather_point); float *BKE_mask_spline_feather_points(struct MaskSpline *spline, float aspx, float aspy, int *tot_feather_point); /* point */ int BKE_mask_point_has_handle(struct MaskSplinePoint *point); void BKE_mask_point_handle(struct MaskSplinePoint *point, float aspx, float aspy, float handle[2]); -void BKE_mask_point_set_handle(struct MaskSplinePoint *point, float loc[2], int keep_direction, float aspx, float aspy, float orig_handle[2], float orig_vec[3][3]); +void BKE_mask_point_set_handle(struct MaskSplinePoint *point, float loc[2], int keep_direction, + float aspx, float aspy, float orig_handle[2], float orig_vec[3][3]); float *BKE_mask_point_segment_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, int *tot_diff_point); float *BKE_mask_point_segment_feather_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, float aspx, float aspy, int *tot_feather_point); void BKE_mask_point_segment_co(struct MaskSpline *spline, struct MaskSplinePoint *point, float u, float co[2]); -void BKE_mask_point_normal(struct MaskSpline *spline, struct MaskSplinePoint *point, float aspx, float aspy, float u, float n[2]); +void BKE_mask_point_normal(struct MaskSpline *spline, struct MaskSplinePoint *point, + float aspx, float aspy, float u, float n[2]); float BKE_mask_point_weight(struct MaskSpline *spline, struct MaskSplinePoint *point, float u); -struct MaskSplinePointUW * BKE_mask_point_sort_uw(struct MaskSplinePoint *point, struct MaskSplinePointUW *uw); +struct MaskSplinePointUW *BKE_mask_point_sort_uw(struct MaskSplinePoint *point, struct MaskSplinePointUW *uw); void BKE_mask_point_add_uw(struct MaskSplinePoint *point, float u, float w); /* general */ @@ -81,15 +83,15 @@ void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime); void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene); void BKE_mask_parent_init(struct MaskParent *parent); -#define MASKPOINT_ISSEL(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT ) -#define MASKPOINT_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } -#define MASKPOINT_DESEL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } -#define MASKPOINT_INVSEL(p) { (p)->bezt.f1 ^= SELECT; (p)->bezt.f2 ^= SELECT; (p)->bezt.f3 ^= SELECT; } +#define MASKPOINT_ISSEL(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT ) +#define MASKPOINT_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 +#define MASKPOINT_DESEL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 +#define MASKPOINT_INVSEL(p) { (p)->bezt.f1 ^= SELECT; (p)->bezt.f2 ^= SELECT; (p)->bezt.f3 ^= SELECT; } (void)0 -#define MASKPOINT_CV_ISSEL(p) ( (p)->bezt.f2 & SELECT ) +#define MASKPOINT_CV_ISSEL(p) ( (p)->bezt.f2 & SELECT ) -#define MASKPOINT_HANDLE_ONLY_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT ) && (((p)->bezt.f2 & SELECT) == 0) ) -#define MASKPOINT_HANDLE_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT ) ) -#define MASKPOINT_HANDLE_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f3 |= SELECT; } +#define MASKPOINT_HANDLE_ONLY_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) && (((p)->bezt.f2 & SELECT) == 0) ) +#define MASKPOINT_HANDLE_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) ) +#define MASKPOINT_HANDLE_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 #endif diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index d359cd077af..55dab26b841 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -217,7 +217,7 @@ float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) /* len+1 because of 'forward_diff_bezier' function */ *tot_diff_point = len; - diff_points = fp = MEM_callocN((len + 1)*2*sizeof(float), "mask spline vets"); + diff_points = fp = MEM_callocN((len + 1) * 2 * sizeof(float), "mask spline vets"); a = spline->tot_point - 1; if (spline->flag & MASK_SPLINE_CYCLIC) @@ -231,7 +231,7 @@ float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) BezTriple *bezt; int j; - if (a==0 && (spline->flag & MASK_SPLINE_CYCLIC)) + if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC)) point = spline->points; prevbezt = &prev->bezt; @@ -245,7 +245,7 @@ float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) fp += 2 * resol; - if (a==0 && (spline->flag & MASK_SPLINE_CYCLIC)==0) { + if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) { copy_v2_v2(fp, bezt->vec[1]); } @@ -257,7 +257,7 @@ float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) } float *BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, float aspx, float aspy, - int *tot_feather_point) + int *tot_feather_point) { float *feather, *fp; int i, j, tot, resol = BKE_mask_spline_feather_resolution(spline); @@ -352,8 +352,8 @@ void BKE_mask_point_handle(MaskSplinePoint *point, float aspx, float aspy, float vec[0] *= aspx; vec[1] *= aspy; - handle[0] = (point->bezt.vec[1][0]*aspx + vec[1]) / aspx; - handle[1] = (point->bezt.vec[1][1]*aspy - vec[0]) / aspy; + handle[0] = (point->bezt.vec[1][0] * aspx + vec[1]) / aspx; + handle[1] = (point->bezt.vec[1][1] * aspy - vec[0]) / aspy; } void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_direction, float aspx, float aspy, @@ -393,7 +393,8 @@ void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_di copy_v3_v3(bezt->vec[0], bezt->vec[1]); copy_v3_v3(bezt->vec[2], bezt->vec[1]); } - } else { + } + else { sub_v2_v2v2(v1, loc, bezt->vec[1]); v2[0] = -v1[1] * aspy / aspx; @@ -450,7 +451,7 @@ float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, i /* resol+1 because of 'forward_diff_bezier' function */ *tot_diff_point = resol + 1; - diff_points = fp = MEM_callocN((resol + 1)*2*sizeof(float), "mask segment vets"); + diff_points = fp = MEM_callocN((resol + 1) * 2 * sizeof(float), "mask segment vets"); for (j = 0; j < 2; j++) { BKE_curve_forward_diff_bezier(bezt->vec[1][j], bezt->vec[2][j], @@ -712,18 +713,18 @@ void BKE_mask_unlink(Main *bmain, Mask *mask) for (scr = bmain->screen.first; scr; scr = scr->id.next) { for (area = scr->areabase.first; area; area = area->next) { - for(sl = area->spacedata.first; sl; sl = sl->next) { - if(sl->spacetype == SPACE_CLIP) { + for (sl = area->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_CLIP) { SpaceClip *sc = (SpaceClip *) sl; - if(sc->mask == mask) + if (sc->mask == mask) sc->mask = NULL; } } } } - mask->id.us= 0; + mask->id.us = 0; } static void evaluate_mask_parent(MaskParent *parent, float ctime, float co[2]) diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c index 2c49be48f7d..1dbe057a869 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mask.c +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -43,13 +43,13 @@ /* **************** Translate ******************** */ static bNodeSocketTemplate cmp_node_mask_in[] = { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_mask_out[] = { - { SOCK_RGBA, 0, "Image"}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image"}, + { -1, 0, "" } }; static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) From 7444613a9a2ff8433712b2dc0525ee91a44c04a7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 13 May 2012 16:51:17 +0000 Subject: [PATCH 032/360] fix for crash when no mask exists when entering mask transform. --- source/blender/editors/transform/transform_conversions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 472e3ae0d1a..3d8e82eeb2f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5868,7 +5868,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t) TransDataMasking *tdm = NULL; /* count */ - shape = mask->shapes.first; + shape = mask ? mask->shapes.first : NULL; while (shape) { MaskSpline *spline = shape->splines.first; From ee9d9f4737ebebcb26ea7c9c3b8e0896f7e6b4db Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 13 May 2012 21:36:42 +0000 Subject: [PATCH 033/360] style cleanup: mask, whitespace edits, also use len_squared_v2 for comparisons. --- intern/raskter/raskter.c | 236 +++++++++--------- intern/raskter/raskter.h | 10 +- source/blender/blenkernel/BKE_mask.h | 4 +- source/blender/blenkernel/intern/idcode.c | 2 +- source/blender/blenkernel/intern/library.c | 2 +- source/blender/editors/include/ED_screen.h | 2 +- source/blender/editors/include/ED_transform.h | 2 +- source/blender/editors/mask/mask_draw.c | 32 ++- source/blender/editors/mask/mask_editor.c | 6 +- source/blender/editors/mask/mask_ops.c | 112 +++++---- 10 files changed, 213 insertions(+), 195 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index 0839e8a09c2..afa8b2102ae 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -32,8 +32,8 @@ #include "raskter.h" // from BLI_utildefines.h -#define MIN2(x,y) ( (x)<(y) ? (x) : (y) ) -#define MAX2(x,y) ( (x)>(y) ? (x) : (y) ) +#define MIN2(x, y) ( (x) < (y) ? (x) : (y) ) +#define MAX2(x, y) ( (x) > (y) ? (x) : (y) ) struct e_status { @@ -64,7 +64,7 @@ static struct r_buffer_stats rb; * just the poly. Since the DEM code could end up being coupled with this, we'll keep it separate * for now. */ -static void preprocess_all_edges(struct poly_vert * verts, int num_verts, struct e_status * open_edge) { +static void preprocess_all_edges(struct poly_vert *verts, int num_verts, struct e_status *open_edge) { int i; int xbeg; int ybeg; @@ -82,21 +82,22 @@ static void preprocess_all_edges(struct poly_vert * verts, int num_verts, struct v = verts; all_edges = NULL; // loop all verts - for(i = 0; i < num_verts; i++) { + for (i = 0; i < num_verts; i++) { // determine beginnings and endings of edges, linking last vertex to first vertex xbeg = v[i].x; ybeg = v[i].y; - if(i) { + if (i) { // we're not at the last vert, so end of the edge is the previous vertex - xend = v[i-1].x; - yend = v[i-1].y; - } else { + xend = v[i - 1].x; + yend = v[i - 1].y; + } + else { // we're at the first vertex, so the "end" of this edge is the last vertex - xend = v[num_verts-1].x; - yend = v[num_verts-1].y; + xend = v[num_verts - 1].x; + yend = v[num_verts - 1].y; } // make sure our edges are facing the correct direction - if(ybeg > yend) { + if (ybeg > yend) { // flip the Xs temp_pos = xbeg; xbeg = xend; @@ -110,16 +111,17 @@ static void preprocess_all_edges(struct poly_vert * verts, int num_verts, struct // calculate y delta dy = yend - ybeg; // dont draw horizontal lines directly, they are scanned as part of the edges they connect, so skip em. :) - if(dy) { + if (dy) { // create the edge and determine it's slope (for incremental line drawing) e_new = open_edge++; // calculate x delta dx = xend - xbeg; - if(dx > 0){ + if (dx > 0) { e_new->xdir = 1; xdist = dx; - }else{ + } + else { e_new->xdir = -1; xdist = -dx; } @@ -130,23 +132,25 @@ static void preprocess_all_edges(struct poly_vert * verts, int num_verts, struct e_new->drift_dec = dy; // calculate deltas for incremental drawing - if(dx >= 0) { + if (dx >= 0) { e_new->drift = 0; - } else { + } + else { e_new->drift = -dy + 1; } - if(dy >= xdist) { + if (dy >= xdist) { e_new->drift_inc = xdist; e_new->xshift = 0; - } else { + } + else { e_new->drift_inc = xdist % dy; e_new->xshift = (xdist / dy) * e_new->xdir; } next_edge_ref = &all_edges; // link in all the edges, in sorted order - for(;;) { + for (;; ) { next_edge = *next_edge_ref; - if(!next_edge || (next_edge->ybeg > ybeg) || ((next_edge->ybeg == ybeg) && (next_edge->x >= xbeg))) { + if (!next_edge || (next_edge->ybeg > ybeg) || ((next_edge->ybeg == ybeg) && (next_edge->x >= xbeg))) { e_new->e_next = next_edge; *next_edge_ref = e_new; break; @@ -162,156 +166,158 @@ static void preprocess_all_edges(struct poly_vert * verts, int num_verts, struct * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need * if it ends up being coupled with this function. */ -int rast_scan_fill(struct poly_vert * verts, int num_verts) { - int x_curr; // current pixel position in X - int y_curr; // current scan line being drawn - int yp; // y-pixel's position in frame buffer - int swixd = 0; // whether or not edges switched position in X - float *cpxl; // pixel pointers... +int rast_scan_fill(struct poly_vert *verts, int num_verts) { + int x_curr; // current pixel position in X + int y_curr; // current scan line being drawn + int yp; // y-pixel's position in frame buffer + int swixd = 0; // whether or not edges switched position in X + float *cpxl; // pixel pointers... float *mpxl; float *spxl; - struct e_status *e_curr; // edge pointers... + struct e_status *e_curr; // edge pointers... struct e_status *e_temp; struct e_status *edgbuf; struct e_status **edgec; /* - If the number of verts specified to render as a polygon is less than 3, - return immediately. Obviously we cant render a poly with sides < 3. The - return for this we set to 1, simply so it can be distinguished from the - next place we could return, which is a failure to allocate memory. + If the number of verts specified to render as a polygon is less than 3, + return immediately. Obviously we cant render a poly with sides < 3. The + return for this we set to 1, simply so it can be distinguished from the + next place we could return, which is a failure to allocate memory. */ - if(num_verts < 3) { + if (num_verts < 3) { return(1); } /* - Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data - multiplied by the number of edges, which is always equal to the number of verts in - a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for - the preceeding error, which was a rasterization request on a 2D poly with less than - 3 sides. + Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data + multiplied by the number of edges, which is always equal to the number of verts in + a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for + the preceeding error, which was a rasterization request on a 2D poly with less than + 3 sides. */ - if((edgbuf = (struct e_status *)(malloc(sizeof(struct e_status) * num_verts))) == NULL) { + if ((edgbuf = (struct e_status *)(malloc(sizeof(struct e_status) * num_verts))) == NULL) { return(0); } /* - Do some preprocessing on all edges. This constructs a table structure in memory of all - the edge properties and can "flip" some edges so sorting works correctly. + Do some preprocessing on all edges. This constructs a table structure in memory of all + the edge properties and can "flip" some edges so sorting works correctly. */ preprocess_all_edges(verts, num_verts, edgbuf); /* - Set the pointer for tracking the edges currently in processing to NULL to make sure - we don't get some crazy value after initialization. + Set the pointer for tracking the edges currently in processing to NULL to make sure + we don't get some crazy value after initialization. */ possible_edges = NULL; /* - Loop through all scan lines to be drawn. Since we sorted by Y values during - preprocess_all_edges(), we can already exact values for the lowest and - highest Y values we could possibly need by induction. The preprocessing sorted - out edges by Y position, we can cycle the current edge being processed once - it runs out of Y pixels. When we have no more edges, meaning the current edge - is NULL after setting the "current" edge to be the previous current edge's - "next" edge in the Y sorted edge connection chain, we can stop looping Y values, - since we can't possibly have more scan lines if we ran out of edges. :) + Loop through all scan lines to be drawn. Since we sorted by Y values during + preprocess_all_edges(), we can already exact values for the lowest and + highest Y values we could possibly need by induction. The preprocessing sorted + out edges by Y position, we can cycle the current edge being processed once + it runs out of Y pixels. When we have no more edges, meaning the current edge + is NULL after setting the "current" edge to be the previous current edge's + "next" edge in the Y sorted edge connection chain, we can stop looping Y values, + since we can't possibly have more scan lines if we ran out of edges. :) - TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here. - Will get changed once DEM code gets in. + TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here. + Will get changed once DEM code gets in. */ - for(y_curr = MAX2(all_edges->ybeg,0); (all_edges || possible_edges) && (y_curr < rb.sizey); y_curr++) { + for (y_curr = MAX2(all_edges->ybeg, 0); (all_edges || possible_edges) && (y_curr < rb.sizey); y_curr++) { /* - Link any edges that start on the current scan line into the list of - edges currently needed to draw at least this, if not several, scan lines. + Link any edges that start on the current scan line into the list of + edges currently needed to draw at least this, if not several, scan lines. */ /* - Set the current edge to the beginning of the list of edges to be rasterized - into this scan line. + Set the current edge to the beginning of the list of edges to be rasterized + into this scan line. - We could have lots of edge here, so iterate over all the edges needed. The - preprocess_all_edges() function sorted edges by X within each chunk of Y sorting - so we safely cycle edges to thier own "next" edges in order. + We could have lots of edge here, so iterate over all the edges needed. The + preprocess_all_edges() function sorted edges by X within each chunk of Y sorting + so we safely cycle edges to thier own "next" edges in order. - At each iteration, make sure we still have a non-NULL edge. + At each iteration, make sure we still have a non-NULL edge. */ - for(edgec = &possible_edges; all_edges && (all_edges->ybeg == y_curr);) { + for (edgec = &possible_edges; all_edges && (all_edges->ybeg == y_curr); ) { x_curr = all_edges->x; // Set current X position. - for(;;) { // Start looping edges. Will break when edges run out. + for (;; ) { // Start looping edges. Will break when edges run out. e_curr = *edgec; // Set up a current edge pointer. - if(!e_curr || (e_curr->x >= x_curr)) { // If we have an no edge, or we need to skip some X-span, + if (!e_curr || (e_curr->x >= x_curr)) { // If we have an no edge, or we need to skip some X-span, e_temp = all_edges->e_next; // set a temp "next" edge to test. *edgec = all_edges; // Add this edge to the list to be scanned. all_edges->e_next = e_curr; // Set up the next edge. edgec = &all_edges->e_next; // Set our list to the next edge's location in memory. all_edges = e_temp; // Skip the NULL or bad X edge, set pointer to next edge. break; // Stop looping edges (since we ran out or hit empty X span. - } else { + } + else { edgec = &e_curr->e_next; // Set the pointer to the edge list the "next" edge. } } } /* - Determine the current scan line's offset in the pixel buffer based on its Y position. - Basically we just multiply the current scan line's Y value by the number of pixels in each line. + Determine the current scan line's offset in the pixel buffer based on its Y position. + Basically we just multiply the current scan line's Y value by the number of pixels in each line. */ yp = y_curr * rb.sizex; /* - Set a "scan line pointer" in memory. The location of the buffer plus the row offset. + Set a "scan line pointer" in memory. The location of the buffer plus the row offset. */ spxl = rb.buf + (yp); /* - Set up the current edge to the first (in X) edge. The edges which could possibly be in this - list were determined in the preceeding edge loop above. They were already sorted in X by the - initial processing function. + Set up the current edge to the first (in X) edge. The edges which could possibly be in this + list were determined in the preceeding edge loop above. They were already sorted in X by the + initial processing function. - At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge - we will eventually hit a NULL when the list runs out. + At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge + we will eventually hit a NULL when the list runs out. */ - for(e_curr = possible_edges; e_curr; e_curr = e_curr->e_next) { + for (e_curr = possible_edges; e_curr; e_curr = e_curr->e_next) { /* - Calculate a span of pixels to fill on the current scan line. + Calculate a span of pixels to fill on the current scan line. - Set the current pixel pointer by adding the X offset to the scan line's start offset. - Cycle the current edge the next edge. - Set the max X value to draw to be one less than the next edge's first pixel. This way we are - sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than - one time because it's on a vertex connecting two edges) + Set the current pixel pointer by adding the X offset to the scan line's start offset. + Cycle the current edge the next edge. + Set the max X value to draw to be one less than the next edge's first pixel. This way we are + sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than + one time because it's on a vertex connecting two edges) - Then blast through all the pixels in the span, advancing the pointer and setting the color to white. + Then blast through all the pixels in the span, advancing the pointer and setting the color to white. - TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor, - but for now it is done here until the DEM code comes in. - */ + TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor, + but for now it is done here until the DEM code comes in. + */ // set up xmin and xmax bounds on this scan line - cpxl = spxl + MAX2(e_curr->x,0); + cpxl = spxl + MAX2(e_curr->x, 0); e_curr = e_curr->e_next; - mpxl = spxl + MIN2(e_curr->x,rb.sizex) - 1; + mpxl = spxl + MIN2(e_curr->x, rb.sizex) - 1; // draw the pixels. - for(; cpxl <= mpxl; *cpxl++ = 1.0f); + for (; cpxl <= mpxl; *cpxl++ = 1.0f) ; } /* - Loop through all edges of polygon that could be hit by this scan line, - and figure out their x-intersections with the next scan line. + Loop through all edges of polygon that could be hit by this scan line, + and figure out their x-intersections with the next scan line. - Either A.) we wont have any more edges to test, or B.) we just add on the - slope delta computed in preprocessing step. Since this draws non-antialiased - polygons, we dont have fractional positions, so we only move in x-direction - when needed to get all the way to the next pixel over... + Either A.) we wont have any more edges to test, or B.) we just add on the + slope delta computed in preprocessing step. Since this draws non-antialiased + polygons, we dont have fractional positions, so we only move in x-direction + when needed to get all the way to the next pixel over... */ - for(edgec = &possible_edges; (e_curr = *edgec);) { - if(!(--(e_curr->num))) { + for (edgec = &possible_edges; (e_curr = *edgec); ) { + if (!(--(e_curr->num))) { *edgec = e_curr->e_next; - } else { + } + else { e_curr->x += e_curr->xshift; - if((e_curr->drift += e_curr->drift_inc) > 0) { + if ((e_curr->drift += e_curr->drift_inc) > 0) { e_curr->x += e_curr->xdir; e_curr->drift -= e_curr->drift_dec; } @@ -319,17 +325,17 @@ int rast_scan_fill(struct poly_vert * verts, int num_verts) { } } /* - It's possible that some edges may have crossed during the last step, so we'll be sure - that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges - sorted by x-intersection coordinate. We'll always scan through at least once to see if - edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial - pass, then we know we need to sort by x, so then cycle through edges again and perform - the sort.- + It's possible that some edges may have crossed during the last step, so we'll be sure + that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges + sorted by x-intersection coordinate. We'll always scan through at least once to see if + edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial + pass, then we know we need to sort by x, so then cycle through edges again and perform + the sort.- */ - if(possible_edges) { - for(edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + if (possible_edges) { + for (edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { // if the current edge hits scan line at greater X than the next edge, we need to exchange the edges - if(e_curr->x > e_curr->e_next->x) { + if (e_curr->x > e_curr->e_next->x) { *edgec = e_curr->e_next; // exchange the pointers e_temp = e_curr->e_next->e_next; @@ -340,12 +346,12 @@ int rast_scan_fill(struct poly_vert * verts, int num_verts) { } } // if we did have a switch, look for more (there will more if there was one) - for(;;) { + for (;; ) { // reset exchange flag so it's only set if we encounter another one swixd = 0; - for(edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + for (edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { // again, if current edge hits scan line at higher X than next edge, exchange the edges and set flag - if(e_curr->x > e_curr->e_next->x) { + if (e_curr->x > e_curr->e_next->x) { *edgec = e_curr->e_next; // exchange the pointers e_temp = e_curr->e_next->e_next; @@ -356,7 +362,7 @@ int rast_scan_fill(struct poly_vert * verts, int num_verts) { } } // if we had no exchanges, we're done reshuffling the pointers - if(!swixd) { + if (!swixd) { break; } } @@ -367,7 +373,7 @@ int rast_scan_fill(struct poly_vert * verts, int num_verts) { return 1; } -int PLX_raskterize(float * verts, int num, float * buf, int buf_x, int buf_y) { +int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y) { int i; // i: Loop counter. struct poly_vert *ply; // ply: Pointer to a list of integer buffer-space vertex coordinates. @@ -378,7 +384,7 @@ int PLX_raskterize(float * verts, int num, float * buf, int buf_x, int buf_y) { * In the event of a failure to allocate the memory, return 0, so this error can * be distinguished as a memory allocation error. */ - if((ply = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num))) == NULL) { + if ((ply = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num))) == NULL) { return(0); } @@ -390,9 +396,9 @@ int PLX_raskterize(float * verts, int num, float * buf, int buf_x, int buf_y) { * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel * drawn will be 1.0f in value, there is no anti-aliasing. */ - for(i = 0; i < num; i++) { // Loop over all verts. - ply[i].x = (verts[i<<1] * buf_x) + 0.5f; // Range expand normalized X to integer buffer-space X. - ply[i].y = (verts[(i<<1)+1] * buf_y) + 0.5f; // Range expand normalized Y to integer buffer-space Y. + for (i = 0; i < num; i++) { // Loop over all verts. + ply[i].x = (verts[i << 1] * buf_x) + 0.5f; // Range expand normalized X to integer buffer-space X. + ply[i].y = (verts[(i << 1) + 1] * buf_y) + 0.5f; // Range expand normalized Y to integer buffer-space Y. } rb.buf = buf; // Set the output buffer pointer. diff --git a/intern/raskter/raskter.h b/intern/raskter/raskter.h index 0b3cf365ff4..98aaf0f6885 100644 --- a/intern/raskter/raskter.h +++ b/intern/raskter/raskter.h @@ -28,27 +28,27 @@ * \ingroup RASKTER */ -struct poly_vert{ +struct poly_vert { int x; int y; }; -struct scan_line{ +struct scan_line { int xstart; int xend; }; -struct scan_line_batch{ +struct scan_line_batch { int num; int ystart; - struct scan_line * slines; + struct scan_line *slines; }; #ifdef __cplusplus extern "C" { #endif -int PLX_raskterize(float * verts, int num, float * buf, int buf_x, int buf_y); +int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index b39e15b4d32..31a872b5056 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -83,12 +83,12 @@ void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime); void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene); void BKE_mask_parent_init(struct MaskParent *parent); -#define MASKPOINT_ISSEL(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT ) +#define MASKPOINT_ISSEL(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT) #define MASKPOINT_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 #define MASKPOINT_DESEL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 #define MASKPOINT_INVSEL(p) { (p)->bezt.f1 ^= SELECT; (p)->bezt.f2 ^= SELECT; (p)->bezt.f3 ^= SELECT; } (void)0 -#define MASKPOINT_CV_ISSEL(p) ( (p)->bezt.f2 & SELECT ) +#define MASKPOINT_CV_ISSEL(p) ( (p)->bezt.f2 & SELECT) #define MASKPOINT_HANDLE_ONLY_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) && (((p)->bezt.f2 & SELECT) == 0) ) #define MASKPOINT_HANDLE_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) ) diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c index 267fa732191..30427a81c4b 100644 --- a/source/blender/blenkernel/intern/idcode.c +++ b/source/blender/blenkernel/intern/idcode.c @@ -79,7 +79,7 @@ static IDType idtypes[] = { { ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE}, { ID_WM, "WindowManager", "window_managers", 0}, { ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE}, - { ID_MSK, "Mask", "masks", IDTYPE_FLAGS_ISLINKABLE}, + { ID_MSK, "Mask", "masks", IDTYPE_FLAGS_ISLINKABLE}, }; static int nidtypes = sizeof(idtypes) / sizeof(idtypes[0]); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index a4326a0cb72..0aae210dd17 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -573,7 +573,7 @@ int set_listbasepointers(Main *main, ListBase **lb) lb[a++] = &(main->library); lb[a++] = &(main->wm); lb[a++] = &(main->movieclip); - lb[a++]= &(main->mask); + lb[a++] = &(main->mask); lb[a] = NULL; diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index a4361321442..3b93eab3192 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -169,7 +169,7 @@ int ED_operator_editmball(struct bContext *C); int ED_operator_uvedit(struct bContext *C); int ED_operator_uvmap(struct bContext *C); int ED_operator_posemode(struct bContext *C); -int ED_operator_mask(struct bContext *C); +int ED_operator_mask(struct bContext *C); /* default keymaps, bitflags */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index ba9c610a7e0..f915612b57a 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -95,7 +95,7 @@ enum { #define CTX_BMESH 64 #define CTX_NDOF 128 #define CTX_MOVIECLIP 256 -#define CTX_MASK 512 +#define CTX_MASK 512 /* Standalone call to get the transformation center corresponding to the current situation * returns 1 if successful, 0 otherwise (usually means there's no selection) diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index d898a1c5232..68494af684e 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -38,7 +38,7 @@ #include "BKE_mask.h" #include "DNA_mask_types.h" -#include "DNA_object_types.h" /* SELECT */ +#include "DNA_object_types.h" /* SELECT */ #include "ED_mask.h" @@ -47,7 +47,7 @@ #include "UI_resources.h" -#include "mask_intern.h" // own include +#include "mask_intern.h" /* own include */ typedef struct PixelSpaceContext { int width, height; @@ -102,11 +102,13 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline, PixelSpaceC glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); - } else + } + else { glColor3f(0.5f, 0.5f, 0.0f); + } glBegin(GL_POINTS); - glVertex2fv(fp); + glVertex2fv(fp); glEnd(); fp += 2; @@ -119,7 +121,7 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline, PixelSpaceC MaskSplinePoint *point = &spline->points[i]; BezTriple *bezt = &point->bezt; float vert[2], handle[2]; - int has_handle = BKE_mask_point_has_handle(point);; + int has_handle = BKE_mask_point_has_handle(point); copy_v2_v2(vert, bezt->vec[1]); BKE_mask_point_handle(point, pixelspace->aspx, pixelspace->aspy, handle); @@ -129,8 +131,8 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline, PixelSpaceC set_spline_color(shape, spline); glBegin(GL_LINES); - glVertex3fv(vert); - glVertex3fv(handle); + glVertex3fv(vert); + glVertex3fv(handle); glEnd(); } @@ -140,11 +142,12 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline, PixelSpaceC glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); - } else + } + else glColor3f(0.5f, 0.5f, 0.0f); glBegin(GL_POINTS); - glVertex3fv(vert); + glVertex3fv(vert); glEnd(); /* draw handle points */ @@ -154,11 +157,13 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline, PixelSpaceC glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); - } else + } + else { glColor3f(0.5f, 0.5f, 0.0f); + } glBegin(GL_POINTS); - glVertex3fv(handle); + glVertex3fv(handle); glEnd(); } } @@ -176,7 +181,8 @@ static void draw_spline_curve_lines(float *points, int tot_point, int closed) else glBegin(GL_LINE_STRIP); - for (i = 0; i < tot_point; i++, fp+=2) { + /* MASK_TODO - vertex arrays */ + for (i = 0; i < tot_point; i++, fp += 2) { glVertex3fv(fp); } glEnd(); @@ -210,7 +216,7 @@ static void draw_spline_curve(MaskShape *shape, MaskSpline *spline, PixelSpaceCo return; feather_points = BKE_mask_spline_feather_differentiated_points(spline, pixelspace->aspx, pixelspace->aspy, - &tot_feather_point); + &tot_feather_point); /* draw feather */ if (spline->flag & SELECT) diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index 2325820880b..633f75c643b 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -47,7 +47,7 @@ #include "RNA_access.h" -#include "mask_intern.h" // own include +#include "mask_intern.h" /* own include */ /********************** generic poll functions *********************/ @@ -204,13 +204,13 @@ void ED_operatormacros_mask(void) wmOperatorType *ot; wmOperatorTypeMacro *otmacro; - ot= WM_operatortype_append_macro("MASK_OT_add_vertex_slide", "Add Vertex and Slide", "Add new vertex and slide it", OPTYPE_UNDO|OPTYPE_REGISTER); + ot = WM_operatortype_append_macro("MASK_OT_add_vertex_slide", "Add Vertex and Slide", "Add new vertex and slide it", OPTYPE_UNDO | OPTYPE_REGISTER); ot->description = "Add new vertex and slide it"; WM_operatortype_macro_define(ot, "MASK_OT_add_vertex"); otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE); - ot= WM_operatortype_append_macro("MASK_OT_add_feather_vertex_slide", "Add Feather Vertex and Slide", "Add new vertex to feater and slide it", OPTYPE_UNDO|OPTYPE_REGISTER); + ot = WM_operatortype_append_macro("MASK_OT_add_feather_vertex_slide", "Add Feather Vertex and Slide", "Add new vertex to feater and slide it", OPTYPE_UNDO | OPTYPE_REGISTER); ot->description = "Add new feather vertex and slide it"; WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex"); otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point"); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index acfd633a811..aee73205c99 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -41,7 +41,7 @@ #include "BKE_mask.h" #include "DNA_mask_types.h" -#include "DNA_object_types.h" /* SELECT */ +#include "DNA_object_types.h" /* SELECT */ #include "WM_api.h" #include "WM_types.h" @@ -53,7 +53,7 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "mask_intern.h" // own include +#include "mask_intern.h" /* own include */ /******************** utility functions *********************/ @@ -88,8 +88,11 @@ static void spline_point_select(MaskSplinePoint *point, int action) } } -static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, float aspx, float aspy, float start_u, float co[2]) + +static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, float aspx, float aspy, float start_u, const float co[2]) { + const float proj_eps = 1e-3; + const float proj_eps_squared = proj_eps * proj_eps; const int N = 1000; float u = -1.0f, du = 1.0f / N, u1 = start_u, u2 = start_u; float ang = -1.0f; @@ -104,7 +107,7 @@ static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, fl BKE_mask_point_normal(spline, point, aspx, aspy, u1, n1); sub_v2_v2v2(v1, co, co1); - if (len_v2(v1) > 1e-3) { + if (len_squared_v2(v1) > proj_eps_squared) { ang1 = angle_v2v2(v1, n1); if (ang1 > M_PI / 2.0f) ang1 = M_PI - ang1; @@ -125,7 +128,7 @@ static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, fl BKE_mask_point_normal(spline, point, aspx, aspy, u2, n2); sub_v2_v2v2(v2, co, co2); - if (len_v2(v2) > 1e-3) { + if (len_squared_v2(v2) > proj_eps_squared) { ang2 = angle_v2v2(v2, n2); if (ang2 > M_PI / 2.0f) ang2 = M_PI - ang2; @@ -441,7 +444,7 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], if (feather) { feather_points = BKE_mask_point_segment_feather_diff(spline, cur_point, - aspx, aspy, &tot_feather_point); + aspx, aspy, &tot_feather_point); points = feather_points; tot_point = tot_feather_point; @@ -563,7 +566,7 @@ static int mask_new_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); Mask *mask; - char name[MAX_ID_NAME-2]; + char name[MAX_ID_NAME - 2]; RNA_string_get(op->ptr, "name", name); @@ -583,14 +586,14 @@ void MASK_OT_new(wmOperatorType *ot) ot->idname = "MASK_OT_new"; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* api callbacks */ ot->exec = mask_new_exec; ot->poll = ED_operator_mask; /* properties */ - RNA_def_string(ot->srna, "name", "", MAX_ID_NAME-2, "Name", "Name of new mask"); + RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new mask"); } /******************** create new shape *********************/ @@ -598,14 +601,14 @@ void MASK_OT_new(wmOperatorType *ot) static int shape_new_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - char name[MAX_ID_NAME-2]; + char name[MAX_ID_NAME - 2]; RNA_string_get(op->ptr, "name", name); BKE_mask_shape_new(mask, name); mask->shapenr = mask->tot_shape - 1; - WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; } @@ -622,10 +625,10 @@ void MASK_OT_shape_new(wmOperatorType *ot) ot->poll = ED_maskediting_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_string(ot->srna, "name", "", MAX_ID_NAME-2, "Name", "Name of new shape"); + RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new shape"); } /******************** remove shape *********************/ @@ -638,7 +641,7 @@ static int shape_remove_exec(bContext *C, wmOperator *UNUSED(op)) if (shape) { BKE_mask_shape_remove(mask, shape); - WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); } return OPERATOR_FINISHED; @@ -656,15 +659,15 @@ void MASK_OT_shape_remove(wmOperatorType *ot) ot->poll = ED_maskediting_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /******************** slide *********************/ -#define SLIDE_ACTION_NONE 0 -#define SLIDE_ACTION_POINT 1 -#define SLIDE_ACTION_HANDLE 2 -#define SLIDE_ACTION_FEATHER 3 +#define SLIDE_ACTION_NONE 0 +#define SLIDE_ACTION_POINT 1 +#define SLIDE_ACTION_HANDLE 2 +#define SLIDE_ACTION_FEATHER 3 typedef struct SlidePointData { int action; @@ -798,7 +801,7 @@ static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) slidedata->shape->act_spline = slidedata->spline; slidedata->shape->act_point = slidedata->point; - WM_event_add_notifier(C, NC_MASK|ND_SELECT, mask); + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); return OPERATOR_RUNNING_MODAL; } @@ -831,18 +834,18 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) BezTriple *bezt = &data->point->bezt; float co[2], dco[2]; - switch(event->type) { + switch (event->type) { case LEFTCTRLKEY: case RIGHTCTRLKEY: case LEFTSHIFTKEY: case RIGHTSHIFTKEY: if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) - data->curvature_only = event->val==KM_PRESS; + data->curvature_only = event->val == KM_PRESS; if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) - data->accurate = event->val==KM_PRESS; + data->accurate = event->val == KM_PRESS; - /* no break! update CV position */ + /* no break! update CV position */ case MOUSEMOVE: ED_mask_mouse_pos(C, event, co); @@ -909,16 +912,16 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) *weight = 0; } - WM_event_add_notifier(C, NC_MASK|NA_EDITED, data->mask); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); DAG_id_tag_update(&data->mask->id, 0); break; case LEFTMOUSE: - if(event->val==KM_RELEASE) { + if (event->val == KM_RELEASE) { free_slide_point_data(op->customdata); - WM_event_add_notifier(C, NC_MASK|NA_EDITED, data->mask); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); DAG_id_tag_update(&data->mask->id, 0); return OPERATOR_FINISHED; @@ -931,7 +934,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) free_slide_point_data(op->customdata); - WM_event_add_notifier(C, NC_MASK|NA_EDITED, data->mask); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); DAG_id_tag_update(&data->mask->id, 0); return OPERATOR_CANCELLED; @@ -953,7 +956,7 @@ void MASK_OT_slide_point(wmOperatorType *ot) ot->poll = ED_maskediting_mask_poll; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; RNA_def_boolean(ot->srna, "slide_feather", 0, "Slide Feather", "First try to slide slide feather instead of vertex"); } @@ -968,7 +971,7 @@ static int select_all_exec(bContext *C, wmOperator *op) toggle_selection_all(mask, action); mask_flush_selection(mask); - WM_event_add_notifier(C, NC_MASK|ND_SELECT, mask); + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); return OPERATOR_FINISHED; } @@ -985,7 +988,7 @@ void MASK_OT_select_all(wmOperatorType *ot) ot->poll = ED_maskediting_mask_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ WM_operator_properties_select_all(ot); @@ -1024,7 +1027,7 @@ static int select_exec(bContext *C, wmOperator *op) mask_flush_selection(mask); - WM_event_add_notifier(C, NC_MASK|ND_SELECT, mask); + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); } else { MaskSplinePointUW *uw; @@ -1040,7 +1043,7 @@ static int select_exec(bContext *C, wmOperator *op) mask_flush_selection(mask); - WM_event_add_notifier(C, NC_MASK|ND_SELECT, mask); + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); } } @@ -1075,9 +1078,9 @@ void MASK_OT_select(wmOperatorType *ot) /* properties */ RNA_def_boolean(ot->srna, "extend", 0, - "Extend", "Extend selection rather than clearing the existing selection"); + "Extend", "Extend selection rather than clearing the existing selection"); RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, - "Location", "Location of vertex in normalized space", -1.0f, 1.0f); + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); } /******************** add vertex *********************/ @@ -1125,7 +1128,8 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask sub_v2_v2(bezt->vec[0], vec); add_v2_v2(bezt->vec[2], vec); - } else { + } + else { /* next points are aligning in the direction of previous/next point */ MaskSplinePoint *point; float v1[2], v2[2], vec[2]; @@ -1134,7 +1138,8 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask if (new_point == spline->points) { point = new_point + 1; dir = -1.0f; - } else + } + else point = new_point - 1; if (spline->tot_point < 3) { @@ -1210,7 +1215,7 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) shape->act_point = new_point; - WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return TRUE; } @@ -1312,7 +1317,7 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) shape->act_point = new_point; setup_vertex_point(C, mask, spline, new_point, co, NULL); - WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return TRUE; } @@ -1356,11 +1361,11 @@ void MASK_OT_add_vertex(wmOperatorType *ot) ot->poll = ED_maskediting_mask_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, - "Location", "Location of vertex in normalized space", -1.0f, 1.0f); + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); } /******************** add feather vertex *********************/ @@ -1385,7 +1390,7 @@ static int add_feather_vertex_exec(bContext *C, wmOperator *op) BKE_mask_point_add_uw(point, u, w); - WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; } @@ -1417,11 +1422,11 @@ void MASK_OT_add_feather_vertex(wmOperatorType *ot) ot->poll = ED_maskediting_mask_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, - "Location", "Location of vertex in normalized space", -1.0f, 1.0f); + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); } /******************** toggle cyclic *********************/ @@ -1444,7 +1449,7 @@ static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) shape = shape->next; } - WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; } @@ -1461,7 +1466,7 @@ void MASK_OT_cyclic_toggle(wmOperatorType *ot) ot->poll = ED_maskediting_mask_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /******************** delete *********************/ @@ -1536,7 +1541,7 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) MaskSplinePoint *new_points; int j; - new_points = MEM_callocN(count*sizeof(MaskSplinePoint), "deleteMaskPoints"); + new_points = MEM_callocN(count * sizeof(MaskSplinePoint), "deleteMaskPoints"); for (i = 0, j = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; @@ -1571,7 +1576,7 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) shape = shape->next; } - WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; } @@ -1589,7 +1594,7 @@ void MASK_OT_delete(wmOperatorType *ot) ot->poll = ED_maskediting_mask_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /******************** set handle type *********************/ @@ -1621,7 +1626,7 @@ static int set_handle_type_exec(bContext *C, wmOperator *op) shape = shape->next; } - WM_event_add_notifier(C, NC_MASK|ND_DATA, mask); + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); DAG_id_tag_update(&mask->id, 0); return OPERATOR_FINISHED; @@ -1629,11 +1634,12 @@ static int set_handle_type_exec(bContext *C, wmOperator *op) void MASK_OT_handle_type_set(wmOperatorType *ot) { - static EnumPropertyItem editcurve_handle_type_items[]= { + static EnumPropertyItem editcurve_handle_type_items[] = { {HD_AUTO, "AUTO", 0, "Auto", ""}, {HD_VECT, "VECTOR", 0, "Vector", ""}, {HD_ALIGN, "ALIGNED", 0, "Aligned", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Set Handle Type"; @@ -1646,7 +1652,7 @@ void MASK_OT_handle_type_set(wmOperatorType *ot) ot->poll = ED_maskediting_mask_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ ot->prop = RNA_def_enum(ot->srna, "type", editcurve_handle_type_items, 1, "Type", "Spline type"); From cf6450256db6eaf0ea37d4c64f648d22d8954099 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 13 May 2012 21:46:18 +0000 Subject: [PATCH 034/360] style cleanup: comments and whitespace --- intern/raskter/raskter.c | 251 ++++++++++++++++++++------------------- 1 file changed, 127 insertions(+), 124 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index afa8b2102ae..b80b7de379b 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -31,7 +31,7 @@ #include #include "raskter.h" -// from BLI_utildefines.h +/* from BLI_utildefines.h */ #define MIN2(x, y) ( (x) < (y) ? (x) : (y) ) #define MAX2(x, y) ( (x) > (y) ? (x) : (y) ) @@ -64,7 +64,8 @@ static struct r_buffer_stats rb; * just the poly. Since the DEM code could end up being coupled with this, we'll keep it separate * for now. */ -static void preprocess_all_edges(struct poly_vert *verts, int num_verts, struct e_status *open_edge) { +static void preprocess_all_edges(struct poly_vert *verts, int num_verts, struct e_status *open_edge) +{ int i; int xbeg; int ybeg; @@ -78,44 +79,44 @@ static void preprocess_all_edges(struct poly_vert *verts, int num_verts, struct struct e_status *next_edge; struct e_status **next_edge_ref; struct poly_vert *v; - // set up pointers + /* set up pointers */ v = verts; all_edges = NULL; - // loop all verts + /* loop all verts */ for (i = 0; i < num_verts; i++) { - // determine beginnings and endings of edges, linking last vertex to first vertex + /* determine beginnings and endings of edges, linking last vertex to first vertex */ xbeg = v[i].x; ybeg = v[i].y; if (i) { - // we're not at the last vert, so end of the edge is the previous vertex + /* we're not at the last vert, so end of the edge is the previous vertex */ xend = v[i - 1].x; yend = v[i - 1].y; } else { - // we're at the first vertex, so the "end" of this edge is the last vertex + /* we're at the first vertex, so the "end" of this edge is the last vertex */ xend = v[num_verts - 1].x; yend = v[num_verts - 1].y; } - // make sure our edges are facing the correct direction + /* make sure our edges are facing the correct direction */ if (ybeg > yend) { - // flip the Xs + /* flip the Xs */ temp_pos = xbeg; xbeg = xend; xend = temp_pos; - // flip the Ys + /* flip the Ys */ temp_pos = ybeg; ybeg = yend; yend = temp_pos; } - // calculate y delta + /* calculate y delta */ dy = yend - ybeg; - // dont draw horizontal lines directly, they are scanned as part of the edges they connect, so skip em. :) + /* dont draw horizontal lines directly, they are scanned as part of the edges they connect, so skip em. :) */ if (dy) { - // create the edge and determine it's slope (for incremental line drawing) + /* create the edge and determine it's slope (for incremental line drawing) */ e_new = open_edge++; - // calculate x delta + /* calculate x delta */ dx = xend - xbeg; if (dx > 0) { e_new->xdir = 1; @@ -131,7 +132,7 @@ static void preprocess_all_edges(struct poly_vert *verts, int num_verts, struct e_new->num = dy; e_new->drift_dec = dy; - // calculate deltas for incremental drawing + /* calculate deltas for incremental drawing */ if (dx >= 0) { e_new->drift = 0; } @@ -147,7 +148,7 @@ static void preprocess_all_edges(struct poly_vert *verts, int num_verts, struct e_new->xshift = (xdist / dy) * e_new->xdir; } next_edge_ref = &all_edges; - // link in all the edges, in sorted order + /* link in all the edges, in sorted order */ for (;; ) { next_edge = *next_edge_ref; if (!next_edge || (next_edge->ybeg > ybeg) || ((next_edge->ybeg == ybeg) && (next_edge->x >= xbeg))) { @@ -166,150 +167,152 @@ static void preprocess_all_edges(struct poly_vert *verts, int num_verts, struct * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need * if it ends up being coupled with this function. */ -int rast_scan_fill(struct poly_vert *verts, int num_verts) { - int x_curr; // current pixel position in X - int y_curr; // current scan line being drawn - int yp; // y-pixel's position in frame buffer - int swixd = 0; // whether or not edges switched position in X - float *cpxl; // pixel pointers... +int rast_scan_fill(struct poly_vert *verts, int num_verts) +{ + int x_curr; /* current pixel position in X */ + int y_curr; /* current scan line being drawn */ + int yp; /* y-pixel's position in frame buffer */ + int swixd = 0; /* whether or not edges switched position in X */ + float *cpxl; /* pixel pointers... */ float *mpxl; float *spxl; - struct e_status *e_curr; // edge pointers... + struct e_status *e_curr; /* edge pointers... */ struct e_status *e_temp; struct e_status *edgbuf; struct e_status **edgec; /* - If the number of verts specified to render as a polygon is less than 3, - return immediately. Obviously we cant render a poly with sides < 3. The - return for this we set to 1, simply so it can be distinguished from the - next place we could return, which is a failure to allocate memory. + * If the number of verts specified to render as a polygon is less than 3, + * return immediately. Obviously we cant render a poly with sides < 3. The + * return for this we set to 1, simply so it can be distinguished from the + * next place we could return, /home/guest/blender-svn/soc-2011-tomato/intern/raskter/raskter.cwhich is a failure to allocate memory. */ if (num_verts < 3) { return(1); } /* - Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data - multiplied by the number of edges, which is always equal to the number of verts in - a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for - the preceeding error, which was a rasterization request on a 2D poly with less than - 3 sides. + * Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data + * multiplied by the number of edges, which is always equal to the number of verts in + * a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for + * the preceeding error, which was a rasterization request on a 2D poly with less than + * 3 sides. */ if ((edgbuf = (struct e_status *)(malloc(sizeof(struct e_status) * num_verts))) == NULL) { return(0); } /* - Do some preprocessing on all edges. This constructs a table structure in memory of all - the edge properties and can "flip" some edges so sorting works correctly. + * Do some preprocessing on all edges. This constructs a table structure in memory of all + * the edge properties and can "flip" some edges so sorting works correctly. */ preprocess_all_edges(verts, num_verts, edgbuf); /* - Set the pointer for tracking the edges currently in processing to NULL to make sure - we don't get some crazy value after initialization. + * Set the pointer for tracking the edges currently in processing to NULL to make sure + * we don't get some crazy value after initialization. */ possible_edges = NULL; /* - Loop through all scan lines to be drawn. Since we sorted by Y values during - preprocess_all_edges(), we can already exact values for the lowest and - highest Y values we could possibly need by induction. The preprocessing sorted - out edges by Y position, we can cycle the current edge being processed once - it runs out of Y pixels. When we have no more edges, meaning the current edge - is NULL after setting the "current" edge to be the previous current edge's - "next" edge in the Y sorted edge connection chain, we can stop looping Y values, - since we can't possibly have more scan lines if we ran out of edges. :) - - TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here. - Will get changed once DEM code gets in. + * Loop through all scan lines to be drawn. Since we sorted by Y values during + * preprocess_all_edges(), we can already exact values for the lowest and + * highest Y values we could possibly need by induction. The preprocessing sorted + * out edges by Y position, we can cycle the current edge being processed once + * it runs out of Y pixels. When we have no more edges, meaning the current edge + * is NULL after setting the "current" edge to be the previous current edge's + * "next" edge in the Y sorted edge connection chain, we can stop looping Y values, + * since we can't possibly have more scan lines if we ran out of edges. :) + * + * TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here. + * Will get changed once DEM code gets in. */ for (y_curr = MAX2(all_edges->ybeg, 0); (all_edges || possible_edges) && (y_curr < rb.sizey); y_curr++) { /* - Link any edges that start on the current scan line into the list of - edges currently needed to draw at least this, if not several, scan lines. + * Link any edges that start on the current scan line into the list of + * edges currently needed to draw at least this, if not several, scan lines. */ /* - Set the current edge to the beginning of the list of edges to be rasterized - into this scan line. - - We could have lots of edge here, so iterate over all the edges needed. The - preprocess_all_edges() function sorted edges by X within each chunk of Y sorting - so we safely cycle edges to thier own "next" edges in order. - - At each iteration, make sure we still have a non-NULL edge. + * Set the current edge to the beginning of the list of edges to be rasterized + * into this scan line. + * + * We could have lots of edge here, so iterate over all the edges needed. The + * preprocess_all_edges() function sorted edges by X within each chunk of Y sorting + * so we safely cycle edges to thier own "next" edges in order. + * + * At each iteration, make sure we still have a non-NULL edge. */ for (edgec = &possible_edges; all_edges && (all_edges->ybeg == y_curr); ) { - x_curr = all_edges->x; // Set current X position. - for (;; ) { // Start looping edges. Will break when edges run out. - e_curr = *edgec; // Set up a current edge pointer. - if (!e_curr || (e_curr->x >= x_curr)) { // If we have an no edge, or we need to skip some X-span, - e_temp = all_edges->e_next; // set a temp "next" edge to test. - *edgec = all_edges; // Add this edge to the list to be scanned. - all_edges->e_next = e_curr; // Set up the next edge. - edgec = &all_edges->e_next; // Set our list to the next edge's location in memory. - all_edges = e_temp; // Skip the NULL or bad X edge, set pointer to next edge. - break; // Stop looping edges (since we ran out or hit empty X span. + x_curr = all_edges->x; /* Set current X position. */ + for (;; ) { /* Start looping edges. Will break when edges run out. */ + e_curr = *edgec; /* Set up a current edge pointer. */ + if (!e_curr || (e_curr->x >= x_curr)) { /* If we have an no edge, or we need to skip some X-span, */ + e_temp = all_edges->e_next; /* set a temp "next" edge to test. */ + *edgec = all_edges; /* Add this edge to the list to be scanned. */ + all_edges->e_next = e_curr; /* Set up the next edge. */ + edgec = &all_edges->e_next; /* Set our list to the next edge's location in memory. */ + all_edges = e_temp; /* Skip the NULL or bad X edge, set pointer to next edge. */ + break; /* Stop looping edges (since we ran out or hit empty X span. */ } else { - edgec = &e_curr->e_next; // Set the pointer to the edge list the "next" edge. + edgec = &e_curr->e_next; /* Set the pointer to the edge list the "next" edge. */ } } } /* - Determine the current scan line's offset in the pixel buffer based on its Y position. - Basically we just multiply the current scan line's Y value by the number of pixels in each line. + * Determine the current scan line's offset in the pixel buffer based on its Y position. + * Basically we just multiply the current scan line's Y value by the number of pixels in each line. */ yp = y_curr * rb.sizex; /* - Set a "scan line pointer" in memory. The location of the buffer plus the row offset. + * Set a "scan line pointer" in memory. The location of the buffer plus the row offset. */ spxl = rb.buf + (yp); /* - Set up the current edge to the first (in X) edge. The edges which could possibly be in this - list were determined in the preceeding edge loop above. They were already sorted in X by the - initial processing function. - - At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge - we will eventually hit a NULL when the list runs out. + * Set up the current edge to the first (in X) edge. The edges which could possibly be in this + * list were determined in the preceeding edge loop above. They were already sorted in X by the + * initial processing function. + * + * At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge + * we will eventually hit a NULL when the list runs out. */ for (e_curr = possible_edges; e_curr; e_curr = e_curr->e_next) { /* - Calculate a span of pixels to fill on the current scan line. - - Set the current pixel pointer by adding the X offset to the scan line's start offset. - Cycle the current edge the next edge. - Set the max X value to draw to be one less than the next edge's first pixel. This way we are - sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than - one time because it's on a vertex connecting two edges) - - Then blast through all the pixels in the span, advancing the pointer and setting the color to white. - - TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor, - but for now it is done here until the DEM code comes in. + * Calculate a span of pixels to fill on the current scan line. + * + * Set the current pixel pointer by adding the X offset to the scan line's start offset. + * Cycle the current edge the next edge. + * Set the max X value to draw to be one less than the next edge's first pixel. This way we are + * sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than + * one time because it's on a vertex connecting two edges) + * + * Then blast through all the pixels in the span, advancing the pointer and setting the color to white. + * + * TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor, + * but for now it is done here until the DEM code comes in. */ - // set up xmin and xmax bounds on this scan line + + /* set up xmin and xmax bounds on this scan line */ cpxl = spxl + MAX2(e_curr->x, 0); e_curr = e_curr->e_next; mpxl = spxl + MIN2(e_curr->x, rb.sizex) - 1; - // draw the pixels. + /* draw the pixels. */ for (; cpxl <= mpxl; *cpxl++ = 1.0f) ; } /* - Loop through all edges of polygon that could be hit by this scan line, - and figure out their x-intersections with the next scan line. - - Either A.) we wont have any more edges to test, or B.) we just add on the - slope delta computed in preprocessing step. Since this draws non-antialiased - polygons, we dont have fractional positions, so we only move in x-direction - when needed to get all the way to the next pixel over... + * Loop through all edges of polygon that could be hit by this scan line, + * and figure out their x-intersections with the next scan line. + * + * Either A.) we wont have any more edges to test, or B.) we just add on the + * slope delta computed in preprocessing step. Since this draws non-antialiased + * polygons, we dont have fractional positions, so we only move in x-direction + * when needed to get all the way to the next pixel over... */ for (edgec = &possible_edges; (e_curr = *edgec); ) { if (!(--(e_curr->num))) { @@ -325,43 +328,43 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) { } } /* - It's possible that some edges may have crossed during the last step, so we'll be sure - that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges - sorted by x-intersection coordinate. We'll always scan through at least once to see if - edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial - pass, then we know we need to sort by x, so then cycle through edges again and perform - the sort.- + * It's possible that some edges may have crossed during the last step, so we'll be sure + * that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges + * sorted by x-intersection coordinate. We'll always scan through at least once to see if + * edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial + * pass, then we know we need to sort by x, so then cycle through edges again and perform + * the sort.- */ if (possible_edges) { for (edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { - // if the current edge hits scan line at greater X than the next edge, we need to exchange the edges + /* if the current edge hits scan line at greater X than the next edge, we need to exchange the edges */ if (e_curr->x > e_curr->e_next->x) { *edgec = e_curr->e_next; - // exchange the pointers + /* exchange the pointers */ e_temp = e_curr->e_next->e_next; e_curr->e_next->e_next = e_curr; e_curr->e_next = e_temp; - // set flag that we had at least one switch + /* set flag that we had at least one switch */ swixd = 1; } } - // if we did have a switch, look for more (there will more if there was one) + /* if we did have a switch, look for more (there will more if there was one) */ for (;; ) { - // reset exchange flag so it's only set if we encounter another one + /* reset exchange flag so it's only set if we encounter another one */ swixd = 0; for (edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { - // again, if current edge hits scan line at higher X than next edge, exchange the edges and set flag + /* again, if current edge hits scan line at higher X than next edge, exchange the edges and set flag */ if (e_curr->x > e_curr->e_next->x) { *edgec = e_curr->e_next; - // exchange the pointers + /* exchange the pointers */ e_temp = e_curr->e_next->e_next; e_curr->e_next->e_next = e_curr; e_curr->e_next = e_temp; - // flip the exchanged flag + /* flip the exchanged flag */ swixd = 1; } } - // if we had no exchanges, we're done reshuffling the pointers + /* if we had no exchanges, we're done reshuffling the pointers */ if (!swixd) { break; } @@ -374,8 +377,8 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) { } int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y) { - int i; // i: Loop counter. - struct poly_vert *ply; // ply: Pointer to a list of integer buffer-space vertex coordinates. + int i; /* i: Loop counter. */ + struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */ /* * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert @@ -396,17 +399,17 @@ int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y) { * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel * drawn will be 1.0f in value, there is no anti-aliasing. */ - for (i = 0; i < num; i++) { // Loop over all verts. - ply[i].x = (verts[i << 1] * buf_x) + 0.5f; // Range expand normalized X to integer buffer-space X. - ply[i].y = (verts[(i << 1) + 1] * buf_y) + 0.5f; // Range expand normalized Y to integer buffer-space Y. + for (i = 0; i < num; i++) { /* Loop over all verts. */ + ply[i].x = (verts[i << 1] * buf_x) + 0.5f; /* Range expand normalized X to integer buffer-space X. */ + ply[i].y = (verts[(i << 1) + 1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */ } - rb.buf = buf; // Set the output buffer pointer. - rb.sizex = buf_x; // Set the output buffer size in X. (width) - rb.sizey = buf_y; // Set the output buffer size in Y. (height) + rb.buf = buf; /* Set the output buffer pointer. */ + rb.sizex = buf_x; /* Set the output buffer size in X. (width) */ + rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ - i = rast_scan_fill(ply, num); // Call our rasterizer, passing in the integer coords for each vert. - free(ply); // Free the memory allocated for the integer coordinate table. - return(i); // Return the value returned by the rasterizer. + i = rast_scan_fill(ply, num); /* Call our rasterizer, passing in the integer coords for each vert. */ + free(ply); /* Free the memory allocated for the integer coordinate table. */ + return(i); /* Return the value returned by the rasterizer. */ } From bac340e6740ea4f5f1ac41a47b6a540d726c4ac6 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Sun, 13 May 2012 23:08:56 +0000 Subject: [PATCH 035/360] Add a planar tracking implementation to libmv This adds a new planar tracking implementation to libmv. The tracker is based on Ceres[1], the new nonlinear minimizer that myself and Sameer released from Google as open source. Since the motion model is more involved, the interface is different than the RegionTracker interface used previously in Blender. The start of a C API in libmv-capi.{cpp,h} is also included. The ESM tracker, also known as the KLT tracker in the UI, is temporarily changed to use the new Ceres-based planar tracker in translation-only mode. Currently it is a bit slower than ESM and also doesn't have all the bells and whistles implemented. Those will come soon. Longer term, both trackers will remain since Ceres is unlikely to be as fast as ESM for pure translation solving, due to its generality. The next step is to implement a new tracking UI. The current UI assumes a translational motion model; the new one must support arbitrary perspective transforms of the pattern regions. [1] http://code.google.com/p/ceres-solver --- extern/libmv/CMakeLists.txt | 2 + extern/libmv/libmv-capi.cpp | 68 +- extern/libmv/libmv-capi.h | 21 + extern/libmv/libmv/multiview/homography.cc | 267 +++++++ extern/libmv/libmv/multiview/homography.h | 84 +++ .../multiview/homography_parameterization.h | 91 +++ .../libmv/tracking/esm_region_tracker.cc | 40 ++ extern/libmv/libmv/tracking/track_region.cc | 651 ++++++++++++++++++ extern/libmv/libmv/tracking/track_region.h | 91 +++ 9 files changed, 1314 insertions(+), 1 deletion(-) create mode 100644 extern/libmv/libmv/multiview/homography.cc create mode 100644 extern/libmv/libmv/multiview/homography.h create mode 100644 extern/libmv/libmv/multiview/homography_parameterization.h create mode 100644 extern/libmv/libmv/tracking/track_region.cc create mode 100644 extern/libmv/libmv/tracking/track_region.h diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt index cf0ad1102e0..60cd84d89d4 100644 --- a/extern/libmv/CMakeLists.txt +++ b/extern/libmv/CMakeLists.txt @@ -62,6 +62,7 @@ set(SRC libmv/multiview/fundamental.cc libmv/multiview/projection.cc libmv/multiview/triangulation.cc + libmv/multiview/homography.cc libmv/numeric/numeric.cc libmv/numeric/poly.cc libmv/simple_pipeline/bundle.cc @@ -84,6 +85,7 @@ set(SRC libmv/tracking/pyramid_region_tracker.cc libmv/tracking/retrack_region_tracker.cc libmv/tracking/trklt_region_tracker.cc + libmv/tracking/track_region.cc third_party/fast/fast_10.c third_party/fast/fast_11.c diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index 6c20d76eeac..ddf69ce5e28 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -45,6 +45,7 @@ #include "libmv/tracking/trklt_region_tracker.h" #include "libmv/tracking/lmicklt_region_tracker.h" #include "libmv/tracking/pyramid_region_tracker.h" +#include "libmv/tracking/track_region.h" #include "libmv/simple_pipeline/callbacks.h" #include "libmv/simple_pipeline/tracks.h" @@ -97,7 +98,7 @@ void libmv_initLogging(const char *argv0) void libmv_startDebugLogging(void) { google::SetCommandLineOption("logtostderr", "1"); - google::SetCommandLineOption("v", "0"); + google::SetCommandLineOption("v", "2"); google::SetCommandLineOption("stderrthreshold", "1"); google::SetCommandLineOption("minloglevel", "0"); V3D::optimizerVerbosenessLevel = 1; @@ -329,6 +330,71 @@ void libmv_regionTrackerDestroy(libmv_RegionTracker *libmv_tracker) delete region_tracker; } +/* ************ Planar tracker ************ */ + +/* TrackRegion (new planar tracker) */ +int libmv_trackRegion(const struct libmv_trackRegionOptions *options, + const float *image1, const float *image2, + int width, int height, + const double *x1, const double *y1, + struct libmv_trackRegionResult *result, + double *x2, double *y2) { + double xx1[4], yy1[4]; + double xx2[4], yy2[4]; + + // Convert to doubles for the libmv api. + for (int i = 0; i < 4; ++i) { + xx1[i] = x1[i]; + yy1[i] = y1[i]; + xx2[i] = x2[i]; + yy2[i] = y2[i]; + } + + libmv::TrackRegionOptions track_region_options; + switch (options->motion_model) { +#define LIBMV_CONVERT(the_model) \ + case libmv::TrackRegionOptions::the_model: \ + track_region_options.mode = libmv::TrackRegionOptions::the_model; \ + break; + LIBMV_CONVERT(TRANSLATION) + LIBMV_CONVERT(TRANSLATION_ROTATION) + LIBMV_CONVERT(TRANSLATION_SCALE) + LIBMV_CONVERT(TRANSLATION_ROTATION_SCALE) + LIBMV_CONVERT(AFFINE) + LIBMV_CONVERT(HOMOGRAPHY) +#undef LIBMV_CONVERT + } + track_region_options.num_samples_x = options->num_samples_x; + track_region_options.num_samples_y = options->num_samples_y; + track_region_options.minimum_correlation = options->minimum_correlation; + track_region_options.max_iterations = options->num_iterations; + track_region_options.sigma = options->sigma; + + // Convert from raw float buffers to libmv's FloatImage. + libmv::FloatImage old_patch, new_patch; + floatBufToImage(image1, width, height, &old_patch); + floatBufToImage(image2, width, height, &new_patch); + + libmv::TrackRegionResult track_region_result; + libmv::TrackRegion(old_patch, new_patch, xx1, yy1, track_region_options, xx2, yy2, &track_region_result); + + // Convert to floats for the blender api. + for (int i = 0; i < 4; ++i) { + x2[i] = xx2[i]; + y2[i] = yy2[i]; + } + + // TODO(keir): Update the termination string with failure details. + if (track_region_result.termination == libmv::TrackRegionResult::PARAMETER_TOLERANCE || + track_region_result.termination == libmv::TrackRegionResult::FUNCTION_TOLERANCE || + track_region_result.termination == libmv::TrackRegionResult::GRADIENT_TOLERANCE || + track_region_result.termination == libmv::TrackRegionResult::NO_CONVERGENCE || + track_region_result.termination == libmv::TrackRegionResult::INSUFFICIENT_CORRELATION) { + return true; + } + return false; +} + /* ************ Tracks ************ */ libmv_Tracks *libmv_tracksNew(void) diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index bccc4706832..d7d132d4f21 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -50,6 +50,27 @@ int libmv_regionTrackerTrack(struct libmv_RegionTracker *libmv_tracker, const fl int width, int height, double x1, double y1, double *x2, double *y2); void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker); +/* TrackRegion (new planar tracker) */ +struct libmv_trackRegionOptions { + int motion_model; + int num_samples_x; + int num_samples_y; + int num_iterations; + double minimum_correlation; + double sigma; +}; +struct libmv_trackRegionResult { + int termination; + const char *termination_reason; + double correlation; +}; +int libmv_trackRegion(const struct libmv_trackRegionOptions *options, + const float *image1, const float *image2, + int width, int height, + const double *x1, const double *y1, + struct libmv_trackRegionResult *result, + double *x2, double *y2); + /* Tracks */ struct libmv_Tracks *libmv_tracksNew(void); void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y); diff --git a/extern/libmv/libmv/multiview/homography.cc b/extern/libmv/libmv/multiview/homography.cc new file mode 100644 index 00000000000..366392f3923 --- /dev/null +++ b/extern/libmv/libmv/multiview/homography.cc @@ -0,0 +1,267 @@ +// Copyright (c) 2008, 2009 libmv authors. +// +// 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. + +#include "libmv/logging/logging.h" +#include "libmv/multiview/homography.h" +#include "libmv/multiview/homography_parameterization.h" + +namespace libmv { +/** 2D Homography transformation estimation in the case that points are in + * euclidean coordinates. + * + * x = H y + * x and y vector must have the same direction, we could write + * crossproduct(|x|, * H * |y| ) = |0| + * + * | 0 -1 x2| |a b c| |y1| |0| + * | 1 0 -x1| * |d e f| * |y2| = |0| + * |-x2 x1 0| |g h 1| |1 | |0| + * + * That gives : + * + * (-d+x2*g)*y1 + (-e+x2*h)*y2 + -f+x2 |0| + * (a-x1*g)*y1 + (b-x1*h)*y2 + c-x1 = |0| + * (-x2*a+x1*d)*y1 + (-x2*b+x1*e)*y2 + -x2*c+x1*f |0| + */ +bool Homography2DFromCorrespondencesLinearEuc( + const Mat &x1, + const Mat &x2, + Mat3 *H, + double expected_precision) { + assert(2 == x1.rows()); + assert(4 <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + int n = x1.cols(); + MatX8 L = Mat::Zero(n * 3, 8); + Mat b = Mat::Zero(n * 3, 1); + for (int i = 0; i < n; ++i) { + int j = 3 * i; + L(j, 0) = x1(0, i); // a + L(j, 1) = x1(1, i); // b + L(j, 2) = 1.0; // c + L(j, 6) = -x2(0, i) * x1(0, i); // g + L(j, 7) = -x2(0, i) * x1(1, i); // h + b(j, 0) = x2(0, i); // i + + ++j; + L(j, 3) = x1(0, i); // d + L(j, 4) = x1(1, i); // e + L(j, 5) = 1.0; // f + L(j, 6) = -x2(1, i) * x1(0, i); // g + L(j, 7) = -x2(1, i) * x1(1, i); // h + b(j, 0) = x2(1, i); // i + + // This ensures better stability + // TODO(julien) make a lite version without this 3rd set + ++j; + L(j, 0) = x2(1, i) * x1(0, i); // a + L(j, 1) = x2(1, i) * x1(1, i); // b + L(j, 2) = x2(1, i); // c + L(j, 3) = -x2(0, i) * x1(0, i); // d + L(j, 4) = -x2(0, i) * x1(1, i); // e + L(j, 5) = -x2(0, i) ; // f + } + // Solve Lx=B + Vec h = L.fullPivLu().solve(b); + Homography2DNormalizedParameterization::To(h, H); + if ((L * h).isApprox(b, expected_precision)) { + return true; + } else { + return false; + } +} + +/** 2D Homography transformation estimation in the case that points are in + * homogeneous coordinates. + * + * | 0 -x3 x2| |a b c| |y1| -x3*d+x2*g -x3*e+x2*h -x3*f+x2*1 |y1| (-x3*d+x2*g)*y1 (-x3*e+x2*h)*y2 (-x3*f+x2*1)*y3 |0| + * | x3 0 -x1| * |d e f| * |y2| = x3*a-x1*g x3*b-x1*h x3*c-x1*1 * |y2| = (x3*a-x1*g)*y1 (x3*b-x1*h)*y2 (x3*c-x1*1)*y3 = |0| + * |-x2 x1 0| |g h 1| |y3| -x2*a+x1*d -x2*b+x1*e -x2*c+x1*f |y3| (-x2*a+x1*d)*y1 (-x2*b+x1*e)*y2 (-x2*c+x1*f)*y3 |0| + * X = |a b c d e f g h|^t + */ +bool Homography2DFromCorrespondencesLinear(const Mat &x1, + const Mat &x2, + Mat3 *H, + double expected_precision) { + if (x1.rows() == 2) { + return Homography2DFromCorrespondencesLinearEuc(x1, x2, H, + expected_precision); + } + assert(3 == x1.rows()); + assert(4 <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + const int x = 0; + const int y = 1; + const int w = 2; + int n = x1.cols(); + MatX8 L = Mat::Zero(n * 3, 8); + Mat b = Mat::Zero(n * 3, 1); + for (int i = 0; i < n; ++i) { + int j = 3 * i; + L(j, 0) = x2(w, i) * x1(x, i);//a + L(j, 1) = x2(w, i) * x1(y, i);//b + L(j, 2) = x2(w, i) * x1(w, i);//c + L(j, 6) = -x2(x, i) * x1(x, i);//g + L(j, 7) = -x2(x, i) * x1(y, i);//h + b(j, 0) = x2(x, i) * x1(w, i); + + ++j; + L(j, 3) = x2(w, i) * x1(x, i);//d + L(j, 4) = x2(w, i) * x1(y, i);//e + L(j, 5) = x2(w, i) * x1(w, i);//f + L(j, 6) = -x2(y, i) * x1(x, i);//g + L(j, 7) = -x2(y, i) * x1(y, i);//h + b(j, 0) = x2(y, i) * x1(w, i); + + // This ensures better stability + ++j; + L(j, 0) = x2(y, i) * x1(x, i);//a + L(j, 1) = x2(y, i) * x1(y, i);//b + L(j, 2) = x2(y, i) * x1(w, i);//c + L(j, 3) = -x2(x, i) * x1(x, i);//d + L(j, 4) = -x2(x, i) * x1(y, i);//e + L(j, 5) = -x2(x, i) * x1(w, i);//f + } + // Solve Lx=B + Vec h = L.fullPivLu().solve(b); + if ((L * h).isApprox(b, expected_precision)) { + Homography2DNormalizedParameterization::To(h, H); + return true; + } else { + return false; + } +} +/** + * x2 ~ A * x1 + * x2^t * Hi * A *x1 = 0 + * H1 = H2 = H3 = + * | 0 0 0 1| |-x2w| |0 0 0 0| | 0 | | 0 0 1 0| |-x2z| + * | 0 0 0 0| -> | 0 | |0 0 1 0| -> |-x2z| | 0 0 0 0| -> | 0 | + * | 0 0 0 0| | 0 | |0-1 0 0| | x2y| |-1 0 0 0| | x2x| + * |-1 0 0 0| | x2x| |0 0 0 0| | 0 | | 0 0 0 0| | 0 | + * H4 = H5 = H6 = + * |0 0 0 0| | 0 | | 0 1 0 0| |-x2y| |0 0 0 0| | 0 | + * |0 0 0 1| -> |-x2w| |-1 0 0 0| -> | x2x| |0 0 0 0| -> | 0 | + * |0 0 0 0| | 0 | | 0 0 0 0| | 0 | |0 0 0 1| |-x2w| + * |0-1 0 0| | x2y| | 0 0 0 0| | 0 | |0 0-1 0| | x2z| + * |a b c d| + * A = |e f g h| + * |i j k l| + * |m n o 1| + * + * x2^t * H1 * A *x1 = (-x2w*a +x2x*m )*x1x + (-x2w*b +x2x*n )*x1y + (-x2w*c +x2x*o )*x1z + (-x2w*d +x2x*1 )*x1w = 0 + * x2^t * H2 * A *x1 = (-x2z*e +x2y*i )*x1x + (-x2z*f +x2y*j )*x1y + (-x2z*g +x2y*k )*x1z + (-x2z*h +x2y*l )*x1w = 0 + * x2^t * H3 * A *x1 = (-x2z*a +x2x*i )*x1x + (-x2z*b +x2x*j )*x1y + (-x2z*c +x2x*k )*x1z + (-x2z*d +x2x*l )*x1w = 0 + * x2^t * H4 * A *x1 = (-x2w*e +x2y*m )*x1x + (-x2w*f +x2y*n )*x1y + (-x2w*g +x2y*o )*x1z + (-x2w*h +x2y*1 )*x1w = 0 + * x2^t * H5 * A *x1 = (-x2y*a +x2x*e )*x1x + (-x2y*b +x2x*f )*x1y + (-x2y*c +x2x*g )*x1z + (-x2y*d +x2x*h )*x1w = 0 + * x2^t * H6 * A *x1 = (-x2w*i +x2z*m )*x1x + (-x2w*j +x2z*n )*x1y + (-x2w*k +x2z*o )*x1z + (-x2w*l +x2z*1 )*x1w = 0 + * + * X = |a b c d e f g h i j k l m n o|^t +*/ +bool Homography3DFromCorrespondencesLinear(const Mat &x1, + const Mat &x2, + Mat4 *H, + double expected_precision) { + assert(4 == x1.rows()); + assert(5 <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + const int x = 0; + const int y = 1; + const int z = 2; + const int w = 3; + int n = x1.cols(); + MatX15 L = Mat::Zero(n * 6, 15); + Mat b = Mat::Zero(n * 6, 1); + for (int i = 0; i < n; ++i) { + int j = 6 * i; + L(j, 0) = -x2(w, i) * x1(x, i);//a + L(j, 1) = -x2(w, i) * x1(y, i);//b + L(j, 2) = -x2(w, i) * x1(z, i);//c + L(j, 3) = -x2(w, i) * x1(w, i);//d + L(j,12) = x2(x, i) * x1(x, i);//m + L(j,13) = x2(x, i) * x1(y, i);//n + L(j,14) = x2(x, i) * x1(z, i);//o + b(j, 0) = -x2(x, i) * x1(w, i); + + ++j; + L(j, 4) = -x2(z, i) * x1(x, i);//e + L(j, 5) = -x2(z, i) * x1(y, i);//f + L(j, 6) = -x2(z, i) * x1(z, i);//g + L(j, 7) = -x2(z, i) * x1(w, i);//h + L(j, 8) = x2(y, i) * x1(x, i);//i + L(j, 9) = x2(y, i) * x1(y, i);//j + L(j,10) = x2(y, i) * x1(z, i);//k + L(j,11) = x2(y, i) * x1(w, i);//l + + ++j; + L(j, 0) = -x2(z, i) * x1(x, i);//a + L(j, 1) = -x2(z, i) * x1(y, i);//b + L(j, 2) = -x2(z, i) * x1(z, i);//c + L(j, 3) = -x2(z, i) * x1(w, i);//d + L(j, 8) = x2(x, i) * x1(x, i);//i + L(j, 9) = x2(x, i) * x1(y, i);//j + L(j,10) = x2(x, i) * x1(z, i);//k + L(j,11) = x2(x, i) * x1(w, i);//l + + ++j; + L(j, 4) = -x2(w, i) * x1(x, i);//e + L(j, 5) = -x2(w, i) * x1(y, i);//f + L(j, 6) = -x2(w, i) * x1(z, i);//g + L(j, 7) = -x2(w, i) * x1(w, i);//h + L(j,12) = x2(y, i) * x1(x, i);//m + L(j,13) = x2(y, i) * x1(y, i);//n + L(j,14) = x2(y, i) * x1(z, i);//o + b(j, 0) = -x2(y, i) * x1(w, i); + + ++j; + L(j, 0) = -x2(y, i) * x1(x, i);//a + L(j, 1) = -x2(y, i) * x1(y, i);//b + L(j, 2) = -x2(y, i) * x1(z, i);//c + L(j, 3) = -x2(y, i) * x1(w, i);//d + L(j, 4) = x2(x, i) * x1(x, i);//e + L(j, 5) = x2(x, i) * x1(y, i);//f + L(j, 6) = x2(x, i) * x1(z, i);//g + L(j, 7) = x2(x, i) * x1(w, i);//h + + ++j; + L(j, 8) = -x2(w, i) * x1(x, i);//i + L(j, 9) = -x2(w, i) * x1(y, i);//j + L(j,10) = -x2(w, i) * x1(z, i);//k + L(j,11) = -x2(w, i) * x1(w, i);//l + L(j,12) = x2(z, i) * x1(x, i);//m + L(j,13) = x2(z, i) * x1(y, i);//n + L(j,14) = x2(z, i) * x1(z, i);//o + b(j, 0) = -x2(z, i) * x1(w, i); + } + // Solve Lx=B + Vec h = L.fullPivLu().solve(b); + if ((L * h).isApprox(b, expected_precision)) { + Homography3DNormalizedParameterization::To(h, H); + return true; + } else { + return false; + } +} +} // namespace libmv diff --git a/extern/libmv/libmv/multiview/homography.h b/extern/libmv/libmv/multiview/homography.h new file mode 100644 index 00000000000..786fd3df8ca --- /dev/null +++ b/extern/libmv/libmv/multiview/homography.h @@ -0,0 +1,84 @@ +// Copyright (c) 2011 libmv authors. +// +// 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 LIBMV_MULTIVIEW_HOMOGRAPHY_H_ +#define LIBMV_MULTIVIEW_HOMOGRAPHY_H_ + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +/** + * 2D homography transformation estimation. + * + * This function estimates the homography transformation from a list of 2D + * correspondences which represents either: + * + * - 3D points on a plane, with a general moving camera. + * - 3D points with a rotating camera (pure rotation). + * - 3D points + different planar projections + * + * \param x1 The first 2xN or 3xN matrix of euclidean or homogeneous points. + * \param x2 The second 2xN or 3xN matrix of euclidean or homogeneous points. + * \param H The 3x3 homography transformation matrix (8 dof) such that + * x2 = H * x1 with |a b c| + * H = |d e f| + * |g h 1| + * \param expected_precision The expected precision in order for instance + * to accept almost homography matrices. + * + * \return True if the transformation estimation has succeeded. + * \note There must be at least 4 non-colinear points. + */ +bool Homography2DFromCorrespondencesLinear(const Mat &x1, + const Mat &x2, + Mat3 *H, + double expected_precision = + EigenDouble::dummy_precision()); + +/** + * 3D Homography transformation estimation. + * + * This function can be used in order to estimate the homography transformation + * from a list of 3D correspondences. + * + * \param[in] x1 The first 4xN matrix of homogeneous points + * \param[in] x2 The second 4xN matrix of homogeneous points + * \param[out] H The 4x4 homography transformation matrix (15 dof) such that + * x2 = H * x1 with |a b c d| + * H = |e f g h| + * |i j k l| + * |m n o 1| + * \param[in] expected_precision The expected precision in order for instance + * to accept almost homography matrices. + * + * \return true if the transformation estimation has succeeded + * + * \note Need at least 5 non coplanar points + * \note Points coordinates must be in homogeneous coordinates + */ +bool Homography3DFromCorrespondencesLinear(const Mat &x1, + const Mat &x2, + Mat4 *H, + double expected_precision = + EigenDouble::dummy_precision()); +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_HOMOGRAPHY_H_ diff --git a/extern/libmv/libmv/multiview/homography_parameterization.h b/extern/libmv/libmv/multiview/homography_parameterization.h new file mode 100644 index 00000000000..b31642eea15 --- /dev/null +++ b/extern/libmv/libmv/multiview/homography_parameterization.h @@ -0,0 +1,91 @@ +// Copyright (c) 2011 libmv authors. +// +// 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 LIBMV_MULTIVIEW_HOMOGRAPHY_PARAMETERIZATION_H_ +#define LIBMV_MULTIVIEW_HOMOGRAPHY_PARAMETERIZATION_H_ + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +/** A parameterization of the 2D homography matrix that uses 8 parameters so + * that the matrix is normalized (H(2,2) == 1). + * The homography matrix H is built from a list of 8 parameters (a, b,...g, h) + * as follows + * |a b c| + * H = |d e f| + * |g h 1| + */ +template +class Homography2DNormalizedParameterization { + public: + typedef Eigen::Matrix Parameters; // a, b, ... g, h + typedef Eigen::Matrix Parameterized; // H + + /// Convert from the 8 parameters to a H matrix. + static void To(const Parameters &p, Parameterized *h) { + *h << p(0), p(1), p(2), + p(3), p(4), p(5), + p(6), p(7), 1.0; + } + + /// Convert from a H matrix to the 8 parameters. + static void From(const Parameterized &h, Parameters *p) { + *p << h(0, 0), h(0, 1), h(0, 2), + h(1, 0), h(1, 1), h(1, 2), + h(2, 0), h(2, 1); + } +}; + +/** A parameterization of the 2D homography matrix that uses 15 parameters so + * that the matrix is normalized (H(3,3) == 1). + * The homography matrix H is built from a list of 15 parameters (a, b,...n, o) + * as follows + * |a b c d| + * H = |e f g h| + * |i j k l| + * |m n o 1| + */ +template +class Homography3DNormalizedParameterization { + public: + typedef Eigen::Matrix Parameters; // a, b, ... n, o + typedef Eigen::Matrix Parameterized; // H + + /// Convert from the 15 parameters to a H matrix. + static void To(const Parameters &p, Parameterized *h) { + *h << p(0), p(1), p(2), p(3), + p(4), p(5), p(6), p(7), + p(8), p(9), p(10), p(11), + p(12), p(13), p(14), 1.0; + } + + /// Convert from a H matrix to the 15 parameters. + static void From(const Parameterized &h, Parameters *p) { + *p << h(0, 0), h(0, 1), h(0, 2), h(0, 3), + h(1, 0), h(1, 1), h(1, 2), h(1, 3), + h(2, 0), h(2, 1), h(2, 2), h(2, 3), + h(3, 0), h(3, 1), h(3, 2); + } +}; + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_HOMOGRAPHY_PARAMETERIZATION_H_ diff --git a/extern/libmv/libmv/tracking/esm_region_tracker.cc b/extern/libmv/libmv/tracking/esm_region_tracker.cc index 221fa4d081b..2491b158154 100644 --- a/extern/libmv/libmv/tracking/esm_region_tracker.cc +++ b/extern/libmv/libmv/tracking/esm_region_tracker.cc @@ -29,6 +29,7 @@ #include "libmv/image/correlation.h" #include "libmv/image/sample.h" #include "libmv/numeric/numeric.h" +#include "libmv/tracking/track_region.h" namespace libmv { @@ -72,6 +73,45 @@ bool EsmRegionTracker::Track(const FloatImage &image1, return false; } + // XXX + // TODO(keir): Delete the block between the XXX's once the planar tracker is + // integrated into blender. + // + // For now, to test, replace the ESM tracker with the Ceres tracker in + // translation mode. In the future, this should get removed and alloed to + // co-exist, since Ceres is not as fast as the ESM implementation since it + // specializes for translation. + double xx1[4], yy1[4]; + double xx2[4], yy2[4]; + // Clockwise winding, starting from the "origin" (top-left). + xx1[0] = xx2[0] = x1 - half_window_size; + yy1[0] = yy2[0] = y1 - half_window_size; + + xx1[1] = xx2[1] = x1 + half_window_size; + yy1[1] = yy2[1] = y1 - half_window_size; + + xx1[2] = xx2[2] = x1 + half_window_size; + yy1[2] = yy2[2] = y1 + half_window_size; + + xx1[3] = xx2[3] = x1 - half_window_size; + yy1[3] = yy2[3] = y1 + half_window_size; + + TrackRegionOptions options; + options.mode = TrackRegionOptions::TRANSLATION; + options.num_samples_x = 2 * half_window_size + 1; + options.num_samples_y = 2 * half_window_size + 1; + options.max_iterations = 20; + options.sigma = sigma; + + TrackRegionResult result; + TrackRegion(image1, image2, xx1, yy1, options, xx2, yy2, &result); + + *x2 = xx2[0] + half_window_size; + *y2 = yy2[0] + half_window_size; + + return true; + + // XXX int width = 2 * half_window_size + 1; // TODO(keir): Avoid recomputing gradients for e.g. the pyramid tracker. diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc new file mode 100644 index 00000000000..5a46c66cd3c --- /dev/null +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -0,0 +1,651 @@ +// Copyright (c) 2012 libmv authors. +// +// 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. +// +// Author: mierle@google.com (Keir Mierle) + +// Necessary for M_E when building with MSVC. +#define _USE_MATH_DEFINES + +#include "libmv/tracking/track_region.h" + +#include +#include +#include +#include "ceres/ceres.h" +#include "libmv/logging/logging.h" +#include "libmv/image/image.h" +#include "libmv/image/sample.h" +#include "libmv/image/convolve.h" +#include "libmv/multiview/homography.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +// TODO(keir): Consider adding padding. +template +bool InBounds(const FloatImage &image, + const T &x, + const T &y) { + return 0.0 <= x && x < image.Width() && + 0.0 <= y && y < image.Height(); +} + +bool AllInBounds(const FloatImage &image, + const double *x, + const double *y) { + for (int i = 0; i < 4; ++i) { + if (!InBounds(image, x[i], y[i])) { + return false; + } + } + return true; +} + +// Because C++03 doesn't support partial template specializations for +// functions, but at the same time member function specializations are not +// supported, the sample function must be inside a template-specialized class +// with a non-templated static member. + +// The "AutoDiffImage::Sample()" function allows sampling an image at an x, y +// position such that if x and y are jets, then the derivative information is +// correctly propagated. + +// Empty default template. +template +struct AutoDiffImage { + static T Sample(const FloatImage &image_and_gradient, + const T &x, const T &y) { + return 0.0; + } +}; + +// Sample only the image when the coordinates are scalars. +template<> +struct AutoDiffImage { + static double Sample(const FloatImage &image_and_gradient, + const double& x, const double& y) { + return SampleLinear(image_and_gradient, y, x, 0); + } +}; + +// Sample the image and gradient when the coordinates are jets, applying the +// jacobian appropriately to propagate the derivatives from the coordinates. +template<> +template +struct AutoDiffImage > { + static ceres::Jet Sample(const FloatImage &image_and_gradient, + const ceres::Jet &x, + const ceres::Jet &y) { + // Sample the image and its derivatives in x and y. One way to think of + // this is that the image is a scalar function with a single vector + // argument, xy, of dimension 2. Call this s(xy). + const T s = SampleLinear(image_and_gradient, y.a, x.a, 0); + const T dsdx = SampleLinear(image_and_gradient, y.a, x.a, 1); + const T dsdy = SampleLinear(image_and_gradient, y.a, x.a, 2); + + // However, xy is itself a function of another variable ("z"); xy(z) = + // [x(z), y(z)]^T. What this function needs to return is "s", but with the + // derivative with respect to z attached to the jet. So combine the + // derivative part of x and y's jets to form a Jacobian matrix between x, y + // and z (i.e. dxy/dz). + Eigen::Matrix dxydz; + dxydz.row(0) = x.v.transpose(); + dxydz.row(1) = y.v.transpose(); + + // Now apply the chain rule to obtain ds/dz. Combine the derivative with + // the scalar part to obtain s with full derivative information. + ceres::Jet jet_s; + jet_s.a = s; + jet_s.v = Matrix(dsdx, dsdy) * dxydz; + return jet_s; + } +}; + +template +class BoundaryCheckingCallback : public ceres::IterationCallback { + public: + BoundaryCheckingCallback(const FloatImage& image2, + const Warp &warp, + const double *x1, const double *y1) + : image2_(image2), warp_(warp), x1_(x1), y1_(y1) {} + + virtual ceres::CallbackReturnType operator()( + const ceres::IterationSummary& summary) { + // Warp the original 4 points with the current warp into image2. + double x2[4]; + double y2[4]; + for (int i = 0; i < 4; ++i) { + warp_.Forward(warp_.parameters, x1_[i], y1_[i], x2 + i, y2 + i); + } + // Enusre they are all in bounds. + if (!AllInBounds(image2_, x2, y2)) { + return ceres::SOLVER_ABORT; + } + return ceres::SOLVER_CONTINUE; + } + + private: + const FloatImage &image2_; + const Warp &warp_; + const double *x1_; + const double *y1_; +}; + +template +class WarpCostFunctor { + public: + WarpCostFunctor(const FloatImage &image_and_gradient1, + const FloatImage &image_and_gradient2, + const Mat3 &canonical_to_image1, + const Warp &warp, + int num_samples_x, + int num_samples_y) + : image_and_gradient1_(image_and_gradient1), + image_and_gradient2_(image_and_gradient2), + canonical_to_image1_(canonical_to_image1), + warp_(warp), + num_samples_x_(num_samples_x), + num_samples_y_(num_samples_y) {} + + template + bool operator()(const T *warp_parameters, T *residuals) const { + for (int i = 0; i < Warp::NUM_PARAMETERS; ++i) { + VLOG(2) << "warp_parameters[" << i << "]: " << warp_parameters[i]; + } + + int cursor = 0; + for (int r = 0; r < num_samples_y_; ++r) { + for (int c = 0; c < num_samples_x_; ++c) { + // Compute the location of the source pixel (via homography). + Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1); + image1_position /= image1_position(2); + + // Compute the location of the destination pixel. + T image2_position[2]; + warp_.Forward(warp_parameters, + T(image1_position[0]), + T(image1_position[1]), + &image2_position[0], + &image2_position[1]); + + // Sample the source and destination. + double src_sample = AutoDiffImage::Sample(image_and_gradient1_, + image1_position[0], + image1_position[1]); + T dst_sample = AutoDiffImage::Sample(image_and_gradient2_, + image2_position[0], + image2_position[1]); + + // The difference is the error. + residuals[cursor++] = T(src_sample) - dst_sample; + } + } + return true; + } + + private: + const FloatImage &image_and_gradient1_; + const FloatImage &image_and_gradient2_; + const Mat3 &canonical_to_image1_; + const Warp &warp_; + int num_samples_x_; + int num_samples_y_; +}; + +// Compute the warp from rectangular coordinates, where one corner is the +// origin, and the opposite corner is at (num_samples_x, num_samples_y). +Mat3 ComputeCanonicalHomography(const double *x1, + const double *y1, + int num_samples_x, + int num_samples_y) { + Mat canonical(2, 4); + canonical << 0, num_samples_x, num_samples_x, 0, + 0, 0, num_samples_y, num_samples_y; + + Mat xy1(2, 4); + xy1 << x1[0], x1[1], x1[2], x1[3], + y1[0], y1[1], y1[2], y1[3]; + + Mat3 H; + if (!Homography2DFromCorrespondencesLinear(canonical, xy1, &H, 1e-12)) { + LG << "Couldn't construct homography."; + } + return H; +} + +class Quad { + public: + Quad(const double *x, const double *y) + : x_(x), y_(y) { + + // Compute the centroid and store it. + centroid_ = Vec2(0.0, 0.0); + for (int i = 0; i < 4; ++i) { + centroid_ += Vec2(x_[i], y_[i]); + } + centroid_ /= 4.0; + } + + // The centroid of the four points representing the quad. + const Vec2& Centroid() const { + return centroid_; + } + + // The average magnitude of the four points relative to the centroid. + double Scale() const { + double scale = 0.0; + for (int i = 0; i < 4; ++i) { + scale += (Vec2(x_[i], y_[i]) - Centroid()).norm(); + } + return scale / 4.0; + } + + Vec2 CornerRelativeToCentroid(int i) const { + return Vec2(x_[i], y_[i]) - centroid_; + } + + private: + const double *x_; + const double *y_; + Vec2 centroid_; +}; + +struct TranslationWarp { + TranslationWarp(const double *x1, const double *y1, + const double *x2, const double *y2) { + Vec2 t = Quad(x1, y1).Centroid() - Quad(x2, y2).Centroid(); + parameters[0] = t[0]; + parameters[1] = t[1]; + } + + template + void Forward(const T *warp_parameters, + const T &x1, const T& y1, T *x2, T* y2) const { + *x2 = x1 + warp_parameters[0]; + *y2 = y1 + warp_parameters[1]; + } + + // Translation x, translation y. + enum { NUM_PARAMETERS = 2 }; + double parameters[NUM_PARAMETERS]; +}; + +struct TranslationScaleWarp { + TranslationScaleWarp(const double *x1, const double *y1, + const double *x2, const double *y2) + : q1(x1, y1) { + Quad q2(x2, y2); + + // The difference in centroids is the best guess for translation. + Vec2 t = q1.Centroid() - q2.Centroid(); + parameters[0] = t[0]; + parameters[1] = t[1]; + + // The difference in scales is the estimate for the scale. + parameters[2] = 1.0 - q2.Scale() / q1.Scale(); + } + + // The strange way of parameterizing the translation and scaling is to make + // the knobs that the optimizer sees easy to adjust. This is less important + // for the scaling case than the rotation case. + template + void Forward(const T *warp_parameters, + const T &x1, const T& y1, T *x2, T* y2) const { + // Make the centroid of Q1 the origin. + const T x1_origin = x1 - q1.Centroid()(0); + const T y1_origin = y1 - q1.Centroid()(1); + + // Scale uniformly about the origin. + const T scale = 1.0 + warp_parameters[2]; + const T x1_origin_scaled = scale * x1_origin; + const T y1_origin_scaled = scale * y1_origin; + + // Translate back into the space of Q1 (but scaled). + const T x1_scaled = x1_origin_scaled + q1.Centroid()(0); + const T y1_scaled = y1_origin_scaled + q1.Centroid()(1); + + // Translate into the space of Q2. + *x2 = x1_scaled + warp_parameters[0]; + *y2 = y1_scaled + warp_parameters[1]; + } + + // Translation x, translation y, scale. + enum { NUM_PARAMETERS = 3 }; + double parameters[NUM_PARAMETERS]; + + Quad q1; +}; + +// Assumes the given points are already zero-centroid and the same size. +Mat2 OrthogonalProcrustes(const Mat2 &correlation_matrix) { + Eigen::JacobiSVD svd(correlation_matrix, + Eigen::ComputeFullU | Eigen::ComputeFullV); + return svd.matrixV() * svd.matrixU().transpose(); +} + +struct TranslationRotationWarp { + TranslationRotationWarp(const double *x1, const double *y1, + const double *x2, const double *y2) + : q1(x1, y1) { + Quad q2(x2, y2); + + // The difference in centroids is the best guess for translation. + Vec2 t = q1.Centroid() - q2.Centroid(); + parameters[0] = t[0]; + parameters[1] = t[1]; + + // Obtain the rotation via orthorgonal procrustes. + Mat2 correlation_matrix; + for (int i = 0; i < 4; ++i) { + correlation_matrix += q1.CornerRelativeToCentroid(i) * + q2.CornerRelativeToCentroid(i).transpose(); + } + Mat2 R = OrthogonalProcrustes(correlation_matrix); + parameters[2] = acos(R(0, 0)); + } + + // The strange way of parameterizing the translation and rotation is to make + // the knobs that the optimizer sees easy to adjust. The reason is that while + // it is always the case that it is possible to express composed rotations + // and translations as a single translation and rotation, the numerical + // values needed for the composition are often large in magnitude. This is + // enough to throw off any minimizer, since it must do the equivalent of + // compose rotations and translations. + // + // Instead, use the parameterization below that offers a parameterization + // that exposes the degrees of freedom in a way amenable to optimization. + template + void Forward(const T *warp_parameters, + const T &x1, const T& y1, T *x2, T* y2) const { + // Make the centroid of Q1 the origin. + const T x1_origin = x1 - q1.Centroid()(0); + const T y1_origin = y1 - q1.Centroid()(1); + + // Rotate about the origin (i.e. centroid of Q1). + const T theta = warp_parameters[2]; + const T costheta = cos(theta); + const T sintheta = sin(theta); + const T x1_origin_rotated = costheta * x1_origin - sintheta * y1_origin; + const T y1_origin_rotated = sintheta * x1_origin + costheta * y1_origin; + + // Translate back into the space of Q1 (but scaled). + const T x1_rotated = x1_origin_rotated + q1.Centroid()(0); + const T y1_rotated = y1_origin_rotated + q1.Centroid()(1); + + // Translate into the space of Q2. + *x2 = x1_rotated + warp_parameters[0]; + *y2 = y1_rotated + warp_parameters[1]; + } + + // Translation x, translation y, rotation about the center of Q1 degrees. + enum { NUM_PARAMETERS = 3 }; + double parameters[NUM_PARAMETERS]; + + Quad q1; +}; + +struct TranslationRotationScaleWarp { + TranslationRotationScaleWarp(const double *x1, const double *y1, + const double *x2, const double *y2) + : q1(x1, y1) { + Quad q2(x2, y2); + + // The difference in centroids is the best guess for translation. + Vec2 t = q1.Centroid() - q2.Centroid(); + parameters[0] = t[0]; + parameters[1] = t[1]; + + // The difference in scales is the estimate for the scale. + parameters[2] = 1.0 - q2.Scale() / q1.Scale(); + + // Obtain the rotation via orthorgonal procrustes. + Mat2 correlation_matrix; + for (int i = 0; i < 4; ++i) { + correlation_matrix += q1.CornerRelativeToCentroid(i) * + q2.CornerRelativeToCentroid(i).transpose(); + } + Mat2 R = OrthogonalProcrustes(correlation_matrix); + parameters[3] = acos(R(0, 0)); + } + + // The strange way of parameterizing the translation and rotation is to make + // the knobs that the optimizer sees easy to adjust. The reason is that while + // it is always the case that it is possible to express composed rotations + // and translations as a single translation and rotation, the numerical + // values needed for the composition are often large in magnitude. This is + // enough to throw off any minimizer, since it must do the equivalent of + // compose rotations and translations. + // + // Instead, use the parameterization below that offers a parameterization + // that exposes the degrees of freedom in a way amenable to optimization. + template + void Forward(const T *warp_parameters, + const T &x1, const T& y1, T *x2, T* y2) const { + // Make the centroid of Q1 the origin. + const T x1_origin = x1 - q1.Centroid()(0); + const T y1_origin = y1 - q1.Centroid()(1); + + // Rotate about the origin (i.e. centroid of Q1). + const T theta = warp_parameters[2]; + const T costheta = cos(theta); + const T sintheta = sin(theta); + const T x1_origin_rotated = costheta * x1_origin - sintheta * y1_origin; + const T y1_origin_rotated = sintheta * x1_origin + costheta * y1_origin; + + // Scale uniformly about the origin. + const T scale = 1.0 + warp_parameters[2]; + const T x1_origin_rotated_scaled = scale * x1_origin_rotated; + const T y1_origin_rotated_scaled = scale * y1_origin_rotated; + + // Translate back into the space of Q1 (but scaled and rotated). + const T x1_rotated_scaled = x1_origin_rotated_scaled + q1.Centroid()(0); + const T y1_rotated_scaled = y1_origin_rotated_scaled + q1.Centroid()(1); + + // Translate into the space of Q2. + *x2 = x1_rotated_scaled + warp_parameters[0]; + *y2 = y1_rotated_scaled + warp_parameters[1]; + } + + // Translation x, translation y, rotation about the center of Q1 degrees, + // scale. + enum { NUM_PARAMETERS = 4 }; + double parameters[NUM_PARAMETERS]; + + Quad q1; +}; + +// TODO(keir): Finish affine warp. + +struct HomographyWarp { + HomographyWarp(const double *x1, const double *y1, + const double *x2, const double *y2) { + Mat quad1(2, 4); + quad1 << x1[0], x1[1], x1[2], x1[3], + y1[0], y1[1], y1[2], y1[3]; + + Mat quad2(2, 4); + quad2 << x2[0], x2[1], x2[2], x2[3], + y2[0], y2[1], y2[2], y2[3]; + + Mat3 H; + if (!Homography2DFromCorrespondencesLinear(quad1, quad2, &H, 1e-12)) { + LG << "Couldn't construct homography."; + } + + // Assume H(2, 2) != 0, and fix scale at H(2, 2) == 1.0. + H /= H(2, 2); + + // Assume H is close to identity, so subtract out the diagonal. + H(0, 0) -= 1.0; + H(1, 1) -= 1.0; + + CHECK_NE(H(2, 2), 0.0) << H; + for (int i = 0; i < 8; ++i) { + parameters[i] = H(i / 3, i % 3); + LG << "Parameters[" << i << "]: " << parameters[i]; + } + } + + template + static void Forward(const T *p, + const T &x1, const T& y1, T *x2, T* y2) { + // Homography warp with manual 3x3 matrix multiply. + const T xx2 = (1.0 + p[0]) * x1 + p[1] * y1 + p[2]; + const T yy2 = p[3] * x1 + (1.0 + p[4]) * y1 + p[5]; + const T zz2 = p[6] * x1 + p[7] * y1 + 1.0; + *x2 = xx2 / zz2; + *y2 = yy2 / zz2; + } + + enum { NUM_PARAMETERS = 8 }; + double parameters[NUM_PARAMETERS]; +}; + +template +void TemplatedTrackRegion(const FloatImage &image1, + const FloatImage &image2, + const double *x1, const double *y1, + const TrackRegionOptions &options, + double *x2, double *y2, + TrackRegionResult *result) { + // Bail early if the points are already outside. + if (!AllInBounds(image1, x1, y1)) { + result->termination = TrackRegionResult::SOURCE_OUT_OF_BOUNDS; + return; + } + if (!AllInBounds(image2, x2, y2)) { + result->termination = TrackRegionResult::DESTINATION_OUT_OF_BOUNDS; + return; + } + // TODO(keir): Check quads to ensure there is some area. + + // Prepare the image and gradient. + Array3Df image_and_gradient1; + Array3Df image_and_gradient2; + BlurredImageAndDerivativesChannels(image1, options.sigma, + &image_and_gradient1); + BlurredImageAndDerivativesChannels(image2, options.sigma, + &image_and_gradient2); + + // Prepare the initial warp parameters from the four correspondences. + Warp warp(x1, y1, x2, y2); + + ceres::Solver::Options solver_options; + solver_options.linear_solver_type = ceres::DENSE_QR; + solver_options.max_num_iterations = options.max_iterations; + solver_options.update_state_every_iteration = true; + solver_options.parameter_tolerance = 1e-16; + solver_options.function_tolerance = 1e-16; + + // TODO(keir): Consider removing these options before committing. + solver_options.numeric_derivative_relative_step_size = 1e-3; + solver_options.gradient_check_relative_precision = 1e-10; + solver_options.minimizer_progress_to_stdout = false; + + // Prevent the corners from going outside the destination image. + BoundaryCheckingCallback callback(image2, warp, x1, y1); + solver_options.callbacks.push_back(&callback); + + // Compute the warp from rectangular coordinates. + Mat3 canonical_homography = ComputeCanonicalHomography(x1, y1, + options.num_samples_x, + options.num_samples_y); + + // Construct the warp cost function. AutoDiffCostFunction takes ownership. + WarpCostFunctor *cost_function = + new WarpCostFunctor(image_and_gradient1, + image_and_gradient2, + canonical_homography, + warp, + options.num_samples_x, + options.num_samples_y); + + // Construct the problem with a single residual. + ceres::Problem::Options problem_options; + problem_options.cost_function_ownership = ceres::DO_NOT_TAKE_OWNERSHIP; + ceres::Problem problem(problem_options); + problem.AddResidualBlock( + new ceres::AutoDiffCostFunction< + WarpCostFunctor, + ceres::DYNAMIC, + Warp::NUM_PARAMETERS>(cost_function, + options.num_samples_x * options.num_samples_y), + NULL, + warp.parameters); + + ceres::Solver::Summary summary; + ceres::Solve(solver_options, &problem, &summary); + + LG << "Summary:\n" << summary.FullReport(); + + // Update the four points with the found solution; if the solver failed, then + // the warp parameters are the identity (so ignore failure). + for (int i = 0; i < 4; ++i) { + warp.Forward(warp.parameters, x1[i], y1[i], x2 + i, y2 + i); + } + + // TODO(keir): Update the result statistics. + + CHECK_NE(summary.termination_type, ceres::USER_ABORT) << "Libmv bug."; + if (summary.termination_type == ceres::USER_ABORT) { + result->termination = TrackRegionResult::FELL_OUT_OF_BOUNDS; + return; + } +#define HANDLE_TERMINATION(termination_enum) \ + if (summary.termination_type == ceres::termination_enum) { \ + result->termination = TrackRegionResult::termination_enum; \ + return; \ + } + HANDLE_TERMINATION(PARAMETER_TOLERANCE); + HANDLE_TERMINATION(FUNCTION_TOLERANCE); + HANDLE_TERMINATION(GRADIENT_TOLERANCE); + HANDLE_TERMINATION(NO_CONVERGENCE); + HANDLE_TERMINATION(DID_NOT_RUN); + HANDLE_TERMINATION(NUMERICAL_FAILURE); +#undef HANDLE_TERMINATION +}; + +void TrackRegion(const FloatImage &image1, + const FloatImage &image2, + const double *x1, const double *y1, + const TrackRegionOptions &options, + double *x2, double *y2, + TrackRegionResult *result) { + // Enum is necessary due to templated nature of autodiff. +#define HANDLE_MODE(mode_enum, mode_type) \ + if (options.mode == TrackRegionOptions::mode_enum) { \ + TemplatedTrackRegion(image1, image2, \ + x1, y1, \ + options, \ + x2, y2, \ + result); \ + return; \ + } + + HANDLE_MODE(TRANSLATION, TranslationWarp); + HANDLE_MODE(TRANSLATION_SCALE, TranslationScaleWarp); + HANDLE_MODE(TRANSLATION_ROTATION, TranslationRotationWarp); + HANDLE_MODE(TRANSLATION_ROTATION_SCALE, TranslationRotationScaleWarp); + //HANDLE_MODE(AFFINE, AffineWarp); + HANDLE_MODE(HOMOGRAPHY, HomographyWarp); +#undef HANDLE_MODE +} + +} // namespace libmv diff --git a/extern/libmv/libmv/tracking/track_region.h b/extern/libmv/libmv/tracking/track_region.h new file mode 100644 index 00000000000..ca783c32a75 --- /dev/null +++ b/extern/libmv/libmv/tracking/track_region.h @@ -0,0 +1,91 @@ +// Copyright (c) 2012 libmv authors. +// +// 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 LIBMV_TRACKING_TRACK_REGION_H_ + +// Necessary for M_E when building with MSVC. +#define _USE_MATH_DEFINES + +#include "libmv/tracking/esm_region_tracker.h" + +#include "libmv/image/image.h" +#include "libmv/image/sample.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +struct TrackRegionOptions { + enum Mode { + TRANSLATION, + TRANSLATION_ROTATION, + TRANSLATION_SCALE, + TRANSLATION_ROTATION_SCALE, + AFFINE, + HOMOGRAPHY, + }; + Mode mode; + + int num_samples_x; + int num_samples_y; + + double minimum_correlation; + int max_iterations; + bool use_esm; + + double sigma; +}; + +struct TrackRegionResult { + enum Termination { + // Ceres termination types, duplicated. + PARAMETER_TOLERANCE = 0, + FUNCTION_TOLERANCE, + GRADIENT_TOLERANCE, + NO_CONVERGENCE, + DID_NOT_RUN, + NUMERICAL_FAILURE, + + // Libmv specific errors. + SOURCE_OUT_OF_BOUNDS, + DESTINATION_OUT_OF_BOUNDS, + FELL_OUT_OF_BOUNDS, + INSUFFICIENT_CORRELATION, + }; + Termination termination; + + int num_iterations; + double correlation; + + // Final parameters? +}; + +// Always needs 4 correspondences. +void TrackRegion(const FloatImage &image1, + const FloatImage &image2, + const double *x1, const double *y1, + const TrackRegionOptions &options, + double *x2, double *y2, + TrackRegionResult *result); + +// TODO(keir): May need a "samplewarp" function. + +} // namespace libmv + +#endif // LIBMV_TRACKING_TRACK_REGION_H_ From 4f81bdf73cf31e70bdf77701c7201471c659e060 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Mon, 14 May 2012 10:47:25 +0000 Subject: [PATCH 036/360] Start migrating away from pat_min and pat_max for markers This starts converting markers in the movie clip editor / 2D tracker from using pat_min and pat_max notation to using the a more general, 4-corner representation. There is still considerable porting work to do; in particular: - The preview widget does not respect the new representation - The corners cannot yet be edited individually. - The clamping does not do the right thing for general corners; e.g. detecting a convex quad. - The tracking code in Blender does not actually invoke the corner tracking version of libmv's tracking API. Next steps: - Convert libmv's legacy ESM tracker and brute tracker to work under the new TrackRegion() API. - Make Blender use the new TrackRegion() API; this will allow real planar tracking tests. - Everything else (UI, etc). This patch is mostly the work of Sergey Sharybin. --- source/blender/blenkernel/BKE_tracking.h | 1 + source/blender/blenkernel/intern/movieclip.c | 12 +- source/blender/blenkernel/intern/tracking.c | 151 +++++++++++------- source/blender/blenloader/intern/readfile.c | 35 ++++ .../blender/editors/space_clip/clip_buttons.c | 32 ++-- source/blender/editors/space_clip/clip_draw.c | 63 +++++--- .../blender/editors/space_clip/space_clip.c | 6 +- .../blender/editors/space_clip/tracking_ops.c | 48 +++++- .../editors/transform/transform_conversions.c | 14 +- source/blender/makesdna/DNA_tracking_types.h | 24 ++- 10 files changed, 276 insertions(+), 110 deletions(-) diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 817cb477aba..84beca4fd96 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -57,6 +57,7 @@ struct MovieTrackingMarker *BKE_tracking_insert_marker(struct MovieTrackingTrack struct MovieTrackingMarker *marker); void BKE_tracking_delete_marker(struct MovieTrackingTrack *track, int framenr); +void BKE_tracking_marker_pattern_minmax(struct MovieTrackingMarker *marker, float min[2], float max[2]); struct MovieTrackingMarker *BKE_tracking_get_marker(struct MovieTrackingTrack *track, int framenr); struct MovieTrackingMarker *BKE_tracking_ensure_marker(struct MovieTrackingTrack *track, int framenr); struct MovieTrackingMarker *BKE_tracking_exact_marker(struct MovieTrackingTrack *track, int framenr); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index f07de7f0127..952e87077dc 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1076,10 +1076,18 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip } if ((track->flag & TRACK_LOCKED) == 0) { + float pat_min[2], pat_max[2]; + scopes->marker = marker; scopes->track = track; - scopes->slide_scale[0] = track->pat_max[0] - track->pat_min[0]; - scopes->slide_scale[1] = track->pat_max[1] - track->pat_min[1]; + + /* XXX: would work fine with non-transformed patterns, but would likely fail + * with transformed patterns, but that would be easier to debug when + * we'll have real pattern sampling (at least to test) */ + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + scopes->slide_scale[0] = pat_max[0] - pat_min[0]; + scopes->slide_scale[1] = pat_max[1] - pat_min[1]; } } } diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 4e2b4be474b..e8168da45fb 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -102,59 +102,67 @@ void BKE_tracking_init_settings(MovieTracking *tracking) void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) { int a; - float pat_min[2]; - float pat_max[2]; + float pat_min[2], pat_max[2]; + float eff_pat_min[2], eff_pat_max[2]; float max_pyramid_level_factor = 1.0; if (track->tracker == TRACKER_KLT) { max_pyramid_level_factor = 1 << (track->pyramid_levels - 1); } - /* sort */ - for (a = 0; a < 2; a++) { - if (track->pat_min[a] > track->pat_max[a]) - SWAP(float, track->pat_min[a], track->pat_max[a]); + /* XXX: currently search area is global, pattern size is per-marker, so we'll need to + * find maximal size of pattern to clamp search size nicely */ + INIT_MINMAX2(pat_min, pat_max); - if (track->search_min[a] > track->search_max[a]) - SWAP(float, track->search_min[a], track->search_max[a]); + for (a = 0; a < track->markersnr; a++) { + float cur_pat_min[2], cur_pat_max[2]; + + BKE_tracking_marker_pattern_minmax(&track->markers[a], cur_pat_min, cur_pat_max); + + DO_MINMAX2(cur_pat_min, pat_min, pat_max); + DO_MINMAX2(cur_pat_max, pat_min, pat_max); } /* compute the effective pattern size, which differs from the fine resolution * pattern size for the pyramid KLT tracker */ for (a = 0; a < 2; a++) { - pat_min[a] = max_pyramid_level_factor * track->pat_min[a]; - pat_max[a] = max_pyramid_level_factor * track->pat_max[a]; + eff_pat_min[a] = max_pyramid_level_factor * pat_min[a]; + eff_pat_max[a] = max_pyramid_level_factor * pat_max[a]; } if (event == CLAMP_PAT_DIM) { for (a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ - track->search_min[a] = MIN2(pat_min[a], track->search_min[a]); - track->search_max[a] = MAX2(pat_max[a], track->search_max[a]); + track->search_min[a] = MIN2(eff_pat_min[a], track->search_min[a]); + track->search_max[a] = MAX2(eff_pat_max[a], track->search_max[a]); } } else if (event == CLAMP_PAT_POS) { float dim[2]; - sub_v2_v2v2(dim, track->pat_max, track->pat_min); + sub_v2_v2v2(dim, pat_max, pat_min); +#if 0 + /* XXX: needs porting, but we need to know marker here, will be ported after a bit + * more global refactoring */ for (a = 0; a < 2; a++) { /* pattern shouldn't be moved outside of search */ - if (pat_min[a] < track->search_min[a]) { - track->pat_min[a] = track->search_min[a] - (pat_min[a] - track->pat_min[a]); + if (eff_pat_min[a] < track->search_min[a]) { + track->pat_min[a] = track->search_min[a] - (eff_pat_min[a] - pat_min[a]); track->pat_max[a] = track->pat_min[a] + dim[a]; } - if (track->pat_max[a] > track->search_max[a]) { - track->pat_max[a] = track->search_max[a] - (pat_max[a] - track->pat_max[a]); + if (eff_pat_max[a] > track->search_max[a]) { + track->pat_max[a] = track->search_max[a] - (eff_pat_max[a] - pat_max[a]); track->pat_min[a] = track->pat_max[a] - dim[a]; } } +#endif } else if (event == CLAMP_SEARCH_DIM) { for (a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ - track->search_min[a] = MIN2(pat_min[a], track->search_min[a]); - track->search_max[a] = MAX2(pat_max[a], track->search_max[a]); + track->search_min[a] = MIN2(eff_pat_min[a], track->search_min[a]); + track->search_max[a] = MAX2(eff_pat_max[a], track->search_max[a]); } } else if (event == CLAMP_SEARCH_POS) { @@ -164,42 +172,30 @@ void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) for (a = 0; a < 2; a++) { /* search shouldn't be moved inside pattern */ - if (track->search_min[a] > pat_min[a]) { - track->search_min[a] = pat_min[a]; + if (track->search_min[a] > eff_pat_min[a]) { + track->search_min[a] = eff_pat_min[a]; track->search_max[a] = track->search_min[a] + dim[a]; } - if (track->search_max[a] < pat_max[a]) { - track->search_max[a] = pat_max[a]; + if (track->search_max[a] < eff_pat_max[a]) { + track->search_max[a] = eff_pat_max[a]; track->search_min[a] = track->search_max[a] - dim[a]; } } } else if (event == CLAMP_PYRAMID_LEVELS || (event == CLAMP_SEARCH_DIM && track->tracker == TRACKER_KLT)) { float dim[2]; - sub_v2_v2v2(dim, track->pat_max, track->pat_min); + sub_v2_v2v2(dim, pat_max, pat_min); { float search_ratio = 2.3f * max_pyramid_level_factor; /* resize the search area to something sensible based * on the number of pyramid levels */ for (a = 0; a < 2; a++) { - track->search_min[a] = search_ratio * track->pat_min[a]; - track->search_max[a] = search_ratio * track->pat_max[a]; + track->search_min[a] = search_ratio * pat_min[a]; + track->search_max[a] = search_ratio * pat_max[a]; } } } - - /* marker's center should be in center of pattern */ - if (event == CLAMP_PAT_DIM || event == CLAMP_PAT_POS) { - float dim[2]; - - sub_v2_v2v2(dim, track->pat_max, track->pat_min); - - for (a = 0; a < 2; a++) { - track->pat_min[a] = -dim[a] / 2.0f; - track->pat_max[a] = dim[a] / 2.0f; - } - } } void BKE_tracking_track_flag(MovieTrackingTrack *track, int area, int flag, int clear) @@ -258,8 +254,14 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tr marker.pos[1] = y; marker.framenr = framenr; - copy_v2_v2(track->pat_max, pat); - negate_v2_v2(track->pat_min, pat); + marker.pattern_corners[0][0] = -pat[0]; + marker.pattern_corners[0][1] = -pat[1]; + + marker.pattern_corners[1][0] = pat[0]; + marker.pattern_corners[1][1] = -pat[1]; + + negate_v2_v2(marker.pattern_corners[2], marker.pattern_corners[0]); + negate_v2_v2(marker.pattern_corners[3], marker.pattern_corners[1]); copy_v2_v2(track->search_max, search); negate_v2_v2(track->search_min, search); @@ -337,6 +339,16 @@ void BKE_tracking_delete_marker(MovieTrackingTrack *track, int framenr) } } +void BKE_tracking_marker_pattern_minmax(MovieTrackingMarker *marker, float min[2], float max[2]) +{ + INIT_MINMAX2(min, max); + + DO_MINMAX2(marker->pattern_corners[0], min, max); + DO_MINMAX2(marker->pattern_corners[1], min, max); + DO_MINMAX2(marker->pattern_corners[2], min, max); + DO_MINMAX2(marker->pattern_corners[3], min, max); +} + MovieTrackingMarker *BKE_tracking_get_marker(MovieTrackingTrack *track, int framenr) { int a = track->markersnr - 1; @@ -1002,28 +1014,38 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u #ifdef WITH_LIBMV { - float patx = (int)((track->pat_max[0] - track->pat_min[0]) * width), - paty = (int)((track->pat_max[1] - track->pat_min[1]) * height); + float search_size_x, search_size_y; + float pattern_size_x, pattern_size_y; + float pat_min[2], pat_max[2], patx, paty; + float search_to_pattern_ratio, log2_search_to_pattern_ratio; + int wndx, wndy, half_wnd, max_pyramid_levels, level; - float search_size_x = (track->search_max[0] - track->search_min[0]) * width; - float search_size_y = (track->search_max[1] - track->search_min[1]) * height; - float pattern_size_x = (track->pat_max[0] - track->pat_min[0]) * width; - float pattern_size_y = (track->pat_max[1] - track->pat_min[1]) * height; - int wndx = (int)patx / 2, wndy = (int)paty / 2; - int half_wnd = MAX2(wndx, wndy); + struct libmv_RegionTracker *region_tracker; - /* compute the maximum pyramid size */ - float search_to_pattern_ratio = MIN2(search_size_x, search_size_y) - / MAX2(pattern_size_x, pattern_size_y); - float log2_search_to_pattern_ratio = log(floor(search_to_pattern_ratio)) / M_LN2; - int max_pyramid_levels = floor(log2_search_to_pattern_ratio + 1); + /* XXX: use boundbox of marker's pattern for now + * no idea how it should behave with non-affine tracking */ + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + patx = (int)((pat_max[0] - pat_min[0]) * width); + paty = (int)((pat_max[1] - pat_min[1]) * height); + wndx = (int)patx / 2; + wndy = (int)paty / 2; + half_wnd = MAX2(wndx, wndy); + + search_size_x = (track->search_max[0] - track->search_min[0]) * width; + search_size_y = (track->search_max[1] - track->search_min[1]) * height; + pattern_size_x = (pat_max[0] - pat_min[0]) * width; + pattern_size_y = (pat_max[1] - pat_min[1]) * height; + + /* compute the maximum pyramid size */ + search_to_pattern_ratio = MIN2(search_size_x, search_size_y) / MAX2(pattern_size_x, pattern_size_y); + log2_search_to_pattern_ratio = log(floor(search_to_pattern_ratio)) / M_LN2; + max_pyramid_levels = floor(log2_search_to_pattern_ratio + 1); /* try to accommodate the user's choice of pyramid level in a way * that doesn't cause the coarsest pyramid pattern to be larger * than the search size */ - int level = MIN2(track->pyramid_levels, max_pyramid_levels); - - struct libmv_RegionTracker *region_tracker; + level = MIN2(track->pyramid_levels, max_pyramid_levels); if (track->tracker == TRACKER_KLT) { region_tracker = libmv_pyramidRegionTrackerNew(100, level, half_wnd, @@ -1226,7 +1248,13 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, int margin, int anchored, float pos[2], int origin[2]) { - return get_area_imbuf(ibuf, track, marker, track->pat_min, track->pat_max, margin, anchored, pos, origin); + float pat_min[2], pat_max[2]; + + /* XXX: need to do real quad sampling here, but currently just assume + * corners represents quad pattern */ + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + return get_area_imbuf(ibuf, track, marker, pat_min, pat_max, margin, anchored, pos, origin); } ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, @@ -1430,7 +1458,7 @@ int BKE_tracking_next(MovieTrackingContext *context) if (marker && (marker->flag & MARKER_DISABLED) == 0) { #ifdef WITH_LIBMV int width, height, origin[2], tracked = 0, need_readjust = 0; - float pos[2], margin[2], dim[2]; + float pos[2], margin[2], dim[2], pat_min[2], pat_max[2]; double x1, y1, x2, y2; ImBuf *ibuf = NULL; MovieTrackingMarker marker_new, *marker_keyed; @@ -1447,7 +1475,8 @@ int BKE_tracking_next(MovieTrackingContext *context) nextfra = curfra + 1; /* margin from frame boundaries */ - sub_v2_v2v2(dim, track->pat_max, track->pat_min); + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + sub_v2_v2v2(dim, pat_max, pat_min); margin[0] = margin[1] = MAX2(dim[0], dim[1]) / 2.0f; margin[0] = MAX2(margin[0], (float)track->margin / ibuf_new->x); @@ -1509,6 +1538,10 @@ int BKE_tracking_next(MovieTrackingContext *context) copy_v2_v2(marker_new.pos, marker->pos); } + /* XXX: currently trackers does not change corners of a track, so + * just copy them from previous position */ + memcpy(marker_new.pattern_corners, marker->pattern_corners, sizeof(marker_new.pattern_corners)); + marker_new.flag |= MARKER_TRACKED; marker_new.framenr = nextfra; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 1e61aa937d6..79a09ab6c23 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7612,6 +7612,41 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + { + MovieClip *clip; + + for (clip = main->movieclip.first; clip; clip = clip->id.next) { + MovieTrackingTrack *track; + + track = clip->tracking.tracks.first; + while (track) { + int i; + + for (i = 0; i < track->markersnr; i++) { + MovieTrackingMarker *marker = &track->markers[i]; + + if (is_zero_v2(marker->pattern_corners[0]) && is_zero_v2(marker->pattern_corners[1]) && + is_zero_v2(marker->pattern_corners[3]) && is_zero_v2(marker->pattern_corners[3])) + { + marker->pattern_corners[0][0] = track->pat_min[0]; + marker->pattern_corners[0][1] = track->pat_min[1]; + + marker->pattern_corners[1][0] = track->pat_max[0]; + marker->pattern_corners[1][1] = track->pat_min[1]; + + marker->pattern_corners[2][0] = track->pat_max[0]; + marker->pattern_corners[2][1] = track->pat_max[1]; + + marker->pattern_corners[3][0] = track->pat_min[0]; + marker->pattern_corners[3][1] = track->pat_max[1]; + } + } + + track = track->next; + } + } + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 18f191a46a6..1f5e838f073 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -186,6 +186,7 @@ typedef struct { MovieClip *clip; MovieClipUser *user; /* user of clip */ MovieTrackingTrack *track; + MovieTrackingMarker *marker; int framenr; /* current frame number */ float marker_pos[2]; /* position of marker in pixel coords */ @@ -238,9 +239,11 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event) ok = TRUE; } else if (event == B_MARKER_PAT_DIM) { - float dim[2], pat_dim[2]; + float dim[2], pat_dim[2], pat_min[2], pat_max[2]; - sub_v2_v2v2(pat_dim, cb->track->pat_max, cb->track->pat_min); + BKE_tracking_marker_pattern_minmax(cb->marker, pat_min, pat_max); + + sub_v2_v2v2(pat_dim, pat_max, pat_min); dim[0] = cb->track_pat[0] / width; dim[1] = cb->track_pat[1] / height; @@ -248,11 +251,17 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event) sub_v2_v2(dim, pat_dim); mul_v2_fl(dim, 0.5f); - cb->track->pat_min[0] -= dim[0]; - cb->track->pat_min[1] -= dim[1]; + cb->marker->pattern_corners[0][0] -= dim[0]; + cb->marker->pattern_corners[0][1] -= dim[1]; - cb->track->pat_max[0] += dim[0]; - cb->track->pat_max[1] += dim[1]; + cb->marker->pattern_corners[1][0] += dim[0]; + cb->marker->pattern_corners[1][1] -= dim[1]; + + cb->marker->pattern_corners[2][0] += dim[0]; + cb->marker->pattern_corners[2][1] += dim[1]; + + cb->marker->pattern_corners[3][0] -= dim[0]; + cb->marker->pattern_corners[3][1] += dim[1]; BKE_tracking_clamp_track(cb->track, CLAMP_PAT_DIM); @@ -337,6 +346,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P MovieTrackingMarker *marker; MarkerUpdateCb *cb; const char *tip; + float pat_min[2], pat_max[2]; if (!ptr->data) return; @@ -366,6 +376,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P cb->clip = clip; cb->user = user; cb->track = track; + cb->marker = marker; cb->marker_flag = marker->flag; cb->framenr = user->framenr; @@ -383,7 +394,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P } else { int width, height, step, digits; - float pat_dim[2], pat_pos[2], search_dim[2], search_pos[2]; + float pat_dim[2], search_dim[2], search_pos[2]; uiLayout *col; BKE_movieclip_get_size(clip, user, &width, &height); @@ -399,15 +410,14 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P step = 100; digits = 2; - sub_v2_v2v2(pat_dim, track->pat_max, track->pat_min); + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + sub_v2_v2v2(pat_dim, pat_max, pat_min); sub_v2_v2v2(search_dim, track->search_max, track->search_min); add_v2_v2v2(search_pos, track->search_max, track->search_min); mul_v2_fl(search_pos, 0.5); - add_v2_v2v2(pat_pos, track->pat_max, track->pat_min); - mul_v2_fl(pat_pos, 0.5); - to_pixel_space(cb->marker_pos, marker->pos, width, height); to_pixel_space(cb->track_pat, pat_dim, width, height); to_pixel_space(cb->track_search, search_dim, width, height); diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index f92f639586d..8a9d9313a6c 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -428,14 +428,17 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT if ((marker->flag & MARKER_DISABLED) == 0) { float pos[2]; - rctf r; + float p[2]; - BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]); add_v2_v2v2(pos, marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, pos, pos); - if (BLI_in_rctf(&r, pos[0] - marker_pos[0], pos[1] - marker_pos[1])) { + sub_v2_v2v2(p, pos, marker_pos); + + if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1], + marker->pattern_corners[2], marker->pattern_corners[3])) + { if (tiny) glPointSize(3.0f); else glPointSize(4.0f); glBegin(GL_POINTS); @@ -471,10 +474,10 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT if (sc->flag & SC_SHOW_MARKER_PATTERN) { glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); + glVertex2fv(marker->pattern_corners[0]); + glVertex2fv(marker->pattern_corners[1]); + glVertex2fv(marker->pattern_corners[2]); + glVertex2fv(marker->pattern_corners[3]); glEnd(); } @@ -528,8 +531,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra /* marker position and offset position */ if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) { - float pos[2]; - rctf r; + float pos[2], p[2]; if (track->flag & TRACK_LOCKED) { if (act) @@ -546,11 +548,14 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra glColor3fv(col); } - BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]); add_v2_v2v2(pos, marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, pos, pos); - if (BLI_in_rctf(&r, pos[0] - marker_pos[0], pos[1] - marker_pos[1])) { + sub_v2_v2v2(p, pos, marker_pos); + + if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1], + marker->pattern_corners[2], marker->pattern_corners[3])) + { if (!tiny) glPointSize(2.0f); @@ -623,10 +628,10 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); + glVertex2fv(marker->pattern_corners[0]); + glVertex2fv(marker->pattern_corners[1]); + glVertex2fv(marker->pattern_corners[2]); + glVertex2fv(marker->pattern_corners[3]); glEnd(); } @@ -698,10 +703,10 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } /* only draw a pattern for the coarsest level */ glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); + glVertex2fv(marker->pattern_corners[0]); + glVertex2fv(marker->pattern_corners[1]); + glVertex2fv(marker->pattern_corners[2]); + glVertex2fv(marker->pattern_corners[3]); glEnd(); glDisable(GL_LINE_STIPPLE); glPopMatrix(); @@ -717,6 +722,18 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int outline, int sel, int act, int width, int height) { +#if 1 + /* XXX: not re-implemented yet */ + (void) sc; + (void) track; + (void) marker; + (void) marker_pos; + (void) outline; + (void) sel; + (void) act; + (void) width; + (void) height; +#else float x, y, dx, dy, patdx, patdy, searchdx, searchdy, tdx, tdy; int tiny = sc->flag & SC_SHOW_TINY_MARKER; float col[3], scol[3], px[2]; @@ -845,6 +862,7 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo if (outline) glLineWidth(1.0f); +#endif } static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, @@ -881,8 +899,11 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra dy = track->search_min[1]; } else if (sc->flag & SC_SHOW_MARKER_PATTERN) { - dx = track->pat_min[0]; - dy = track->pat_min[1]; + float pat_min[2], pat_max[2]; + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + dx = pat_min[0]; + dy = pat_min[1]; } pos[0] = (marker_pos[0] + dx) * width; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index a85d2352fbb..d2bff340b97 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -440,7 +440,8 @@ static void clip_operatortypes(void) /* markers */ WM_operatortype_append(CLIP_OT_add_marker); - WM_operatortype_append(CLIP_OT_slide_marker); + /* XXX: need porting! */ + //WM_operatortype_append(CLIP_OT_slide_marker); WM_operatortype_append(CLIP_OT_delete_track); WM_operatortype_append(CLIP_OT_delete_marker); @@ -614,7 +615,8 @@ static void clip_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", DELKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", XKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "CLIP_OT_slide_marker", LEFTMOUSE, KM_PRESS, 0, 0); + /* XXX: need porting */ + //WM_keymap_add_item(keymap, "CLIP_OT_slide_marker", LEFTMOUSE, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "CLIP_OT_disable_markers", DKEY, KM_PRESS, KM_SHIFT, 0); RNA_enum_set(kmi->ptr, "action", 2); /* toggle */ diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index fc93bcc0409..cf88a59f705 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -78,6 +78,8 @@ #include "clip_intern.h" // own include +static float dist_to_crns(float co[2], float pos[2], float crns[4][2]); + /********************** add marker operator *********************/ static void add_marker(SpaceClip *sc, float x, float y) @@ -245,6 +247,8 @@ void CLIP_OT_delete_marker(wmOperatorType *ot) } /********************** slide marker operator *********************/ +/* XXX: need porting! */ +#if 0 #define SLIDE_ACTION_POS 0 #define SLIDE_ACTION_SIZE 1 @@ -646,6 +650,8 @@ void CLIP_OT_slide_marker(wmOperatorType *ot) "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX); } +#endif + /********************** mouse select operator *********************/ static int mouse_on_side(float co[2], float x1, float y1, float x2, float y2, float epsx, float epsy) @@ -668,18 +674,28 @@ static int mouse_on_rect(float co[2], float pos[2], float min[2], float max[2], mouse_on_side(co, pos[0] + max[0], pos[1] + min[1], pos[0] + max[0], pos[1] + max[1], epsx, epsy); } +static int mouse_on_crns(float co[2], float pos[2], float crns[4][2], float epsx, float epsy) +{ + float dist = dist_to_crns(co, pos, crns); + + return dist < MAX2(epsx, epsy); +} + static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *track) { MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + float pat_min[2], pat_max[2]; float epsx, epsy; int width, height; ED_space_clip_size(sc, &width, &height); - epsx = MIN4(track->pat_min[0] - track->search_min[0], track->search_max[0] - track->pat_max[0], - fabsf(track->pat_min[0]), fabsf(track->pat_max[0])) / 2; - epsy = MIN4(track->pat_min[1] - track->search_min[1], track->search_max[1] - track->pat_max[1], - fabsf(track->pat_min[1]), fabsf(track->pat_max[1])) / 2; + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + epsx = MIN4(pat_min[0] - track->search_min[0], track->search_max[0] - pat_max[0], + fabsf(pat_min[0]), fabsf(pat_max[0])) / 2; + epsy = MIN4(pat_min[1] - track->search_min[1], track->search_max[1] - pat_max[1], + fabsf(pat_min[1]), fabsf(pat_max[1])) / 2; epsx = MAX2(epsx, 2.0f / width); epsy = MAX2(epsy, 2.0f / height); @@ -691,7 +707,7 @@ static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *trac if ((marker->flag & MARKER_DISABLED) == 0) { if (sc->flag & SC_SHOW_MARKER_PATTERN) - if (mouse_on_rect(co, marker->pos, track->pat_min, track->pat_max, epsx, epsy)) + if (mouse_on_crns(co, marker->pos, marker->pattern_corners, epsx, epsy)) return TRACK_AREA_PAT; epsx = 12.0f / width; @@ -722,6 +738,21 @@ static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2]) return MIN4(d1, d2, d3, d4); } +static float dist_to_crns(float co[2], float pos[2], float crns[4][2]) +{ + float d1, d2, d3, d4; + float p[2] = {co[0] - pos[0], co[1] - pos[1]}; + float *v1 = crns[0], *v2 = crns[1], + *v3 = crns[2], *v4 = crns[3]; + + d1 = dist_to_line_segment_v2(p, v1, v2); + d2 = dist_to_line_segment_v2(p, v2, v3); + d3 = dist_to_line_segment_v2(p, v3, v4); + d4 = dist_to_line_segment_v2(p, v4, v1); + + return MIN4(d1, d2, d3, d4); +} + static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2]) { MovieTrackingTrack *track = NULL, *cur; @@ -736,11 +767,11 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbas /* distance to marker point */ d1 = sqrtf((co[0] - marker->pos[0] - cur->offset[0]) * (co[0] - marker->pos[0] - cur->offset[0]) + - (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); + (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); /* distance to pattern boundbox */ if (sc->flag & SC_SHOW_MARKER_PATTERN) - d2 = dist_to_rect(co, marker->pos, cur->pat_min, cur->pat_max); + d2 = dist_to_crns(co, marker->pos, marker->pattern_corners); /* distance to search boundbox */ if (sc->flag & SC_SHOW_MARKER_SEARCH && TRACK_VIEW_SELECTED(sc, cur)) @@ -822,6 +853,8 @@ static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) int extend = RNA_boolean_get(op->ptr, "extend"); if (!extend) { +#if 0 + /* XXX: need porting */ SlideMarkerData *slidedata = slide_marker_customdata(C, event); if (slidedata) { @@ -836,6 +869,7 @@ static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_PASS_THROUGH; } +#endif } ED_clip_mouse_pos(C, event, co); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 661f6ba7842..7949ecd5d19 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5420,8 +5420,10 @@ static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d, markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, marker->pos, NULL, NULL); if (track->pat_flag & SELECT) { - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_min, marker->pos, NULL); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_max, marker->pos, NULL); + markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, marker->pattern_corners[0], marker->pos, NULL); + markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, marker->pattern_corners[1], marker->pos, NULL); + markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, marker->pattern_corners[2], marker->pos, NULL); + markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, marker->pattern_corners[3], marker->pos, NULL); } if (track->search_flag & SELECT) { @@ -5468,7 +5470,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) t->total++; if (track->pat_flag & SELECT) - t->total+= 2; + t->total+= 4; if (track->search_flag & SELECT) t->total+= 2; @@ -5507,9 +5509,9 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) } if (track->pat_flag & SELECT) { - td += 2; - td2d += 2; - tdt +=2; + td += 4; + td2d += 4; + tdt += 4; } } diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 6bf059c7ecb..1e7552f918f 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -35,6 +35,7 @@ #ifndef __DNA_TRACKING_TYPES_H__ #define __DNA_TRACKING_TYPES_H__ +#include "DNA_defs.h" #include "DNA_listBase.h" /* match-moving data */ @@ -68,6 +69,20 @@ typedef struct MovieTrackingCamera { typedef struct MovieTrackingMarker { float pos[2]; /* 2d position of marker on frame (in unified 0..1 space) */ + + /* corners of pattern in the following order: + * + * Y + * ^ + * | (3) --- (2) + * | | | + * | | | + * | | | + * | (0) --- (1) + * +-------------> X + */ + float pattern_corners[4][2]; + int framenr; /* number of frame marker is associated with */ int flag; /* Marker's flag (alive, ...) */ } MovieTrackingMarker; @@ -78,8 +93,13 @@ typedef struct MovieTrackingTrack { char name[64]; /* MAX_NAME */ /* ** setings ** */ - float pat_min[2], pat_max[2]; /* positions of left-bottom and right-top corners of pattern (in unified 0..1 space) */ - float search_min[2], search_max[2]; /* positions of left-bottom and right-top corners of search area (in unified 0..1 space) */ + + /* positions of left-bottom and right-top corners of pattern (in unified 0..1 space) */ + float pat_min[2], pat_max[2] DNA_DEPRECATED; + + /* positions of left-bottom and right-top corners of search area (in unified 0..1 space) */ + float search_min[2], search_max[2]; + float offset[2]; /* offset to "parenting" point */ /* ** track ** */ From 04d26bf44c4f2c5eb86aee117d818479d92f790b Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Mon, 14 May 2012 12:15:38 +0000 Subject: [PATCH 037/360] "Efficient Second-order Minimization" for the planar tracker This implements the "Efficient Second-order Minimization" scheme, as supported by the existing translation tracker. This increases the amount of per-iteration work, but decreases the number of iterations required to converge and also increases the size of the basin of attraction for the optimization. --- .../libmv/tracking/esm_region_tracker.cc | 1 + extern/libmv/libmv/tracking/track_region.cc | 99 ++++++++++++------- extern/libmv/libmv/tracking/track_region.h | 3 + 3 files changed, 67 insertions(+), 36 deletions(-) diff --git a/extern/libmv/libmv/tracking/esm_region_tracker.cc b/extern/libmv/libmv/tracking/esm_region_tracker.cc index 2491b158154..e6d0b9830f4 100644 --- a/extern/libmv/libmv/tracking/esm_region_tracker.cc +++ b/extern/libmv/libmv/tracking/esm_region_tracker.cc @@ -102,6 +102,7 @@ bool EsmRegionTracker::Track(const FloatImage &image1, options.num_samples_y = 2 * half_window_size + 1; options.max_iterations = 20; options.sigma = sigma; + options.use_esm = true; TrackRegionResult result; TrackRegion(image1, image2, xx1, yy1, options, xx2, yy2, &result); diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index 5a46c66cd3c..0bb8ae221b1 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -63,33 +63,32 @@ bool AllInBounds(const FloatImage &image, // supported, the sample function must be inside a template-specialized class // with a non-templated static member. -// The "AutoDiffImage::Sample()" function allows sampling an image at an x, y +// The "AutoDiff::Sample()" function allows sampling an image at an x, y // position such that if x and y are jets, then the derivative information is // correctly propagated. // Empty default template. template -struct AutoDiffImage { +struct AutoDiff { + // Sample only the image when the coordinates are scalars. static T Sample(const FloatImage &image_and_gradient, const T &x, const T &y) { - return 0.0; - } -}; - -// Sample only the image when the coordinates are scalars. -template<> -struct AutoDiffImage { - static double Sample(const FloatImage &image_and_gradient, - const double& x, const double& y) { return SampleLinear(image_and_gradient, y, x, 0); } + + static void SetScalarPart(double scalar, T *value) { + *value = scalar; + } + static void ScaleDerivative(double scale_by, T *value) { + // For double, there is no derivative to scale. + } }; // Sample the image and gradient when the coordinates are jets, applying the // jacobian appropriately to propagate the derivatives from the coordinates. template<> template -struct AutoDiffImage > { +struct AutoDiff > { static ceres::Jet Sample(const FloatImage &image_and_gradient, const ceres::Jet &x, const ceres::Jet &y) { @@ -116,6 +115,13 @@ struct AutoDiffImage > { jet_s.v = Matrix(dsdx, dsdy) * dxydz; return jet_s; } + + static void SetScalarPart(double scalar, ceres::Jet *value) { + value->a = scalar; + } + static void ScaleDerivative(double scale_by, ceres::Jet *value) { + value->v *= scale_by; + } }; template @@ -151,18 +157,16 @@ class BoundaryCheckingCallback : public ceres::IterationCallback { template class WarpCostFunctor { public: - WarpCostFunctor(const FloatImage &image_and_gradient1, + WarpCostFunctor(const TrackRegionOptions &options, + const FloatImage &image_and_gradient1, const FloatImage &image_and_gradient2, const Mat3 &canonical_to_image1, - const Warp &warp, - int num_samples_x, - int num_samples_y) - : image_and_gradient1_(image_and_gradient1), + const Warp &warp) + : options_(options), + image_and_gradient1_(image_and_gradient1), image_and_gradient2_(image_and_gradient2), canonical_to_image1_(canonical_to_image1), - warp_(warp), - num_samples_x_(num_samples_x), - num_samples_y_(num_samples_y) {} + warp_(warp) {} template bool operator()(const T *warp_parameters, T *residuals) const { @@ -171,8 +175,8 @@ class WarpCostFunctor { } int cursor = 0; - for (int r = 0; r < num_samples_y_; ++r) { - for (int c = 0; c < num_samples_x_; ++c) { + for (int r = 0; r < options_.num_samples_y; ++r) { + for (int c = 0; c < options_.num_samples_x; ++c) { // Compute the location of the source pixel (via homography). Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1); image1_position /= image1_position(2); @@ -185,28 +189,52 @@ class WarpCostFunctor { &image2_position[0], &image2_position[1]); - // Sample the source and destination. - double src_sample = AutoDiffImage::Sample(image_and_gradient1_, - image1_position[0], - image1_position[1]); - T dst_sample = AutoDiffImage::Sample(image_and_gradient2_, - image2_position[0], - image2_position[1]); + + // Sample the destination, propagating derivatives. + T dst_sample = AutoDiff::Sample(image_and_gradient2_, + image2_position[0], + image2_position[1]); + + // Sample the source. This is made complicated by ESM mode. + T src_sample; + if (options_.use_esm) { + // In ESM mode, the derivative of the source is also taken into + // account. This changes the linearization in a way that causes + // better convergence. Copy the derivative of the warp parameters + // onto the jets for the image1 position. This is the ESM hack. + T image1_position_x = image2_position[0]; + T image1_position_y = image2_position[1]; + AutoDiff::SetScalarPart(image1_position[0], &image1_position_x); + AutoDiff::SetScalarPart(image1_position[1], &image1_position_y); + src_sample = AutoDiff::Sample(image_and_gradient1_, + image1_position_x, + image1_position_y); + + // The jacobians for these should be averaged. Due to the subtraction + // below, flip the sign of the src derivative so that the effect + // after subtraction of the jets is that they are averaged. + AutoDiff::ScaleDerivative(-0.5, &src_sample); + AutoDiff::ScaleDerivative(0.5, &dst_sample); + } else { + // This is the traditional, forward-mode KLT solution. + src_sample = T(AutoDiff::Sample(image_and_gradient1_, + image1_position[0], + image1_position[1])); + } // The difference is the error. - residuals[cursor++] = T(src_sample) - dst_sample; + residuals[cursor++] = src_sample - dst_sample; } } return true; } private: + const TrackRegionOptions &options_; const FloatImage &image_and_gradient1_; const FloatImage &image_and_gradient2_; const Mat3 &canonical_to_image1_; const Warp &warp_; - int num_samples_x_; - int num_samples_y_; }; // Compute the warp from rectangular coordinates, where one corner is the @@ -570,12 +598,11 @@ void TemplatedTrackRegion(const FloatImage &image1, // Construct the warp cost function. AutoDiffCostFunction takes ownership. WarpCostFunctor *cost_function = - new WarpCostFunctor(image_and_gradient1, + new WarpCostFunctor(options, + image_and_gradient1, image_and_gradient2, canonical_homography, - warp, - options.num_samples_x, - options.num_samples_y); + warp); // Construct the problem with a single residual. ceres::Problem::Options problem_options; diff --git a/extern/libmv/libmv/tracking/track_region.h b/extern/libmv/libmv/tracking/track_region.h index ca783c32a75..7c937c04794 100644 --- a/extern/libmv/libmv/tracking/track_region.h +++ b/extern/libmv/libmv/tracking/track_region.h @@ -47,6 +47,9 @@ struct TrackRegionOptions { double minimum_correlation; int max_iterations; + + // Use the "Efficient Second-order Minimization" scheme. This increases + // convergence speed at the cost of more per-iteration work. bool use_esm; double sigma; From e9d520f482561cba0fe01ffa44b5f6eb97ee0276 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Mon, 14 May 2012 13:46:38 +0000 Subject: [PATCH 038/360] Refactor byte/float RGBA to grayscale conversion in tracking.c This is the first in a series of tracking.c refactorings to disentangle functionality that is sprinkled across unrelated functions. --- source/blender/blenkernel/intern/tracking.c | 45 ++++++++++++--------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index e8168da45fb..43188cc7877 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1264,11 +1264,29 @@ ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mov } #ifdef WITH_LIBMV + +/* Convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */ +static void float_rgba_to_gray(const float *rgba, float *gray, int num_pixels, float weight_red, float weight_green, float weight_blue) { + int i; + for (i = 0; i < num_pixels; ++i) { + const float *pixel = rgba + 4 * i; + gray[i] = weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]; + } +} + +static void uint8_rgba_to_float_gray(const unsigned char *rgba, float *gray, int num_pixels, float weight_red, float weight_green, float weight_blue) { + int i; + for (i = 0; i < num_pixels; ++i) { + const unsigned char *pixel = rgba + i * 4; + *gray++ = (weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]) / 255.0f; + } +} + static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, int *width_r, int *height_r, float pos[2], int origin[2]) { ImBuf *tmpibuf; - float *pixels, *fp; + float *gray_pixels; int x, y, width, height; width = (track->search_max[0] - track->search_min[0]) * ibuf->x; @@ -1280,29 +1298,18 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT *width_r = width; *height_r = height; - fp = pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf"); - for (y = 0; y < (int)height; y++) { - for (x = 0; x < (int)width; x++) { - int pixel = tmpibuf->x * y + x; + gray_pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf"); - if (tmpibuf->rect_float) { - float *rrgbf = tmpibuf->rect_float + pixel * 4; - - *fp = 0.2126 * rrgbf[0] + 0.7152 * rrgbf[1] + 0.0722 * rrgbf[2]; - } - else { - unsigned char *rrgb = (unsigned char*)tmpibuf->rect + pixel * 4; - - *fp = (0.2126 * rrgb[0] + 0.7152 * rrgb[1] + 0.0722 * rrgb[2]) / 255.0f; - } - - fp++; - } + if (tmpibuf->rect_float) { + float_rgba_to_gray(tmpibuf->rect_float, gray_pixels, height * width, 0.2126f, 0.7152f, 0.0722f); + } + else { + uint8_rgba_to_float_gray((unsigned char *)tmpibuf->rect, gray_pixels, height * width, 0.2126f, 0.7152f, 0.0722f); } IMB_freeImBuf(tmpibuf); - return pixels; + return gray_pixels; } static unsigned char *get_ucharbuf(ImBuf *ibuf) From 255e9ce15ad775a9cfef0713d7f280a656f11367 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 14 May 2012 15:24:13 +0000 Subject: [PATCH 039/360] fix for glitch adding markers, when there are 2 splines, and the first spline wasnt active but _was_ selected, Ctrl+Click would use the non-active selected spline. now use the active spline when available. also no need to de-select when adding a new vertex inbetween 2 verts in a spline. --- source/blender/editors/mask/mask_ops.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index aee73205c99..56d8abb5836 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1197,7 +1197,10 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) MaskSplinePoint *new_point_array, *new_point; int point_index = point - spline->points; + /* adding _could_ deselect, for now don't */ +#if 0 toggle_selection_all(mask, SEL_DESELECT); +#endif new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); @@ -1225,13 +1228,21 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) /* **** add extrude vertex **** */ -static void finSelectedSplinePoint(MaskShape *shape, MaskSpline **spline, MaskSplinePoint **point) +static void finSelectedSplinePoint(MaskShape *shape, MaskSpline **spline, MaskSplinePoint **point, short check_active) { MaskSpline *cur_spline = shape->splines.first; *spline = NULL; *point = NULL; + if (check_active) { + if (shape->act_spline && shape->act_point) { + *spline = shape->act_spline; + *point = shape->act_point; + return; + } + } + while (cur_spline) { int i; @@ -1264,6 +1275,11 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) MaskSpline *spline; MaskSplinePoint *point, *new_point = NULL; + /* adding _could_ deselect, for now don't */ +#if 0 + toggle_selection_all(mask, SEL_DESELECT); +#endif + shape = BKE_mask_shape_active(mask); if (!shape) { @@ -1274,7 +1290,7 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) point = NULL; } else { - finSelectedSplinePoint(shape, &spline, &point); + finSelectedSplinePoint(shape, &spline, &point, TRUE); } if (!spline) { From 389ae7131664a2404fc3409f969f7ff9fb9171d0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 14 May 2012 15:59:53 +0000 Subject: [PATCH 040/360] when adding new points to mask - base when adding between 2 points use their handle types. - when extruding an existing point use its handle type. --- source/blender/editors/mask/mask_ops.c | 29 ++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 56d8abb5836..e4f6c2656e2 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1086,8 +1086,11 @@ void MASK_OT_select(wmOperatorType *ot) /******************** add vertex *********************/ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point, - float point_co[2], float tangent[2]) + const float point_co[2], const float tangent[2], + MaskSplinePoint *reference_point, const short reference_adjacent) { + MaskSplinePoint *prev_point = NULL; + MaskSplinePoint *next_point = NULL; BezTriple *bezt; int width, height; float co[3]; @@ -1103,6 +1106,21 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask bezt->h1 = bezt->h2 = HD_ALIGN; + if (reference_point) { + bezt->h1 = bezt->h2 = MAX2(reference_point->bezt.h2, reference_point->bezt.h1); + } + else if (reference_adjacent) { + if (spline->tot_point != 1) { + int index = (int)(new_point - spline->points); + prev_point = &spline->points[(index - 1) % spline->tot_point]; + next_point = &spline->points[(index + 1) % spline->tot_point]; + + bezt->h1 = bezt->h2 = MAX2(prev_point->bezt.h2, next_point->bezt.h1); + + /* note, we may want to copy other attributes later, radius? pressure? color? */ + } + } + copy_v3_v3(bezt->vec[0], co); copy_v3_v3(bezt->vec[1], co); copy_v3_v3(bezt->vec[2], co); @@ -1214,7 +1232,7 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) new_point = &new_point_array[point_index + 1]; - setup_vertex_point(C, mask, spline, new_point, co, tangent); + setup_vertex_point(C, mask, spline, new_point, co, tangent, NULL, TRUE); shape->act_point = new_point; @@ -1273,7 +1291,8 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) { MaskShape *shape; MaskSpline *spline; - MaskSplinePoint *point, *new_point = NULL; + MaskSplinePoint *point; + MaskSplinePoint *new_point = NULL, *ref_point = NULL; /* adding _could_ deselect, for now don't */ #if 0 @@ -1312,6 +1331,7 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) spline->tot_point++; new_point = &spline->points[spline->tot_point - 1]; + ref_point = &spline->points[spline->tot_point - 2]; } else if (point == &spline->points[0]) { MASKPOINT_DESEL(point); @@ -1322,6 +1342,7 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) spline->tot_point++; new_point = &spline->points[0]; + ref_point = &spline->points[1]; } else { spline = BKE_mask_spline_add(shape); @@ -1332,7 +1353,7 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) shape->act_point = new_point; - setup_vertex_point(C, mask, spline, new_point, co, NULL); + setup_vertex_point(C, mask, spline, new_point, co, NULL, ref_point, FALSE); WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return TRUE; From c62077ce66ca40b564176e5fb6f8b1c1907626c4 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 14 May 2012 17:23:37 +0000 Subject: [PATCH 041/360] Per-track grease pencil data blocks Added support of tracks to have their own grease pencil datablock. This is controllable by Clip/Track toggle in Grease Pencil panel in Clip Editor. This toggle shows whether grease pencil stroke should go to movie clip's datablock or to active track. As soon as this toggle is switched to Track, all further strokes would be added to active track and only strokes which belongs to active track would be displayed on the screen. This strokes would be relative to track's position, which means if one made some strokes to track and started moving it, stokes would be moved together with track. Different tracks might share the same grease pencil datablock. Also hide draw modes which are not supported by space clip. Initial idea why tracks should have grease pencil datablocks was to support easy mask creation for tracking. This seemed fastest and easiest way to achieve mask editing for tracks. To get mask for specified track there's function BKE_tracking_track_mask_get which requires MovieTracking structure, track for which mask is creating and also width and height of current overall frame. it'll return ImBuf with mask (probably it's more like overkill, because internally it works with single-channel value buffer and probably that's one should be passing to libmv). Probably hacking grease pencil in such way is not ideal solution, but that part of code might be cleaned up further and it seems to be straightforward to use grease pencil for such a purpose. Note: this is commit to tomato branch, not to trunk. --- source/blender/blenkernel/BKE_tracking.h | 1 + source/blender/blenkernel/CMakeLists.txt | 1 + source/blender/blenkernel/SConscript | 1 + source/blender/blenkernel/intern/tracking.c | 102 ++++++++++++++++++ source/blender/blenloader/intern/readfile.c | 7 +- source/blender/blenloader/intern/writefile.c | 2 +- .../blender/editors/gpencil/gpencil_buttons.c | 29 +++-- source/blender/editors/gpencil/gpencil_edit.c | 21 +++- .../blender/editors/gpencil/gpencil_paint.c | 10 ++ source/blender/editors/space_clip/clip_draw.c | 47 ++++++-- .../blender/editors/space_clip/space_clip.c | 7 +- source/blender/makesdna/DNA_space_types.h | 9 +- source/blender/makesdna/DNA_tracking_types.h | 3 + .../blender/makesrna/intern/rna_movieclip.c | 1 + source/blender/makesrna/intern/rna_space.c | 13 +++ source/blender/makesrna/intern/rna_tracking.c | 8 ++ 16 files changed, 238 insertions(+), 24 deletions(-) diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 84beca4fd96..f8869bfc74c 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -77,6 +77,7 @@ struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTra struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int margin, int anchored, float pos[2], int origin[2]); +struct ImBuf *BKE_tracking_track_mask_get(struct MovieTracking *tracking, struct MovieTrackingTrack *track, int width, int height); void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 61461044fa7..521cabe31e5 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -43,6 +43,7 @@ set(INC ../../../intern/memutil ../../../intern/mikktspace ../../../intern/opennl/extern + ../../../intern/raskter # XXX - BAD LEVEL CALL WM_api.h ../windowmanager diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index ee9e6bc7739..64544adb26d 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -17,6 +17,7 @@ incs += ' #/intern/smoke/extern' incs += ' #/intern/mikktspace' incs += ' #/intern/audaspace/intern' incs += ' #/intern/ffmpeg' +incs += ' #/intern/raskter' incs += ' ' + env['BF_OPENGL_INC'] incs += ' ' + env['BF_ZLIB_INC'] diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 43188cc7877..2299860b5ae 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -59,6 +59,8 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "raskter.h" + #ifdef WITH_LIBMV # include "libmv-capi.h" #else @@ -1263,6 +1265,106 @@ ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mov return get_area_imbuf(ibuf, track, marker, track->search_min, track->search_max, margin, anchored, pos, origin); } +static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track) +{ + bGPDlayer *layer; + + if (!track->gpd) + return NULL; + + layer = track->gpd->layers.first; + + while (layer) { + if (layer->flag & GP_LAYER_ACTIVE) + return layer; + + layer = layer->next; + } + + return NULL; +} + +static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTrackingTrack *track, + bGPDlayer *layer, ImBuf *ibuf, int width, int height) +{ + bGPDframe *frame = layer->frames.first; + float *mask; + int x, y; + float aspy = 1.0f / tracking->camera.pixel_aspect; + + mask = MEM_callocN(ibuf->x * ibuf->y * sizeof(float), "track mask"); + + while (frame) { + bGPDstroke *stroke = frame->strokes.first; + + while (stroke) { + bGPDspoint *stroke_points = stroke->points; + float *mask_points, *fp; + int i; + + if (stroke->flag & GP_STROKE_2DSPACE) { + fp = mask_points = MEM_callocN(2 * stroke->totpoints * sizeof(float), + "track mask rasterization points"); + + for (i = 0; i < stroke->totpoints; i++, fp += 2) { + fp[0] = stroke_points[i].x * width / ibuf->x - track->search_min[0]; + fp[1] = stroke_points[i].y * height * aspy / ibuf->x - track->search_min[1]; + } + + PLX_raskterize(mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y); + + MEM_freeN(mask_points); + } + + stroke = stroke->next; + } + + frame = frame->next; + } + + for (y = 0; y < ibuf->y; y++) { + for (x = 0; x < ibuf->x; x++) { + float *pixel = &ibuf->rect_float[4 * (y * ibuf->x + x)]; + float val = mask[y * ibuf->x + x]; + + pixel[0] = val; + pixel[1] = val; + pixel[2] = val; + pixel[3] = 1.0f; + } + } + + MEM_freeN(mask); + + IMB_rect_from_float(ibuf); +} + +ImBuf *BKE_tracking_track_mask_get(MovieTracking *tracking, MovieTrackingTrack *track, int width, int height) +{ + ImBuf *ibuf; + bGPDlayer *layer = track_mask_gpencil_layer_get(track); + int mask_width, mask_height; + + /* XXX: currently copied from get_area_ibuf */ + mask_width = (track->search_max[0] - track->search_min[0]) * width; + mask_height = (track->search_max[1] - track->search_min[1]) * height; + + mask_width = mask_width | 1; + mask_height = mask_height | 1; + + ibuf = IMB_allocImBuf(mask_width, mask_height, 32, IB_rect | IB_rectfloat); + + if (layer) { + track_mask_gpencil_layer_rasterize(tracking, track, layer, ibuf, width, height); + } + else { + float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + IMB_rectfill(ibuf, white); + } + + return ibuf; +} + #ifdef WITH_LIBMV /* Convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 79a09ab6c23..a3ea1f3c841 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6198,7 +6198,7 @@ static void direct_link_movieReconstruction(FileData *fd, MovieTrackingReconstru reconstruction->cameras= newdataadr(fd, reconstruction->cameras); } -static void direct_link_movieTracks(FileData *fd, ListBase *tracksbase) +static void direct_link_movieTracks(FileData *fd, MovieClip *clip, ListBase *tracksbase) { MovieTrackingTrack *track; @@ -6207,6 +6207,7 @@ static void direct_link_movieTracks(FileData *fd, ListBase *tracksbase) track= tracksbase->first; while (track) { track->markers= newdataadr(fd, track->markers); + track->gpd= newlibadr_us(fd, clip->id.lib, track->gpd); track= track->next; } @@ -6225,7 +6226,7 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip) if (fd->movieclipmap) clip->tracking.camera.intrinsics= newmclipadr(fd, clip->tracking.camera.intrinsics); else clip->tracking.camera.intrinsics= NULL; - direct_link_movieTracks(fd, &tracking->tracks); + direct_link_movieTracks(fd, clip, &tracking->tracks); direct_link_movieReconstruction(fd, &tracking->reconstruction); clip->tracking.act_track= newdataadr(fd, clip->tracking.act_track); @@ -6245,7 +6246,7 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip) object= tracking->objects.first; while (object) { - direct_link_movieTracks(fd, &object->tracks); + direct_link_movieTracks(fd, clip, &object->tracks); direct_link_movieReconstruction(fd, &object->reconstruction); object= object->next; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 93d7f9bdc2f..539b19c5561 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2886,6 +2886,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil write_windowmanagers(wd, &mainvar->wm); write_screens (wd, &mainvar->screen); } + write_gpencils (wd, &mainvar->gpencil); write_movieclips (wd, &mainvar->movieclip); write_masks (wd, &mainvar->mask); write_scenes (wd, &mainvar->scene); @@ -2912,7 +2913,6 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil write_nodetrees(wd, &mainvar->nodetree); write_brushes (wd, &mainvar->brush); write_scripts (wd, &mainvar->script); - write_gpencils (wd, &mainvar->gpencil); write_libraries(wd, mainvar->next); if (write_user_block) { diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 3a7e806c2ed..b59f3756819 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -40,6 +40,7 @@ #include "DNA_gpencil_types.h" #include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "BKE_context.h" #include "BKE_global.h" @@ -236,6 +237,7 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin PointerRNA gpd_ptr; bGPDlayer *gpl; uiLayout *col, *row; + SpaceClip *sc= CTX_wm_space_clip(C); short v3d_stroke_opts = STROKE_OPTS_NORMAL; const short is_v3d = CTX_wm_view3d(C) != NULL; @@ -244,6 +246,16 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin /* draw gpd settings first ------------------------------------- */ col = uiLayoutColumn(layout, 0); + + if (sc) { + bScreen *screen = CTX_wm_screen(C); + PointerRNA sc_ptr; + + RNA_pointer_create(&screen->id, &RNA_SpaceClipEditor, sc, &sc_ptr); + row = uiLayoutRow(col, 1); + uiItemR(row, &sc_ptr, "grease_pencil_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + } + /* current Grease Pencil block */ /* TODO: show some info about who owns this? */ uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink"); @@ -281,14 +293,17 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin row = uiLayoutRow(col, 1); uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "VIEW", NULL, ICON_NONE); uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "CURSOR", NULL, ICON_NONE); - row = uiLayoutRow(col, 1); - uiLayoutSetActive(row, v3d_stroke_opts); - uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE); - uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE); - row = uiLayoutRow(col, 0); - uiLayoutSetActive(row, v3d_stroke_opts == STROKE_OPTS_V3D_ON); - uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE); + if (sc == NULL) { + row = uiLayoutRow(col, 1); + uiLayoutSetActive(row, v3d_stroke_opts); + uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE); + uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE); + + row = uiLayoutRow(col, 0); + uiLayoutSetActive(row, v3d_stroke_opts == STROKE_OPTS_V3D_ON); + uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE); + } } diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 9250d48a20c..71cbabe9114 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -57,6 +57,7 @@ #include "BKE_library.h" #include "BKE_object.h" #include "BKE_report.h" +#include "BKE_tracking.h" #include "WM_api.h" @@ -144,9 +145,23 @@ bGPdata **gpencil_data_get_pointers(bContext *C, PointerRNA *ptr) MovieClip *clip = ED_space_clip(sc); if (clip) { - /* for now, as long as there's a clip, default to using that in Clip Editor */ - if (ptr) RNA_id_pointer_create(&clip->id, ptr); - return &clip->gpd; + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + MovieTrackingTrack *track = BKE_tracking_active_track(&clip->tracking); + + if (!track) + return NULL; + + if (ptr) + RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr); + + return &track->gpd; + } + else { + if (ptr) + RNA_id_pointer_create(&clip->id, ptr); + + return &clip->gpd; + } } } break; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 5c23aba9024..4021b82b2df 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -44,6 +44,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_report.h" +#include "BKE_tracking.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -1125,6 +1126,15 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) p->custom_color[1] = 0.0f; p->custom_color[2] = 0.5f; p->custom_color[3] = 0.9f; + + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + int framenr = sc->user.framenr; + MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + p->imat[3][0] -= marker->pos[0]; + p->imat[3][1] -= marker->pos[1]; + } } break; diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 8a9d9313a6c..27a4532c89f 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -1196,8 +1196,10 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, int i, j, a; float pos[2], tpos[2], grid[11][11][2]; MovieTracking *tracking = &clip->tracking; + bGPdata *gpd = NULL; float aspy = 1.0f / tracking->camera.pixel_aspect; float dx = (float)width / n, dy = (float)height / n * aspy; + float offsx = 0.0f, offsy = 0.0f; if (sc->mode != SC_MODE_DISTORTION) return; @@ -1305,8 +1307,27 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, } } - if (sc->flag & SC_MANUAL_CALIBRATION && clip->gpd) { - bGPDlayer *layer = clip->gpd->layers.first; + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); + + if (track) { + int framenr = sc->user.framenr; + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + offsx = marker->pos[0]; + offsy = marker->pos[1]; + + gpd = track->gpd; + } + + } + else { + gpd = clip->gpd; + } + + + if (sc->flag & SC_MANUAL_CALIBRATION) { + bGPDlayer *layer = gpd->layers.first; while (layer) { bGPDframe *frame = layer->frames.first; @@ -1331,11 +1352,11 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, float npos[2], dpos[2], len; int steps; - pos[0] = stroke->points[i].x * width; - pos[1] = stroke->points[i].y * height * aspy; + pos[0] = (stroke->points[i].x + offsx) * width; + pos[1] = (stroke->points[i].y + offsy) * height * aspy; - npos[0] = stroke->points[i + 1].x * width; - npos[1] = stroke->points[i + 1].y * height * aspy; + npos[0] = (stroke->points[i + 1].x + offsx) * width; + npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy; len = len_v2v2(pos, npos); steps = ceil(len / 5.0f); @@ -1360,7 +1381,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, } else if (stroke->totpoints == 1) { glBegin(GL_POINTS); - glVertex2f(stroke->points[0].x, stroke->points[0].y); + glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy); glEnd(); } } @@ -1464,6 +1485,18 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d) if (ibuf) { glPushMatrix(); glMultMatrixf(sc->unistabmat); + + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); + + if (track) { + int framenr = sc->user.framenr; + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + glTranslatef(marker->pos[0], marker->pos[1], 0.0f); + } + } + draw_gpencil_2dimage(C, ibuf); IMB_freeImBuf(ibuf); diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 75c60ed5b60..2db563643a3 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -389,8 +389,11 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) } break; case NC_SCREEN: - if (wmn->data == ND_ANIMPLAY) { - ED_area_tag_redraw(sa); + switch (wmn->data) { + case ND_ANIMPLAY: + case ND_GPENCIL: + ED_area_tag_redraw(sa); + break; } break; case NC_SPACE: diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index a0528347658..640961f80f2 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -521,7 +521,10 @@ typedef struct SpaceClip { * defined when drawing and used for mouse position calculation */ /* movie postprocessing */ - int postproc_flag, pad2; + int postproc_flag; + + /* grease pencil */ + short gpencil_src, pad2; void *draw_context; @@ -935,6 +938,10 @@ enum { /* SpaceClip->dope_flag */ #define SC_DOPE_SORT_INVERSE 1 +/* SPaceClip->gpencil_src */ +#define SC_GPENCIL_SRC_CLIP 0 +#define SC_GPENCIL_SRC_TRACK 1 + /* space types, moved from DNA_screen_types.h */ /* Do NOT change order, append on end. types are hardcoded needed */ enum { diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 1e7552f918f..feb77c5c9ec 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -40,6 +40,7 @@ /* match-moving data */ +struct bGPdata; struct ImBuf; struct MovieReconstructedCamera; struct MovieTrackingCamera; @@ -127,6 +128,8 @@ typedef struct MovieTrackingTrack { /* ** SAD tracker settings ** */ float minimum_correlation; /* minimal correlation which is still treated as successful tracking */ + + struct bGPdata *gpd; /* grease-pencil data */ } MovieTrackingTrack; typedef struct MovieTrackingSettings { diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c index 2cbe6946485..13c11f6402f 100644 --- a/source/blender/makesrna/intern/rna_movieclip.c +++ b/source/blender/makesrna/intern/rna_movieclip.c @@ -284,6 +284,7 @@ static void rna_def_movieclip(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this movie clip"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); } void RNA_def_movieclip(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 5f92071ded7..13d25c78d5d 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2980,6 +2980,12 @@ static void rna_def_space_clip(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem gpencil_source_items[] = { + {SC_GPENCIL_SRC_CLIP, "CLIP", 0, "Clip", "Show grease pencil datablock which belongs to movie clip"}, + {SC_GPENCIL_SRC_TRACK, "TRACK", 0, "Track", "Show grease pencil datablock which belongs to active track"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SpaceClipEditor", "Space"); RNA_def_struct_sdna(srna, "SpaceClip"); RNA_def_struct_ui_text(srna, "Space Clip Editor", "Clip editor space data"); @@ -3166,6 +3172,13 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); + /* grease pencil source */ + prop = RNA_def_property(srna, "grease_pencil_source", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "gpencil_src"); + RNA_def_property_enum_items(prop, gpencil_source_items); + RNA_def_property_ui_text(prop, "Grease Pencil Source", "Where the grease pencil comes from"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); + /* ** dopesheet ** */ /* dopesheet sort */ diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 7a6753ad588..9f5dc75506b 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -1088,6 +1088,14 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "error"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Average Error", "Average error of re-projection"); + + /* grease pencil */ + prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "gpd"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this track"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); } static void rna_def_trackingStabilization(BlenderRNA *brna) From a673e70e7c9ffe27b28c1bcf4de9e8f4a65fc23e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 14 May 2012 19:41:27 +0000 Subject: [PATCH 042/360] fix for odd mask curve handle calculation - reuses auto handle calculation - keeps handle length relate to surrounding handles todo - only works well when cyclic is off - isnt aspect aware (looks like other tools are not aspect aware too) --- source/blender/blenkernel/BKE_mask.h | 6 ++ source/blender/blenkernel/intern/mask.c | 137 +++++++++++++++++++----- source/blender/editors/mask/mask_ops.c | 12 ++- 3 files changed, 126 insertions(+), 29 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 31a872b5056..be14229b323 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -82,6 +82,12 @@ void BKE_mask_unlink(struct Main *bmain, struct Mask *mask); void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime); void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene); void BKE_mask_parent_init(struct MaskParent *parent); +void BKE_mask_calc_handle_point(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point); +void BKE_mask_calc_handle_point_auto(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, + const short do_length_match); +void BKE_mask_get_handle_point_adjacent(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, + struct MaskSplinePoint **r_point_prev, struct MaskSplinePoint **r_point_next); +void BKE_mask_calc_handles(struct Mask *mask); #define MASKPOINT_ISSEL(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT) #define MASKPOINT_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 55dab26b841..3f5a5783950 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -794,42 +794,125 @@ static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *prev } } -void BKE_mask_calc_handles(Mask *mask) +void BKE_mask_get_handle_point_adjacent(Mask *UNUSED(mask), MaskSpline *spline, MaskSplinePoint *point, + MaskSplinePoint **r_point_prev, MaskSplinePoint **r_point_next) { - MaskShape *shape = mask->shapes.first; + MaskSplinePoint *prev_point, *next_point; + int i = (int)(point - spline->points); - while (shape) { - MaskSpline *spline = shape->splines.first; - int i; + BLI_assert(i >= i && i < spline->tot_point); - while (spline) { - for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; - MaskSplinePoint *prev_point, *next_point; + if (i == 0) { + if (spline->flag & MASK_SPLINE_CYCLIC) { + prev_point = &spline->points[spline->tot_point - 1]; + } + else { + prev_point = NULL; + } + } + else { + prev_point = point - 1; + } - if (i == 0) { - if (spline->flag & MASK_SPLINE_CYCLIC) - prev_point = &spline->points[spline->tot_point - 1]; - else - prev_point = NULL; - } - else prev_point = point - 1; + if (i == spline->tot_point - 1) { + if (spline->flag & MASK_SPLINE_CYCLIC) { + next_point = &spline->points[0]; + } + else { + next_point = NULL; + } + } + else { + next_point = point + 1; + } - if (i == spline->tot_point - 1) { - if (spline->flag & MASK_SPLINE_CYCLIC) - next_point = &spline->points[0]; - else - next_point = NULL; - } - else next_point = point + 1; + *r_point_prev = prev_point; + *r_point_next = next_point; +} - mask_calc_point_handle(point, prev_point, next_point); - } +void BKE_mask_calc_handle_point(Mask *mask, MaskSpline *spline, MaskSplinePoint *point) +{ + MaskSplinePoint *prev_point, *next_point; - spline = spline->next; + BKE_mask_get_handle_point_adjacent(mask, spline, point, + &prev_point, &next_point); + + mask_calc_point_handle(point, prev_point, next_point); +} + +static void enforce_dist_v2_v2fl(float v1[2], const float v2[2], const float dist) +{ + if (!equals_v2v2(v2, v1)) { + float nor[2]; + + sub_v2_v2v2(nor, v1, v2); + normalize_v2(nor); + madd_v2_v2v2fl(v1, v2, nor, dist); + } +} + +/** + * \brief Resets auto handles even for non-auto bezier points + * + * Useful for giving sane defaults. + */ +void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplinePoint *point, + const short do_length_match) +{ + MaskSplinePoint *prev_point, *next_point; + + const char h_back[2] = {point->bezt.h1, point->bezt.h2}; + + BKE_mask_get_handle_point_adjacent(mask, spline, point, + &prev_point, &next_point); + + point->bezt.h1 = HD_AUTO; + point->bezt.h2 = HD_AUTO; + mask_calc_point_handle(point, prev_point, next_point); + + point->bezt.h1 = h_back[0]; + point->bezt.h2 = h_back[1]; + mask_calc_point_handle(point, prev_point, next_point); + + /* TODO! - make this aspect aware! */ + /* TODO! - not working right with cyclic curves, need to investigate! */ + if (do_length_match) { + int length_tot = 0; + float length_average = 0.0f; + + if (prev_point) { + length_average += len_v2v2(prev_point->bezt.vec[0], prev_point->bezt.vec[1]); + length_tot++; } - shape = shape->next; + if (next_point) { + length_average += len_v2v2(next_point->bezt.vec[2], next_point->bezt.vec[1]); + length_tot++; + } + + if (length_tot) { + length_average /= (float)length_tot; + + enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average); + enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average); + } + } +} + +void BKE_mask_calc_handles(Mask *mask) +{ + MaskShape *shape; + + for (shape = mask->shapes.first; shape; shape = shape->next) { + MaskSpline *spline; + + for (spline = shape->splines.first; spline; spline = spline->next) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + BKE_mask_calc_handle_point(mask, spline, &spline->points[i]); + } + } } } diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index e4f6c2656e2..661030cb382 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -480,9 +480,9 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], if (feather_points) MEM_freeN(feather_points); - } - MEM_freeN(diff_points); + MEM_freeN(diff_points); + } } spline = spline->next; @@ -1148,6 +1148,9 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask add_v2_v2(bezt->vec[2], vec); } else { + + /* calculating auto handles works much nicer */ +#if 0 /* next points are aligning in the direction of previous/next point */ MaskSplinePoint *point; float v1[2], v2[2], vec[2]; @@ -1192,6 +1195,11 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask add_v2_v2(bezt->vec[0], vec); sub_v2_v2(bezt->vec[2], vec); +#else + BKE_mask_calc_handle_point_auto(mask, spline, new_point, TRUE); + +#endif + } BKE_mask_parent_init(&new_point->parent); From 432ff1a17e77e80067bd29a7ec92ff7ed7e19620 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 15 May 2012 10:55:26 +0000 Subject: [PATCH 043/360] Tomato: support of corners sliding for mouse sliding operator This commits re-enables mouse sliding operator which behaves in the same way as it used to for search area and marker position, but for pattern it's now using individual corners. This allows to define affine transformation which later would be used by tracker algorithm. For non-affine tracking code is also ported but currently it's hardcoded to use affine transformation. When real affine trackers and RNA/DNA changes would be commited, easy to switch sliding operator to old-school behavior for non-affine patterns. --- source/blender/editors/space_clip/clip_draw.c | 162 +++++++------ .../blender/editors/space_clip/space_clip.c | 6 +- .../blender/editors/space_clip/tracking_ops.c | 212 ++++++++++++++---- 3 files changed, 252 insertions(+), 128 deletions(-) diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 27a4532c89f..7fd4f1bafae 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -719,24 +719,69 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra glPopMatrix(); } +static float get_shortest_pattern_side(MovieTrackingMarker *marker) +{ + int i, next; + float len = FLT_MAX; + + for (i = 0; i < 4; i++) { + float cur_len; + + next = (i + 1) % 4; + + cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]); + + len = MIN2(cur_len, len); + } + + return len; +} + +static void draw_marker_slide_square(float x, float y, float dx, float dy, int outline, float px[2]) +{ + float tdx, tdy; + + tdx = dx; + tdy = dy; + + if (outline) { + tdx += px[0]; + tdy += px[1]; + } + + glBegin(GL_QUADS); + glVertex3f(x - tdx, y + tdy, 0.0f); + glVertex3f(x + tdx, y + tdy, 0.0f); + glVertex3f(x + tdx, y - tdy, 0.0f); + glVertex3f(x - tdx, y - tdy, 0.0f); + glEnd(); +} + +static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int outline, float px[2]) +{ + float tdx, tdy; + + tdx = dx * 2.0f; + tdy = dy * 2.0f; + + if (outline) { + tdx += px[0]; + tdy += px[1]; + } + + glBegin(GL_TRIANGLES); + glVertex3f(x, y, 0.0f); + glVertex3f(x - tdx, y, 0.0f); + glVertex3f(x, y + tdy, 0.0f); + glEnd(); +} + static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int outline, int sel, int act, int width, int height) { -#if 1 - /* XXX: not re-implemented yet */ - (void) sc; - (void) track; - (void) marker; - (void) marker_pos; - (void) outline; - (void) sel; - (void) act; - (void) width; - (void) height; -#else - float x, y, dx, dy, patdx, patdy, searchdx, searchdy, tdx, tdy; + float dx, dy, patdx, patdy, searchdx, searchdy; int tiny = sc->flag & SC_SHOW_TINY_MARKER; - float col[3], scol[3], px[2]; + float col[3], scol[3], px[2], side; if ((tiny && outline) || (marker->flag & MARKER_DISABLED)) return; @@ -757,8 +802,9 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo dx = 6.0f / width / sc->zoom; dy = 6.0f / height / sc->zoom; - patdx = MIN2(dx * 2.0f / 3.0f, (track->pat_max[0] - track->pat_min[0]) / 6.0f); - patdy = MIN2(dy * 2.0f / 3.0f, (track->pat_max[1] - track->pat_min[1]) / 6.0f); + side = get_shortest_pattern_side(marker); + patdx = MIN2(dx * 2.0f / 3.0f, side / 6.0f); + patdy = MIN2(dy * 2.0f / 3.0f, side * width / height / 6.0f); searchdx = MIN2(dx, (track->search_max[0] - track->search_min[0]) / 6.0f); searchdy = MIN2(dy, (track->search_max[1] - track->search_min[1]) / 6.0f); @@ -775,41 +821,10 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo } /* search offset square */ - x = track->search_min[0]; - y = track->search_max[1]; - - tdx = searchdx; - tdy = searchdy; - - if (outline) { - tdx += px[0]; - tdy += px[1]; - } - - glBegin(GL_QUADS); - glVertex3f(x - tdx, y + tdy, 0); - glVertex3f(x + tdx, y + tdy, 0); - glVertex3f(x + tdx, y - tdy, 0); - glVertex3f(x - tdx, y - tdy, 0); - glEnd(); + draw_marker_slide_square(track->search_min[0], track->search_max[1], searchdx, searchdy, outline, px); /* search re-sizing triangle */ - x = track->search_max[0]; - y = track->search_min[1]; - - tdx = searchdx * 2.0f; - tdy = searchdy * 2.0f; - - if (outline) { - tdx += px[0]; - tdy += px[1]; - } - - glBegin(GL_TRIANGLES); - glVertex3f(x, y, 0); - glVertex3f(x - tdx, y, 0); - glVertex3f(x, y + tdy, 0); - glEnd(); + draw_marker_slide_triangle(track->search_max[0], track->search_min[1], searchdx, searchdy, outline, px); } if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) { @@ -820,49 +835,32 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo glColor3fv(col); } - /* pattern offset square */ - x = track->pat_min[0]; - y = track->pat_max[1]; + /* XXX: need to be real check if affine tracking is enabled, but for now not + * sure how to do this, so assume affine tracker is always enabled */ + if (TRUE) { + int i; - tdx = patdx; - tdy = patdy; - - if (outline) { - tdx += px[0]; - tdy += px[1]; + /* pattern's corners sliding squares */ + for (i = 0; i < 4; i++) { + draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1], + patdx / 1.5f, patdy / 1.5f, outline, px); + } } + else { + /* pattern offset square */ + draw_marker_slide_square(marker->pattern_corners[3][0], marker->pattern_corners[3][1], + patdx, patdy, outline, px); - glBegin(GL_QUADS); - glVertex3f(x - tdx, y + tdy, 0); - glVertex3f(x + tdx, y + tdy, 0); - glVertex3f(x + tdx, y - tdy, 0); - glVertex3f(x - tdx, y - tdy, 0); - glEnd(); - - /* pattern re-sizing triangle */ - x = track->pat_max[0]; - y = track->pat_min[1]; - - tdx = patdx*2.0f; - tdy = patdy*2.0f; - - if (outline) { - tdx += px[0]; - tdy += px[1]; + /* pattern re-sizing triangle */ + draw_marker_slide_triangle(marker->pattern_corners[1][0], marker->pattern_corners[1][1], + patdx, patdy, outline, px); } - - glBegin(GL_TRIANGLES); - glVertex3f(x, y, 0); - glVertex3f(x - tdx, y, 0); - glVertex3f(x, y + tdy, 0); - glEnd(); } glPopMatrix(); if (outline) glLineWidth(1.0f); -#endif } static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 2db563643a3..c1bbc75c87a 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -444,8 +444,7 @@ static void clip_operatortypes(void) /* markers */ WM_operatortype_append(CLIP_OT_add_marker); - /* XXX: need porting! */ - //WM_operatortype_append(CLIP_OT_slide_marker); + WM_operatortype_append(CLIP_OT_slide_marker); WM_operatortype_append(CLIP_OT_delete_track); WM_operatortype_append(CLIP_OT_delete_marker); @@ -624,8 +623,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", DELKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", XKEY, KM_PRESS, KM_SHIFT, 0); - /* XXX: need porting */ - //WM_keymap_add_item(keymap, "CLIP_OT_slide_marker", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_slide_marker", LEFTMOUSE, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "CLIP_OT_disable_markers", DKEY, KM_PRESS, KM_SHIFT, 0); RNA_enum_set(kmi->ptr, "action", 2); /* toggle */ diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 6021e0e15ce..d50bed005ab 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -248,8 +248,6 @@ void CLIP_OT_delete_marker(wmOperatorType *ot) } /********************** slide marker operator *********************/ -/* XXX: need porting! */ -#if 0 #define SLIDE_ACTION_POS 0 #define SLIDE_ACTION_SIZE 1 @@ -262,15 +260,16 @@ typedef struct { int mval[2]; int width, height; - float *min, *max, *pos, *offset; - float smin[2], smax[2], spos[2], soff[2]; + float *min, *max, *pos, *offset, (*corners)[2]; + float smin[2], smax[2], spos[2], soff[2], scorners[4][2]; float (*smarkers)[2]; int lock, accurate; } SlideMarkerData; static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track, - MovieTrackingMarker *marker, wmEvent *event, int area, int action, int width, int height) + MovieTrackingMarker *marker, wmEvent *event, + int area, int corner, int action, int width, int height) { SlideMarkerData *data = MEM_callocN(sizeof(SlideMarkerData), "slide marker data"); @@ -289,10 +288,9 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra } else if (area == TRACK_AREA_PAT) { if (action == SLIDE_ACTION_SIZE) { - data->min = track->pat_min; - data->max = track->pat_max; + data->corners = marker->pattern_corners; } - else { + else if (action == SLIDE_ACTION_OFFSET) { int a; data->pos = marker->pos; @@ -304,15 +302,28 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra for (a = 0; a < track->markersnr; a++) copy_v2_v2(data->smarkers[a], track->markers[a].pos); } + else if (action == SLIDE_ACTION_POS) { + data->corners = marker->pattern_corners; + data->pos = marker->pattern_corners[corner]; + + copy_v2_v2(data->spos, data->pos); + } } else if (area == TRACK_AREA_SEARCH) { data->min = track->search_min; data->max = track->search_max; } - if (area == TRACK_AREA_SEARCH || (area == TRACK_AREA_PAT && action != SLIDE_ACTION_OFFSET)) { - copy_v2_v2(data->smin, data->min); - copy_v2_v2(data->smax, data->max); + if ((area == TRACK_AREA_SEARCH) || + (area == TRACK_AREA_PAT && !ELEM(action, SLIDE_ACTION_OFFSET, SLIDE_ACTION_POS))) + { + if (data->corners) { + memcpy(data->scorners, data->corners, sizeof(data->scorners)); + } + else { + copy_v2_v2(data->smin, data->min); + copy_v2_v2(data->smax, data->max); + } } data->mval[0] = event->mval[0]; @@ -327,8 +338,6 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra return data; } -/* corner = 0: right-bottom corner, - * corner = 1: left-top corner */ static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, int area, float co[2], int corner, int width, int height) { @@ -342,8 +351,7 @@ static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTracki copy_v2_v2(max, track->search_max); } else { - copy_v2_v2(min, track->pat_min); - copy_v2_v2(max, track->pat_max); + BKE_tracking_marker_pattern_minmax(marker, min, max); } dx = size / width / sc->zoom; @@ -371,22 +379,95 @@ static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTracki return inside; } +static int get_mouse_pattern_corner(SpaceClip *sc, MovieTrackingMarker *marker, float co[2], int width, int height) +{ + int i, next; + float len = FLT_MAX, dx, dy; + + for (i = 0; i < 4; i++) { + float cur_len; + + next = (i + 1) % 4; + + cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]); + + len = MIN2(cur_len, len); + } + + dx = 6.0f / width / sc->zoom; + dy = 6.0f / height / sc->zoom; + + dx = MIN2(dx * 2.0f / 3.0f, len / 6.0f); + dy = MIN2(dy * 2.0f / 3.0f, len * width / height / 6.0f); + + for (i = 0; i < 4; i++) { + float crn[2]; + int inside; + + add_v2_v2v2(crn, marker->pattern_corners[i], marker->pos); + + inside = IN_RANGE_INCL(co[0], crn[0] - dx, crn[0] + dx) && + IN_RANGE_INCL(co[1], crn[1] - dy, crn[1] + dy); + + if (inside) + return i; + } + + return -1; +} + static int mouse_on_offset(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, - float co[2], int width, int height) + float co[2], int width, int height) { float pos[2], dx, dy; + float pat_min[2], pat_max[2]; + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); add_v2_v2v2(pos, marker->pos, track->offset); dx = 12.0f / width / sc->zoom; dy = 12.0f / height / sc->zoom; - dx = MIN2(dx, (track->pat_max[0] - track->pat_min[0]) / 2.0f); - dy = MIN2(dy, (track->pat_max[1] - track->pat_min[1]) / 2.0f); + dx = MIN2(dx, (pat_max[0] - pat_min[0]) / 2.0f); + dy = MIN2(dy, (pat_max[1] - pat_min[1]) / 2.0f); return co[0] >= pos[0] - dx && co[0] <= pos[0] + dx && co[1] >= pos[1] - dy && co[1] <= pos[1] + dy; } +static int slide_check_corners(float (*corners)[2]) +{ + int i, next, prev; + float cross = 0.0f; + float p[2] = {0.0f, 0.0f}; + + if (!isect_point_quad_v2(p, corners[0], corners[1], corners[2], corners[3])) + return FALSE; + + for (i = 0; i < 4; i++) { + float v1[2], v2[2], cur_cross; + + next = (i + 1) % 4; + prev = (4 + i - 1) % 4; + + sub_v2_v2v2(v1, corners[i], corners[prev]); + sub_v2_v2v2(v2, corners[next], corners[i]); + + cur_cross = cross_v2v2(v1, v2); + + if (fabsf(cur_cross) > FLT_EPSILON) { + if (cross == 0.0f) { + cross = cur_cross; + } + else if (cross * cur_cross < 0.0f) { + return FALSE; + } + } + } + + return TRUE; +} + static void hide_cursor(bContext *C) { wmWindow *win = CTX_wm_window(C); @@ -424,28 +505,45 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); if ((marker->flag & MARKER_DISABLED) == 0) { - if (!customdata) + if (!customdata) { if (mouse_on_offset(sc, track, marker, co, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_POINT, + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_POINT, 0, SLIDE_ACTION_POS, width, height); + } if (sc->flag & SC_SHOW_MARKER_SEARCH) { - if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 1, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, + if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 1, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, SLIDE_ACTION_OFFSET, width, height); - else if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 0, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, + } + else if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 0, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, SLIDE_ACTION_SIZE, width, height); + } } if (!customdata && (sc->flag & SC_SHOW_MARKER_PATTERN)) { - if (mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 1, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, - SLIDE_ACTION_OFFSET, width, height); + /* XXX: need to be real check if affine tracking is enabled, but for now not + * sure how to do this, so assume affine tracker is always enabled */ + if (TRUE) { + int corner = get_mouse_pattern_corner(sc, marker, co, width, height); - if (!customdata && mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 0, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, - SLIDE_ACTION_SIZE, width, height); + if (corner != -1) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, corner, + SLIDE_ACTION_POS, width, height); + } + } + else { + if (mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 1, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, + SLIDE_ACTION_OFFSET, width, height); + } + + if (!customdata && mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 0, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, + SLIDE_ACTION_SIZE, width, height); + } + } } if (customdata) @@ -494,8 +592,13 @@ static void cancel_mouse_slide(SlideMarkerData *data) } else { if (data->action == SLIDE_ACTION_SIZE) { - copy_v2_v2(data->min, data->smin); - copy_v2_v2(data->max, data->smax); + if (data->corners) { + memcpy(data->corners, data->scorners, sizeof(data->scorners)); + } + else { + copy_v2_v2(data->min, data->smin); + copy_v2_v2(data->max, data->smax); + } } else { int a; @@ -569,18 +672,33 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } else { if (data->action == SLIDE_ACTION_SIZE) { - data->min[0] = data->smin[0] - dx; - data->max[0] = data->smax[0] + dx; + if (data->corners) { + data->corners[0][0] = data->scorners[0][0] - dx; + data->corners[0][1] = data->scorners[0][1] + dy; - data->min[1] = data->smin[1] + dy; - data->max[1] = data->smax[1] - dy; + data->corners[1][0] = data->scorners[1][0] + dx; + data->corners[1][1] = data->scorners[1][1] + dy; + + data->corners[2][0] = data->scorners[2][0] + dx; + data->corners[2][1] = data->scorners[2][1] - dy; + + data->corners[3][0] = data->scorners[3][0] - dx; + data->corners[3][1] = data->scorners[3][1] - dy; + } + else { + data->min[0] = data->smin[0] - dx; + data->max[0] = data->smax[0] + dx; + + data->min[1] = data->smin[1] + dy; + data->max[1] = data->smax[1] - dy; + } if (data->area == TRACK_AREA_SEARCH) BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_DIM); else BKE_tracking_clamp_track(data->track, CLAMP_PAT_DIM); } - else { + else if (data->action == SLIDE_ACTION_OFFSET) { float d[2] = {dx, dy}; if (data->area == TRACK_AREA_SEARCH) { @@ -599,6 +717,21 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) if (data->area == TRACK_AREA_SEARCH) BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_POS); } + else if (data->action == SLIDE_ACTION_POS) { + float spos[2]; + + copy_v2_v2(spos, data->pos); + + data->pos[0] = data->spos[0] + dx; + data->pos[1] = data->spos[1] + dy; + + if (!slide_check_corners(data->corners)) { + copy_v2_v2(data->pos, spos); + } + + /* currently only patterns are allowed to have such combination of event and data */ + BKE_tracking_clamp_track(data->track, CLAMP_PAT_DIM); + } } WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL); @@ -651,8 +784,6 @@ void CLIP_OT_slide_marker(wmOperatorType *ot) "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX); } -#endif - /********************** mouse select operator *********************/ static int mouse_on_side(float co[2], float x1, float y1, float x2, float y2, float epsx, float epsy) @@ -854,8 +985,6 @@ static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) int extend = RNA_boolean_get(op->ptr, "extend"); if (!extend) { -#if 0 - /* XXX: need porting */ SlideMarkerData *slidedata = slide_marker_customdata(C, event); if (slidedata) { @@ -870,7 +999,6 @@ static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_PASS_THROUGH; } -#endif } ED_clip_mouse_pos(C, event, co); From b5ac36671a510a67eede9d89c8bf539f3509dc05 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 15 May 2012 14:01:02 +0000 Subject: [PATCH 044/360] Tomato: fixed crash when using manual calibration without GP strokes done --- source/blender/editors/space_clip/clip_draw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 7fd4f1bafae..aa9af704280 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -1323,8 +1323,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, gpd = clip->gpd; } - - if (sc->flag & SC_MANUAL_CALIBRATION) { + if (sc->flag & SC_MANUAL_CALIBRATION && gpd) { bGPDlayer *layer = gpd->layers.first; while (layer) { From 3e4e7bfc42286af77e178e51d842256ccb9944a6 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 15 May 2012 14:44:32 +0000 Subject: [PATCH 045/360] Tomato: fix usage of uninitialized variables in applyAspectRatio Thanks Keir for pointing into issue! --- source/blender/editors/transform/transform.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 26f313aadfb..2c19f44f7a3 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -305,10 +305,12 @@ void applyAspectRatio(TransInfo *t, float vec[2]) float aspx, aspy; int width, height; + ED_space_clip_size(sc, &width, &height); + if (t->options & CTX_MOVIECLIP) - ED_space_clip_size(sc, &width, &height); - else if (t->options & CTX_MASK) ED_space_clip_aspect(sc, &aspx, &aspy); + else if (t->options & CTX_MASK) + ED_space_clip_mask_aspect(sc, &aspx, &aspy); vec[0] *= width / aspx; vec[1] *= height / aspy; From e5927b8cc5bb9a5e06008ab29d04d70db70316e8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 15 May 2012 15:05:45 +0000 Subject: [PATCH 046/360] Tomato: fixes for marker sliding operator - Fixed crash on slide undo. Was caused by some typos in slide data initialization and not checking for slide action in cancel callback - Always create keyframe for frame when marker is stared sliding. --- source/blender/editors/space_clip/tracking_ops.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index d50bed005ab..89b14b06220 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -315,7 +315,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra } if ((area == TRACK_AREA_SEARCH) || - (area == TRACK_AREA_PAT && !ELEM(action, SLIDE_ACTION_OFFSET, SLIDE_ACTION_POS))) + (area == TRACK_AREA_PAT && action != SLIDE_ACTION_OFFSET)) { if (data->corners) { memcpy(data->scorners, data->corners, sizeof(data->scorners)); @@ -591,7 +591,9 @@ static void cancel_mouse_slide(SlideMarkerData *data) copy_v2_v2(data->pos, data->spos); } else { - if (data->action == SLIDE_ACTION_SIZE) { + if ((data->action == SLIDE_ACTION_SIZE) || + (data->action == SLIDE_ACTION_POS && data->area == TRACK_AREA_PAT)) + { if (data->corners) { memcpy(data->corners, data->scorners, sizeof(data->scorners)); } @@ -663,8 +665,6 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) else { data->pos[0] = data->spos[0] + dx; data->pos[1] = data->spos[1] + dy; - - data->marker->flag &= ~MARKER_TRACKED; } WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); @@ -734,6 +734,8 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } } + data->marker->flag &= ~MARKER_TRACKED; + WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL); break; From 7e5348f4c5a464ebf3ec7f1bf532a0658f388283 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 16 May 2012 18:05:35 +0000 Subject: [PATCH 047/360] improvements to mask editor path editing - adding new points de-selects previous so Ctrl+Click+Drag works usefully. - cyclic curves now extrude properly - adding new points inbetween existing now use the surrounding points handle length. --- source/blender/blenkernel/BKE_mask.h | 4 +- source/blender/blenkernel/intern/mask.c | 100 +++++++++--------------- source/blender/editors/mask/mask_ops.c | 14 ++-- 3 files changed, 45 insertions(+), 73 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index be14229b323..26beed4645c 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -82,9 +82,9 @@ void BKE_mask_unlink(struct Main *bmain, struct Mask *mask); void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime); void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene); void BKE_mask_parent_init(struct MaskParent *parent); +void BKE_mask_calc_handle_adjacent_length(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point); void BKE_mask_calc_handle_point(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point); -void BKE_mask_calc_handle_point_auto(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, - const short do_length_match); +void BKE_mask_calc_handle_point_auto(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point); void BKE_mask_get_handle_point_adjacent(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, struct MaskSplinePoint **r_point_prev, struct MaskSplinePoint **r_point_next); void BKE_mask_calc_handles(struct Mask *mask); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index d497ba612ae..0af0c1c7aa5 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -758,7 +758,7 @@ static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *prev { BezTriple *bezt = &point->bezt; BezTriple *prev_bezt = NULL, *next_bezt = NULL; - int handle_type = bezt->h1; + //int handle_type = bezt->h1; if (prev_point) prev_bezt = &prev_point->bezt; @@ -766,6 +766,9 @@ static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *prev if (next_point) next_bezt = &next_point->bezt; +#if 1 + BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0); +#else if (handle_type == HD_VECT) { BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0); } @@ -792,6 +795,7 @@ static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *prev add_v3_v3v3(bezt->vec[0], bezt->vec[1], h); sub_v3_v3v3(bezt->vec[2], bezt->vec[1], h); } +#endif } void BKE_mask_get_handle_point_adjacent(Mask *UNUSED(mask), MaskSpline *spline, MaskSplinePoint *point, @@ -851,85 +855,55 @@ static void enforce_dist_v2_v2fl(float v1[2], const float v2[2], const float dis } } +void BKE_mask_calc_handle_adjacent_length(Mask *mask, MaskSpline *spline, MaskSplinePoint *point) +{ + /* TODO! - make this aspect aware! */ + int length_tot = 0; + float length_average = 0.0f; + + MaskSplinePoint *prev_point, *next_point; + BKE_mask_get_handle_point_adjacent(mask, spline, point, + &prev_point, &next_point); + + if (prev_point) { + length_average += len_v2v2(prev_point->bezt.vec[0], prev_point->bezt.vec[1]); + length_tot++; + } + + if (next_point) { + length_average += len_v2v2(next_point->bezt.vec[2], next_point->bezt.vec[1]); + length_tot++; + } + + if (length_tot) { + length_average /= (float)length_tot; + + enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average); + enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average); + } +} + + /** * \brief Resets auto handles even for non-auto bezier points * * Useful for giving sane defaults. */ -void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplinePoint *point, - const short do_length_match) +void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplinePoint *point) { + /* TODO! - make this aspect aware! */ MaskSplinePoint *prev_point, *next_point; - const char h_back[2] = {point->bezt.h1, point->bezt.h2}; -int i1=999, i2=999; + BKE_mask_get_handle_point_adjacent(mask, spline, point, &prev_point, &next_point); - if (prev_point) i1 = (int)(prev_point - spline->points); - if (next_point) i2 = (int)(next_point - spline->points); - -printf("found points %d %d : %d\n", i1, i2, (int)(point - spline->points)); - point->bezt.h1 = HD_AUTO; point->bezt.h2 = HD_AUTO; mask_calc_point_handle(point, prev_point, next_point); point->bezt.h1 = h_back[0]; point->bezt.h2 = h_back[1]; - mask_calc_point_handle(point, prev_point, next_point); - - /* TODO! - make this aspect aware! */ - /* TODO! - not working right with cyclic curves, need to investigate! */ - if (do_length_match) { - int length_tot = 0; - float length_average = 0.0f; - - if (prev_point) { - length_average += len_v2v2(prev_point->bezt.vec[0], prev_point->bezt.vec[1]); - length_tot++; - } - - if (next_point) { - length_average += len_v2v2(next_point->bezt.vec[2], next_point->bezt.vec[1]); - length_tot++; - } - - if (length_tot) { - length_average /= (float)length_tot; - - enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average); - enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average); - } - } - - mask_calc_point_handle(point, prev_point, next_point); - - // XXX - if ((point->bezt.h1 == HD_ALIGN || point->bezt.h2 == HD_ALIGN) ){ - float vec[2]; - sub_v2_v2(point->bezt.vec[0], point->bezt.vec[1]); - sub_v2_v2(point->bezt.vec[2], point->bezt.vec[1]); - - copy_v2_v2(vec, point->bezt.vec[0]); - point->bezt.vec[0][0] = vec[1]; - point->bezt.vec[0][0] = -vec[0]; - add_v2_v2(point->bezt.vec[0], point->bezt.vec[1]); - - copy_v2_v2(vec, point->bezt.vec[2]); - point->bezt.vec[2][0] = vec[1]; - point->bezt.vec[2][0] = -vec[0]; - add_v2_v2(point->bezt.vec[2], point->bezt.vec[1]); - - copy_v2_v2(vec, point->bezt.vec[2]); - copy_v2_v2(point->bezt.vec[0], vec); - copy_v2_v2(point->bezt.vec[2], point->bezt.vec[0]); - - - - } - - mask_calc_point_handle(point, prev_point, next_point); } void BKE_mask_calc_handles(Mask *mask) diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 661030cb382..5518fedf91a 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1146,6 +1146,10 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask sub_v2_v2(bezt->vec[0], vec); add_v2_v2(bezt->vec[2], vec); + + if (reference_adjacent) { + BKE_mask_calc_handle_adjacent_length(mask, spline, new_point); + } } else { @@ -1196,10 +1200,10 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask add_v2_v2(bezt->vec[0], vec); sub_v2_v2(bezt->vec[2], vec); #else - BKE_mask_calc_handle_point_auto(mask, spline, new_point, TRUE); + BKE_mask_calc_handle_point_auto(mask, spline, new_point); + BKE_mask_calc_handle_adjacent_length(mask, spline, new_point); #endif - } BKE_mask_parent_init(&new_point->parent); @@ -1223,10 +1227,7 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) MaskSplinePoint *new_point_array, *new_point; int point_index = point - spline->points; - /* adding _could_ deselect, for now don't */ -#if 0 toggle_selection_all(mask, SEL_DESELECT); -#endif new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); @@ -1302,10 +1303,7 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) MaskSplinePoint *point; MaskSplinePoint *new_point = NULL, *ref_point = NULL; - /* adding _could_ deselect, for now don't */ -#if 0 toggle_selection_all(mask, SEL_DESELECT); -#endif shape = BKE_mask_shape_active(mask); From 0a917fa1c36f0544867297442f00216bf1021577 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Thu, 17 May 2012 02:31:52 +0000 Subject: [PATCH 048/360] Add new planar tracker features and use the new planar API This commit removes the use of the legacy RegionTracker API from Blender, and replaces it with the new TrackRegion API. This also adds several features to the planar tracker in libmv: - Do a brute-force initialization of tracking similar to "Hybrid" mode in the stable release, but using all floats. This is slower but more accurate. It is still necessary to evaluate if the performance loss is worth it. In particular, this change is necessary to support high bit depth imagery. - Add support for masks over the search window. This is a step towards supporting user-defined tracker masks. The tracker masks will make it easy for users to make a mask for e.g. a ball. - Add Pearson product moment correlation coefficient checking (aka "Correlation" in the UI. This causes tracking failure if the tracked patch is not linearly related to the template. - Add support for warping a few points in addition to the supplied points. This is useful because the tracking code deliberately does not expose the underlying warp representation. Instead, warps are specified in an aparametric way via the correspondences. - Remove the "num_samples_xy" concept and replace it with automatic determination of the number of samples. This makes the API easier for users. - Fix various bugs in the parameterizations. There remains a bug with subpixel precision tracking when in "keyframe" mode; this will get fixed shortly. --- extern/libmv/libmv-capi.cpp | 132 +++--- extern/libmv/libmv-capi.h | 2 - .../libmv/tracking/esm_region_tracker.cc | 2 - extern/libmv/libmv/tracking/track_region.cc | 440 ++++++++++++++++-- extern/libmv/libmv/tracking/track_region.h | 28 +- source/blender/blenkernel/intern/tracking.c | 346 +++++++++----- source/blender/makesdna/DNA_tracking_types.h | 22 +- 7 files changed, 749 insertions(+), 223 deletions(-) diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index ddf69ce5e28..7d3dca5c4e8 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -28,6 +28,10 @@ tracking between which failed */ #undef DUMP_FAILURE +/* define this to generate PNG images with content of search areas + on every itteration of tracking */ +#undef DUMP_ALWAYS + #include "libmv-capi.h" #include "third_party/gflags/gflags/gflags.h" @@ -60,7 +64,7 @@ #include #include -#ifdef DUMP_FAILURE +#if defined(DUMP_FAILURE) || defined (DUMP_ALWAYS) # include #endif @@ -172,7 +176,7 @@ static void floatBufToImage(const float *buf, int width, int height, libmv::Floa } } -#ifdef DUMP_FAILURE +#if defined(DUMP_FAILURE) || defined (DUMP_ALWAYS) void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int color_type, char *file_name) { png_infop info_ptr; @@ -306,16 +310,20 @@ int libmv_regionTrackerTrack(libmv_RegionTracker *libmv_tracker, const float *im floatBufToImage(ima1, width, height, &old_patch); floatBufToImage(ima2, width, height, &new_patch); -#ifndef DUMP_FAILURE +#if !defined(DUMP_FAILURE) && !defined(DUMP_ALWAYS) return region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2); #else { - double sx2 = *x2, sy2 = *y2; + /* double sx2 = *x2, sy2 = *y2; */ int result = region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2); +#if defined(DUMP_ALWAYS) + { +#else if (!result) { +#endif saveImage("old_patch", old_patch, x1, y1); - saveImage("new_patch", new_patch, sx2, sy2); + saveImage("new_patch", new_patch, *x2, *y2); } return result; @@ -334,65 +342,81 @@ void libmv_regionTrackerDestroy(libmv_RegionTracker *libmv_tracker) /* TrackRegion (new planar tracker) */ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, - const float *image1, const float *image2, - int width, int height, - const double *x1, const double *y1, - struct libmv_trackRegionResult *result, - double *x2, double *y2) { - double xx1[4], yy1[4]; - double xx2[4], yy2[4]; + const float *image1, const float *image2, + int width, int height, + const double *x1, const double *y1, + struct libmv_trackRegionResult *result, + double *x2, double *y2) +{ + double xx1[5], yy1[5]; + double xx2[5], yy2[5]; + bool tracking_result = false; - // Convert to doubles for the libmv api. - for (int i = 0; i < 4; ++i) { - xx1[i] = x1[i]; - yy1[i] = y1[i]; - xx2[i] = x2[i]; - yy2[i] = y2[i]; - } + /* Convert to doubles for the libmv api. The four corners and the center. */ + for (int i = 0; i < 5; ++i) { + xx1[i] = x1[i]; + yy1[i] = y1[i]; + xx2[i] = x2[i]; + yy2[i] = y2[i]; + } - libmv::TrackRegionOptions track_region_options; - switch (options->motion_model) { + libmv::TrackRegionOptions track_region_options; + switch (options->motion_model) { #define LIBMV_CONVERT(the_model) \ case libmv::TrackRegionOptions::the_model: \ track_region_options.mode = libmv::TrackRegionOptions::the_model; \ break; - LIBMV_CONVERT(TRANSLATION) - LIBMV_CONVERT(TRANSLATION_ROTATION) - LIBMV_CONVERT(TRANSLATION_SCALE) - LIBMV_CONVERT(TRANSLATION_ROTATION_SCALE) - LIBMV_CONVERT(AFFINE) - LIBMV_CONVERT(HOMOGRAPHY) + LIBMV_CONVERT(TRANSLATION) + LIBMV_CONVERT(TRANSLATION_ROTATION) + LIBMV_CONVERT(TRANSLATION_SCALE) + LIBMV_CONVERT(TRANSLATION_ROTATION_SCALE) + LIBMV_CONVERT(AFFINE) + LIBMV_CONVERT(HOMOGRAPHY) #undef LIBMV_CONVERT - } - track_region_options.num_samples_x = options->num_samples_x; - track_region_options.num_samples_y = options->num_samples_y; - track_region_options.minimum_correlation = options->minimum_correlation; - track_region_options.max_iterations = options->num_iterations; - track_region_options.sigma = options->sigma; - - // Convert from raw float buffers to libmv's FloatImage. - libmv::FloatImage old_patch, new_patch; - floatBufToImage(image1, width, height, &old_patch); - floatBufToImage(image2, width, height, &new_patch); + } - libmv::TrackRegionResult track_region_result; - libmv::TrackRegion(old_patch, new_patch, xx1, yy1, track_region_options, xx2, yy2, &track_region_result); + track_region_options.minimum_correlation = options->minimum_correlation; + track_region_options.max_iterations = options->num_iterations; + track_region_options.sigma = options->sigma; + track_region_options.num_extra_points = 1; + track_region_options.image1_mask = NULL; - // Convert to floats for the blender api. - for (int i = 0; i < 4; ++i) { - x2[i] = xx2[i]; - y2[i] = yy2[i]; - } + /* Convert from raw float buffers to libmv's FloatImage. */ + libmv::FloatImage old_patch, new_patch; + floatBufToImage(image1, width, height, &old_patch); + floatBufToImage(image2, width, height, &new_patch); - // TODO(keir): Update the termination string with failure details. - if (track_region_result.termination == libmv::TrackRegionResult::PARAMETER_TOLERANCE || - track_region_result.termination == libmv::TrackRegionResult::FUNCTION_TOLERANCE || - track_region_result.termination == libmv::TrackRegionResult::GRADIENT_TOLERANCE || - track_region_result.termination == libmv::TrackRegionResult::NO_CONVERGENCE || - track_region_result.termination == libmv::TrackRegionResult::INSUFFICIENT_CORRELATION) { - return true; - } - return false; + libmv::TrackRegionResult track_region_result; + libmv::TrackRegion(old_patch, new_patch, xx1, yy1, track_region_options, xx2, yy2, &track_region_result); + + /* Convert to floats for the blender api. */ + for (int i = 0; i < 5; ++i) { + x2[i] = xx2[i]; + y2[i] = yy2[i]; + } + + /* TODO(keir): Update the termination string with failure details. */ + if (track_region_result.termination == libmv::TrackRegionResult::PARAMETER_TOLERANCE || + track_region_result.termination == libmv::TrackRegionResult::FUNCTION_TOLERANCE || + track_region_result.termination == libmv::TrackRegionResult::GRADIENT_TOLERANCE || + track_region_result.termination == libmv::TrackRegionResult::NO_CONVERGENCE || + track_region_result.termination == libmv::TrackRegionResult::INSUFFICIENT_CORRELATION) + { + tracking_result = true; + } + +#if defined(DUMP_FAILURE) || defined(DUMP_ALWAYS) +#if defined(DUMP_ALWAYS) + { +#else + if (!tracking_result) { +#endif + saveImage("old_patch", old_patch, x1[4], y1[4]); + saveImage("new_patch", new_patch, x2[4], y2[4]); + } +#endif + + return tracking_result; } /* ************ Tracks ************ */ diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index d7d132d4f21..d3f02f99e51 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -53,8 +53,6 @@ void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker); /* TrackRegion (new planar tracker) */ struct libmv_trackRegionOptions { int motion_model; - int num_samples_x; - int num_samples_y; int num_iterations; double minimum_correlation; double sigma; diff --git a/extern/libmv/libmv/tracking/esm_region_tracker.cc b/extern/libmv/libmv/tracking/esm_region_tracker.cc index e6d0b9830f4..a8dc46d439b 100644 --- a/extern/libmv/libmv/tracking/esm_region_tracker.cc +++ b/extern/libmv/libmv/tracking/esm_region_tracker.cc @@ -98,8 +98,6 @@ bool EsmRegionTracker::Track(const FloatImage &image1, TrackRegionOptions options; options.mode = TrackRegionOptions::TRANSLATION; - options.num_samples_x = 2 * half_window_size + 1; - options.num_samples_y = 2 * half_window_size + 1; options.max_iterations = 20; options.sigma = sigma; options.use_esm = true; diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index 0bb8ae221b1..0dac56aeff7 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -38,6 +38,19 @@ namespace libmv { +TrackRegionOptions::TrackRegionOptions() + : mode(TRANSLATION), + minimum_correlation(0), + max_iterations(20), + use_esm(true), + use_brute_initialization(true), + sigma(0.9), + num_extra_points(0), + image1_mask(NULL) { +} + +namespace { + // TODO(keir): Consider adding padding. template bool InBounds(const FloatImage &image, @@ -161,22 +174,26 @@ class WarpCostFunctor { const FloatImage &image_and_gradient1, const FloatImage &image_and_gradient2, const Mat3 &canonical_to_image1, + int num_samples_x, + int num_samples_y, const Warp &warp) : options_(options), image_and_gradient1_(image_and_gradient1), image_and_gradient2_(image_and_gradient2), canonical_to_image1_(canonical_to_image1), + num_samples_x_(num_samples_x), + num_samples_y_(num_samples_y), warp_(warp) {} - template - bool operator()(const T *warp_parameters, T *residuals) const { - for (int i = 0; i < Warp::NUM_PARAMETERS; ++i) { - VLOG(2) << "warp_parameters[" << i << "]: " << warp_parameters[i]; - } + template + bool operator()(const T *warp_parameters, T *residuals) const { + for (int i = 0; i < Warp::NUM_PARAMETERS; ++i) { + VLOG(2) << "warp_parameters[" << i << "]: " << warp_parameters[i]; + } - int cursor = 0; - for (int r = 0; r < options_.num_samples_y; ++r) { - for (int c = 0; c < options_.num_samples_x; ++c) { + int cursor = 0; + for (int r = 0; r < num_samples_y_; ++r) { + for (int c = 0; c < num_samples_x_; ++c) { // Compute the location of the source pixel (via homography). Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1); image1_position /= image1_position(2); @@ -223,17 +240,102 @@ class WarpCostFunctor { } // The difference is the error. + T error = src_sample - dst_sample; + + // Weight the error by the mask, if one is present. + if (options_.image1_mask != NULL) { + error *= T(AutoDiff::Sample(*options_.image1_mask, + image1_position[0], + image1_position[1])); + } residuals[cursor++] = src_sample - dst_sample; } } return true; } + // TODO(keir): Consider also computing the cost here. + double PearsonProductMomentCorrelationCoefficient( + const double *warp_parameters) const { + for (int i = 0; i < Warp::NUM_PARAMETERS; ++i) { + VLOG(2) << "Correlation warp_parameters[" << i << "]: " + << warp_parameters[i]; + } + + // The single-pass PMCC computation is somewhat numerically unstable, but + // it's sufficient for the tracker. + double sX = 0, sY = 0, sXX = 0, sYY = 0, sXY = 0; + + // Due to masking, it's important to account for fractional samples. + // Samples with a 50% mask get counted as a half sample. + double num_samples = 0; + + for (int r = 0; r < num_samples_y_; ++r) { + for (int c = 0; c < num_samples_x_; ++c) { + // Compute the location of the source pixel (via homography). + // TODO(keir): Cache these projections. + Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1); + image1_position /= image1_position(2); + + // Compute the location of the destination pixel. + double image2_position[2]; + warp_.Forward(warp_parameters, + image1_position[0], + image1_position[1], + &image2_position[0], + &image2_position[1]); + + double x = AutoDiff::Sample(image_and_gradient2_, + image2_position[0], + image2_position[1]); + + double y = AutoDiff::Sample(image_and_gradient1_, + image1_position[0], + image1_position[1]); + + // Weight the signals by the mask, if one is present. + if (options_.image1_mask != NULL) { + double mask_value = AutoDiff::Sample(*options_.image1_mask, + image1_position[0], + image1_position[1]); + x *= mask_value; + y *= mask_value; + num_samples += mask_value; + } else { + num_samples++; + } + sX += x; + sY += y; + sXX += x*x; + sYY += y*y; + sXY += x*y; + } + } + // Normalize. + sX /= num_samples; + sY /= num_samples; + sXX /= num_samples; + sYY /= num_samples; + sXY /= num_samples; + + double var_x = sXX - sX*sX; + double var_y = sYY - sY*sY; + double covariance_xy = sXY - sX*sY; + + double correlation = covariance_xy / sqrt(var_x * var_y); + LG << "Covariance xy: " << covariance_xy + << ", var 1: " << var_x << ", var 2: " << var_y + << ", correlation: " << correlation; + return correlation; + } + private: const TrackRegionOptions &options_; const FloatImage &image_and_gradient1_; const FloatImage &image_and_gradient2_; const Mat3 &canonical_to_image1_; + int num_samples_x_; + int num_samples_y_; const Warp &warp_; }; @@ -260,9 +362,7 @@ Mat3 ComputeCanonicalHomography(const double *x1, class Quad { public: - Quad(const double *x, const double *y) - : x_(x), y_(y) { - + Quad(const double *x, const double *y) : x_(x), y_(y) { // Compute the centroid and store it. centroid_ = Vec2(0.0, 0.0); for (int i = 0; i < 4; ++i) { @@ -298,7 +398,7 @@ class Quad { struct TranslationWarp { TranslationWarp(const double *x1, const double *y1, const double *x2, const double *y2) { - Vec2 t = Quad(x1, y1).Centroid() - Quad(x2, y2).Centroid(); + Vec2 t = Quad(x2, y2).Centroid() - Quad(x1, y1).Centroid() ; parameters[0] = t[0]; parameters[1] = t[1]; } @@ -310,6 +410,13 @@ struct TranslationWarp { *y2 = y1 + warp_parameters[1]; } + template + void Backward(const T *warp_parameters, + const T &x2, const T& y2, T *x1, T* y1) const { + *x1 = x2 - warp_parameters[0]; + *y1 = y2 - warp_parameters[1]; + } + // Translation x, translation y. enum { NUM_PARAMETERS = 2 }; double parameters[NUM_PARAMETERS]; @@ -322,7 +429,7 @@ struct TranslationScaleWarp { Quad q2(x2, y2); // The difference in centroids is the best guess for translation. - Vec2 t = q1.Centroid() - q2.Centroid(); + Vec2 t = q2.Centroid() - q1.Centroid(); parameters[0] = t[0]; parameters[1] = t[1]; @@ -354,6 +461,12 @@ struct TranslationScaleWarp { *y2 = y1_scaled + warp_parameters[1]; } + template + void Backward(const T *warp_parameters, + const T &x2, const T& y2, T *x1, T* y1) const { + // XXX + } + // Translation x, translation y, scale. enum { NUM_PARAMETERS = 3 }; double parameters[NUM_PARAMETERS]; @@ -375,7 +488,7 @@ struct TranslationRotationWarp { Quad q2(x2, y2); // The difference in centroids is the best guess for translation. - Vec2 t = q1.Centroid() - q2.Centroid(); + Vec2 t = q2.Centroid() - q1.Centroid(); parameters[0] = t[0]; parameters[1] = t[1]; @@ -387,6 +500,10 @@ struct TranslationRotationWarp { } Mat2 R = OrthogonalProcrustes(correlation_matrix); parameters[2] = acos(R(0, 0)); + + std::cout << "correlation_matrix:\n" << correlation_matrix << "\n"; + std::cout << "R:\n" << R << "\n"; + std::cout << "theta:" << parameters[2] << "\n"; } // The strange way of parameterizing the translation and rotation is to make @@ -422,6 +539,12 @@ struct TranslationRotationWarp { *y2 = y1_rotated + warp_parameters[1]; } + template + void Backward(const T *warp_parameters, + const T &x2, const T& y2, T *x1, T* y1) const { + // XXX + } + // Translation x, translation y, rotation about the center of Q1 degrees. enum { NUM_PARAMETERS = 3 }; double parameters[NUM_PARAMETERS]; @@ -436,7 +559,7 @@ struct TranslationRotationScaleWarp { Quad q2(x2, y2); // The difference in centroids is the best guess for translation. - Vec2 t = q1.Centroid() - q2.Centroid(); + Vec2 t = q2.Centroid() - q1.Centroid(); parameters[0] = t[0]; parameters[1] = t[1]; @@ -449,8 +572,11 @@ struct TranslationRotationScaleWarp { correlation_matrix += q1.CornerRelativeToCentroid(i) * q2.CornerRelativeToCentroid(i).transpose(); } + std::cout << "correlation_matrix:\n" << correlation_matrix << "\n"; Mat2 R = OrthogonalProcrustes(correlation_matrix); + std::cout << "R:\n" << R << "\n"; parameters[3] = acos(R(0, 0)); + std::cout << "theta:" << parameters[3] << "\n"; } // The strange way of parameterizing the translation and rotation is to make @@ -471,7 +597,7 @@ struct TranslationRotationScaleWarp { const T y1_origin = y1 - q1.Centroid()(1); // Rotate about the origin (i.e. centroid of Q1). - const T theta = warp_parameters[2]; + const T theta = warp_parameters[3]; const T costheta = cos(theta); const T sintheta = sin(theta); const T x1_origin_rotated = costheta * x1_origin - sintheta * y1_origin; @@ -491,6 +617,12 @@ struct TranslationRotationScaleWarp { *y2 = y1_rotated_scaled + warp_parameters[1]; } + template + void Backward(const T *warp_parameters, + const T &x2, const T& y2, T *x1, T* y1) const { + // XXX + } + // Translation x, translation y, rotation about the center of Q1 degrees, // scale. enum { NUM_PARAMETERS = 4 }; @@ -542,10 +674,216 @@ struct HomographyWarp { *y2 = yy2 / zz2; } + template + void Backward(const T *warp_parameters, + const T &x2, const T& y2, T *x1, T* y1) const { + // XXX + } + enum { NUM_PARAMETERS = 8 }; double parameters[NUM_PARAMETERS]; }; +// Determine the number of samples to use for x and y. Quad winding goes: +// +// 0 1 +// 3 2 +// +// The idea is to take the maximum x or y distance. This may be oversampling. +// TODO(keir): Investigate the various choices; perhaps average is better? +void PickSampling(const double *x1, const double *y1, + const double *x2, const double *y2, + int *num_samples_x, int *num_samples_y) { + Vec2 a0(x1[0], y1[0]); + Vec2 a1(x1[1], y1[1]); + Vec2 a2(x1[2], y1[2]); + Vec2 a3(x1[3], y1[3]); + + Vec2 b0(x1[0], y1[0]); + Vec2 b1(x1[1], y1[1]); + Vec2 b2(x1[2], y1[2]); + Vec2 b3(x1[3], y1[3]); + + double x_dimensions[4] = { + (a1 - a0).norm(), + (a3 - a2).norm(), + (b1 - b0).norm(), + (b3 - b2).norm() + }; + + double y_dimensions[4] = { + (a3 - a0).norm(), + (a1 - a2).norm(), + (b3 - b0).norm(), + (b1 - b2).norm() + }; + const double kScaleFactor = 1.0; + *num_samples_x = static_cast( + kScaleFactor * *std::max_element(x_dimensions, x_dimensions + 4)); + *num_samples_y = static_cast( + kScaleFactor * *std::max_element(y_dimensions, y_dimensions + 4)); + LG << "Automatic num_samples_x: " << *num_samples_x + << ", num_samples_y: " << *num_samples_y; +} + +bool SearchAreaTooBigForDescent(const FloatImage &image2, + const double *x2, const double *y2) { + // TODO(keir): Check the bounds and enable only when it makes sense. + return true; +} + +bool PointOnRightHalfPlane(const Vec2 &a, const Vec2 &b, double x, double y) { + Vec2 ba = b - a; + return ((Vec2(x, y) - b).transpose() * Vec2(-ba.y(), ba.x())) > 0; +} + +// Determine if a point is in a quad. The quad is arranged as: +// +// +--> x +// | +// | 0 1 +// v 3 2 +// y +// +// The idea is to take the maximum x or y distance. This may be oversampling. +// TODO(keir): Investigate the various choices; perhaps average is better? +bool PointInQuad(const double *xs, const double *ys, double x, double y) { + Vec2 a0(xs[0], ys[0]); + Vec2 a1(xs[1], ys[1]); + Vec2 a2(xs[2], ys[2]); + Vec2 a3(xs[3], ys[3]); + + return PointOnRightHalfPlane(a0, a1, x, y) && + PointOnRightHalfPlane(a1, a2, x, y) && + PointOnRightHalfPlane(a2, a3, x, y) && + PointOnRightHalfPlane(a3, a0, x, y); +} + +typedef Eigen::Array FloatArray; + +// This creates a pattern in the frame of image2, from the pixel is image1, +// based on the initial guess represented by the two quads x1, y1, and x2, y2. +template +void CreateBrutePattern(const double *x1, const double *y1, + const double *x2, const double *y2, + const FloatImage &image1, + const FloatImage *image1_mask, + FloatArray *pattern, + FloatArray *mask, + int *origin_x, + int *origin_y) { + // Get integer bounding box of quad2 in image2. + int min_x = static_cast(floor(*std::min_element(x2, x2 + 4))); + int min_y = static_cast(floor(*std::min_element(y2, y2 + 4))); + int max_x = static_cast(ceil (*std::max_element(x2, x2 + 4))); + int max_y = static_cast(ceil (*std::max_element(y2, y2 + 4))); + + int w = max_x - min_x; + int h = max_y - min_y; + + pattern->resize(h, w); + mask->resize(h, w); + + Warp inverse_warp(x2, y2, x1, y1); + + // r,c are in the coordinate frame of image2. + for (int r = min_y; r < max_y; ++r) { + for (int c = min_x; c < max_x; ++c) { + // i and j are in the coordinate frame of the pattern in image2. + int i = r - min_y; + int j = c - min_x; + + double dst_x = c; + double dst_y = r; + double src_x; + double src_y; + inverse_warp.Forward(inverse_warp.parameters, + dst_x, dst_y, + &src_x, &src_y); + + if (PointInQuad(x1, y1, src_x, src_y)) { + (*pattern)(i, j) = SampleLinear(image1, src_y, src_x); + (*mask)(i, j) = 1.0; + if (image1_mask) { + (*mask)(i, j) = SampleLinear(*image1_mask, src_y, src_x);; + } + } else { + (*pattern)(i, j) = 0.0; + (*mask)(i, j) = 0.0; + } + } + } + *origin_x = min_x; + *origin_y = min_y; +} + +template +void BruteTranslationOnlyInitialize(const FloatImage &image1, + const FloatImage *image1_mask, + const FloatImage &image2, + const int num_extra_points, + const double *x1, const double *y1, + double *x2, double *y2) { + // Create the pattern to match in the space of image2, assuming our inital + // guess isn't too far from the template in image1. If there is no image1 + // mask, then the resulting mask is binary. + FloatArray pattern; + FloatArray mask; + int origin_x = -1, origin_y = -1; + CreateBrutePattern(x1, y1, x2, y2, image1, image1_mask, + &pattern, &mask, &origin_x, &origin_y); + + // Use Eigen on the images via maps for strong vectorization. + Map search(image2.Data(), image2.Height(), image2.Width()); + + // Try all possible locations inside the search area. Yes, everywhere. + // + // TODO(keir): There are a number of possible optimizations here. One choice + // is to make a grid and only try one out of every N possible samples. + // + // Another, slightly more clever idea, is to compute some sort of spatial + // frequency distribution of the pattern patch. If the spatial resolution is + // high (e.g. a grating pattern or fine lines) then checking every possible + // translation is necessary, since a 1-pixel shift may induce a massive + // change in the cost function. If the image is a blob or splotch with blurry + // edges, then fewer samples are necessary since a few pixels offset won't + // change the cost function much. + double best_sad = std::numeric_limits::max(); + int best_r = -1; + int best_c = -1; + int w = pattern.cols(); + int h = pattern.rows(); + for (int r = 0; r < (image2.Height() - h); ++r) { + for (int c = 0; c < (image2.Width() - w); ++c) { + // Compute the weighted sum of absolute differences, Eigen style. + double sad = (mask * (pattern - search.block(r, c, h, w))).abs().sum(); + if (sad < best_sad) { + best_r = r; + best_c = c; + best_sad = sad; + } + } + } + CHECK_NE(best_r, -1); + CHECK_NE(best_c, -1); + + LG << "Brute force translation found a shift. " + << "best_c: " << best_c << ", best_r: " << best_r << ", " + << "origin_x: " << origin_x << ", origin_y: " << origin_y << ", " + << "dc: " << (best_c - origin_x) << ", " + << "dr: " << (best_r - origin_y) + << ", tried " << ((image2.Height() - h) * (image2.Width() - w)) + << " shifts."; + + // Apply the shift. + for (int i = 0; i < 4 + num_extra_points; ++i) { + x2[i] += best_c - origin_x; + y2[i] += best_r - origin_y; + } +} + +} // namespace + template void TemplatedTrackRegion(const FloatImage &image1, const FloatImage &image2, @@ -553,6 +891,12 @@ void TemplatedTrackRegion(const FloatImage &image1, const TrackRegionOptions &options, double *x2, double *y2, TrackRegionResult *result) { + for (int i = 0; i < 4; ++i) { + LG << "P" << i << ": (" << x1[i] << ", " << y1[i] << "); guess (" + << x2[i] << ", " << y2[i] << "); (dx, dy): (" << (x2[i] - x1[i]) << ", " + << (y2[i] - y1[i]) << ")."; + } + // Bail early if the points are already outside. if (!AllInBounds(image1, x1, y1)) { result->termination = TrackRegionResult::SOURCE_OUT_OF_BOUNDS; @@ -564,6 +908,19 @@ void TemplatedTrackRegion(const FloatImage &image1, } // TODO(keir): Check quads to ensure there is some area. + // Prepare the initial warp parameters from the four correspondences. + Warp warp(x1, y1, x2, y2); + + // Decide how many samples to use in the x and y dimensions. + int num_samples_x; + int num_samples_y; + PickSampling(x1, y1, x2, y2, &num_samples_x, &num_samples_y); + + // Compute the warp from rectangular coordinates. + Mat3 canonical_homography = ComputeCanonicalHomography(x1, y1, + num_samples_x, + num_samples_y); + // Prepare the image and gradient. Array3Df image_and_gradient1; Array3Df image_and_gradient2; @@ -572,8 +929,16 @@ void TemplatedTrackRegion(const FloatImage &image1, BlurredImageAndDerivativesChannels(image2, options.sigma, &image_and_gradient2); - // Prepare the initial warp parameters from the four correspondences. - Warp warp(x1, y1, x2, y2); + // Possibly do a brute-force translation-only initialization. + if (SearchAreaTooBigForDescent(image2, x2, y2) && + options.use_brute_initialization) { + LG << "Running brute initialization..."; + BruteTranslationOnlyInitialize(image_and_gradient1, + options.image1_mask, + image2, + options.num_extra_points, + x1, y1, x2, y2); + } ceres::Solver::Options solver_options; solver_options.linear_solver_type = ceres::DENSE_QR; @@ -591,17 +956,14 @@ void TemplatedTrackRegion(const FloatImage &image1, BoundaryCheckingCallback callback(image2, warp, x1, y1); solver_options.callbacks.push_back(&callback); - // Compute the warp from rectangular coordinates. - Mat3 canonical_homography = ComputeCanonicalHomography(x1, y1, - options.num_samples_x, - options.num_samples_y); - // Construct the warp cost function. AutoDiffCostFunction takes ownership. - WarpCostFunctor *cost_function = + WarpCostFunctor *warp_cost_function = new WarpCostFunctor(options, image_and_gradient1, image_and_gradient2, canonical_homography, + num_samples_x, + num_samples_y, warp); // Construct the problem with a single residual. @@ -612,8 +974,8 @@ void TemplatedTrackRegion(const FloatImage &image1, new ceres::AutoDiffCostFunction< WarpCostFunctor, ceres::DYNAMIC, - Warp::NUM_PARAMETERS>(cost_function, - options.num_samples_x * options.num_samples_y), + Warp::NUM_PARAMETERS>(warp_cost_function, + num_samples_x * num_samples_y), NULL, warp.parameters); @@ -624,11 +986,17 @@ void TemplatedTrackRegion(const FloatImage &image1, // Update the four points with the found solution; if the solver failed, then // the warp parameters are the identity (so ignore failure). - for (int i = 0; i < 4; ++i) { + // + // Also warp any extra points on the end of the array. + for (int i = 0; i < 4 + options.num_extra_points; ++i) { warp.Forward(warp.parameters, x1[i], y1[i], x2 + i, y2 + i); + LG << "Warped point " << i << ": (" << x1[i] << ", " << y1[i] << ") -> (" + << x2[i] << ", " << y2[i] << "); (dx, dy): (" << (x2[i] - x1[i]) << ", " + << (y2[i] - y1[i]) << ")."; } // TODO(keir): Update the result statistics. + // TODO(keir): Add a normalize-cross-correlation variant. CHECK_NE(summary.termination_type, ceres::USER_ABORT) << "Libmv bug."; if (summary.termination_type == ceres::USER_ABORT) { @@ -640,12 +1008,26 @@ void TemplatedTrackRegion(const FloatImage &image1, result->termination = TrackRegionResult::termination_enum; \ return; \ } + + // Avoid computing correlation for tracking failures. + HANDLE_TERMINATION(DID_NOT_RUN); + HANDLE_TERMINATION(NUMERICAL_FAILURE); + + // Otherwise, run a final correlation check. + if (options.minimum_correlation > 0.0) { + result->correlation = warp_cost_function-> + PearsonProductMomentCorrelationCoefficient(warp.parameters); + if (result->correlation < options.minimum_correlation) { + LG << "Failing with insufficient correlation."; + result->termination = TrackRegionResult::INSUFFICIENT_CORRELATION; + return; + } + } + HANDLE_TERMINATION(PARAMETER_TOLERANCE); HANDLE_TERMINATION(FUNCTION_TOLERANCE); HANDLE_TERMINATION(GRADIENT_TOLERANCE); HANDLE_TERMINATION(NO_CONVERGENCE); - HANDLE_TERMINATION(DID_NOT_RUN); - HANDLE_TERMINATION(NUMERICAL_FAILURE); #undef HANDLE_TERMINATION }; diff --git a/extern/libmv/libmv/tracking/track_region.h b/extern/libmv/libmv/tracking/track_region.h index 7c937c04794..1a1346f544f 100644 --- a/extern/libmv/libmv/tracking/track_region.h +++ b/extern/libmv/libmv/tracking/track_region.h @@ -32,6 +32,8 @@ namespace libmv { struct TrackRegionOptions { + TrackRegionOptions(); + enum Mode { TRANSLATION, TRANSLATION_ROTATION, @@ -42,9 +44,6 @@ struct TrackRegionOptions { }; Mode mode; - int num_samples_x; - int num_samples_y; - double minimum_correlation; int max_iterations; @@ -52,13 +51,28 @@ struct TrackRegionOptions { // convergence speed at the cost of more per-iteration work. bool use_esm; + // If true, apply a brute-force translation-only search before attempting the + // full search. This is not enabled if the destination image ("image2") is + // too small; in that case eithen the basin of attraction is close enough + // that the nearby minima is correct, or the search area is too small. + bool use_brute_initialization; + double sigma; + + // Extra points that should get transformed by the warp. This is useful + // because the actual warp parameters are not exposed. + int num_extra_points; + + // If non-null, this is used as the pattern mask. It should match the size of + // image1, even though only values inside the image1 quad are examined. The + // values must be in the range 0.0 to 0.1. + FloatImage *image1_mask; }; struct TrackRegionResult { enum Termination { - // Ceres termination types, duplicated. - PARAMETER_TOLERANCE = 0, + // Ceres termination types, duplicated; though, not the int values. + PARAMETER_TOLERANCE, FUNCTION_TOLERANCE, GRADIENT_TOLERANCE, NO_CONVERGENCE, @@ -70,6 +84,7 @@ struct TrackRegionResult { DESTINATION_OUT_OF_BOUNDS, FELL_OUT_OF_BOUNDS, INSUFFICIENT_CORRELATION, + CONFIGURATION_ERROR, }; Termination termination; @@ -77,6 +92,7 @@ struct TrackRegionResult { double correlation; // Final parameters? + bool used_brute_translation_initialization; }; // Always needs 4 correspondences. @@ -87,8 +103,6 @@ void TrackRegion(const FloatImage &image1, double *x2, double *y2, TrackRegionResult *result); -// TODO(keir): May need a "samplewarp" function. - } // namespace libmv #endif // LIBMV_TRACKING_TRACK_REGION_H_ diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index abb45608822..3bf5c735cb7 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -20,6 +20,7 @@ * * Contributor(s): Blender Foundation, * Sergey Sharybin + * Keir Mierle * * ***** END GPL LICENSE BLOCK ***** */ @@ -943,10 +944,14 @@ static void tracks_map_free(TracksMap *map, void (*customdata_free) (void *custo typedef struct TrackContext { #ifdef WITH_LIBMV - float keyframed_pos[2]; + /* the reference marker and cutout search area */ + MovieTrackingMarker marker; - struct libmv_RegionTracker *region_tracker; - float *patch; /* keyframed patch */ + /* keyframed patch. This is the search area */ + float *search_area; + int search_area_height; + int search_area_width; + int framenr; #else int pad; #endif @@ -1011,59 +1016,7 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u if ((marker->flag & MARKER_DISABLED) == 0) { TrackContext track_context; - memset(&track_context, 0, sizeof(TrackContext)); - -#ifdef WITH_LIBMV - { - float search_size_x, search_size_y; - float pattern_size_x, pattern_size_y; - float pat_min[2], pat_max[2], patx, paty; - float search_to_pattern_ratio, log2_search_to_pattern_ratio; - int wndx, wndy, half_wnd, max_pyramid_levels, level; - - struct libmv_RegionTracker *region_tracker; - - /* XXX: use boundbox of marker's pattern for now - * no idea how it should behave with non-affine tracking */ - BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - - patx = (int)((pat_max[0] - pat_min[0]) * width); - paty = (int)((pat_max[1] - pat_min[1]) * height); - wndx = (int)patx / 2; - wndy = (int)paty / 2; - half_wnd = MAX2(wndx, wndy); - - search_size_x = (track->search_max[0] - track->search_min[0]) * width; - search_size_y = (track->search_max[1] - track->search_min[1]) * height; - pattern_size_x = (pat_max[0] - pat_min[0]) * width; - pattern_size_y = (pat_max[1] - pat_min[1]) * height; - - /* compute the maximum pyramid size */ - search_to_pattern_ratio = MIN2(search_size_x, search_size_y) / MAX2(pattern_size_x, pattern_size_y); - log2_search_to_pattern_ratio = log(floor(search_to_pattern_ratio)) / M_LN2; - max_pyramid_levels = floor(log2_search_to_pattern_ratio + 1); - - /* try to accommodate the user's choice of pyramid level in a way - * that doesn't cause the coarsest pyramid pattern to be larger - * than the search size */ - level = MIN2(track->pyramid_levels, max_pyramid_levels); - - if (track->tracker == TRACKER_KLT) { - region_tracker = libmv_pyramidRegionTrackerNew(100, level, half_wnd, - track->minimum_correlation); - } - else if (track->tracker == TRACKER_HYBRID) { - region_tracker = libmv_hybridRegionTrackerNew(100, half_wnd, track->minimum_correlation); - } - else if (track->tracker == TRACKER_SAD) { - region_tracker = libmv_bruteRegionTrackerNew(MAX2(wndx, wndy), track->minimum_correlation); - } - - track_context.region_tracker = region_tracker; - } -#endif - tracks_map_insert(context->tracks_map, track, &track_context); } } @@ -1099,11 +1052,8 @@ static void track_context_free(void *customdata) TrackContext *track_context = (TrackContext *)customdata; #if WITH_LIBMV - if (track_context->region_tracker) - libmv_regionTrackerDestroy(track_context->region_tracker); - - if (track_context->patch) - MEM_freeN(track_context->patch); + if (track_context->search_area) + MEM_freeN(track_context->search_area); #else (void) track_context; @@ -1370,50 +1320,172 @@ ImBuf *BKE_tracking_track_mask_get(MovieTracking *tracking, MovieTrackingTrack * /* Convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */ static void float_rgba_to_gray(const float *rgba, float *gray, int num_pixels, float weight_red, float weight_green, float weight_blue) { int i; - for (i = 0; i < num_pixels; ++i) { + + for (i = 0; i < num_pixels; i++) { const float *pixel = rgba + 4 * i; + gray[i] = weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]; } } static void uint8_rgba_to_float_gray(const unsigned char *rgba, float *gray, int num_pixels, float weight_red, float weight_green, float weight_blue) { int i; - for (i = 0; i < num_pixels; ++i) { + + for (i = 0; i < num_pixels; i++) { const unsigned char *pixel = rgba + i * 4; + *gray++ = (weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]) / 255.0f; } } -static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int *width_r, int *height_r, float pos[2], int origin[2]) +static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, int *width_r, int *height_r) { - ImBuf *tmpibuf; + ImBuf *searchibuf; float *gray_pixels; - int x, y, width, height; + int width, height; + /* ignored */ + float pos[2]; + int origin[2]; - width = (track->search_max[0] - track->search_min[0]) * ibuf->x; - height = (track->search_max[1] - track->search_min[1]) * ibuf->y; + searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin); + disable_imbuf_channels(searchibuf, track, FALSE /* don't grayscale */); - tmpibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin); - disable_imbuf_channels(tmpibuf, track, FALSE /* don't grayscale */); + width = searchibuf->x; + height = searchibuf->y; - *width_r = width; - *height_r = height; + *width_r = searchibuf->x; + *height_r = searchibuf->y; gray_pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf"); - if (tmpibuf->rect_float) { - float_rgba_to_gray(tmpibuf->rect_float, gray_pixels, height * width, 0.2126f, 0.7152f, 0.0722f); + if (searchibuf->rect_float) { + float_rgba_to_gray(searchibuf->rect_float, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f); } else { - uint8_rgba_to_float_gray((unsigned char *)tmpibuf->rect, gray_pixels, height * width, 0.2126f, 0.7152f, 0.0722f); + uint8_rgba_to_float_gray((unsigned char *)searchibuf->rect, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f); } - IMB_freeImBuf(tmpibuf); + IMB_freeImBuf(searchibuf); return gray_pixels; } +/* Three coordinate frames: Frame, Search, and Marker + * Two units: Pixels, Unified + * Notation: {coordinate frame}_{unit}; for example, "search_pixel" are search + * window relative coordinates in pixels, and "frame_unified" are unified 0..1 + * coordinates relative to the entire frame. + */ +static void unified_to_pixel(const ImBuf *ibuf, const float unified_coords[2], float pixel_coords[2]) +{ + pixel_coords[0] = unified_coords[0] * ibuf->x; + pixel_coords[1] = unified_coords[1] * ibuf->y; +} + +static void pixel_to_unified(const ImBuf *ibuf, const float pixel_coords[2], float unified_coords[2]) +{ + unified_coords[0] = pixel_coords[0] / ibuf->x; + unified_coords[1] = pixel_coords[1] / ibuf->y; +} + +static void marker_to_frame_unified(const MovieTrackingMarker *marker, const float marker_unified_coords[2], float frame_unified_coords[2]) +{ + frame_unified_coords[0] = marker_unified_coords[0] + marker->pos[0]; + frame_unified_coords[1] = marker_unified_coords[1] + marker->pos[1]; +} + +static void marker_unified_to_frame_pixel_coordinates(const ImBuf *ibuf, const MovieTrackingMarker *marker, + const float marker_unified_coords[2], float frame_pixel_coords[2]) +{ + marker_to_frame_unified(marker, marker_unified_coords, frame_pixel_coords); + unified_to_pixel(ibuf, frame_pixel_coords, frame_pixel_coords); +} + +static void get_search_origin_frame_pixel(const ImBuf *ibuf, const MovieTrackingTrack *track, const MovieTrackingMarker *marker, float frame_pixel[2]) +{ + /* Get the lower left coordinate of the search window and snap to pixel coordinates */ + marker_unified_to_frame_pixel_coordinates(ibuf, marker, track->search_min, frame_pixel); + frame_pixel[0] = (int)frame_pixel[0]; + frame_pixel[1] = (int)frame_pixel[1]; +} + +static void marker_unified_to_search_pixel(const ImBuf *ibuf, const MovieTrackingTrack *track, const MovieTrackingMarker *marker, + const float marker_unified[2], float search_pixel[2]) +{ + float frame_pixel[2]; + float search_origin_frame_pixel[2]; + marker_unified_to_frame_pixel_coordinates(ibuf, marker, marker_unified, frame_pixel); + get_search_origin_frame_pixel(ibuf, track, marker, search_origin_frame_pixel); + sub_v2_v2v2(search_pixel, frame_pixel, search_origin_frame_pixel); +} + +static void search_pixel_to_marker_unified(const ImBuf *ibuf, const MovieTrackingTrack *track, const MovieTrackingMarker *marker, + const float search_pixel[2], float marker_unified[2]) +{ + float frame_unified[2]; + float search_origin_frame_pixel[2]; + get_search_origin_frame_pixel(ibuf, track, marker, search_origin_frame_pixel); + add_v2_v2v2(frame_unified, search_pixel, search_origin_frame_pixel); + pixel_to_unified(ibuf, frame_unified, frame_unified); + sub_v2_v2v2(marker_unified, frame_unified, marker->pos /* marker pos is in frame unified */); +} + +/* Each marker has 5 coordinates associated with it that get warped with + * tracking: the four corners ("pattern_corners"), and the cernter ("pos"). + * This function puts those 5 points into the appropriate frame for tracking + * (the "search" coordinate frame). + */ +static void get_marker_coords_for_tracking(const ImBuf *ibuf, const MovieTrackingTrack *track, const MovieTrackingMarker *marker, + double search_pixel_x[5], double search_pixel_y[5]) { + int i; + float unified_coords[2]; + float pixel_coords[2]; + + /* Convert the corners into search space coordinates. */ + for (i = 0; i < 4; ++i) { + marker_unified_to_search_pixel(ibuf, track, marker, marker->pattern_corners[i], pixel_coords); + search_pixel_x[i] = pixel_coords[0]; + search_pixel_y[i] = pixel_coords[1]; + } + /* Convert the center position (aka "pos"); this is the origin */ + unified_coords[0] = 0.0; + unified_coords[1] = 0.0; + marker_unified_to_search_pixel(ibuf, track, marker, unified_coords, pixel_coords); + search_pixel_x[4] = pixel_coords[0]; + search_pixel_y[4] = pixel_coords[1]; +} + +/* Inverse of above. */ +static void set_marker_coords_from_tracking(const ImBuf *ibuf, const MovieTrackingTrack *track, MovieTrackingMarker *marker, + const double search_pixel_x[5], const double search_pixel_y[5]) +{ + int i; + float marker_unified[2]; + float search_pixel[2]; + + /* Convert the corners into search space coordinates. */ + for (i = 0; i < 4; ++i) { + search_pixel[0] = search_pixel_x[i]; + search_pixel[1] = search_pixel_y[i]; + search_pixel_to_marker_unified(ibuf, track, marker, search_pixel, marker->pattern_corners[i]); + } + + /* Convert the center position (aka "pos"); this is the origin */ + search_pixel[0] = search_pixel_x[4]; + search_pixel[1] = search_pixel_y[4]; + search_pixel_to_marker_unified(ibuf, track, marker, search_pixel, marker_unified); + + /* If the tracker tracked nothing, then "marker_unified" would be zero. + * Otherwise, the entire patch shifted, and that delta should be applied to + * all the coordinates. */ + for (i = 0; i < 4; ++i) { + marker->pattern_corners[i][0] -= marker_unified[0]; + marker->pattern_corners[i][1] -= marker_unified[1]; + } + marker->pos[0] += marker_unified[0]; + marker->pos[1] += marker_unified[1]; +} + static unsigned char *get_ucharbuf(ImBuf *ibuf) { int x, y; @@ -1535,7 +1607,7 @@ void BKE_tracking_sync_user(MovieClipUser *user, MovieTrackingContext *context) int BKE_tracking_next(MovieTrackingContext *context) { - ImBuf *ibuf_new; + ImBuf *destination_ibuf; int curfra = context->user.framenr; int a, ok = FALSE, map_size; @@ -1550,26 +1622,27 @@ int BKE_tracking_next(MovieTrackingContext *context) else context->user.framenr++; - ibuf_new = BKE_movieclip_get_ibuf_flag(context->clip, &context->user, context->clip_flag, MOVIECLIP_CACHE_SKIP); - if (!ibuf_new) + destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user, context->clip_flag, MOVIECLIP_CACHE_SKIP); + if (!destination_ibuf) return FALSE; - #pragma omp parallel for private(a) shared(ibuf_new, ok) if (map_size>1) + #pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1) for (a = 0; a < map_size; a++) { TrackContext *track_context = NULL; MovieTrackingTrack *track; MovieTrackingMarker *marker; + double dst_pixel_x[5]; + double dst_pixel_y[5]; + tracks_map_get(context->tracks_map, a, &track, (void**)&track_context); marker = BKE_tracking_exact_marker(track, curfra); if (marker && (marker->flag & MARKER_DISABLED) == 0) { #ifdef WITH_LIBMV - int width, height, origin[2], tracked = 0, need_readjust = 0; - float pos[2], margin[2], dim[2], pat_min[2], pat_max[2]; - double x1, y1, x2, y2; - ImBuf *ibuf = NULL; + int width, height, tracked = 0, need_readjust = 0; + float margin[2], dim[2], pat_min[2], pat_max[2]; MovieTrackingMarker marker_new, *marker_keyed; int onbound = FALSE, nextfra; @@ -1588,8 +1661,8 @@ int BKE_tracking_next(MovieTrackingContext *context) sub_v2_v2v2(dim, pat_max, pat_min); margin[0] = margin[1] = MAX2(dim[0], dim[1]) / 2.0f; - margin[0] = MAX2(margin[0], (float)track->margin / ibuf_new->x); - margin[1] = MAX2(margin[1], (float)track->margin / ibuf_new->y); + margin[0] = MAX2(margin[0], (float)track->margin / destination_ibuf->x); + margin[1] = MAX2(margin[1], (float)track->margin / destination_ibuf->y); /* do not track markers which are too close to boundary */ if (marker->pos[0] < margin[0] || marker->pos[0] > 1.0f - margin[0] || @@ -1598,62 +1671,97 @@ int BKE_tracking_next(MovieTrackingContext *context) onbound = TRUE; } else { + /* to convert to the x/y split array format for libmv. */ + double src_pixel_x[5]; + double src_pixel_y[5]; + + /* settings for the tracker */ + struct libmv_trackRegionOptions options; + struct libmv_trackRegionResult result; + float *patch_new; if (need_readjust) { + ImBuf *reference_ibuf = NULL; /* calculate patch for keyframed position */ - ibuf = get_adjust_ibuf(context, track, marker, curfra, &marker_keyed); + reference_ibuf = get_adjust_ibuf(context, track, marker, curfra, &marker_keyed); + track_context->marker = *marker_keyed; - if (track_context->patch) - MEM_freeN(track_context->patch); + if (track_context->search_area) + MEM_freeN(track_context->search_area); - track_context->patch = get_search_floatbuf(ibuf, track, marker_keyed, &width, &height, - track_context->keyframed_pos, origin); + track_context->search_area = get_search_floatbuf(reference_ibuf, track, marker_keyed, &width, &height); + track_context->search_area_height = height; + track_context->search_area_width = width; - IMB_freeImBuf(ibuf); + IMB_freeImBuf(reference_ibuf); } - patch_new = get_search_floatbuf(ibuf_new, track, marker, &width, &height, pos, origin); + /* XXX for now, the width & height always match because the + * settings are per-track. This will change soon and in that + * case different sizes must be used */ + patch_new = get_search_floatbuf(destination_ibuf, track, marker, &width, &height); - x1 = track_context->keyframed_pos[0]; - y1 = track_context->keyframed_pos[1]; + /* Configure the tracker */ + options.motion_model = 0; + options.num_iterations = 10; + options.minimum_correlation = track->minimum_correlation; + options.sigma = 0.9; - x2 = pos[0]; - y2 = pos[1]; + /* Convert the marker corners and center into pixel coordinates in the search/destination images. */ + printf("track_context: %p\n", track_context); + printf("track_context->marker.framenr: %d\n", track_context->marker.framenr); + printf("marker: %p\n", marker); + printf("marker.framenr: %d\n", marker->framenr); + printf("track: %p\n", track); + printf("destination_ibuf: %p\n", destination_ibuf); + printf("\n"); + get_marker_coords_for_tracking(destination_ibuf, track, &track_context->marker, src_pixel_x, src_pixel_y); + get_marker_coords_for_tracking(destination_ibuf, track, marker, dst_pixel_x, dst_pixel_y); - tracked = libmv_regionTrackerTrack(track_context->region_tracker, track_context->patch, patch_new, - width, height, x1, y1, &x2, &y2); +#if 1 + /* Run the tracker! */ + tracked = libmv_trackRegion(&options, + track_context->search_area, patch_new, + width, height, + src_pixel_x, src_pixel_y, + &result, + dst_pixel_x, dst_pixel_y); +#else + { + /* XXX: just for debug + * easy to see that marker isn't getting updated properly if it've got + * non-integer initial coordinates */ + int i; + + for (i = 0; i < 5; i++) { + dst_pixel_x[i] = src_pixel_x[i] + 0.5f; + dst_pixel_y[i] = src_pixel_y[i] + 0.5f; + } + + tracked = TRUE; + } +#endif MEM_freeN(patch_new); } - if (tracked && !onbound && finite(x2) && finite(y2)) { + if (tracked && !onbound) { + memset(&marker_new, 0, sizeof(marker_new)); + marker_new = *marker; + set_marker_coords_from_tracking(destination_ibuf, track, &marker_new, dst_pixel_x, dst_pixel_y); + marker_new.flag |= MARKER_TRACKED; + marker_new.framenr = nextfra; + if (context->first_time) { #pragma omp critical { /* check if there's no keyframe/tracked markers before tracking marker. * if so -- create disabled marker before currently tracking "segment" */ - put_disabled_marker(track, marker, !context->backwards, 0); + put_disabled_marker(track, &marker_new, !context->backwards, 0); } } - memset(&marker_new, 0, sizeof(marker_new)); - - if (!onbound) { - marker_new.pos[0] = (origin[0] + x2) / ibuf_new->x; - marker_new.pos[1] = (origin[1] + y2) / ibuf_new->y; - } - else { - copy_v2_v2(marker_new.pos, marker->pos); - } - - /* XXX: currently trackers does not change corners of a track, so - * just copy them from previous position */ - memcpy(marker_new.pattern_corners, marker->pattern_corners, sizeof(marker_new.pattern_corners)); - - marker_new.flag |= MARKER_TRACKED; - marker_new.framenr = nextfra; - #pragma omp critical { BKE_tracking_insert_marker(track, &marker_new); @@ -1682,7 +1790,7 @@ int BKE_tracking_next(MovieTrackingContext *context) } } - IMB_freeImBuf(ibuf_new); + IMB_freeImBuf(destination_ibuf); context->first_time = FALSE; context->frames++; diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index feb77c5c9ec..6f2e017b1f1 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -73,14 +73,16 @@ typedef struct MovieTrackingMarker { /* corners of pattern in the following order: * - * Y - * ^ - * | (3) --- (2) - * | | | - * | | | - * | | | - * | (0) --- (1) - * +-------------> X + * Y + * ^ + * | (3) --- (2) + * | | | + * | | | + * | | | + * | (0) --- (1) + * +-------------> X + * + * the coordinates are stored relative to pos. */ float pattern_corners[4][2]; @@ -95,10 +97,10 @@ typedef struct MovieTrackingTrack { /* ** setings ** */ - /* positions of left-bottom and right-top corners of pattern (in unified 0..1 space) */ + /* positions of left-bottom and right-top corners of pattern (in unified 0..1 units, relative to marker->pos) */ float pat_min[2], pat_max[2] DNA_DEPRECATED; - /* positions of left-bottom and right-top corners of search area (in unified 0..1 space) */ + /* positions of left-bottom and right-top corners of search area (in unified 0..1 units, relative to marker->pos */ float search_min[2], search_max[2]; float offset[2]; /* offset to "parenting" point */ From fddb05024e55c96421f5e0709d981ebab6122095 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 17 May 2012 12:08:37 +0000 Subject: [PATCH 049/360] use vertex arrays for drawing mask splines --- source/blender/editors/mask/mask_draw.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 68494af684e..e3fe67df16b 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -171,21 +171,12 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline, PixelSpaceC glPointSize(1.0f); } -static void draw_spline_curve_lines(float *points, int tot_point, int closed) +static void draw_spline_curve_lines(const float *points, int tot_point, int closed) { - int i; - float *fp = points; - - if (closed) - glBegin(GL_LINE_LOOP); - else - glBegin(GL_LINE_STRIP); - - /* MASK_TODO - vertex arrays */ - for (i = 0; i < tot_point; i++, fp += 2) { - glVertex3fv(fp); - } - glEnd(); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, points); + glDrawArrays(closed ? GL_LINE_LOOP : GL_LINE_STRIP, 0, tot_point); + glDisableClientState(GL_VERTEX_ARRAY); } static void draw_dashed_curve(MaskSpline *spline, float *points, int tot_point) From 1670b1ed99fe2d119bb7b62a881330696c7a0008 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 17 May 2012 13:53:20 +0000 Subject: [PATCH 050/360] Remove debug code and clean up sources to match common style used Also made BKE_tracking_get_search_imbuf use space conversion utility functions, so now it's not so annoying that search area calculation is happening differently in different paces. Also allow even sizes for search area. Another small fix is about flipping search area dumping by libmv-capi. It used to be flipped since in blender Y axis is up-aimed. --- extern/libmv/libmv-capi.cpp | 4 +- source/blender/blenkernel/BKE_tracking.h | 3 +- source/blender/blenkernel/intern/tracking.c | 296 +++++++++++--------- 3 files changed, 167 insertions(+), 136 deletions(-) diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index 7d3dca5c4e8..8894930f3b9 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -239,14 +239,14 @@ static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0) row_pointers[y]= (png_bytep)malloc(sizeof(png_byte)*4*image.Width()); for (x = 0; x < image.Width(); x++) { - if (x0 == x && y0 == y) { + if (x0 == x && image.Height() - y0 - 1 == y) { row_pointers[y][x*4+0]= 255; row_pointers[y][x*4+1]= 0; row_pointers[y][x*4+2]= 0; row_pointers[y][x*4+3]= 255; } else { - float pixel = image(y, x, 0); + float pixel = image(image.Height() - y - 1, x, 0); row_pointers[y][x*4+0]= pixel*255; row_pointers[y][x*4+1]= pixel*255; row_pointers[y][x*4+2]= pixel*255; diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index f8869bfc74c..6ff1a6e8298 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -75,8 +75,7 @@ struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTra struct MovieTrackingMarker *marker, int margin, int anchored, float pos[2], int origin[2]); struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker, int margin, int anchored, - float pos[2], int origin[2]); + struct MovieTrackingMarker *marker); struct ImBuf *BKE_tracking_track_mask_get(struct MovieTracking *tracking, struct MovieTrackingTrack *track, int width, int height); void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 3bf5c735cb7..151881edb34 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -76,6 +76,78 @@ static struct { ListBase tracks; } tracking_clipboard; +/*********************** space transformation functions *************************/ + +/* Three coordinate frames: Frame, Search, and Marker + * Two units: Pixels, Unified + * Notation: {coordinate frame}_{unit}; for example, "search_pixel" are search + * window relative coordinates in pixels, and "frame_unified" are unified 0..1 + * coordinates relative to the entire frame. + */ +static void unified_to_pixel(const ImBuf *ibuf, const float unified_coords[2], float pixel_coords[2]) +{ + pixel_coords[0] = unified_coords[0] * ibuf->x; + pixel_coords[1] = unified_coords[1] * ibuf->y; +} + +static void marker_to_frame_unified(const MovieTrackingMarker *marker, const float marker_unified_coords[2], + float frame_unified_coords[2]) +{ + frame_unified_coords[0] = marker_unified_coords[0] + marker->pos[0]; + frame_unified_coords[1] = marker_unified_coords[1] + marker->pos[1]; +} + +static void marker_unified_to_frame_pixel_coordinates(const ImBuf *ibuf, const MovieTrackingMarker *marker, + const float marker_unified_coords[2], float frame_pixel_coords[2]) +{ + marker_to_frame_unified(marker, marker_unified_coords, frame_pixel_coords); + unified_to_pixel(ibuf, frame_pixel_coords, frame_pixel_coords); +} + +static void get_search_origin_frame_pixel(const ImBuf *ibuf, const MovieTrackingTrack *track, + const MovieTrackingMarker *marker, float frame_pixel[2]) +{ + /* Get the lower left coordinate of the search window and snap to pixel coordinates */ + marker_unified_to_frame_pixel_coordinates(ibuf, marker, track->search_min, frame_pixel); + frame_pixel[0] = (int)frame_pixel[0]; + frame_pixel[1] = (int)frame_pixel[1]; +} + +#ifdef WITH_LIBMV +static void pixel_to_unified(const ImBuf *ibuf, const float pixel_coords[2], float unified_coords[2]) +{ + unified_coords[0] = pixel_coords[0] / ibuf->x; + unified_coords[1] = pixel_coords[1] / ibuf->y; +} + +static void marker_unified_to_search_pixel(const ImBuf *ibuf, const MovieTrackingTrack *track, + const MovieTrackingMarker *marker, const float marker_unified[2], + float search_pixel[2]) +{ + float frame_pixel[2]; + float search_origin_frame_pixel[2]; + + marker_unified_to_frame_pixel_coordinates(ibuf, marker, marker_unified, frame_pixel); + get_search_origin_frame_pixel(ibuf, track, marker, search_origin_frame_pixel); + sub_v2_v2v2(search_pixel, frame_pixel, search_origin_frame_pixel); +} + +static void search_pixel_to_marker_unified(const ImBuf *ibuf, const MovieTrackingTrack *track, + const MovieTrackingMarker *marker, const float search_pixel[2], + float marker_unified[2]) +{ + float frame_unified[2]; + float search_origin_frame_pixel[2]; + + get_search_origin_frame_pixel(ibuf, track, marker, search_origin_frame_pixel); + add_v2_v2v2(frame_unified, search_pixel, search_origin_frame_pixel); + pixel_to_unified(ibuf, frame_unified, frame_unified); + + /* marker pos is in frame unified */ + sub_v2_v2v2(marker_unified, frame_unified, marker->pos); +} +#endif + /*********************** common functions *************************/ void BKE_tracking_init_settings(MovieTracking *tracking) @@ -114,7 +186,8 @@ void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) } /* XXX: currently search area is global, pattern size is per-marker, so we'll need to - * find maximal size of pattern to clamp search size nicely */ + * find maximal size of pattern to clamp search size nicely + */ INIT_MINMAX2(pat_min, pat_max); for (a = 0; a < track->markersnr; a++) { @@ -127,7 +200,8 @@ void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) } /* compute the effective pattern size, which differs from the fine resolution - * pattern size for the pyramid KLT tracker */ + * pattern size for the pyramid KLT tracker + */ for (a = 0; a < 2; a++) { eff_pat_min[a] = max_pyramid_level_factor * pat_min[a]; eff_pat_max[a] = max_pyramid_level_factor * pat_max[a]; @@ -147,7 +221,8 @@ void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) #if 0 /* XXX: needs porting, but we need to know marker here, will be ported after a bit - * more global refactoring */ + * more global refactoring + */ for (a = 0; a < 2; a++) { /* pattern shouldn't be moved outside of search */ if (eff_pat_min[a] < track->search_min[a]) { @@ -192,7 +267,8 @@ void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) float search_ratio = 2.3f * max_pyramid_level_factor; /* resize the search area to something sensible based - * on the number of pyramid levels */ + * on the number of pyramid levels + */ for (a = 0; a < 2; a++) { track->search_min[a] = search_ratio * pat_min[a]; track->search_max[a] = search_ratio * pat_max[a]; @@ -542,7 +618,8 @@ void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack if ((dst_track->markers[b].flag & MARKER_DISABLED) == 0) { /* both tracks are enabled on this frame, so find the whole segment * on which tracks are intersecting and blend tracks using linear - * interpolation to prevent jumps */ + * interpolation to prevent jumps + */ MovieTrackingMarker *marker_a, *marker_b; int start_a = a, start_b = b, len = 0, frame = src_track->markers[a].framenr; @@ -842,7 +919,8 @@ static void tracks_map_merge(TracksMap *map, MovieTracking *tracking) /* duplicate currently operating tracks to temporary list. * this is needed to keep names in unique state and it's faster to change names - * of currently operating tracks (if needed) */ + * of currently operating tracks (if needed) + */ for (a = 0; a < map->num_tracks; a++) { int replace_sel = 0, replace_rot = 0; MovieTrackingTrack *new_track, *old; @@ -1034,7 +1112,8 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u * would be used for images * - MCLIP_USE_PROXY_CUSTOM_DIR is needed because proxy/timecode files might * be stored in a different location - * ignore all the rest possible flags for now */ + * ignore all the rest possible flags for now + */ context->clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS; context->user = *user; @@ -1072,7 +1151,8 @@ void BKE_tracking_context_free(MovieTrackingContext *context) /* zap channels from the imbuf that are disabled by the user. this can lead to * better tracks sometimes. however, instead of simply zeroing the channels - * out, do a partial grayscale conversion so the display is better. */ + * out, do a partial grayscale conversion so the display is better. + */ void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disable_green, int disable_blue, int grayscale) { @@ -1083,7 +1163,8 @@ void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disab return; /* If only some components are selected, it's important to rescale the result - * appropriately so that e.g. if only blue is selected, it's not zeroed out. */ + * appropriately so that e.g. if only blue is selected, it's not zeroed out. + */ scale = (disable_red ? 0.0f : 0.2126f) + (disable_green ? 0.0f : 0.7152f) + (disable_blue ? 0.0f : 0.0722f); @@ -1203,16 +1284,41 @@ ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mo float pat_min[2], pat_max[2]; /* XXX: need to do real quad sampling here, but currently just assume - * corners represents quad pattern */ + * corners represents quad pattern + */ BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); return get_area_imbuf(ibuf, track, marker, pat_min, pat_max, margin, anchored, pos, origin); } -ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int margin, int anchored, float pos[2], int origin[2]) +ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker) { - return get_area_imbuf(ibuf, track, marker, track->search_min, track->search_max, margin, anchored, pos, origin); + ImBuf *searchibuf; + int x, y, w, h; + float search_origin[2]; + + get_search_origin_frame_pixel(ibuf, track, marker, search_origin); + + x = search_origin[0]; + y = search_origin[1]; + + w = (track->search_max[0] - track->search_min[0]) * ibuf->x; + h = (track->search_max[1] - track->search_min[1]) * ibuf->y; + + searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); + searchibuf->profile = ibuf->profile; + + IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h); + + if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || + (track->flag & TRACK_DISABLE_RED) || + (track->flag & TRACK_DISABLE_GREEN) || + (track->flag & TRACK_DISABLE_BLUE)) + { + disable_imbuf_channels(searchibuf, track, FALSE); + } + + return searchibuf; } static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track) @@ -1295,13 +1401,9 @@ ImBuf *BKE_tracking_track_mask_get(MovieTracking *tracking, MovieTrackingTrack * bGPDlayer *layer = track_mask_gpencil_layer_get(track); int mask_width, mask_height; - /* XXX: currently copied from get_area_ibuf */ mask_width = (track->search_max[0] - track->search_min[0]) * width; mask_height = (track->search_max[1] - track->search_min[1]) * height; - mask_width = mask_width | 1; - mask_height = mask_height | 1; - ibuf = IMB_allocImBuf(mask_width, mask_height, 32, IB_rect | IB_rectfloat); if (layer) { @@ -1318,7 +1420,9 @@ ImBuf *BKE_tracking_track_mask_get(MovieTracking *tracking, MovieTrackingTrack * #ifdef WITH_LIBMV /* Convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */ -static void float_rgba_to_gray(const float *rgba, float *gray, int num_pixels, float weight_red, float weight_green, float weight_blue) { +static void float_rgba_to_gray(const float *rgba, float *gray, int num_pixels, + float weight_red, float weight_green, float weight_blue) +{ int i; for (i = 0; i < num_pixels; i++) { @@ -1328,7 +1432,9 @@ static void float_rgba_to_gray(const float *rgba, float *gray, int num_pixels, f } } -static void uint8_rgba_to_float_gray(const unsigned char *rgba, float *gray, int num_pixels, float weight_red, float weight_green, float weight_blue) { +static void uint8_rgba_to_float_gray(const unsigned char *rgba, float *gray, int num_pixels, + float weight_red, float weight_green, float weight_blue) +{ int i; for (i = 0; i < num_pixels; i++) { @@ -1338,17 +1444,14 @@ static void uint8_rgba_to_float_gray(const unsigned char *rgba, float *gray, int } } -static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, int *width_r, int *height_r) +static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int *width_r, int *height_r) { ImBuf *searchibuf; float *gray_pixels; int width, height; - /* ignored */ - float pos[2]; - int origin[2]; - searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin); - disable_imbuf_channels(searchibuf, track, FALSE /* don't grayscale */); + searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker); width = searchibuf->x; height = searchibuf->y; @@ -1359,10 +1462,12 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT gray_pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf"); if (searchibuf->rect_float) { - float_rgba_to_gray(searchibuf->rect_float, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f); + float_rgba_to_gray(searchibuf->rect_float, gray_pixels, width * height, + 0.2126f, 0.7152f, 0.0722f); } else { - uint8_rgba_to_float_gray((unsigned char *)searchibuf->rect, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f); + uint8_rgba_to_float_gray((unsigned char *)searchibuf->rect, gray_pixels, width * height, + 0.2126f, 0.7152f, 0.0722f); } IMB_freeImBuf(searchibuf); @@ -1370,79 +1475,21 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT return gray_pixels; } -/* Three coordinate frames: Frame, Search, and Marker - * Two units: Pixels, Unified - * Notation: {coordinate frame}_{unit}; for example, "search_pixel" are search - * window relative coordinates in pixels, and "frame_unified" are unified 0..1 - * coordinates relative to the entire frame. - */ -static void unified_to_pixel(const ImBuf *ibuf, const float unified_coords[2], float pixel_coords[2]) -{ - pixel_coords[0] = unified_coords[0] * ibuf->x; - pixel_coords[1] = unified_coords[1] * ibuf->y; -} - -static void pixel_to_unified(const ImBuf *ibuf, const float pixel_coords[2], float unified_coords[2]) -{ - unified_coords[0] = pixel_coords[0] / ibuf->x; - unified_coords[1] = pixel_coords[1] / ibuf->y; -} - -static void marker_to_frame_unified(const MovieTrackingMarker *marker, const float marker_unified_coords[2], float frame_unified_coords[2]) -{ - frame_unified_coords[0] = marker_unified_coords[0] + marker->pos[0]; - frame_unified_coords[1] = marker_unified_coords[1] + marker->pos[1]; -} - -static void marker_unified_to_frame_pixel_coordinates(const ImBuf *ibuf, const MovieTrackingMarker *marker, - const float marker_unified_coords[2], float frame_pixel_coords[2]) -{ - marker_to_frame_unified(marker, marker_unified_coords, frame_pixel_coords); - unified_to_pixel(ibuf, frame_pixel_coords, frame_pixel_coords); -} - -static void get_search_origin_frame_pixel(const ImBuf *ibuf, const MovieTrackingTrack *track, const MovieTrackingMarker *marker, float frame_pixel[2]) -{ - /* Get the lower left coordinate of the search window and snap to pixel coordinates */ - marker_unified_to_frame_pixel_coordinates(ibuf, marker, track->search_min, frame_pixel); - frame_pixel[0] = (int)frame_pixel[0]; - frame_pixel[1] = (int)frame_pixel[1]; -} - -static void marker_unified_to_search_pixel(const ImBuf *ibuf, const MovieTrackingTrack *track, const MovieTrackingMarker *marker, - const float marker_unified[2], float search_pixel[2]) -{ - float frame_pixel[2]; - float search_origin_frame_pixel[2]; - marker_unified_to_frame_pixel_coordinates(ibuf, marker, marker_unified, frame_pixel); - get_search_origin_frame_pixel(ibuf, track, marker, search_origin_frame_pixel); - sub_v2_v2v2(search_pixel, frame_pixel, search_origin_frame_pixel); -} - -static void search_pixel_to_marker_unified(const ImBuf *ibuf, const MovieTrackingTrack *track, const MovieTrackingMarker *marker, - const float search_pixel[2], float marker_unified[2]) -{ - float frame_unified[2]; - float search_origin_frame_pixel[2]; - get_search_origin_frame_pixel(ibuf, track, marker, search_origin_frame_pixel); - add_v2_v2v2(frame_unified, search_pixel, search_origin_frame_pixel); - pixel_to_unified(ibuf, frame_unified, frame_unified); - sub_v2_v2v2(marker_unified, frame_unified, marker->pos /* marker pos is in frame unified */); -} - /* Each marker has 5 coordinates associated with it that get warped with * tracking: the four corners ("pattern_corners"), and the cernter ("pos"). * This function puts those 5 points into the appropriate frame for tracking * (the "search" coordinate frame). */ -static void get_marker_coords_for_tracking(const ImBuf *ibuf, const MovieTrackingTrack *track, const MovieTrackingMarker *marker, - double search_pixel_x[5], double search_pixel_y[5]) { +static void get_marker_coords_for_tracking(const ImBuf *ibuf, const MovieTrackingTrack *track, + const MovieTrackingMarker *marker, + double search_pixel_x[5], double search_pixel_y[5]) +{ int i; float unified_coords[2]; float pixel_coords[2]; /* Convert the corners into search space coordinates. */ - for (i = 0; i < 4; ++i) { + for (i = 0; i < 4; i++) { marker_unified_to_search_pixel(ibuf, track, marker, marker->pattern_corners[i], pixel_coords); search_pixel_x[i] = pixel_coords[0]; search_pixel_y[i] = pixel_coords[1]; @@ -1451,20 +1498,22 @@ static void get_marker_coords_for_tracking(const ImBuf *ibuf, const MovieTrackin unified_coords[0] = 0.0; unified_coords[1] = 0.0; marker_unified_to_search_pixel(ibuf, track, marker, unified_coords, pixel_coords); + search_pixel_x[4] = pixel_coords[0]; search_pixel_y[4] = pixel_coords[1]; } /* Inverse of above. */ -static void set_marker_coords_from_tracking(const ImBuf *ibuf, const MovieTrackingTrack *track, MovieTrackingMarker *marker, - const double search_pixel_x[5], const double search_pixel_y[5]) +static void set_marker_coords_from_tracking(const ImBuf *ibuf, const MovieTrackingTrack *track, + MovieTrackingMarker *marker, const double search_pixel_x[5], + const double search_pixel_y[5]) { int i; float marker_unified[2]; float search_pixel[2]; /* Convert the corners into search space coordinates. */ - for (i = 0; i < 4; ++i) { + for (i = 0; i < 4; i++) { search_pixel[0] = search_pixel_x[i]; search_pixel[1] = search_pixel_y[i]; search_pixel_to_marker_unified(ibuf, track, marker, search_pixel, marker->pattern_corners[i]); @@ -1477,11 +1526,13 @@ static void set_marker_coords_from_tracking(const ImBuf *ibuf, const MovieTracki /* If the tracker tracked nothing, then "marker_unified" would be zero. * Otherwise, the entire patch shifted, and that delta should be applied to - * all the coordinates. */ - for (i = 0; i < 4; ++i) { + * all the coordinates. + */ + for (i = 0; i < 4; i++) { marker->pattern_corners[i][0] -= marker_unified[0]; marker->pattern_corners[i][1] -= marker_unified[1]; } + marker->pos[0] += marker_unified[0]; marker->pos[1] += marker_unified[1]; } @@ -1622,7 +1673,8 @@ int BKE_tracking_next(MovieTrackingContext *context) else context->user.framenr++; - destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user, context->clip_flag, MOVIECLIP_CACHE_SKIP); + destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user, + context->clip_flag, MOVIECLIP_CACHE_SKIP); if (!destination_ibuf) return FALSE; @@ -1632,10 +1684,7 @@ int BKE_tracking_next(MovieTrackingContext *context) MovieTrackingTrack *track; MovieTrackingMarker *marker; - double dst_pixel_x[5]; - double dst_pixel_y[5]; - - tracks_map_get(context->tracks_map, a, &track, (void**)&track_context); + tracks_map_get(context->tracks_map, a, &track, (void **)&track_context); marker = BKE_tracking_exact_marker(track, curfra); @@ -1645,6 +1694,7 @@ int BKE_tracking_next(MovieTrackingContext *context) float margin[2], dim[2], pat_min[2], pat_max[2]; MovieTrackingMarker marker_new, *marker_keyed; int onbound = FALSE, nextfra; + double dst_pixel_x[5], dst_pixel_y[5]; if (track->pattern_match == TRACK_MATCH_KEYFRAME) need_readjust = context->first_time; @@ -1690,16 +1740,17 @@ int BKE_tracking_next(MovieTrackingContext *context) if (track_context->search_area) MEM_freeN(track_context->search_area); - track_context->search_area = get_search_floatbuf(reference_ibuf, track, marker_keyed, &width, &height); + track_context->search_area = get_search_floatbuf(reference_ibuf, track, + marker_keyed, &width, &height); track_context->search_area_height = height; track_context->search_area_width = width; IMB_freeImBuf(reference_ibuf); } - /* XXX for now, the width & height always match because the - * settings are per-track. This will change soon and in that - * case different sizes must be used */ + /* XXX: for now, the width & height always match because the + * settings are per-track. This will change soon and in that + * case different sizes must be used */ patch_new = get_search_floatbuf(destination_ibuf, track, marker, &width, &height); /* Configure the tracker */ @@ -1709,17 +1760,12 @@ int BKE_tracking_next(MovieTrackingContext *context) options.sigma = 0.9; /* Convert the marker corners and center into pixel coordinates in the search/destination images. */ - printf("track_context: %p\n", track_context); - printf("track_context->marker.framenr: %d\n", track_context->marker.framenr); - printf("marker: %p\n", marker); - printf("marker.framenr: %d\n", marker->framenr); - printf("track: %p\n", track); - printf("destination_ibuf: %p\n", destination_ibuf); - printf("\n"); - get_marker_coords_for_tracking(destination_ibuf, track, &track_context->marker, src_pixel_x, src_pixel_y); - get_marker_coords_for_tracking(destination_ibuf, track, marker, dst_pixel_x, dst_pixel_y); + get_marker_coords_for_tracking(destination_ibuf, track, &track_context->marker, + src_pixel_x, src_pixel_y); + + get_marker_coords_for_tracking(destination_ibuf, track, marker, + dst_pixel_x, dst_pixel_y); -#if 1 /* Run the tracker! */ tracked = libmv_trackRegion(&options, track_context->search_area, patch_new, @@ -1727,22 +1773,6 @@ int BKE_tracking_next(MovieTrackingContext *context) src_pixel_x, src_pixel_y, &result, dst_pixel_x, dst_pixel_y); -#else - { - /* XXX: just for debug - * easy to see that marker isn't getting updated properly if it've got - * non-integer initial coordinates */ - int i; - - for (i = 0; i < 5; i++) { - dst_pixel_x[i] = src_pixel_x[i] + 0.5f; - dst_pixel_y[i] = src_pixel_y[i] + 0.5f; - } - - tracked = TRUE; - } -#endif - MEM_freeN(patch_new); } @@ -1757,7 +1787,8 @@ int BKE_tracking_next(MovieTrackingContext *context) #pragma omp critical { /* check if there's no keyframe/tracked markers before tracking marker. - * if so -- create disabled marker before currently tracking "segment" */ + * if so -- create disabled marker before currently tracking "segment" + */ put_disabled_marker(track, &marker_new, !context->backwards, 0); } } @@ -3013,7 +3044,8 @@ ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, if (tangle == 0.0f) { /* if angle is zero, then it's much faster to use rect copy - * but could be issues with subpixel precisions */ + * but could be issues with subpixel precisions + */ IMB_rectcpy(tmpibuf, ibuf, tloc[0] - (tscale - 1.0f) * width / 2.0f, tloc[1] - (tscale - 1.0f) * height / 2.0f, From 81016d59b63b5e5231ea99c5b8ccce55985de851 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 17 May 2012 15:01:51 +0000 Subject: [PATCH 051/360] fix for building without aud --- source/blender/makesrna/intern/rna_sequencer_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 41c6f046c04..3825bc35d3a 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -213,8 +213,8 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor return seq; } #else /* WITH_AUDASPACE */ -static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), bMain *UNUSED(main), ReportList *UNUSED(reports), - const char *UNUSED(name), bSound *UNUSED(sound), int UNUSED(channel), int UNUSED(start_frame)) +static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Main *UNUSED(bmain), ReportList *reports, + const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel), int UNUSED(start_frame)) { BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support."); return NULL; From 892888ec64ebc7e939d07ced841202749331d9e9 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Thu, 17 May 2012 15:52:56 +0000 Subject: [PATCH 052/360] Adds basic curves with holes support for multi-spline mask curves. --- intern/raskter/raskter.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index b80b7de379b..f9c2f851f6e 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -302,7 +302,13 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) mpxl = spxl + MIN2(e_curr->x, rb.sizex) - 1; /* draw the pixels. */ - for (; cpxl <= mpxl; *cpxl++ = 1.0f) ; + for (; cpxl <= mpxl; cpxl++){ + if(*cpxl < 0.5f){ + *cpxl = 1.0f; + }else{ + *cpxl = 0.0f; + } + } } /* From 9932bb1dd6b2c9e4d7ae0c5753857605a25d8e24 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 17 May 2012 16:45:02 +0000 Subject: [PATCH 053/360] Tomato: sliding corner with Ctrl holded down would have scaling behavior --- .../blender/editors/space_clip/tracking_ops.c | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 89b14b06220..b072b7475ac 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -264,7 +264,7 @@ typedef struct { float smin[2], smax[2], spos[2], soff[2], scorners[4][2]; float (*smarkers)[2]; - int lock, accurate; + int lock, accurate, scale; } SlideMarkerData; static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track, @@ -636,6 +636,10 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) data->lock = event->val == KM_RELEASE; + if (data->action == SLIDE_ACTION_POS) + if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) + data->scale = event->val == KM_PRESS; + if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) data->accurate = event->val == KM_PRESS; @@ -718,15 +722,31 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_POS); } else if (data->action == SLIDE_ACTION_POS) { - float spos[2]; + if (data->scale) { + float scale = 1.0f + 10.0f * (dx - dy); - copy_v2_v2(spos, data->pos); + if (scale > 0.0f) { + int a; - data->pos[0] = data->spos[0] + dx; - data->pos[1] = data->spos[1] + dy; + for (a = 0; a < 4; a++) { + mul_v2_v2fl(data->corners[a], data->scorners[a], scale); + } + } + } + else { + float spos[2]; - if (!slide_check_corners(data->corners)) { - copy_v2_v2(data->pos, spos); + copy_v2_v2(spos, data->pos); + + /* corners might've been scaled before, restore their original position */ + memcpy(data->corners, data->scorners, sizeof(data->scorners)); + + data->pos[0] = data->spos[0] + dx; + data->pos[1] = data->spos[1] + dy; + + if (!slide_check_corners(data->corners)) { + copy_v2_v2(data->pos, spos); + } } /* currently only patterns are allowed to have such combination of event and data */ From 82e45dd275205c84a72ba9aedac0bdc4f04e055a Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Thu, 17 May 2012 17:09:51 +0000 Subject: [PATCH 054/360] Add panels for the new planar tracker This replaces the old style tracker configuration panel with the new planar tracking panel. From a users perspective, this means: - The old "tracking algorithm" picker is gone. There is only 1 algorithm now. We may revisit this later, but I would much prefer to have only 1 algorithm. So far no optimization work has been done so the speed is not there yet. - There is now a dropdown to select the motion model. Choices: * Translation * Translation, rotation * Translation, scale * Translation, rotation, scale * Affine (Not implemented yet) * Perspective The most stable is the "translation" parameterization. The others work but still require some tweaking. - The old "Hybrid" mode is gone; instead there is a toggle to enable or disable translation-only tracker initialization. This is the equivalent of the hyrbid mode before, but rewritten to work with the new planar tracking modes. - The pyramid levels setting is gone. At a future date, the planar tracker will decide to use pyramids or not automatically. The pyramid setting was ultimately a mistake; with the brute force initialization it is unnecessary. --- extern/libmv/libmv-capi.cpp | 1 + extern/libmv/libmv-capi.h | 1 + extern/libmv/libmv/tracking/track_region.cc | 5 +- release/scripts/startup/bl_ui/space_clip.py | 12 +- source/blender/blenkernel/BKE_tracking.h | 1 - source/blender/blenkernel/intern/tracking.c | 44 ++---- source/blender/blenloader/intern/readfile.c | 8 +- source/blender/editors/space_clip/clip_draw.c | 45 ------ source/blender/makesdna/DNA_tracking_types.h | 43 +++--- source/blender/makesrna/intern/rna_tracking.c | 134 ++++++------------ 10 files changed, 89 insertions(+), 205 deletions(-) diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index 8894930f3b9..482a4c98245 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -380,6 +380,7 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, track_region_options.sigma = options->sigma; track_region_options.num_extra_points = 1; track_region_options.image1_mask = NULL; + track_region_options.use_brute_initialization = options->use_brute; /* Convert from raw float buffers to libmv's FloatImage. */ libmv::FloatImage old_patch, new_patch; diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index d3f02f99e51..9fedb9b9683 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -54,6 +54,7 @@ void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker); struct libmv_trackRegionOptions { int motion_model; int num_iterations; + int use_brute; double minimum_correlation; double sigma; }; diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index 0dac56aeff7..22c86a7f5b9 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -499,7 +499,7 @@ struct TranslationRotationWarp { q2.CornerRelativeToCentroid(i).transpose(); } Mat2 R = OrthogonalProcrustes(correlation_matrix); - parameters[2] = acos(R(0, 0)); + parameters[2] = atan2(R(1, 0), R(0, 0)); std::cout << "correlation_matrix:\n" << correlation_matrix << "\n"; std::cout << "R:\n" << R << "\n"; @@ -575,7 +575,7 @@ struct TranslationRotationScaleWarp { std::cout << "correlation_matrix:\n" << correlation_matrix << "\n"; Mat2 R = OrthogonalProcrustes(correlation_matrix); std::cout << "R:\n" << R << "\n"; - parameters[3] = acos(R(0, 0)); + parameters[3] = atan2(R(1, 0), R(0, 0)); std::cout << "theta:" << parameters[3] << "\n"; } @@ -949,6 +949,7 @@ void TemplatedTrackRegion(const FloatImage &image1, // TODO(keir): Consider removing these options before committing. solver_options.numeric_derivative_relative_step_size = 1e-3; + solver_options.check_gradients = false; solver_options.gradient_check_relative_precision = 1e-10; solver_options.minimizer_progress_to_stdout = false; diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 358c534a3a7..c17266cf303 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -187,10 +187,8 @@ class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel): sub.prop(settings, "default_search_size") col.label(text="Tracker:") - col.prop(settings, "default_tracker", text="") - - if settings.default_tracker == 'KLT': - col.prop(settings, "default_pyramid_levels") + col.prop(settings, "default_motion_model") + col.prop(settings, "default_use_brute") col.prop(settings, "default_correlation_min") col.separator() @@ -488,10 +486,8 @@ class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel): active = clip.tracking.tracks.active if active: - col.prop(active, "tracker") - - if active.tracker == 'KLT': - col.prop(active, "pyramid_levels") + col.prop(active, "motion_model") + col.prop(active, "use_brute") col.prop(active, "correlation_min") col.separator() diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 6ff1a6e8298..4b94fcb7260 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -190,7 +190,6 @@ void BKE_tracking_dopesheet_update(struct MovieTracking *tracking, int sort_meth #define CLAMP_PAT_POS 2 #define CLAMP_SEARCH_DIM 3 #define CLAMP_SEARCH_POS 4 -#define CLAMP_PYRAMID_LEVELS 5 #define TRACK_AREA_NONE -1 #define TRACK_AREA_POINT 1 diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 151881edb34..1956492fce9 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -156,11 +156,10 @@ void BKE_tracking_init_settings(MovieTracking *tracking) tracking->camera.pixel_aspect = 1.0f; tracking->camera.units = CAMERA_UNITS_MM; - tracking->settings.default_tracker = TRACKER_HYBRID; + tracking->settings.default_motion_model = TRACK_MOTION_MODEL_TRANSLATION; tracking->settings.default_minimum_correlation = 0.75; tracking->settings.default_pattern_size = 11; tracking->settings.default_search_size = 61; - tracking->settings.default_pyramid_levels = 2; tracking->settings.keyframe1 = 1; tracking->settings.keyframe2 = 30; tracking->settings.dist = 1; @@ -179,11 +178,6 @@ void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) int a; float pat_min[2], pat_max[2]; float eff_pat_min[2], eff_pat_max[2]; - float max_pyramid_level_factor = 1.0; - - if (track->tracker == TRACKER_KLT) { - max_pyramid_level_factor = 1 << (track->pyramid_levels - 1); - } /* XXX: currently search area is global, pattern size is per-marker, so we'll need to * find maximal size of pattern to clamp search size nicely @@ -199,13 +193,8 @@ void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) DO_MINMAX2(cur_pat_max, pat_min, pat_max); } - /* compute the effective pattern size, which differs from the fine resolution - * pattern size for the pyramid KLT tracker - */ - for (a = 0; a < 2; a++) { - eff_pat_min[a] = max_pyramid_level_factor * pat_min[a]; - eff_pat_max[a] = max_pyramid_level_factor * pat_max[a]; - } + copy_v2_v2(eff_pat_min, pat_min); + copy_v2_v2(eff_pat_max, pat_max); if (event == CLAMP_PAT_DIM) { for (a = 0; a < 2; a++) { @@ -260,19 +249,12 @@ void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) } } } - else if (event == CLAMP_PYRAMID_LEVELS || (event == CLAMP_SEARCH_DIM && track->tracker == TRACKER_KLT)) { + else if (event == CLAMP_SEARCH_DIM) { float dim[2]; sub_v2_v2v2(dim, pat_max, pat_min); - { - float search_ratio = 2.3f * max_pyramid_level_factor; - - /* resize the search area to something sensible based - * on the number of pyramid levels - */ - for (a = 0; a < 2; a++) { - track->search_min[a] = search_ratio * pat_min[a]; - track->search_max[a] = search_ratio * pat_max[a]; - } + for (a = 0; a < 2; a++) { + track->search_min[a] = pat_min[a]; + track->search_max[a] = pat_max[a]; } } } @@ -320,13 +302,13 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tr track = MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track"); strcpy(track->name, "Track"); - track->tracker = settings->default_tracker; - track->pyramid_levels = settings->default_pyramid_levels; + track->motion_model = settings->default_motion_model; track->minimum_correlation = settings->default_minimum_correlation; track->margin = settings->default_margin; track->pattern_match = settings->default_pattern_match; track->frames_limit = settings->default_frames_limit; track->flag = settings->default_flag; + track->algorithm_flag = settings->default_algorithm_flag; memset(&marker, 0, sizeof(marker)); marker.pos[0] = x; @@ -347,9 +329,6 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tr BKE_tracking_insert_marker(track, &marker); - if (track->tracker == TRACKER_KLT) - BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS); - BLI_addtail(tracksbase, track); BKE_track_unique_name(tracksbase, track); @@ -1754,8 +1733,9 @@ int BKE_tracking_next(MovieTrackingContext *context) patch_new = get_search_floatbuf(destination_ibuf, track, marker, &width, &height); /* Configure the tracker */ - options.motion_model = 0; - options.num_iterations = 10; + options.motion_model = track->motion_model; + options.use_brute = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) == 0); + options.num_iterations = 50; options.minimum_correlation = track->minimum_correlation; options.sigma = 0.9; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 3e3d24d7281..bb944eaf429 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7122,9 +7122,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) track= clip->tracking.tracks.first; while (track) { - if (track->pyramid_levels==0) - track->pyramid_levels= 2; - if (track->minimum_correlation==0.0f) track->minimum_correlation= 0.75f; @@ -7146,9 +7143,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for (clip= main->movieclip.first; clip; clip= clip->id.next) { MovieTrackingSettings *settings= &clip->tracking.settings; - if (settings->default_pyramid_levels==0) { - settings->default_tracker= TRACKER_KLT; - settings->default_pyramid_levels= 2; + if (settings->default_pattern_size == 0.0f) { + settings->default_motion_model= TRACK_MOTION_MODEL_TRANSLATION; settings->default_minimum_correlation= 0.75; settings->default_pattern_size= 11; settings->default_search_size= 51; diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index aa9af704280..a06da289326 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -668,51 +668,6 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra glEnd(); } - /* pyramid */ - if (sel && TRACK_VIEW_SELECTED(sc, track) && - (track->tracker == TRACKER_KLT) && - (marker->flag & MARKER_DISABLED) == 0) - { - if (track->flag & TRACK_LOCKED) { - if (act) - UI_ThemeColor(TH_ACT_MARKER); - else if (track->pat_flag & SELECT) - UI_ThemeColorShade(TH_LOCK_MARKER, 64); - else UI_ThemeColor(TH_LOCK_MARKER); - } - else if (marker->flag & MARKER_DISABLED) { - if (act) - UI_ThemeColor(TH_ACT_MARKER); - else if (track->pat_flag & SELECT) - UI_ThemeColorShade(TH_DIS_MARKER, 128); - else UI_ThemeColor(TH_DIS_MARKER); - } - else { - if (track->pat_flag & SELECT) - glColor3fv(scol); - else - glColor3fv(col); - } - - { - int i = 0; - glPushMatrix(); - glEnable(GL_LINE_STIPPLE); - for (i = 1; i < track->pyramid_levels; ++i) { - glScalef(2.0f, 2.0f, 1.0); - } - /* only draw a pattern for the coarsest level */ - glBegin(GL_LINE_LOOP); - glVertex2fv(marker->pattern_corners[0]); - glVertex2fv(marker->pattern_corners[1]); - glVertex2fv(marker->pattern_corners[2]); - glVertex2fv(marker->pattern_corners[3]); - glEnd(); - glDisable(GL_LINE_STIPPLE); - glPopMatrix(); - } - } - if (tiny) glDisable(GL_LINE_STIPPLE); diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 6f2e017b1f1..f15bf4ba8d8 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -118,17 +118,14 @@ typedef struct MovieTrackingTrack { int flag, pat_flag, search_flag; /* flags (selection, ...) */ float color[3]; /* custom color for track */ - /* tracking algorithm to use; can be KLT or SAD */ + /* ** control how tracking happens */ short frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */ short margin; /* margin from frame boundaries */ short pattern_match; /* re-adjust every N frames */ - short tracker; /* tracking algorithm used for this track */ - - /* ** KLT tracker settings ** */ - short pyramid_levels, pad2; /* number of pyramid levels to use for KLT tracking */ - - /* ** SAD tracker settings ** */ + /* tracking parameters */ + short motion_model; /* model of the motion for this track */ + int algorithm_flag; /* flags for the tracking algorithm (use brute, use esm, use pyramid, etc */ float minimum_correlation; /* minimal correlation which is still treated as successful tracking */ struct bGPdata *gpd; /* grease-pencil data */ @@ -138,15 +135,15 @@ typedef struct MovieTrackingSettings { int flag; /* ** default tracker settings */ - short default_tracker; /* tracking algorithm used by default */ - short default_pyramid_levels; /* number of pyramid levels to use for KLT tracking */ - float default_minimum_correlation; /* minimal correlation which is still treated as successful tracking */ - short default_pattern_size; /* size of pattern area for new tracks */ - short default_search_size; /* size of search area for new tracks */ - short default_frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */ - short default_margin; /* margin from frame boundaries */ - short default_pattern_match; /* re-adjust every N frames */ - short default_flag; /* default flags like color channels used by default */ + short default_motion_model; /* model of the motion for this track */ + short default_algorithm_flag; /* flags for the tracking algorithm (use brute, use esm, use pyramid, etc */ + float default_minimum_correlation; /* minimal correlation which is still treated as successful tracking */ + short default_pattern_size; /* size of pattern area for new tracks */ + short default_search_size; /* size of search area for new tracks */ + short default_frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */ + short default_margin; /* margin from frame boundaries */ + short default_pattern_match; /* re-adjust every N frames */ + short default_flag; /* default flags like color channels used by default */ short motion_flag; /* flags describes motion type */ @@ -280,10 +277,16 @@ enum { #define TRACK_PREVIEW_GRAYSCALE (1<<9) #define TRACK_DOPE_SEL (1<<10) -/* MovieTrackingTrack->tracker */ -#define TRACKER_KLT 0 -#define TRACKER_SAD 1 -#define TRACKER_HYBRID 2 +/* MovieTrackingTrack->motion_model */ +#define TRACK_MOTION_MODEL_TRANSLATION 0 +#define TRACK_MOTION_MODEL_TRANSLATION_ROTATION 1 +#define TRACK_MOTION_MODEL_TRANSLATION_SCALE 2 +#define TRACK_MOTION_MODEL_TRANSLATION_ROTATION_SCALE 3 +#define TRACK_MOTION_MODEL_AFFINE 4 +#define TRACK_MOTION_MODEL_HOMOGRAPHY 5 + +/* MovieTrackingTrack->algorithm_flag */ +#define TRACK_ALGORITHM_FLAG_USE_BRUTE 0 /* MovieTrackingTrack->adjframes */ #define TRACK_MATCH_KEYFRAME 0 diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 9f5dc75506b..34dd471e9c1 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -59,20 +59,6 @@ static char *rna_tracking_path(PointerRNA *UNUSED(ptr)) return BLI_sprintfN("tracking"); } -static void rna_tracking_defaultSettings_levelsUpdate(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - MovieClip *clip = (MovieClip*)ptr->id.data; - MovieTracking *tracking = &clip->tracking; - MovieTrackingSettings *settings = &tracking->settings; - - if (settings->default_tracker == TRACKER_KLT) { - int max_pyramid_level_factor = 1 << (settings->default_pyramid_levels - 1); - float search_ratio = 2.3f * max_pyramid_level_factor; - - settings->default_search_size = settings->default_pattern_size*search_ratio; - } -} - static void rna_tracking_defaultSettings_patternUpdate(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { MovieClip *clip = (MovieClip*)ptr->id.data; @@ -223,23 +209,6 @@ static void rna_tracking_trackerSearch_update(Main *UNUSED(bmain), Scene *UNUSED BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); } -static void rna_tracking_trackerAlgorithm_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - MovieTrackingTrack *track = (MovieTrackingTrack *)ptr->data; - - if (track->tracker == TRACKER_KLT) - BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS); - else - BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); -} - -static void rna_tracking_trackerPyramid_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - MovieTrackingTrack *track = (MovieTrackingTrack *)ptr->data; - - BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS); -} - static char *rna_trackingCamera_path(PointerRNA *UNUSED(ptr)) { return BLI_sprintfN("tracking.camera"); @@ -484,11 +453,19 @@ void rna_trackingMarkers_delete_frame(MovieTrackingTrack *track, int framenr) #else -static EnumPropertyItem tracker_items[] = { - {TRACKER_KLT, "KLT", 0, "KLT", - "Kanade–Lucas–Tomasi tracker which works with most of video clips, a bit slower than SAD"}, - {TRACKER_SAD, "SAD", 0, "SAD", "Sum of Absolute Differences tracker which can be used when KLT tracker fails"}, - {TRACKER_HYBRID, "Hybrid", 0, "Hybrid", "A hybrid tracker that uses SAD for rough tracking, KLT for refinement."}, +static EnumPropertyItem tracker_motion_model[] = { + {TRACK_MOTION_MODEL_HOMOGRAPHY, "Perspective", 0, "Perspective", + "Search for markers that are perspectively deformed (homography) between frames."}, + {TRACK_MOTION_MODEL_AFFINE, "Affine", 0, "Affine", + "Search for markers that are affine-deformed (t, r, k, and skew) between frames."}, + {TRACK_MOTION_MODEL_TRANSLATION_ROTATION_SCALE, "LocRotScale", 0, "LocRotScale", + "Search for markers that are translated, rotated, and scaled between frames."}, + {TRACK_MOTION_MODEL_TRANSLATION_SCALE, "LocScale", 0, "LocScale", + "Search for markers that are translated and scaled between frames."}, + {TRACK_MOTION_MODEL_TRANSLATION_ROTATION, "LocRot", 0, "LocRot", + "Search for markers that are translated and rotated between frames."}, + {TRACK_MOTION_MODEL_TRANSLATION, "Loc", 0, "Loc", + "Search for markers that are translated between frames."}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem pattern_match_items[] = { @@ -635,33 +612,29 @@ static void rna_def_trackingSettings(BlenderRNA *brna) RNA_def_property_range(prop, 0, 300); RNA_def_property_ui_text(prop, "Margin", "Default distance from image boudary at which marker stops tracking"); - /* tracking algorithm */ - prop = RNA_def_property(srna, "default_tracker", PROP_ENUM, PROP_NONE); + /* tracking motion model */ + prop = RNA_def_property(srna, "default_motion_model", PROP_ENUM, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_enum_items(prop, tracker_items); - RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_levelsUpdate"); - RNA_def_property_ui_text(prop, "Tracker", "Default tracking algorithm to use"); + RNA_def_property_enum_items(prop, tracker_motion_model); + RNA_def_property_ui_text(prop, "Motion model", "Default motion model to use for tracking"); - /* pyramid level for pyramid klt tracking */ - prop = RNA_def_property(srna, "default_pyramid_levels", PROP_INT, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_sdna(prop, NULL, "default_pyramid_levels"); - RNA_def_property_range(prop, 1, 16); - RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_levelsUpdate"); - RNA_def_property_ui_text(prop, "Pyramid levels", "Default number of pyramid levels (increase on blurry footage)"); + /* use_brute */ + prop = RNA_def_property(srna, "default_use_brute", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); + RNA_def_property_ui_text(prop, "Translation-only initialization", "Use a brute-force translation-only initialization when tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); - /* minmal correlation - only used for SAD tracker */ + /* minmal correlation */ prop = RNA_def_property(srna, "default_correlation_min", PROP_FLOAT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_float_sdna(prop, NULL, "default_minimum_correlation"); - RNA_def_property_range(prop, -1.0f, 1.0f); - RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.05, 3); RNA_def_property_ui_text(prop, "Correlation", - "Default minimal value of correlation between matched pattern and reference " - "which is still treated as successful tracking"); + "Default minimum value of correlation between matched pattern and reference " + "that is still treated as successful tracking"); /* default pattern size */ prop = RNA_def_property(srna, "default_pattern_size", PROP_INT, PROP_NONE); @@ -886,25 +859,7 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_struct_name_property(srna, prop); /* Pattern */ - prop = RNA_def_property(srna, "pattern_min", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_array(prop, 2); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); - RNA_def_property_float_sdna(prop, NULL, "pat_min"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Pattern Min", - "Left-bottom corner of pattern area in normalized coordinates relative " - "to marker position"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPattern_update"); - - prop = RNA_def_property(srna, "pattern_max", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_array(prop, 2); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); - RNA_def_property_float_sdna(prop, NULL, "pat_max"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Pattern Max", - "Right-bottom corner of pattern area in normalized coordinates relative " - "to marker position"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPattern_update"); + /* XXX The four pattern corners are not exported to rna yet */ /* Search */ prop = RNA_def_property(srna, "search_min", PROP_FLOAT, PROP_TRANSLATION); @@ -952,32 +907,29 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_range(prop, 0, 300); RNA_def_property_ui_text(prop, "Margin", "Distance from image boudary at which marker stops tracking"); - /* tracking algorithm */ - prop = RNA_def_property(srna, "tracker", PROP_ENUM, PROP_NONE); + /* tracking motion model */ + prop = RNA_def_property(srna, "motion_model", PROP_ENUM, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_enum_items(prop, tracker_items); + RNA_def_property_enum_items(prop, tracker_motion_model); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Tracker", "Tracking algorithm to use"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerAlgorithm_update"); + RNA_def_property_ui_text(prop, "Motion model", "Default motion model to use for tracking"); - /* pyramid level for pyramid klt tracking */ - prop = RNA_def_property(srna, "pyramid_levels", PROP_INT, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_sdna(prop, NULL, "pyramid_levels"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 1, 16); - RNA_def_property_ui_text(prop, "Pyramid levels", "Number of pyramid levels (increase on blurry footage)"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPyramid_update"); - - /* minmal correlation - only used for SAD tracker */ + /* minimum correlation */ prop = RNA_def_property(srna, "correlation_min", PROP_FLOAT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_float_sdna(prop, NULL, "minimum_correlation"); - RNA_def_property_range(prop, -1.0f, 1.0f); - RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.05, 3); RNA_def_property_ui_text(prop, "Correlation", "Minimal value of correlation between matched pattern and reference " - "which is still treated as successful tracking"); + "that is still treated as successful tracking"); + + /* use_brute */ + prop = RNA_def_property(srna, "use_brute", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Translation-only initialization", "Use a brute-force translation only pre-track before refinement"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); /* markers */ prop = RNA_def_property(srna, "markers", PROP_COLLECTION, PROP_NONE); From db46f9b5526bab22a9668f0c9e86e7dd9ea4f116 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 17 May 2012 18:55:34 +0000 Subject: [PATCH 055/360] fix a bug and storing a bool as a float --- source/blender/editors/transform/transform.c | 2 +- source/blender/editors/transform/transform_conversions.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 0b23bbc1b55..296da01a73e 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -237,7 +237,7 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) copy_v2_v2(v, vec); - if (t->options & CTX_MASK) { + if (t->options & CTX_MOVIECLIP) { float aspx, aspy; ED_space_clip_aspect(t->sa->spacedata.first, &aspx, &aspy); v[0] /= aspx; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index ee649888259..fa6dedc5990 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5824,7 +5824,7 @@ void flushTransTracking(TransInfo *t) /* * masking * */ typedef struct TransDataMasking{ - float is_handle; + int is_handle; float handle[2], orig_handle[2]; float vec[3][3]; From d78b7fc946de639bf1c29796b9ce6959ee4aad8f Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Thu, 17 May 2012 20:21:26 +0000 Subject: [PATCH 056/360] Fix the brute-force toggle in the motion tracker. --- source/blender/makesdna/DNA_tracking_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index f15bf4ba8d8..2be7722df8c 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -286,7 +286,7 @@ enum { #define TRACK_MOTION_MODEL_HOMOGRAPHY 5 /* MovieTrackingTrack->algorithm_flag */ -#define TRACK_ALGORITHM_FLAG_USE_BRUTE 0 +#define TRACK_ALGORITHM_FLAG_USE_BRUTE 1 /* MovieTrackingTrack->adjframes */ #define TRACK_MATCH_KEYFRAME 0 From d0ec55b8c28f9abe436fed339c59c1bb2104c494 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Thu, 17 May 2012 21:26:06 +0000 Subject: [PATCH 057/360] For the planar tracker, initialize the warp from the four correspondences after brute force translation search. --- extern/libmv/libmv-capi.cpp | 3 +- extern/libmv/libmv/tracking/track_region.cc | 34 ++++++++++++--------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index 482a4c98245..1781eaa747c 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -400,8 +400,7 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, if (track_region_result.termination == libmv::TrackRegionResult::PARAMETER_TOLERANCE || track_region_result.termination == libmv::TrackRegionResult::FUNCTION_TOLERANCE || track_region_result.termination == libmv::TrackRegionResult::GRADIENT_TOLERANCE || - track_region_result.termination == libmv::TrackRegionResult::NO_CONVERGENCE || - track_region_result.termination == libmv::TrackRegionResult::INSUFFICIENT_CORRELATION) + track_region_result.termination == libmv::TrackRegionResult::NO_CONVERGENCE) { tracking_result = true; } diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index 22c86a7f5b9..22b417c22f6 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -398,7 +398,7 @@ class Quad { struct TranslationWarp { TranslationWarp(const double *x1, const double *y1, const double *x2, const double *y2) { - Vec2 t = Quad(x2, y2).Centroid() - Quad(x1, y1).Centroid() ; + Vec2 t = Quad(x2, y2).Centroid() - Quad(x1, y1).Centroid(); parameters[0] = t[0]; parameters[1] = t[1]; } @@ -908,19 +908,6 @@ void TemplatedTrackRegion(const FloatImage &image1, } // TODO(keir): Check quads to ensure there is some area. - // Prepare the initial warp parameters from the four correspondences. - Warp warp(x1, y1, x2, y2); - - // Decide how many samples to use in the x and y dimensions. - int num_samples_x; - int num_samples_y; - PickSampling(x1, y1, x2, y2, &num_samples_x, &num_samples_y); - - // Compute the warp from rectangular coordinates. - Mat3 canonical_homography = ComputeCanonicalHomography(x1, y1, - num_samples_x, - num_samples_y); - // Prepare the image and gradient. Array3Df image_and_gradient1; Array3Df image_and_gradient2; @@ -938,8 +925,22 @@ void TemplatedTrackRegion(const FloatImage &image1, image2, options.num_extra_points, x1, y1, x2, y2); + for (int i = 0; i < 4; ++i) { + LG << "P" << i << ": (" << x1[i] << ", " << y1[i] << "); brute (" + << x2[i] << ", " << y2[i] << "); (dx, dy): (" << (x2[i] - x1[i]) << ", " + << (y2[i] - y1[i]) << ")."; + } } + // Prepare the initial warp parameters from the four correspondences. + // Note: This must happen after the brute initialization runs. + Warp warp(x1, y1, x2, y2); + + // Decide how many samples to use in the x and y dimensions. + int num_samples_x; + int num_samples_y; + PickSampling(x1, y1, x2, y2, &num_samples_x, &num_samples_y); + ceres::Solver::Options solver_options; solver_options.linear_solver_type = ceres::DENSE_QR; solver_options.max_num_iterations = options.max_iterations; @@ -957,6 +958,11 @@ void TemplatedTrackRegion(const FloatImage &image1, BoundaryCheckingCallback callback(image2, warp, x1, y1); solver_options.callbacks.push_back(&callback); + // Compute the warp from rectangular coordinates. + Mat3 canonical_homography = ComputeCanonicalHomography(x1, y1, + num_samples_x, + num_samples_y); + // Construct the warp cost function. AutoDiffCostFunction takes ownership. WarpCostFunctor *warp_cost_function = new WarpCostFunctor(options, From d38f2bc99fa274fbc957b504bbaf7fa9ec07d39e Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Thu, 17 May 2012 23:53:32 +0000 Subject: [PATCH 058/360] Implement support for affine tracking in the planar tracker; cleanups. --- extern/libmv/libmv/tracking/track_region.cc | 97 ++++++++++++++------- 1 file changed, 64 insertions(+), 33 deletions(-) diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index 22b417c22f6..58a2077acce 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -410,13 +410,6 @@ struct TranslationWarp { *y2 = y1 + warp_parameters[1]; } - template - void Backward(const T *warp_parameters, - const T &x2, const T& y2, T *x1, T* y1) const { - *x1 = x2 - warp_parameters[0]; - *y1 = y2 - warp_parameters[1]; - } - // Translation x, translation y. enum { NUM_PARAMETERS = 2 }; double parameters[NUM_PARAMETERS]; @@ -461,12 +454,6 @@ struct TranslationScaleWarp { *y2 = y1_scaled + warp_parameters[1]; } - template - void Backward(const T *warp_parameters, - const T &x2, const T& y2, T *x1, T* y1) const { - // XXX - } - // Translation x, translation y, scale. enum { NUM_PARAMETERS = 3 }; double parameters[NUM_PARAMETERS]; @@ -539,12 +526,6 @@ struct TranslationRotationWarp { *y2 = y1_rotated + warp_parameters[1]; } - template - void Backward(const T *warp_parameters, - const T &x2, const T& y2, T *x1, T* y1) const { - // XXX - } - // Translation x, translation y, rotation about the center of Q1 degrees. enum { NUM_PARAMETERS = 3 }; double parameters[NUM_PARAMETERS]; @@ -617,12 +598,6 @@ struct TranslationRotationScaleWarp { *y2 = y1_rotated_scaled + warp_parameters[1]; } - template - void Backward(const T *warp_parameters, - const T &x2, const T& y2, T *x1, T* y1) const { - // XXX - } - // Translation x, translation y, rotation about the center of Q1 degrees, // scale. enum { NUM_PARAMETERS = 4 }; @@ -631,7 +606,69 @@ struct TranslationRotationScaleWarp { Quad q1; }; -// TODO(keir): Finish affine warp. +struct AffineWarp { + AffineWarp(const double *x1, const double *y1, + const double *x2, const double *y2) + : q1(x1, y1) { + Quad q2(x2, y2); + + // The difference in centroids is the best guess for translation. + Vec2 t = q2.Centroid() - q1.Centroid(); + parameters[0] = t[0]; + parameters[1] = t[1]; + + // Estimate the four affine parameters with the usual least squares. + Mat Q1(8, 4); + Vec Q2(8); + for (int i = 0; i < 4; ++i) { + Vec2 v1 = q1.CornerRelativeToCentroid(i); + Vec2 v2 = q2.CornerRelativeToCentroid(i); + + Q1.row(2 * i + 0) << v1[0], v1[1], 0, 0 ; + Q1.row(2 * i + 1) << 0, 0, v1[0], v1[1]; + + Q2(2 * i + 0) = v2[0]; + Q2(2 * i + 1) = v2[1]; + } + + // TODO(keir): Check solution quality. + Vec4 a = Q1.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(Q2); + parameters[2] = a[0]; + parameters[3] = a[1]; + parameters[4] = a[2]; + parameters[5] = a[3]; + + std::cout << "a:" << a.transpose() << "\n"; + std::cout << "t:" << t.transpose() << "\n"; + } + + // See comments in other parameterizations about why the centroid is used. + template + void Forward(const T *p, const T &x1, const T& y1, T *x2, T* y2) const { + // Make the centroid of Q1 the origin. + const T x1_origin = x1 - q1.Centroid()(0); + const T y1_origin = y1 - q1.Centroid()(1); + + // Apply the affine transformation. + const T x1_origin_affine = p[2] * x1_origin + p[3] * y1_origin; + const T y1_origin_affine = p[4] * x1_origin + p[5] * y1_origin; + + // Translate back into the space of Q1 (but affine transformed). + const T x1_affine = x1_origin_affine + q1.Centroid()(0); + const T y1_affine = y1_origin_affine + q1.Centroid()(1); + + // Translate into the space of Q2. + *x2 = x1_affine + p[0]; + *y2 = y1_affine + p[1]; + } + + // Translation x, translation y, rotation about the center of Q1 degrees, + // scale. + enum { NUM_PARAMETERS = 6 }; + double parameters[NUM_PARAMETERS]; + + Quad q1; +}; struct HomographyWarp { HomographyWarp(const double *x1, const double *y1, @@ -674,12 +711,6 @@ struct HomographyWarp { *y2 = yy2 / zz2; } - template - void Backward(const T *warp_parameters, - const T &x2, const T& y2, T *x1, T* y1) const { - // XXX - } - enum { NUM_PARAMETERS = 8 }; double parameters[NUM_PARAMETERS]; }; @@ -1059,7 +1090,7 @@ void TrackRegion(const FloatImage &image1, HANDLE_MODE(TRANSLATION_SCALE, TranslationScaleWarp); HANDLE_MODE(TRANSLATION_ROTATION, TranslationRotationWarp); HANDLE_MODE(TRANSLATION_ROTATION_SCALE, TranslationRotationScaleWarp); - //HANDLE_MODE(AFFINE, AffineWarp); + HANDLE_MODE(AFFINE, AffineWarp); HANDLE_MODE(HOMOGRAPHY, HomographyWarp); #undef HANDLE_MODE } From 7414ccfeeb745ef0e86ee010137865b5398d10a0 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Fri, 18 May 2012 02:12:47 +0000 Subject: [PATCH 059/360] Add light-normalized tracking to the planar tracker This commit adds the ability to normalize patterns by their average value while tracking, to make them invariant to global illumination changes. To see this in action, check out the "Lobby" scene from Hollywood VFX. If you track the markers that are shadowed by the actress, previously they would not track. With the scale adaption on, the tracker would shrink the area to compensate for the changed illumination, losing the track. With "Normalize" turned on, the patch is correctly tracked and scale is maintained. A remaining problem is that only the Ceres cost function is updated to handle the normalization. The brute translation search does not take this into account. Perhaps "Prepass" (see below) should get disabled if normalization is enabled until I fix the prepass to normalize as well. There are a few other changes: - Cleanups in tracking RNA comments. - Bail out of the sampling loop early if the mask is zero; this saves expensive samples of the image derivatives. - Rename the wordy "Translation initialization" to "Prepass" at Sebastian's suggestion. - Fix a bug where the mask was ignored when sampling in the cost functor. --- extern/libmv/libmv-capi.cpp | 1 + extern/libmv/libmv-capi.h | 1 + extern/libmv/libmv/tracking/track_region.cc | 102 +++++++++++++++++- extern/libmv/libmv/tracking/track_region.h | 10 ++ release/scripts/startup/bl_ui/space_clip.py | 2 + source/blender/blenkernel/intern/tracking.c | 1 + source/blender/makesdna/DNA_tracking_types.h | 1 + source/blender/makesrna/intern/rna_tracking.c | 33 ++++-- 8 files changed, 139 insertions(+), 12 deletions(-) diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index 1781eaa747c..eba4698f198 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -381,6 +381,7 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, track_region_options.num_extra_points = 1; track_region_options.image1_mask = NULL; track_region_options.use_brute_initialization = options->use_brute; + track_region_options.use_normalized_intensities = options->use_normalization; /* Convert from raw float buffers to libmv's FloatImage. */ libmv::FloatImage old_patch, new_patch; diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index 9fedb9b9683..bbd8f0c30d0 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -55,6 +55,7 @@ struct libmv_trackRegionOptions { int motion_model; int num_iterations; int use_brute; + int use_normalization; double minimum_correlation; double sigma; }; diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index 58a2077acce..ababd0cee90 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -44,6 +44,7 @@ TrackRegionOptions::TrackRegionOptions() max_iterations(20), use_esm(true), use_brute_initialization(true), + use_normalized_intensities(false), sigma(0.9), num_extra_points(0), image1_mask(NULL) { @@ -191,6 +192,14 @@ class WarpCostFunctor { VLOG(2) << "warp_parameters[" << i << "]: " << warp_parameters[i]; } + T src_mean = T(1.0); + T dst_mean = T(1.0); + if (options_.use_normalized_intensities) { + ComputeNormalizingCoefficients(warp_parameters, + &src_mean, + &dst_mean); + } + int cursor = 0; for (int r = 0; r < num_samples_y_; ++r) { for (int c = 0; c < num_samples_x_; ++c) { @@ -198,6 +207,19 @@ class WarpCostFunctor { Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1); image1_position /= image1_position(2); + // Sample the mask early; if it's zero, this pixel has no effect. This + // allows early bailout from the expensive sampling that happens below. + double mask_value = 1.0; + if (options_.image1_mask != NULL) { + mask_value = AutoDiff::Sample(*options_.image1_mask, + image1_position[0], + image1_position[1]); + if (mask_value == 0.0) { + residuals[cursor++] = T(0.0); + continue; + } + } + // Compute the location of the destination pixel. T image2_position[2]; warp_.Forward(warp_parameters, @@ -206,7 +228,6 @@ class WarpCostFunctor { &image2_position[0], &image2_position[1]); - // Sample the destination, propagating derivatives. T dst_sample = AutoDiff::Sample(image_and_gradient2_, image2_position[0], @@ -239,6 +260,15 @@ class WarpCostFunctor { image1_position[1])); } + // Normalize the samples by the mean values of each signal. The typical + // light model assumes multiplicative intensity changes with changing + // light, so this is a reasonable choice. Note that dst_mean has + // derivative information attached thanks to autodiff. + if (options_.use_normalized_intensities) { + src_sample /= src_mean; + dst_sample /= dst_mean; + } + // The difference is the error. T error = src_sample - dst_sample; @@ -248,12 +278,80 @@ class WarpCostFunctor { image1_position[0], image1_position[1])); } - residuals[cursor++] = src_sample - dst_sample; + residuals[cursor++] = error; } } return true; } + // For normalized matching, the average and + template + void ComputeNormalizingCoefficients(const T *warp_parameters, + T *src_mean, + T *dst_mean) const { + + *src_mean = T(0.0); + *dst_mean = T(0.0); + double num_samples = 0.0; + for (int r = 0; r < num_samples_y_; ++r) { + for (int c = 0; c < num_samples_x_; ++c) { + // Compute the location of the source pixel (via homography). + Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1); + image1_position /= image1_position(2); + + // Sample the mask early; if it's zero, this pixel has no effect. This + // allows early bailout from the expensive sampling that happens below. + double mask_value = 1.0; + if (options_.image1_mask != NULL) { + mask_value = AutoDiff::Sample(*options_.image1_mask, + image1_position[0], + image1_position[1]); + if (mask_value == 0.0) { + continue; + } + } + + // Compute the location of the destination pixel. + T image2_position[2]; + warp_.Forward(warp_parameters, + T(image1_position[0]), + T(image1_position[1]), + &image2_position[0], + &image2_position[1]); + + + // Sample the destination, propagating derivatives. + // TODO(keir): This accumulation can, surprisingly, be done as a + // pre-pass by using integral images. This is complicated by the need + // to store the jets in the integral image, but it is possible. + T dst_sample = AutoDiff::Sample(image_and_gradient2_, + image2_position[0], + image2_position[1]); + + // Sample the source. + // TODO(keir): There is no reason to do this inside the loop; + // precompute this and reuse it. + T src_sample = T(AutoDiff::Sample(image_and_gradient1_, + image1_position[0], + image1_position[1])); + + // Weight the sample by the mask, if one is present. + if (options_.image1_mask != NULL) { + src_sample *= T(mask_value); + dst_sample *= T(mask_value); + } + + *src_mean += src_sample; + *dst_mean += dst_sample; + num_samples += mask_value; + } + } + *src_mean /= T(num_samples); + *dst_mean /= T(num_samples); + std::cout << "Normalization for src:\n" << *src_mean << "\n"; + std::cout << "Normalization for dst:\n" << *dst_mean << "\n"; + } + // TODO(keir): Consider also computing the cost here. double PearsonProductMomentCorrelationCoefficient( const double *warp_parameters) const { diff --git a/extern/libmv/libmv/tracking/track_region.h b/extern/libmv/libmv/tracking/track_region.h index 1a1346f544f..4a1427a6b9f 100644 --- a/extern/libmv/libmv/tracking/track_region.h +++ b/extern/libmv/libmv/tracking/track_region.h @@ -57,6 +57,16 @@ struct TrackRegionOptions { // that the nearby minima is correct, or the search area is too small. bool use_brute_initialization; + // If true, normalize the image patches by their mean before doing the sum of + // squared error calculation. This is reasonable since the effect of + // increasing light intensity is multiplicative on the pixel intensities. + // + // Note: This does nearly double the solving time, so it is not advised to + // turn this on all the time. + bool use_normalized_intensities; + + // The size in pixels of the blur kernel used to both smooth the image and + // take the image derivative. double sigma; // Extra points that should get transformed by the warp. This is useful diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index c17266cf303..ac5b4fe52f4 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -189,6 +189,7 @@ class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel): col.label(text="Tracker:") col.prop(settings, "default_motion_model") col.prop(settings, "default_use_brute") + col.prop(settings, "default_use_normalization") col.prop(settings, "default_correlation_min") col.separator() @@ -488,6 +489,7 @@ class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel): if active: col.prop(active, "motion_model") col.prop(active, "use_brute") + col.prop(active, "use_normalization") col.prop(active, "correlation_min") col.separator() diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 1956492fce9..2456411c2c2 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1735,6 +1735,7 @@ int BKE_tracking_next(MovieTrackingContext *context) /* Configure the tracker */ options.motion_model = track->motion_model; options.use_brute = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) == 0); + options.use_normalization = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) == 0); options.num_iterations = 50; options.minimum_correlation = track->minimum_correlation; options.sigma = 0.9; diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 2be7722df8c..a720a14fdcb 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -287,6 +287,7 @@ enum { /* MovieTrackingTrack->algorithm_flag */ #define TRACK_ALGORITHM_FLAG_USE_BRUTE 1 +#define TRACK_ALGORITHM_FLAG_USE_NORMALIZATION 2 /* MovieTrackingTrack->adjframes */ #define TRACK_MATCH_KEYFRAME 0 diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 34dd471e9c1..565655ccf37 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -590,14 +590,14 @@ static void rna_def_trackingSettings(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "motion_flag", TRACKING_MOTION_TRIPOD); RNA_def_property_ui_text(prop, "Tripod Motion", "Use special solver to track a stable camera position, such as a tripod"); - /* limit frames */ + /* default_limit_frames */ prop = RNA_def_property(srna, "default_frames_limit", PROP_INT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_sdna(prop, NULL, "default_frames_limit"); RNA_def_property_range(prop, 0, SHRT_MAX); RNA_def_property_ui_text(prop, "Frames Limit", "Every tracking cycle, this number of frames are tracked"); - /* pattern match */ + /* default_pattern_match */ prop = RNA_def_property(srna, "default_pattern_match", PROP_ENUM, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_enum_sdna(prop, NULL, "default_pattern_match"); @@ -605,14 +605,14 @@ static void rna_def_trackingSettings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Pattern Match", "Track pattern from given frame when tracking marker to next frame"); - /* margin */ + /* default_margin */ prop = RNA_def_property(srna, "default_margin", PROP_INT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_sdna(prop, NULL, "default_margin"); RNA_def_property_range(prop, 0, 300); RNA_def_property_ui_text(prop, "Margin", "Default distance from image boudary at which marker stops tracking"); - /* tracking motion model */ + /* default_tracking_motion_model */ prop = RNA_def_property(srna, "default_motion_model", PROP_ENUM, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -622,10 +622,16 @@ static void rna_def_trackingSettings(BlenderRNA *brna) /* use_brute */ prop = RNA_def_property(srna, "default_use_brute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); - RNA_def_property_ui_text(prop, "Translation-only initialization", "Use a brute-force translation-only initialization when tracking"); + RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation-only initialization when tracking"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); - /* minmal correlation */ + /* default use_normalization */ + prop = RNA_def_property(srna, "default_use_normalization", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); + RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking. Slower."); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* default minmal correlation */ prop = RNA_def_property(srna, "default_correlation_min", PROP_FLOAT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -652,19 +658,19 @@ static void rna_def_trackingSettings(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_searchUpdate"); RNA_def_property_ui_text(prop, "Search Size", "Size of search area for newly created tracks"); - /* use_red_channel */ + /* default use_red_channel */ prop = RNA_def_property(srna, "use_default_red_channel", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_RED); RNA_def_property_ui_text(prop, "Use Red Channel", "Use red channel from footage for tracking"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); - /* use_green_channel */ + /* default_use_green_channel */ prop = RNA_def_property(srna, "use_default_green_channel", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_GREEN); RNA_def_property_ui_text(prop, "Use Green Channel", "Use green channel from footage for tracking"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); - /* use_blue_channel */ + /* default_use_blue_channel */ prop = RNA_def_property(srna, "use_default_blue_channel", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_BLUE); RNA_def_property_ui_text(prop, "Use Blue Channel", "Use blue channel from footage for tracking"); @@ -928,7 +934,14 @@ static void rna_def_trackingTrack(BlenderRNA *brna) prop = RNA_def_property(srna, "use_brute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Translation-only initialization", "Use a brute-force translation only pre-track before refinement"); + RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation only pre-track before refinement"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* use_brute */ + prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking. Slower."); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); /* markers */ From f21cd531d6233ec95e1f3515ba1d77977154d5c9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 May 2012 08:59:05 +0000 Subject: [PATCH 060/360] mask editor now stores points/handles in 1:1 aspect, makes tool code _much_ more logical/easier. --- source/blender/blenkernel/BKE_mask.h | 5 ++ source/blender/blenkernel/intern/mask.c | 50 ++++++++++++++++++- source/blender/editors/mask/mask_editor.c | 1 + .../editors/space_clip/clip_dopesheet_ops.c | 2 + .../blender/editors/space_clip/clip_editor.c | 5 +- .../blender/editors/space_clip/space_clip.c | 22 +++++++- source/blender/editors/transform/transform.c | 48 +++++++++++++----- .../editors/transform/transform_conversions.c | 5 +- .../composite/nodes/node_composite_mask.c | 20 ++++++++ 9 files changed, 136 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 26beed4645c..1c64e00630c 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -34,6 +34,8 @@ struct MaskShape; struct MaskSpline; struct MaskSplinePoint; struct MaskSplinePointUW; +struct MovieClip; +struct MovieClipUser; struct Scene; /* shapes */ @@ -77,6 +79,9 @@ struct Mask *BKE_mask_new(const char *name); void BKE_mask_free(struct Mask *mask); void BKE_mask_unlink(struct Main *bmain, struct Mask *mask); +void BKE_mask_coord_from_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]); +void BKE_mask_coord_to_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]); + /* parenting */ void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 0af0c1c7aa5..ae8a6fa737c 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -52,6 +52,7 @@ #include "BKE_main.h" #include "BKE_mask.h" #include "BKE_tracking.h" +#include "BKE_movieclip.h" #include "BKE_utildefines.h" /* shapes */ @@ -727,6 +728,49 @@ void BKE_mask_unlink(Main *bmain, Mask *mask) mask->id.us = 0; } +void BKE_mask_coord_from_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) +{ + int width, height; + + /* scaling for the clip */ + BKE_movieclip_get_size(clip, user, &width, &height); + + if (width == height) { + r_co[0] = co[0]; + r_co[1] = co[1]; + } + else if (width < height) { + r_co[0] = ((co[0] - 0.5f) * ((float)width / (float)height)) + 0.5f; + r_co[1] = co[1]; + } + else { /* (width > height) */ + r_co[0] = co[0]; + r_co[1] = ((co[1] - 0.5f) * ((float)height / (float)width)) + 0.5f; + } +} + +/* as above but divide */ +void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) +{ + int width, height; + + /* scaling for the clip */ + BKE_movieclip_get_size(clip, user, &width, &height); + + if (width == height) { + r_co[0] = co[0]; + r_co[1] = co[1]; + } + else if (width < height) { + r_co[0] = ((co[0] - 0.5f) / ((float)width / (float)height)) + 0.5f; + r_co[1] = co[1]; + } + else { /* (width > height) */ + r_co[0] = co[0]; + r_co[1] = ((co[1] - 0.5f) / ((float)height / (float)width)) + 0.5f; + } +} + static void evaluate_mask_parent(MaskParent *parent, float ctime, float co[2]) { if (!parent) @@ -744,10 +788,12 @@ static void evaluate_mask_parent(MaskParent *parent, float ctime, float co[2]) if (ob) { MovieTrackingTrack *track = BKE_tracking_named_track(tracking, ob, parent->sub_parent); + MovieClipUser user = {0}; + user.framenr = ctime; + if (track) { MovieTrackingMarker *marker = BKE_tracking_get_marker(track, ctime); - - copy_v2_v2(co, marker->pos); + BKE_mask_coord_from_movieclip(clip, &user, co, marker->pos); } } } diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index 633f75c643b..a868696941c 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -81,6 +81,7 @@ void ED_mask_mouse_pos(bContext *C, wmEvent *event, float co[2]) if (sc) { ED_clip_mouse_pos(C, event, co); + BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co); } else { /* possible other spaces from which mask editing is available */ diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c index 78e346cba47..4a390241629 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_ops.c +++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c @@ -59,6 +59,7 @@ #include "clip_intern.h" // own include +#if 0 static int ED_space_clip_dopesheet_poll(bContext *C) { SpaceClip *sc = CTX_wm_space_clip(C); @@ -73,6 +74,7 @@ static int ED_space_clip_dopesheet_poll(bContext *C) return FALSE; } +#endif /********************** select channel operator *********************/ diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 1126e96b194..afcd18dfbe8 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -268,10 +268,13 @@ void ED_space_clip_mask_aspect(SpaceClip *sc, float *aspx, float *aspy) int w, h; ED_space_clip_aspect(sc, aspx, aspy); - ED_space_clip_size(sc, &w, &h); + ED_space_clip_size(sc, &w, &h); + /* now this is not accounted for! */ +#if 0 *aspx *= (float)w; *aspy *= (float)h; +#endif if(*aspx < *aspy) { *aspy= *aspy / *aspx; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index c1bbc75c87a..b4810a22608 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -1101,6 +1101,10 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) int width, height; float zoomx, zoomy, aspx, aspy; + /* frame image */ + float maxdim; + float xofs, yofs; + /* find window pixel coordinates of origin */ UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); @@ -1108,10 +1112,24 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); ED_space_clip_aspect(sc, &aspx, &aspy); + /* frame the image */ + maxdim = maxf(width, height); + if (width == height) { + xofs = yofs = 0; + } + else if (width < height) { + xofs = ((height - width) / -2.0f) * zoomx; + yofs = 0.0f; + } + else { /* (width > height) */ + xofs = 0.0f; + yofs = ((width - height) / -2.0f) * zoomy; + } + /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ glPushMatrix(); - glTranslatef(x, y, 0); - glScalef(width*zoomx, height*zoomy, 0); + glTranslatef(x + xofs, y + yofs, 0); + glScalef(maxdim * zoomx, maxdim * zoomy, 0); glMultMatrixf(sc->stabmat); ED_mask_draw((bContext *)C, width*aspx, height*aspy, zoomx, zoomy); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 296da01a73e..d3626851173 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -163,12 +163,22 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) else if (t->spacetype==SPACE_CLIP) { View2D *v2d = t->view; float divx, divy; + float mulx, muly; divx = v2d->mask.xmax-v2d->mask.xmin; divy = v2d->mask.ymax-v2d->mask.ymin; - r_vec[0] = (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx; - r_vec[1] = (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy; + mulx = (v2d->cur.xmax-v2d->cur.xmin); + muly = (v2d->cur.ymax-v2d->cur.ymin); + + if (t->options & CTX_MASK) { + /* clamp w/h, mask only */ + divx = divy = minf(divx, divy); + mulx = muly = minf(mulx, muly); + } + + r_vec[0] = mulx * (dx) / divx; + r_vec[1] = muly * (dy) / divy; r_vec[2] = 0.0f; if (t->options & CTX_MASK) { @@ -303,17 +313,22 @@ void applyAspectRatio(TransInfo *t, float vec[2]) if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { SpaceClip *sc = t->sa->spacedata.first; float aspx, aspy; - int width, height; - ED_space_clip_size(sc, &width, &height); - if (t->options & CTX_MOVIECLIP) + if (t->options & CTX_MOVIECLIP) { + int width, height; + ED_space_clip_size(sc, &width, &height); ED_space_clip_aspect(sc, &aspx, &aspy); - else if (t->options & CTX_MASK) + + vec[0] *= width / aspx; + vec[1] *= height / aspy; + } + else if (t->options & CTX_MASK) { ED_space_clip_mask_aspect(sc, &aspx, &aspy); - vec[0] *= width / aspx; - vec[1] *= height / aspy; + vec[0] /= aspx; + vec[1] /= aspy; + } } } } @@ -340,15 +355,22 @@ void removeAspectRatio(TransInfo *t, float vec[2]) if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { SpaceClip *sc = t->sa->spacedata.first; float aspx, aspy; - int width, height; - if (t->options & CTX_MOVIECLIP) + if (t->options & CTX_MOVIECLIP) { + int width, height; ED_space_clip_size(sc, &width, &height); - else if (t->options & CTX_MASK) ED_space_clip_aspect(sc, &aspx, &aspy); - vec[0] *= aspx / width; - vec[1] *= aspy / height; + vec[0] *= aspx / width; + vec[1] *= aspy / height; + } + else if (t->options & CTX_MASK) { + ED_space_clip_aspect(sc, &aspx, &aspy); + ED_space_clip_mask_aspect(sc, &aspx, &aspy); + + vec[0] *= aspx; + vec[1] *= aspy; + } } } } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index fa6dedc5990..1ea32b78a9e 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5875,12 +5875,9 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, TransDat } } else { - int width, height; - tdm->is_handle = TRUE; - ED_space_clip_mask_size(sc, &width, &height); - BKE_mask_point_handle(point, width, height, tdm->handle); + BKE_mask_point_handle(point, aspx, aspy, tdm->handle); copy_v2_v2(tdm->orig_handle, tdm->handle); diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c index 1dbe057a869..a586824e6e1 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mask.c +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -94,6 +94,26 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); + /* TODO, make this optional! */ + if (sx != sy) { + float *fp; + int i; + float asp; + + if (sx < sy) { + fp = &diff_points[0]; + asp = (float)sx / (float)sy; + } + else { + fp = &diff_points[1]; + asp = (float)sy / (float)sx; + } + + for (i = 0; i < tot_diff_point; i++, fp += 2) { + (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; + } + } + if (tot_diff_point) { PLX_raskterize(diff_points, tot_diff_point, res, sx, sy); From 2da49c4a8f1eea7ac382c0a38e69f2c3de30f4ea Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 18 May 2012 09:33:50 +0000 Subject: [PATCH 061/360] Rotation support for motion tracking markers Implemented general transformation tool Rotation for motion tracking data. Mainly used to rotate pattern of markers. To achieve most of usability, added configurable pivot point which is in fact was median point before, but now can be chosen from boundbox center, median point or individual centers. Individual centers means transformation would be performed around marker's position, which is useful for rotation and scale. Also implemented alternative scaling transformation -- hit S, S leads to scaling of pattern area only. TODO: - clamping in some cases isn't working well, but that's easier to be resolved after moving search are to marker. - Update startup.blend so clip editor in Motion Tracking screen would be set to Individual Centers by default. --- release/scripts/startup/bl_ui/space_clip.py | 3 +- source/blender/blenloader/intern/readfile.c | 19 +++ source/blender/editors/include/ED_clip.h | 1 + .../blender/editors/space_clip/clip_editor.c | 39 +++++- .../blender/editors/space_clip/space_clip.c | 2 + source/blender/editors/transform/transform.c | 55 +++++---- .../editors/transform/transform_conversions.c | 113 +++++++++++------- .../editors/transform/transform_generics.c | 9 ++ source/blender/makesdna/DNA_space_types.h | 2 +- source/blender/makesrna/intern/rna_space.c | 17 +++ 10 files changed, 190 insertions(+), 70 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index ac5b4fe52f4..90b3901c002 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -54,7 +54,8 @@ class CLIP_HT_header(Header): if clip: if sc.view == 'CLIP': layout.prop(sc, "mode", text="") - if sc.view == 'GRAPH': + layout.prop(sc, "pivot_point", text="", icon_only=True) + elif sc.view == 'GRAPH': row = layout.row(align=True) if sc.show_filters: diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index bb944eaf429..2e30f756b43 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7612,6 +7612,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) { MovieClip *clip; + bScreen *sc; for (clip = main->movieclip.first; clip; clip = clip->id.next) { MovieTrackingTrack *track; @@ -7643,6 +7644,24 @@ static void do_versions(FileData *fd, Library *lib, Main *main) track = track->next; } } + + for (sc = main->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_CLIP) { + SpaceClip *sclip = (SpaceClip *)sl; + + if (sclip->around == 0) { + sclip->around = V3D_CENTROID; + } + } + } + } + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 846100b0d19..7e1505b652f 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -58,6 +58,7 @@ struct Mask *ED_space_clip_mask(struct SpaceClip *sc); void ED_space_clip_size(struct SpaceClip *sc, int *width, int *height); void ED_space_clip_zoom(struct SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy); void ED_space_clip_aspect(struct SpaceClip *sc, float *aspx, float *aspy); +void ED_space_clip_aspect_dimension_aware(struct SpaceClip *sc, float *aspx, float *aspy); void ED_space_clip_mask_size(struct SpaceClip *sc, int *width, int *height); void ED_space_clip_mask_aspect(struct SpaceClip *sc, float *aspx, float *aspy); diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index afcd18dfbe8..f16ef21b707 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -249,9 +249,15 @@ void ED_space_clip_size(SpaceClip *sc, int *width, int *height) void ED_space_clip_mask_size(SpaceClip *sc, int *width, int *height) { - if(!sc->mask) { - *width= 0; - *height= 0; + /* quite the same as ED_space_clip_size, but it also runs aspect correction on output resolution + * this is needed because mask should be rasterized with exactly the same resolution as + * currently displaying frame and it doesn't have access to aspect correction currently + * used for display. (sergey) + */ + + if (!sc->mask) { + *width = 0; + *height = 0; } else { float aspx, aspy; @@ -306,6 +312,33 @@ void ED_space_clip_aspect(SpaceClip *sc, float *aspx, float *aspy) *aspx = *aspy = 1.0f; } +void ED_space_clip_aspect_dimension_aware(SpaceClip *sc, float *aspx, float *aspy) +{ + int w, h; + + /* most of tools does not require aspect to be returned with dimensions correction + * due to they're invariant to this stuff, but some transformation tools like rotation + * should be aware of aspect correction caused by different resolution in different + * directions. + * mainly this is sued for transformation stuff + */ + + ED_space_clip_aspect(sc, aspx, aspy); + ED_space_clip_size(sc, &w, &h); + + *aspx *= (float)w; + *aspy *= (float)h; + + if(*aspx < *aspy) { + *aspy= *aspy / *aspx; + *aspx= 1.0f; + } + else { + *aspx= *aspx / *aspy; + *aspy= 1.0f; + } +} + void ED_clip_update_frame(const Main *mainp, int cfra) { wmWindowManager *wm; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index b4810a22608..6ebcaf4ea16 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -35,6 +35,7 @@ #include "DNA_scene_types.h" #include "DNA_mask_types.h" #include "DNA_movieclip_types.h" +#include "DNA_view3d_types.h" /* for pivot point */ #include "MEM_guardedalloc.h" @@ -239,6 +240,7 @@ static SpaceLink *clip_new(const bContext *C) sc->zoom = 1.0f; sc->path_length = 20; sc->scopes.track_preview_height = 120; + sc->around = V3D_LOCAL; /* header */ ar = MEM_callocN(sizeof(ARegion), "header for clip"); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index d3626851173..06bcf11bfe4 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -244,21 +244,17 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) } else if (t->spacetype==SPACE_CLIP) { float v[2]; + float aspx = 1.0f, aspy = 1.0f; copy_v2_v2(v, vec); - if (t->options & CTX_MOVIECLIP) { - float aspx, aspy; - ED_space_clip_aspect(t->sa->spacedata.first, &aspx, &aspy); - v[0] /= aspx; - v[1] /= aspy; - } - else if (t->options & CTX_MASK) { - float aspx, aspy; + if (t->options & CTX_MOVIECLIP) + ED_space_clip_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy); + else if (t->options & CTX_MASK) ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy); - v[0] /= aspx; - v[1] /= aspy; - } + + v[0] /= aspx; + v[1] /= aspy; UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr+1); } @@ -316,12 +312,10 @@ void applyAspectRatio(TransInfo *t, float vec[2]) if (t->options & CTX_MOVIECLIP) { - int width, height; - ED_space_clip_size(sc, &width, &height); - ED_space_clip_aspect(sc, &aspx, &aspy); + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); - vec[0] *= width / aspx; - vec[1] *= height / aspy; + vec[0] /= aspx; + vec[1] /= aspy; } else if (t->options & CTX_MASK) { ED_space_clip_mask_aspect(sc, &aspx, &aspy); @@ -357,12 +351,10 @@ void removeAspectRatio(TransInfo *t, float vec[2]) float aspx, aspy; if (t->options & CTX_MOVIECLIP) { - int width, height; - ED_space_clip_size(sc, &width, &height); - ED_space_clip_aspect(sc, &aspx, &aspy); + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); - vec[0] *= aspx / width; - vec[1] *= aspy / height; + vec[0] *= aspx; + vec[1] *= aspy; } else if (t->options & CTX_MASK) { ED_space_clip_aspect(sc, &aspx, &aspy); @@ -711,7 +703,7 @@ int transformEvent(TransInfo *t, wmEvent *event) t->redraw |= TREDRAW_HARD; } else if (t->mode == TFM_TRANSLATION) { - if(t->options & (CTX_MOVIECLIP | CTX_MASK)) { + if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { restoreTransObjects(t); t->flag ^= T_ALT_TRANSFORM; @@ -721,7 +713,7 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case TFM_MODAL_ROTATE: /* only switch when... */ - if (!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) { + if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) { if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { resetTransRestrictions(t); @@ -748,6 +740,14 @@ int transformEvent(TransInfo *t, wmEvent *event) initSnapping(t, NULL); // need to reinit after mode change t->redraw |= TREDRAW_HARD; } + else if (t->mode == TFM_RESIZE) { + if (t->options & CTX_MOVIECLIP) { + restoreTransObjects(t); + + t->flag ^= T_ALT_TRANSFORM; + t->redraw |= TREDRAW_HARD; + } + } break; case TFM_MODAL_SNAP_INV_ON: @@ -976,7 +976,7 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case RKEY: /* only switch when... */ - if (!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) { + if (!(t->options & CTX_TEXTURE)) { if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { resetTransRestrictions(t); @@ -2737,6 +2737,9 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { copy_v3_v3(center, td->center); } + else if (t->options & CTX_MOVIECLIP) { + copy_v3_v3(center, td->center); + } else { copy_v3_v3(center, t->center); } @@ -3020,6 +3023,10 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short { center = td->center; } + + if (t->options & CTX_MOVIECLIP) { + center = td->center; + } } if (t->flag & T_POINTS) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 1ea32b78a9e..85d54c0d6e3 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5388,23 +5388,24 @@ typedef struct TransDataTracking { short coord; } TransDataTracking; -static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt, MovieTrackingTrack *track, - int area, float *loc, float *rel, float *off) +static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt, + MovieTrackingTrack *track, MovieTrackingMarker *marker, + int area, float *loc, float *rel, float *off, float aspx, float aspy) { int anchor = area == TRACK_AREA_POINT && off; tdt->mode = transDataTracking_ModeTracks; if (anchor) { - td2d->loc[0] = rel[0]; /* hold original location */ - td2d->loc[1] = rel[1]; + td2d->loc[0] = rel[0] * aspx; /* hold original location */ + td2d->loc[1] = rel[1] * aspy; tdt->loc= loc; td2d->loc2d = loc; /* current location */ } else { - td2d->loc[0] = loc[0]; /* hold original location */ - td2d->loc[1] = loc[1]; + td2d->loc[0] = loc[0] * aspx; /* hold original location */ + td2d->loc[1] = loc[1] * aspy; td2d->loc2d = loc; /* current location */ } @@ -5418,8 +5419,8 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra if (rel) { if (!anchor) { - td2d->loc[0] += rel[0]; - td2d->loc[1] += rel[1]; + td2d->loc[0] += rel[0] * aspx; + td2d->loc[1] += rel[1] * aspy; } copy_v2_v2(tdt->srelative, rel); @@ -5430,9 +5431,12 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra td->flag = 0; td->loc = td2d->loc; - copy_v3_v3(td->center, td->loc); copy_v3_v3(td->iloc, td->loc); + //copy_v3_v3(td->center, td->loc); + td->center[0] = marker->pos[0] * aspx; + td->center[1] = marker->pos[1] * aspy; + memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; @@ -5447,28 +5451,36 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra } static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d, - TransDataTracking *tdt, MovieTrackingTrack *track) + TransDataTracking *tdt, MovieTrackingTrack *track, float aspx, float aspy) { MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, sc->user.framenr); tdt->flag = marker->flag; marker->flag &= ~(MARKER_DISABLED|MARKER_TRACKED); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, track->offset, marker->pos, track->offset); + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT, + track->offset, marker->pos, track->offset, aspx, aspy); - if (track->flag & SELECT) - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, marker->pos, NULL, NULL); + if (track->flag & SELECT) { + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT, + marker->pos, NULL, NULL, aspx, aspy); + } if (track->pat_flag & SELECT) { - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, marker->pattern_corners[0], marker->pos, NULL); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, marker->pattern_corners[1], marker->pos, NULL); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, marker->pattern_corners[2], marker->pos, NULL); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, marker->pattern_corners[3], marker->pos, NULL); + int a; + + for (a = 0; a < 4; a++) { + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_PAT, + marker->pattern_corners[a], marker->pos, NULL, aspx, aspy); + } } if (track->search_flag & SELECT) { - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_min, marker->pos, NULL); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_max, marker->pos, NULL); + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH, + track->search_min, marker->pos, NULL, aspx, aspy); + + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH, + track->search_max, marker->pos, NULL, aspx, aspy); } } @@ -5495,6 +5507,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) MovieTrackingMarker *marker; TransDataTracking *tdt; int framenr = sc->user.framenr; + float aspx, aspy; /* count */ t->total = 0; @@ -5522,6 +5535,8 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) if (t->total == 0) return; + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); + td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransTracking TransData"); td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransTracking TransData2D"); tdt = t->customData = MEM_callocN(t->total*sizeof(TransDataTracking), "TransTracking TransDataTracking"); @@ -5534,7 +5549,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { marker = BKE_tracking_get_marker(track, framenr); - trackToTransData(sc, td, td2d, tdt, track); + trackToTransData(sc, td, td2d, tdt, track, aspx, aspy); /* offset */ td++; @@ -5704,9 +5719,6 @@ static void createTransTrackingData(bContext *C, TransInfo *t) if (!clip || width == 0 || height == 0) return; - if (!ELEM(t->mode, TFM_RESIZE, TFM_TRANSLATION)) - return; - if (ar->regiontype == RGN_TYPE_PREVIEW) { /* transformation was called from graph editor */ createTransTrackingCurvesData(C, t); @@ -5774,10 +5786,14 @@ static void cancelTransTracking(TransInfo *t) void flushTransTracking(TransInfo *t) { + SpaceClip *sc = t->sa->spacedata.first; TransData *td; TransData2D *td2d; TransDataTracking *tdt; int a; + float aspx, aspy; + + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); if (t->state == TRANS_CANCEL) cancelTransTracking(t); @@ -5785,31 +5801,46 @@ void flushTransTracking(TransInfo *t) /* flush to 2d vector from internally used 3d vector */ for (a=0, td= t->data, td2d= t->data2d, tdt= t->customData; atotal; a++, td2d++, td++, tdt++) { if (tdt->mode == transDataTracking_ModeTracks) { + float loc2d[2]; + + if (t->mode == TFM_ROTATION && tdt->area == TRACK_AREA_SEARCH) { + continue; + } + + loc2d[0] = td2d->loc[0] / aspx; + loc2d[1] = td2d->loc[1] / aspy; + if (t->flag & T_ALT_TRANSFORM) { - if (tdt->area == TRACK_AREA_POINT && tdt->relative) { - float d[2], d2[2]; + if (t->mode == TFM_RESIZE) { + if (tdt->area != TRACK_AREA_PAT) + continue; + } + else if (t->mode == TFM_TRANSLATION) { + if (tdt->area == TRACK_AREA_POINT && tdt->relative) { + float d[2], d2[2]; - if (!tdt->smarkers) { - tdt->smarkers = MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers"); - for (a = 0; a < tdt->markersnr; a++) - copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos); + if (!tdt->smarkers) { + tdt->smarkers = MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers"); + for (a = 0; a < tdt->markersnr; a++) + copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos); + } + + sub_v2_v2v2(d, loc2d, tdt->soffset); + sub_v2_v2(d, tdt->srelative); + + sub_v2_v2v2(d2, loc2d, tdt->srelative); + + for (a= 0; amarkersnr; a++) + add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2); + + negate_v2_v2(td2d->loc2d, d); } - - sub_v2_v2v2(d, td2d->loc, tdt->soffset); - sub_v2_v2(d, tdt->srelative); - - sub_v2_v2v2(d2, td2d->loc, tdt->srelative); - - for (a= 0; amarkersnr; a++) - add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2); - - negate_v2_v2(td2d->loc2d, d); } } if (tdt->area!=TRACK_AREA_POINT || tdt->relative==0) { - td2d->loc2d[0] = td2d->loc[0]; - td2d->loc2d[1] = td2d->loc[1]; + td2d->loc2d[0] = loc2d[0]; + td2d->loc2d[1] = loc2d[1]; if (tdt->relative) sub_v2_v2(td2d->loc2d, tdt->relative); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index d2f27b87b8c..e3ca0957c25 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -660,6 +660,10 @@ static void recalcData_spaceclip(TransInfo *t) if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); } + else if (t->mode == TFM_ROTATION) { + if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) + BKE_tracking_clamp_track(track, CLAMP_PAT_DIM); + } } track = track->next; @@ -1114,6 +1118,11 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->view = &ar->v2d; t->around = sipo->around; } + else if (t->spacetype==SPACE_CLIP) { + SpaceClip *sclip = sa->spacedata.first; + t->view = &ar->v2d; + t->around = sclip->around; + } else { if (ar) { // XXX for now, get View2D from the active region diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 640961f80f2..da07ffd7f9a 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -532,7 +532,7 @@ typedef struct SpaceClip { short dope_sort; /* sort order in dopesheet view */ short dope_flag; /* dopsheet view flags */ - int pad3; + int around; /* pivot point for transforms */ /* **** mask editing **** */ struct Mask *mask; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index d63110c4646..b2c13f8717a 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2989,6 +2989,16 @@ static void rna_def_space_clip(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem pivot_items[] = { + {V3D_CENTER, "BOUNDING_BOX_CENTER", ICON_ROTATE, "Bounding Box Center", + "Pivot around bounding box center of selected object(s)"}, + {V3D_LOCAL, "INDIVIDUAL_ORIGINS", ICON_ROTATECOLLECTION, + "Individual Origins", "Pivot around each object's own origin"}, + {V3D_CENTROID, "MEDIAN_POINT", ICON_ROTATECENTER, "Median Point", + "Pivot around the median point of selected objects"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SpaceClipEditor", "Space"); RNA_def_struct_sdna(srna, "SpaceClip"); RNA_def_struct_ui_text(srna, "Space Clip Editor", "Clip editor space data"); @@ -3182,6 +3192,13 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Grease Pencil Source", "Where the grease pencil comes from"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); + /* pivot point */ + prop = RNA_def_property(srna, "pivot_point", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "around"); + RNA_def_property_enum_items(prop, pivot_items); + RNA_def_property_ui_text(prop, "Pivot Point", "Pivot center for rotation/scaling"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + /* ** dopesheet ** */ /* dopesheet sort */ From a8a22d968c637a877210fc756e74731d9403f455 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 May 2012 09:36:32 +0000 Subject: [PATCH 062/360] mask: remove aspect arguments which are no longer needed. --- source/blender/blenkernel/BKE_mask.h | 11 ++--- source/blender/blenkernel/intern/mask.c | 48 +++++++------------ source/blender/editors/include/ED_mask.h | 2 +- source/blender/editors/mask/mask_draw.c | 43 +++++------------ source/blender/editors/mask/mask_ops.c | 24 +++++----- .../blender/editors/space_clip/space_clip.c | 2 +- .../editors/transform/transform_conversions.c | 2 +- source/blender/makesdna/DNA_mask_types.h | 12 ++--- 8 files changed, 55 insertions(+), 89 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 1c64e00630c..88934e4af84 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -54,21 +54,20 @@ void BKE_mask_shape_unique_name(struct Mask *mask, struct MaskShape *shape); struct MaskSpline *BKE_mask_spline_add(struct MaskShape *shape); int BKE_mask_spline_resolution(struct MaskSpline *spline); float *BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point); -float *BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, float aspx, - float aspy, int *tot_feather_point); -float *BKE_mask_spline_feather_points(struct MaskSpline *spline, float aspx, float aspy, int *tot_feather_point); +float *BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point); +float *BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point); /* point */ int BKE_mask_point_has_handle(struct MaskSplinePoint *point); -void BKE_mask_point_handle(struct MaskSplinePoint *point, float aspx, float aspy, float handle[2]); +void BKE_mask_point_handle(struct MaskSplinePoint *point, float handle[2]); void BKE_mask_point_set_handle(struct MaskSplinePoint *point, float loc[2], int keep_direction, float aspx, float aspy, float orig_handle[2], float orig_vec[3][3]); float *BKE_mask_point_segment_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, int *tot_diff_point); float *BKE_mask_point_segment_feather_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, - float aspx, float aspy, int *tot_feather_point); + int *tot_feather_point); void BKE_mask_point_segment_co(struct MaskSpline *spline, struct MaskSplinePoint *point, float u, float co[2]); void BKE_mask_point_normal(struct MaskSpline *spline, struct MaskSplinePoint *point, - float aspx, float aspy, float u, float n[2]); + float u, float n[2]); float BKE_mask_point_weight(struct MaskSpline *spline, struct MaskSplinePoint *point, float u); struct MaskSplinePointUW *BKE_mask_point_sort_uw(struct MaskSplinePoint *point, struct MaskSplinePointUW *uw); void BKE_mask_point_add_uw(struct MaskSplinePoint *point, float u, float w); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index ae8a6fa737c..863945e6baf 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -257,8 +257,7 @@ float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) return diff_points; } -float *BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, float aspx, float aspy, - int *tot_feather_point) +float *BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point) { float *feather, *fp; int i, j, tot, resol = BKE_mask_spline_feather_resolution(spline); @@ -274,7 +273,7 @@ float *BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, float a float co[2], n[2]; BKE_mask_point_segment_co(spline, point, u, co); - BKE_mask_point_normal(spline, point, aspx, aspy, u, n); + BKE_mask_point_normal(spline, point, u, n); weight = BKE_mask_point_weight(spline, point, u); fp[0] = co[0] + n[0] * weight; @@ -287,7 +286,7 @@ float *BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, float a return feather; } -float *BKE_mask_spline_feather_points(MaskSpline *spline, float aspx, float aspy, int *tot_feather_point) +float *BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point) { int i, tot = 0; float *feather, *fp; @@ -308,7 +307,7 @@ float *BKE_mask_spline_feather_points(MaskSpline *spline, float aspx, float aspy float weight, n[2]; int j; - BKE_mask_point_normal(spline, point, aspx, aspy, 0.0f, n); + BKE_mask_point_normal(spline, point, 0.0f, n); weight = BKE_mask_point_weight(spline, point, 0.0f); fp[0] = bezt->vec[1][0] + n[0] * weight; @@ -320,7 +319,7 @@ float *BKE_mask_spline_feather_points(MaskSpline *spline, float aspx, float aspy float co[2]; BKE_mask_point_segment_co(spline, point, u, co); - BKE_mask_point_normal(spline, point, aspx, aspy, u, n); + BKE_mask_point_normal(spline, point, u, n); weight = BKE_mask_point_weight(spline, point, u); fp[0] = co[0] + n[0] * weight; @@ -344,17 +343,14 @@ int BKE_mask_point_has_handle(MaskSplinePoint *point) return bezt->h1 == HD_ALIGN; } -void BKE_mask_point_handle(MaskSplinePoint *point, float aspx, float aspy, float handle[2]) +void BKE_mask_point_handle(MaskSplinePoint *point, float handle[2]) { float vec[2]; sub_v2_v2v2(vec, point->bezt.vec[0], point->bezt.vec[1]); - vec[0] *= aspx; - vec[1] *= aspy; - - handle[0] = (point->bezt.vec[1][0] * aspx + vec[1]) / aspx; - handle[1] = (point->bezt.vec[1][1] * aspy - vec[0]) / aspy; + handle[0] = (point->bezt.vec[1][0] + vec[1]); + handle[1] = (point->bezt.vec[1][1] - vec[0]); } void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_direction, float aspx, float aspy, @@ -406,8 +402,7 @@ void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_di } } -float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, float aspx, float aspy, - int *tot_feather_point) +float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_feather_point) { float *feather, *fp; int i, resol = BKE_mask_spline_feather_resolution(spline); @@ -419,7 +414,7 @@ float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint * float co[2], n[2]; BKE_mask_point_segment_co(spline, point, u, co); - BKE_mask_point_normal(spline, point, aspx, aspy, u, n); + BKE_mask_point_normal(spline, point, u, n); weight = BKE_mask_point_weight(spline, point, u); fp[0] = co[0] + n[0] * weight; @@ -493,7 +488,7 @@ void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float interp_v2_v2v2(co, r0, r1, u); } -void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float aspx, float aspy, float u, float n[2]) +void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float u, float n[2]) { BezTriple *bezt = &point->bezt, *next; float q0[2], q1[2], q2[2], r0[2], r1[2], vec[2]; @@ -504,21 +499,15 @@ void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float asp else next = NULL; } - else next = &((point + 1))->bezt; + else { + next = &((point + 1))->bezt; + } if (!next) { - BKE_mask_point_handle(point, aspx, aspy, vec); + BKE_mask_point_handle(point, vec); sub_v2_v2v2(n, vec, bezt->vec[1]); - - n[0] *= aspx; - n[1] *= aspy; - normalize_v2(n); - - n[0] /= aspx; - n[1] /= aspy; - return; } @@ -531,13 +520,10 @@ void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float asp sub_v2_v2v2(vec, r1, r0); - n[0] = -vec[1] * aspy; - n[1] = vec[0] * aspx; + n[0] = -vec[1]; + n[1] = vec[0]; normalize_v2(n); - - n[0] /= aspx; - n[1] /= aspy; } float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, float u) diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h index 5df91b4032a..01495561912 100644 --- a/source/blender/editors/include/ED_mask.h +++ b/source/blender/editors/include/ED_mask.h @@ -39,6 +39,6 @@ void ED_keymap_mask(struct wmKeyConfig *keyconf); void ED_operatormacros_mask(void); /* mask_draw.c */ -void ED_mask_draw(bContext *C, int width, int height, float zoomx, float zoomy); +void ED_mask_draw(const bContext *C); #endif /* ED_TEXT_H */ diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index e3fe67df16b..152dc6d03da 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -49,12 +49,6 @@ #include "mask_intern.h" /* own include */ -typedef struct PixelSpaceContext { - int width, height; - float zoomx, zoomy; - float aspx, aspy; -} PixelSpaceContext; - static void set_spline_color(MaskShape *shape, MaskSpline *spline) { if (spline->flag & SELECT) { @@ -69,7 +63,7 @@ static void set_spline_color(MaskShape *shape, MaskSpline *spline) } /* return non-zero if spline is selected */ -static void draw_spline_points(MaskShape *shape, MaskSpline *spline, PixelSpaceContext *pixelspace) +static void draw_spline_points(MaskShape *shape, MaskSpline *spline) { int i, hsize, tot_feather_point; float *feather_points, *fp; @@ -82,7 +76,7 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline, PixelSpaceC glPointSize(hsize); /* feather points */ - feather_points = fp = BKE_mask_spline_feather_points(spline, pixelspace->aspx, pixelspace->aspy, &tot_feather_point); + feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); for (i = 0; i < spline->tot_point; i++) { int j; MaskSplinePoint *point = &spline->points[i]; @@ -119,12 +113,11 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline, PixelSpaceC /* control points */ for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; - BezTriple *bezt = &point->bezt; - float vert[2], handle[2]; + float handle[2]; + float *vert = point->bezt.vec[1]; int has_handle = BKE_mask_point_has_handle(point); - copy_v2_v2(vert, bezt->vec[1]); - BKE_mask_point_handle(point, pixelspace->aspx, pixelspace->aspy, handle); + BKE_mask_point_handle(point, handle); /* draw handle segment */ if (has_handle) { @@ -196,7 +189,7 @@ static void draw_dashed_curve(MaskSpline *spline, float *points, int tot_point) glDisable(GL_LINE_STIPPLE); } -static void draw_spline_curve(MaskShape *shape, MaskSpline *spline, PixelSpaceContext *pixelspace) +static void draw_spline_curve(MaskShape *shape, MaskSpline *spline) { float *diff_points, *feather_points; int tot_diff_point, tot_feather_point; @@ -206,8 +199,7 @@ static void draw_spline_curve(MaskShape *shape, MaskSpline *spline, PixelSpaceCo if (!diff_points) return; - feather_points = BKE_mask_spline_feather_differentiated_points(spline, pixelspace->aspx, pixelspace->aspy, - &tot_feather_point); + feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_feather_point); /* draw feather */ if (spline->flag & SELECT) @@ -224,7 +216,7 @@ static void draw_spline_curve(MaskShape *shape, MaskSpline *spline, PixelSpaceCo MEM_freeN(feather_points); } -static void draw_shapes(Mask *mask, PixelSpaceContext *pixelspace) +static void draw_shapes(Mask *mask) { MaskShape *shape = mask->shapes.first; @@ -233,10 +225,10 @@ static void draw_shapes(Mask *mask, PixelSpaceContext *pixelspace) while (spline) { /* draw curve itself first... */ - draw_spline_curve(shape, spline, pixelspace); + draw_spline_curve(shape, spline); /* ...and then handles over the curve so they're nicely visible */ - draw_spline_points(shape, spline, pixelspace); + draw_spline_points(shape, spline); spline = spline->next; } @@ -245,23 +237,12 @@ static void draw_shapes(Mask *mask, PixelSpaceContext *pixelspace) } } -void ED_mask_draw(bContext *C, int width, int height, float zoomx, float zoomy) +void ED_mask_draw(const bContext *C) { Mask *mask = CTX_data_edit_mask(C); - PixelSpaceContext pixelspace; - float aspx, aspy; if (!mask) return; - ED_mask_aspect(C, &aspx, &aspy); - - pixelspace.width = width; - pixelspace.height = height; - pixelspace.zoomx = zoomx; - pixelspace.zoomy = zoomy; - pixelspace.aspx = aspx; - pixelspace.aspy = aspy; - - draw_shapes(mask, &pixelspace); + draw_shapes(mask); } diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 5518fedf91a..16f201293d5 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -89,7 +89,7 @@ static void spline_point_select(MaskSplinePoint *point, int action) } -static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, float aspx, float aspy, float start_u, const float co[2]) +static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, float start_u, const float co[2]) { const float proj_eps = 1e-3; const float proj_eps_squared = proj_eps * proj_eps; @@ -104,7 +104,7 @@ static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, fl if (u1 >= 0.0f) { BKE_mask_point_segment_co(spline, point, u1, co1); - BKE_mask_point_normal(spline, point, aspx, aspy, u1, n1); + BKE_mask_point_normal(spline, point, u1, n1); sub_v2_v2v2(v1, co, co1); if (len_squared_v2(v1) > proj_eps_squared) { @@ -125,7 +125,7 @@ static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, fl if (u2 <= 1.0f) { BKE_mask_point_segment_co(spline, point, u2, co2); - BKE_mask_point_normal(spline, point, aspx, aspy, u2, n2); + BKE_mask_point_normal(spline, point, u2, n2); sub_v2_v2v2(v2, co, co2); if (len_squared_v2(v2) > proj_eps_squared) { @@ -249,7 +249,7 @@ static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal vec[1] = cur_point->bezt.vec[1][1] * scaley; if (BKE_mask_point_has_handle(cur_point)) { - BKE_mask_point_handle(cur_point, aspx, aspy, handle); + BKE_mask_point_handle(cur_point, handle); handle[0] *= scalex; handle[1] *= scaley; @@ -336,7 +336,7 @@ static int find_nearest_feather(bContext *C, Mask *mask, float normal_co[2], int int i, tot_feather_point; float *feather_points, *fp; - feather_points = fp = BKE_mask_spline_feather_points(spline, aspx, aspy, &tot_feather_point); + feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); for (i = 0; i < spline->tot_point; i++) { int j; @@ -444,7 +444,7 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], if (feather) { feather_points = BKE_mask_point_segment_feather_diff(spline, cur_point, - aspx, aspy, &tot_feather_point); + &tot_feather_point); points = feather_points; tot_point = tot_feather_point; @@ -502,7 +502,7 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], *point_r = point; if (u_r) { - u = projection_on_spline(point_spline, point, aspx, aspy, u, normal_co); + u = projection_on_spline(point_spline, point, u, normal_co); *u_r = u; } @@ -748,14 +748,14 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) customdata->weight = uw->w; BKE_mask_point_segment_co(spline, point, uw->u, co); - BKE_mask_point_normal(spline, point, customdata->aspx, customdata->aspy, uw->u, customdata->no); + BKE_mask_point_normal(spline, point, uw->u, customdata->no); customdata->feather[0] = co[0] + customdata->no[0] * uw->w; customdata->feather[1] = co[1] + customdata->no[1] * uw->w; } else { BezTriple *bezt = &point->bezt; - BKE_mask_point_normal(spline, point, customdata->aspx, customdata->aspy, 0.0f, customdata->no); + BKE_mask_point_normal(spline, point, 0.0f, customdata->no); customdata->feather[0] = bezt->vec[1][0] + customdata->no[0] * bezt->weight; customdata->feather[1] = bezt->vec[1][1] + customdata->no[1] * bezt->weight; @@ -763,7 +763,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) copy_m3_m3(customdata->vec, point->bezt.vec); if (BKE_mask_point_has_handle(point)) - BKE_mask_point_handle(point, customdata->aspx, customdata->aspy, customdata->handle); + BKE_mask_point_handle(point, customdata->handle); ED_mask_mouse_pos(C, event, customdata->co); } @@ -882,14 +882,14 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) add_v2_v2v2(offco, data->feather, dco); if (data->uw) { - float u = projection_on_spline(data->spline, data->point, data->aspx, data->aspy, data->uw->u, offco); + float u = projection_on_spline(data->spline, data->point, data->uw->u, offco); if (u > 0.0f && u < 1.0f) data->uw->u = u; data->uw = BKE_mask_point_sort_uw(data->point, data->uw); weight = &data->uw->w; - BKE_mask_point_normal(data->spline, data->point, data->aspx, data->aspy, data->uw->u, no); + BKE_mask_point_normal(data->spline, data->point, data->uw->u, no); BKE_mask_point_segment_co(data->spline, data->point, data->uw->u, p); } else { diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 6ebcaf4ea16..8e92a9198b1 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -1134,7 +1134,7 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) glScalef(maxdim * zoomx, maxdim * zoomy, 0); glMultMatrixf(sc->stabmat); - ED_mask_draw((bContext *)C, width*aspx, height*aspy, zoomx, zoomy); + ED_mask_draw((bContext *)C); glPopMatrix(); } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 85d54c0d6e3..50d6beb0681 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5908,7 +5908,7 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, TransDat else { tdm->is_handle = TRUE; - BKE_mask_point_handle(point, aspx, aspy, tdm->handle); + BKE_mask_point_handle(point, tdm->handle); copy_v2_v2(tdm->orig_handle, tdm->handle); diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index 7597a21fd03..dbdde515804 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -54,9 +54,9 @@ typedef struct MaskParent { ID *id; /* ID block of entity to which mask/spline is parented to * in case of parenting to movie tracking data set to MovieClip datablock */ char parent[64]; /* entity of parent to which parenting happened - * in case of parenting to movie tracking data contains name of object */ + * in case of parenting to movie tracking data contains name of object */ char sub_parent[64]; /* sub-entity of parent to which parenting happened - * in case of parenting to movie tracking data contains name of track */ + * in case of parenting to movie tracking data contains name of track */ float offset[2]; /* offset from parent position, so object/control point can be parented to a * motion track and also be animated (see ZanQdo's request below) */ } MaskParent; @@ -96,13 +96,13 @@ typedef struct MaskShape { } MaskShape; /* MaskParent->flag */ -#define MASK_PARENT_ACTIVE (1<<0) +#define MASK_PARENT_ACTIVE (1 << 0) /* MaskSpline->flag */ -#define MASK_SPLINE_CYCLIC (1<<1) +#define MASK_SPLINE_CYCLIC (1 << 1) /* MaskSpline->weight_interp */ -#define MASK_SPLINE_INTERP_LINEAR 1 -#define MASK_SPLINE_INTERP_EASE 2 +#define MASK_SPLINE_INTERP_LINEAR 1 +#define MASK_SPLINE_INTERP_EASE 2 #endif // __DNA_MASK_TYPES_H__ From f82bb6fb4e3a32e727205678eed2457cdd7f12cc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 May 2012 10:02:14 +0000 Subject: [PATCH 063/360] fix error with mask translation not quite following the mouse. --- source/blender/editors/transform/transform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 06bcf11bfe4..d06de6be3ae 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -173,7 +173,7 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) if (t->options & CTX_MASK) { /* clamp w/h, mask only */ - divx = divy = minf(divx, divy); + divx = divy = maxf(divx, divy); mulx = muly = minf(mulx, muly); } @@ -181,6 +181,7 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) r_vec[1] = muly * (dy) / divy; r_vec[2] = 0.0f; + /* TODO - NOT WORKING, this isnt so bad since its only display aspect */ if (t->options & CTX_MASK) { float aspx, aspy; ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy); From 837eb6bb182c2020571ded2f4cf155a55e16bd0c Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Fri, 18 May 2012 12:05:10 +0000 Subject: [PATCH 064/360] Support normalization in the tracking prepass The last tracker commit added normalized tracking. This makes tracking patches undergoing uniform illumination change easier. However, the prepass which computes a quick translation-only estimate of the warp did not take this into account. This commit fixes that. This works reasonably well but in some examples the brute initialization fails. I suspect this is due to the warped template estimate in the current frame being too different from the original, so there are multiple peaks in the normalized-SAD correlation function. The solution is to use the previous frame for the brute initialization and the keyframe for refinement, but that requires architecture changes. --- extern/libmv/libmv/tracking/track_region.cc | 67 ++++++++++++++++++--- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index ababd0cee90..6fad3f7af3f 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -19,6 +19,11 @@ // IN THE SOFTWARE. // // Author: mierle@google.com (Keir Mierle) +// +// TODO(keir): While this tracking code works rather well, it has some +// outragous inefficiencies. There is probably a 5-10x speedup to be had if a +// smart coder went through the TODO's and made the suggested performance +// enhancements. // Necessary for M_E when building with MSVC. #define _USE_MATH_DEFINES @@ -868,14 +873,17 @@ bool PointOnRightHalfPlane(const Vec2 &a, const Vec2 &b, double x, double y) { // Determine if a point is in a quad. The quad is arranged as: // -// +--> x +// +-------> x // | -// | 0 1 -// v 3 2 +// | a0------a1 +// | | | +// | | | +// | | | +// | a3------a2 +// v // y // -// The idea is to take the maximum x or y distance. This may be oversampling. -// TODO(keir): Investigate the various choices; perhaps average is better? +// The implementation does up to four half-plane comparisons. bool PointInQuad(const double *xs, const double *ys, double x, double y) { Vec2 a0(xs[0], ys[0]); Vec2 a1(xs[1], ys[1]); @@ -888,6 +896,8 @@ bool PointInQuad(const double *xs, const double *ys, double x, double y) { PointOnRightHalfPlane(a3, a0, x, y); } +// This makes it possible to map between Eigen float arrays and FloatImage +// without using comparisons. typedef Eigen::Array FloatArray; // This creates a pattern in the frame of image2, from the pixel is image1, @@ -946,11 +956,26 @@ void CreateBrutePattern(const double *x1, const double *y1, *origin_y = min_y; } +// Compute a translation-only estimate of the warp, using brute force search. A +// smarter implementation would use the FFT to compute the normalized cross +// correlation. Instead, this is a dumb implementation. Surprisingly, it is +// fast enough in practice. +// +// TODO(keir): The normalization is less effective for the brute force search +// than it is with the Ceres solver. It's unclear if this is a bug or due to +// the original frame being too different from the reprojected reference in the +// destination frame. +// +// The likely solution is to use the previous frame, instead of the original +// pattern, when doing brute initialization. Unfortunately that implies a +// totally different warping interface, since access to more than a the source +// and current destination frame is necessary. template void BruteTranslationOnlyInitialize(const FloatImage &image1, const FloatImage *image1_mask, const FloatImage &image2, const int num_extra_points, + const bool use_normalized_intensities, const double *x1, const double *y1, double *x2, double *y2) { // Create the pattern to match in the space of image2, assuming our inital @@ -959,8 +984,18 @@ void BruteTranslationOnlyInitialize(const FloatImage &image1, FloatArray pattern; FloatArray mask; int origin_x = -1, origin_y = -1; - CreateBrutePattern(x1, y1, x2, y2, image1, image1_mask, - &pattern, &mask, &origin_x, &origin_y); + CreateBrutePattern(x1, y1, x2, y2, + image1, image1_mask, + &pattern, &mask, + &origin_x, &origin_y); + + // For normalization, premultiply the pattern by the inverse pattern mean. + double mask_sum = 1.0; + if (use_normalized_intensities) { + mask_sum = mask.sum(); + double inverse_pattern_mean = mask_sum / ((mask * pattern).sum()); + pattern *= inverse_pattern_mean; + } // Use Eigen on the images via maps for strong vectorization. Map search(image2.Data(), image2.Height(), image2.Width()); @@ -984,8 +1019,21 @@ void BruteTranslationOnlyInitialize(const FloatImage &image1, int h = pattern.rows(); for (int r = 0; r < (image2.Height() - h); ++r) { for (int c = 0; c < (image2.Width() - w); ++c) { - // Compute the weighted sum of absolute differences, Eigen style. - double sad = (mask * (pattern - search.block(r, c, h, w))).abs().sum(); + // Compute the weighted sum of absolute differences, Eigen style. Note + // that the block from the search image is never stored in a variable, to + // avoid copying overhead and permit inlining. + double sad; + if (use_normalized_intensities) { + // TODO(keir): It's really dumb to recompute the search mean for every + // shift. A smarter implementation would use summed area tables + // instead, reducing the mean calculation to an O(1) operation. + double inverse_search_mean = + mask_sum / ((mask * search.block(r, c, h, w)).sum()); + sad = (mask * (pattern - (search.block(r, c, h, w) * + inverse_search_mean))).abs().sum(); + } else { + sad = (mask * (pattern - search.block(r, c, h, w))).abs().sum(); + } if (sad < best_sad) { best_r = r; best_c = c; @@ -1053,6 +1101,7 @@ void TemplatedTrackRegion(const FloatImage &image1, options.image1_mask, image2, options.num_extra_points, + options.use_normalized_intensities, x1, y1, x2, y2); for (int i = 0; i < 4; ++i) { LG << "P" << i << ": (" << x1[i] << ", " << y1[i] << "); brute (" From 2870366d72df618fa4ea267cc0c33a1f66fd04df Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 May 2012 12:51:11 +0000 Subject: [PATCH 065/360] rename 'mask shape' to mask object, will make adding shape keys less confusing. --- release/scripts/startup/bl_ui/space_clip.py | 22 +- source/blender/blenkernel/BKE_mask.h | 18 +- source/blender/blenkernel/intern/mask.c | 88 +++--- source/blender/blenloader/intern/readfile.c | 28 +- source/blender/blenloader/intern/writefile.c | 12 +- source/blender/editors/mask/mask_draw.c | 34 +-- source/blender/editors/mask/mask_editor.c | 6 +- source/blender/editors/mask/mask_intern.h | 4 +- source/blender/editors/mask/mask_ops.c | 254 +++++++++--------- .../editors/transform/transform_conversions.c | 18 +- source/blender/makesdna/DNA_mask_types.h | 16 +- source/blender/makesrna/intern/rna_mask.c | 176 ++++++------ .../composite/nodes/node_composite_mask.c | 10 +- 13 files changed, 343 insertions(+), 343 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 90b3901c002..c6ea5633f23 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -555,10 +555,10 @@ class CLIP_PT_tracking_camera(Panel): col.prop(clip.tracking.camera, "k3") -class CLIP_PT_shapes(Panel): +class CLIP_PT_mask_objects(Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' - bl_label = "Shapes" + bl_label = "Mask Objects" @classmethod def poll(cls, context): @@ -573,15 +573,15 @@ class CLIP_PT_shapes(Panel): mask = sc.mask row = layout.row() - row.template_list(mask, "shapes", - mask, "active_shape_index", rows=3) + row.template_list(mask, "objects", + mask, "active_object_index", rows=3) sub = row.column(align=True) - sub.operator("mask.shape_new", icon='ZOOMIN', text="") - sub.operator("mask.shape_remove", icon='ZOOMOUT', text="") + sub.operator("mask.object_new", icon='ZOOMIN', text="") + sub.operator("mask.object_remove", icon='ZOOMOUT', text="") - active = mask.shapes.active + active = mask.objects.active if active: layout.prop(active, "name") @@ -597,7 +597,7 @@ class CLIP_PT_active_mask_spline(Panel): mask = sc.mask if mask and sc.mode == 'MASKEDITING': - return mask.shapes.active and mask.shapes.active.splines.active + return mask.objects.active and mask.objects.active.splines.active return False @@ -606,7 +606,7 @@ class CLIP_PT_active_mask_spline(Panel): sc = context.space_data mask = sc.mask - spline = mask.shapes.active.splines.active + spline = mask.objects.active.splines.active col = layout.column() col.prop(spline, "weight_interpolation") @@ -624,7 +624,7 @@ class CLIP_PT_active_mask_point(Panel): mask = sc.mask if mask and sc.mode == 'MASKEDITING': - return mask.shapes.active and mask.shapes.active.splines.active_point + return mask.objects.active and mask.objects.active.splines.active_point return False @@ -633,7 +633,7 @@ class CLIP_PT_active_mask_point(Panel): sc = context.space_data mask = sc.mask - point = mask.shapes.active.splines.active_point + point = mask.objects.active.splines.active_point parent = point.parent col = layout.column() diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 88934e4af84..361de2c38ce 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -30,7 +30,7 @@ struct Main; struct Mask; struct MaskParent; -struct MaskShape; +struct MaskObject; struct MaskSpline; struct MaskSplinePoint; struct MaskSplinePointUW; @@ -38,20 +38,20 @@ struct MovieClip; struct MovieClipUser; struct Scene; -/* shapes */ -struct MaskShape *BKE_mask_shape_new(struct Mask *mask, const char *name); -struct MaskShape *BKE_mask_shape_active(struct Mask *mask); -void BKE_mask_shape_active_set(struct Mask *mask, struct MaskShape *shape); -void BKE_mask_shape_remove(struct Mask *mask, struct MaskShape *shape); +/* mask objects */ +struct MaskObject *BKE_mask_object_new(struct Mask *mask, const char *name); +struct MaskObject *BKE_mask_object_active(struct Mask *mask); +void BKE_mask_object_active_set(struct Mask *mask, struct MaskObject *maskobj); +void BKE_mask_object_remove(struct Mask *mask, struct MaskObject *maskobj); -void BKE_mask_shape_free(struct MaskShape *shape); +void BKE_mask_object_free(struct MaskObject *maskobj); void BKE_mask_spline_free(struct MaskSpline *spline); void BKE_mask_point_free(struct MaskSplinePoint *point); -void BKE_mask_shape_unique_name(struct Mask *mask, struct MaskShape *shape); +void BKE_mask_object_unique_name(struct Mask *mask, struct MaskObject *maskobj); /* splines */ -struct MaskSpline *BKE_mask_spline_add(struct MaskShape *shape); +struct MaskSpline *BKE_mask_spline_add(struct MaskObject *maskobj); int BKE_mask_spline_resolution(struct MaskSpline *spline); float *BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point); float *BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 863945e6baf..e3c2570ab93 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -55,68 +55,68 @@ #include "BKE_movieclip.h" #include "BKE_utildefines.h" -/* shapes */ +/* mask objects */ -MaskShape *BKE_mask_shape_new(Mask *mask, const char *name) +MaskObject *BKE_mask_object_new(Mask *mask, const char *name) { - MaskShape *shape = MEM_callocN(sizeof(MaskShape), "new mask shape"); + MaskObject *maskobj = MEM_callocN(sizeof(MaskObject), "new mask object"); if (name && name[0]) - BLI_strncpy(shape->name, name, sizeof(shape->name)); + BLI_strncpy(maskobj->name, name, sizeof(maskobj->name)); else - strcpy(shape->name, "Shape"); + strcpy(maskobj->name, "MaskObject"); - BLI_addtail(&mask->shapes, shape); + BLI_addtail(&mask->maskobjs, maskobj); - BKE_mask_shape_unique_name(mask, shape); + BKE_mask_object_unique_name(mask, maskobj); - mask->tot_shape++; + mask->tot_maskobj++; - return shape; + return maskobj; } -MaskShape *BKE_mask_shape_active(Mask *mask) +MaskObject *BKE_mask_object_active(Mask *mask) { - return BLI_findlink(&mask->shapes, mask->shapenr); + return BLI_findlink(&mask->maskobjs, mask->act_maskobj); } -void BKE_mask_shape_active_set(Mask *mask, MaskShape *shape) +void BKE_mask_object_active_set(Mask *mask, MaskObject *maskobj) { - int index = BLI_findindex(&mask->shapes, shape); + int index = BLI_findindex(&mask->maskobjs, maskobj); if (index >= 0) - mask->shapenr = index; + mask->act_maskobj = index; else - mask->shapenr = 0; + mask->act_maskobj = 0; } -void BKE_mask_shape_remove(Mask *mask, MaskShape *shape) +void BKE_mask_object_remove(Mask *mask, MaskObject *maskobj) { - BLI_remlink(&mask->shapes, shape); - BKE_mask_shape_free(shape); + BLI_remlink(&mask->maskobjs, maskobj); + BKE_mask_object_free(maskobj); - mask->tot_shape--; + mask->tot_maskobj--; - if (mask->shapenr >= mask->tot_shape) - mask->shapenr = mask->tot_shape - 1; + if (mask->act_maskobj >= mask->tot_maskobj) + mask->act_maskobj = mask->tot_maskobj - 1; } -void BKE_mask_shape_unique_name(Mask *mask, MaskShape *shape) +void BKE_mask_object_unique_name(Mask *mask, MaskObject *maskobj) { - BLI_uniquename(&mask->shapes, shape, "Shape", '.', offsetof(MaskShape, name), sizeof(shape->name)); + BLI_uniquename(&mask->maskobjs, maskobj, "MaskObject", '.', offsetof(MaskObject, name), sizeof(maskobj->name)); } /* splines */ -MaskSpline *BKE_mask_spline_add(MaskShape *shape) +MaskSpline *BKE_mask_spline_add(MaskObject *maskobj) { MaskSpline *spline; - spline = MEM_callocN(sizeof(MaskSpline), "new shape spline"); - BLI_addtail(&shape->splines, spline); + spline = MEM_callocN(sizeof(MaskSpline), "new mask spline"); + BLI_addtail(&maskobj->splines, spline); /* spline shall have one point at least */ - spline->points = MEM_callocN(sizeof(MaskSplinePoint), "new shape spline point"); + spline->points = MEM_callocN(sizeof(MaskSplinePoint), "new mask spline point"); spline->tot_point = 1; /* cyclic shapes are more usually used */ @@ -662,33 +662,33 @@ void BKE_mask_spline_free(MaskSpline *spline) MEM_freeN(spline); } -void BKE_mask_shape_free(MaskShape *shape) +void BKE_mask_object_free(MaskObject *maskobj) { - MaskSpline *spline = shape->splines.first; + MaskSpline *spline = maskobj->splines.first; while (spline) { MaskSpline *next_spline = spline->next; - BLI_remlink(&shape->splines, spline); + BLI_remlink(&maskobj->splines, spline); BKE_mask_spline_free(spline); spline = next_spline; } - MEM_freeN(shape); + MEM_freeN(maskobj); } void BKE_mask_free(Mask *mask) { - MaskShape *shape = mask->shapes.first; + MaskObject *maskobj = mask->maskobjs.first; - while (shape) { - MaskShape *next_shape = shape->next; + while (maskobj) { + MaskObject *next_maskobj = maskobj->next; - BLI_remlink(&mask->shapes, shape); - BKE_mask_shape_free(shape); + BLI_remlink(&mask->maskobjs, maskobj); + BKE_mask_object_free(maskobj); - shape = next_shape; + maskobj = next_maskobj; } } @@ -940,12 +940,12 @@ void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplineP void BKE_mask_calc_handles(Mask *mask) { - MaskShape *shape; + MaskObject *maskobj; - for (shape = mask->shapes.first; shape; shape = shape->next) { + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; - for (spline = shape->splines.first; spline; spline = spline->next) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { @@ -957,10 +957,10 @@ void BKE_mask_calc_handles(Mask *mask) void BKE_mask_evaluate(Mask *mask, float ctime) { - MaskShape *shape = mask->shapes.first; + MaskObject *maskobj = mask->maskobjs.first; - while (shape) { - MaskSpline *spline = shape->splines.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; int i; while (spline) { @@ -981,7 +981,7 @@ void BKE_mask_evaluate(Mask *mask, float ctime) spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } BKE_mask_calc_handles(mask); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 2e30f756b43..d0b9808697f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6276,19 +6276,19 @@ static void lib_link_movieclip(FileData *fd, Main *main) static void direct_link_mask(FileData *fd, Mask *mask) { - MaskShape *shape; + MaskObject *maskobj; mask->adt = newdataadr(fd, mask->adt); - link_list(fd, &mask->shapes); + link_list(fd, &mask->maskobjs); - shape = mask->shapes.first; - while (shape) { + maskobj = mask->maskobjs.first; + while (maskobj) { MaskSpline *spline; - link_list(fd, &shape->splines); + link_list(fd, &maskobj->splines); - spline = shape->splines.first; + spline = maskobj->splines.first; while (spline) { int i; @@ -6304,10 +6304,10 @@ static void direct_link_mask(FileData *fd, Mask *mask) spline = spline->next; } - shape->act_spline = newdataadr(fd, shape->act_spline); - shape->act_point = newdataadr(fd, shape->act_point); + maskobj->act_spline = newdataadr(fd, maskobj->act_spline); + maskobj->act_point = newdataadr(fd, maskobj->act_point); - shape = shape->next; + maskobj = maskobj->next; } } @@ -6323,16 +6323,16 @@ static void lib_link_mask(FileData *fd, Main *main) mask = main->mask.first; while (mask) { if(mask->id.flag & LIB_NEEDLINK) { - MaskShape *shape; + MaskObject *maskobj; if (mask->adt) lib_link_animdata(fd, &mask->id, mask->adt); - shape = mask->shapes.first; - while (shape) { + maskobj = mask->maskobjs.first; + while (maskobj) { MaskSpline *spline; - spline = shape->splines.first; + spline = maskobj->splines.first; while (spline) { int i; @@ -6347,7 +6347,7 @@ static void lib_link_mask(FileData *fd, Main *main) spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } mask->id.flag -= LIB_NEEDLINK; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 539b19c5561..a514a3283b1 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2762,20 +2762,20 @@ static void write_masks(WriteData *wd, ListBase *idbase) mask = idbase->first; while (mask) { if (mask->id.us > 0 || wd->current) { - MaskShape *shape; + MaskObject *maskobj; writestruct(wd, ID_MSK, "Mask", 1, mask); if (mask->adt) write_animdata(wd, mask->adt); - shape = mask->shapes.first; - while (shape) { + maskobj = mask->maskobjs.first; + while (maskobj) { MaskSpline *spline; - writestruct(wd, DATA, "MaskShape", 1, shape); + writestruct(wd, DATA, "MaskObject", 1, maskobj); - spline = shape->splines.first; + spline = maskobj->splines.first; while (spline) { int i; @@ -2792,7 +2792,7 @@ static void write_masks(WriteData *wd, ListBase *idbase) spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } } diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 152dc6d03da..06f24c6fa8f 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -49,10 +49,10 @@ #include "mask_intern.h" /* own include */ -static void set_spline_color(MaskShape *shape, MaskSpline *spline) +static void set_spline_color(MaskObject *maskobj, MaskSpline *spline) { if (spline->flag & SELECT) { - if (shape->act_spline == spline) + if (maskobj->act_spline == spline) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 0.0f, 0.0f); @@ -63,7 +63,7 @@ static void set_spline_color(MaskShape *shape, MaskSpline *spline) } /* return non-zero if spline is selected */ -static void draw_spline_points(MaskShape *shape, MaskSpline *spline) +static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) { int i, hsize, tot_feather_point; float *feather_points, *fp; @@ -92,7 +92,7 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline) } if (sel) { - if (point == shape->act_point) + if (point == maskobj->act_point) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); @@ -121,7 +121,7 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline) /* draw handle segment */ if (has_handle) { - set_spline_color(shape, spline); + set_spline_color(maskobj, spline); glBegin(GL_LINES); glVertex3fv(vert); @@ -131,7 +131,7 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline) /* draw CV point */ if (MASKPOINT_CV_ISSEL(point)) { - if (point == shape->act_point) + if (point == maskobj->act_point) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); @@ -146,7 +146,7 @@ static void draw_spline_points(MaskShape *shape, MaskSpline *spline) /* draw handle points */ if (has_handle) { if (MASKPOINT_HANDLE_ISSEL(point)) { - if (point == shape->act_point) + if (point == maskobj->act_point) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); @@ -189,7 +189,7 @@ static void draw_dashed_curve(MaskSpline *spline, float *points, int tot_point) glDisable(GL_LINE_STIPPLE); } -static void draw_spline_curve(MaskShape *shape, MaskSpline *spline) +static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline) { float *diff_points, *feather_points; int tot_diff_point, tot_feather_point; @@ -209,31 +209,31 @@ static void draw_spline_curve(MaskShape *shape, MaskSpline *spline) draw_dashed_curve(spline, feather_points, tot_feather_point); /* draw main curve */ - set_spline_color(shape, spline); + set_spline_color(maskobj, spline); draw_dashed_curve(spline, diff_points, tot_diff_point); MEM_freeN(diff_points); MEM_freeN(feather_points); } -static void draw_shapes(Mask *mask) +static void draw_maskobjs(Mask *mask) { - MaskShape *shape = mask->shapes.first; + MaskObject *maskobj = mask->maskobjs.first; - while (shape) { - MaskSpline *spline = shape->splines.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { /* draw curve itself first... */ - draw_spline_curve(shape, spline); + draw_spline_curve(maskobj, spline); /* ...and then handles over the curve so they're nicely visible */ - draw_spline_points(shape, spline); + draw_spline_points(maskobj, spline); spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } } @@ -244,5 +244,5 @@ void ED_mask_draw(const bContext *C) if (!mask) return; - draw_shapes(mask); + draw_maskobjs(mask); } diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index a868696941c..e8311935d86 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -146,9 +146,9 @@ void ED_operatortypes_mask(void) { WM_operatortype_append(MASK_OT_new); - /* shapes */ - WM_operatortype_append(MASK_OT_shape_new); - WM_operatortype_append(MASK_OT_shape_remove); + /* mask objects */ + WM_operatortype_append(MASK_OT_object_new); + WM_operatortype_append(MASK_OT_object_remove); /* geometry */ WM_operatortype_append(MASK_OT_add_vertex); diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index 073eba3efc9..163239eade7 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -40,8 +40,8 @@ struct wmOperatorType; /* mask_ops.c */ void MASK_OT_new(struct wmOperatorType *ot); -void MASK_OT_shape_new(struct wmOperatorType *ot); -void MASK_OT_shape_remove(struct wmOperatorType *ot); +void MASK_OT_object_new(struct wmOperatorType *ot); +void MASK_OT_object_remove(struct wmOperatorType *ot); void MASK_OT_add_vertex(struct wmOperatorType *ot); void MASK_OT_add_feather_vertex(struct wmOperatorType *ot); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 16f201293d5..9b9dbcec7e5 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -167,10 +167,10 @@ static int points_has_selection(MaskSplinePoint *points, int tot_point) static int mask_has_selection(Mask *mask) { - MaskShape *shape = mask->shapes.first; + MaskObject *maskobj = mask->maskobjs.first; - while (shape) { - MaskSpline *spline = shape->splines.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { if (points_has_selection(spline->points, spline->tot_point)) @@ -179,7 +179,7 @@ static int mask_has_selection(Mask *mask) spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } return FALSE; @@ -187,7 +187,7 @@ static int mask_has_selection(Mask *mask) static void toggle_selection_all(Mask *mask, int action) { - MaskShape *shape = mask->shapes.first; + MaskObject *maskobj = mask->maskobjs.first; if (action == SEL_TOGGLE) { if (mask_has_selection(mask)) @@ -196,8 +196,8 @@ static void toggle_selection_all(Mask *mask, int action) action = SEL_SELECT; } - while (shape) { - MaskSpline *spline = shape->splines.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { int i; @@ -211,16 +211,16 @@ static void toggle_selection_all(Mask *mask, int action) spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } } static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal_co[2], int threshold, - MaskShape **shape_r, MaskSpline **spline_r, int *is_handle_r, + MaskObject **maskobj_r, MaskSpline **spline_r, int *is_handle_r, float *score) { - MaskShape *shape; - MaskShape *point_shape = NULL; + MaskObject *maskobj; + MaskObject *point_maskobj = NULL; MaskSpline *point_spline = NULL; MaskSplinePoint *point = NULL; float co[2], aspx, aspy; @@ -234,9 +234,9 @@ static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; - shape = mask->shapes.first; - while (shape) { - MaskSpline *spline = shape->splines.first; + maskobj = mask->maskobjs.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { int i; @@ -256,7 +256,7 @@ static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal cur_len = len_v2v2(co, handle); if (cur_len < len) { - point_shape = shape; + point_maskobj = maskobj; point_spline = spline; point = cur_point; len = cur_len; @@ -268,7 +268,7 @@ static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal if (cur_len < len) { point_spline = spline; - point_shape = shape; + point_maskobj = maskobj; point = cur_point; len = cur_len; is_handle = FALSE; @@ -278,12 +278,12 @@ static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } if (len < threshold) { - if (shape_r) - *shape_r = point_shape; + if (maskobj_r) + *maskobj_r = point_maskobj; if (spline_r) *spline_r = point_spline; @@ -297,8 +297,8 @@ static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal return point; } - if (shape_r) - *shape_r = NULL; + if (maskobj_r) + *maskobj_r = NULL; if (spline_r) *spline_r = NULL; @@ -310,10 +310,10 @@ static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal } static int find_nearest_feather(bContext *C, Mask *mask, float normal_co[2], int threshold, - MaskShape **shape_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + MaskObject **maskobj_r, MaskSpline **spline_r, MaskSplinePoint **point_r, MaskSplinePointUW **uw_r, float *score) { - MaskShape *shape, *point_shape = NULL; + MaskObject *maskobj, *point_maskobj = NULL; MaskSpline *point_spline = NULL; MaskSplinePoint *point = NULL; MaskSplinePointUW *uw = NULL; @@ -328,9 +328,9 @@ static int find_nearest_feather(bContext *C, Mask *mask, float normal_co[2], int co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; - shape = mask->shapes.first; - while (shape) { - MaskSpline *spline = shape->splines.first; + maskobj = mask->maskobjs.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { int i, tot_feather_point; @@ -356,7 +356,7 @@ static int find_nearest_feather(bContext *C, Mask *mask, float normal_co[2], int else uw = &cur_point->uw[j - 1]; - point_shape = shape; + point_maskobj = maskobj; point_spline = spline; point = cur_point; len = cur_len; @@ -371,12 +371,12 @@ static int find_nearest_feather(bContext *C, Mask *mask, float normal_co[2], int spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } if (len < threshold) { - if (shape_r) - *shape_r = point_shape; + if (maskobj_r) + *maskobj_r = point_maskobj; if (spline_r) *spline_r = point_spline; @@ -393,8 +393,8 @@ static int find_nearest_feather(bContext *C, Mask *mask, float normal_co[2], int return TRUE; } - if (shape_r) - *shape_r = NULL; + if (maskobj_r) + *maskobj_r = NULL; if (spline_r) *spline_r = NULL; @@ -406,10 +406,10 @@ static int find_nearest_feather(bContext *C, Mask *mask, float normal_co[2], int } static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], int threshold, int feather, - MaskShape **shape_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + MaskObject **maskobj_r, MaskSpline **spline_r, MaskSplinePoint **point_r, float *u_r, float tangent[2]) { - MaskShape *shape, *point_shape; + MaskObject *maskobj, *point_maskobj; MaskSpline *point_spline; MaskSplinePoint *point = NULL; float dist, co[2]; @@ -424,9 +424,9 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; - shape = mask->shapes.first; - while (shape) { - MaskSpline *spline = shape->splines.first; + maskobj = mask->maskobjs.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { int i; @@ -469,7 +469,7 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], if (tangent) sub_v2_v2v2(tangent, &diff_points[2 * i + 2], &diff_points[2 * i]); - point_shape = shape; + point_maskobj = maskobj; point_spline = spline; point = cur_point; dist = cur_dist; @@ -488,12 +488,12 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } if (point && dist < threshold) { - if (shape_r) - *shape_r = point_shape; + if (maskobj_r) + *maskobj_r = point_maskobj; if (spline_r) *spline_r = point_spline; @@ -510,8 +510,8 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], return TRUE; } - if (shape_r) - *shape_r = NULL; + if (maskobj_r) + *maskobj_r = NULL; if (spline_r) *spline_r = NULL; @@ -524,11 +524,11 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], static void mask_flush_selection(Mask *mask) { - MaskShape *shape; + MaskObject *maskobj; - shape = mask->shapes.first; - while (shape) { - MaskSpline *spline = shape->splines.first; + maskobj = mask->maskobjs.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { int i; @@ -556,7 +556,7 @@ static void mask_flush_selection(Mask *mask) spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } } @@ -596,50 +596,50 @@ void MASK_OT_new(wmOperatorType *ot) RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new mask"); } -/******************** create new shape *********************/ +/******************** create new maskobj *********************/ -static int shape_new_exec(bContext *C, wmOperator *op) +static int maskobj_new_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); char name[MAX_ID_NAME - 2]; RNA_string_get(op->ptr, "name", name); - BKE_mask_shape_new(mask, name); - mask->shapenr = mask->tot_shape - 1; + BKE_mask_object_new(mask, name); + mask->act_maskobj = mask->tot_maskobj - 1; WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; } -void MASK_OT_shape_new(wmOperatorType *ot) +void MASK_OT_object_new(wmOperatorType *ot) { /* identifiers */ - ot->name = "Add Shape"; - ot->description = "Add new shape for masking"; - ot->idname = "MASK_OT_shape_new"; + ot->name = "Add Mask Object"; + ot->description = "Add new mask object for masking"; + ot->idname = "MASK_OT_object_new"; /* api callbacks */ - ot->exec = shape_new_exec; + ot->exec = maskobj_new_exec; ot->poll = ED_maskediting_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new shape"); + RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new mask object"); } -/******************** remove shape *********************/ +/******************** remove mask object *********************/ -static int shape_remove_exec(bContext *C, wmOperator *UNUSED(op)) +static int maskobj_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); - MaskShape *shape = BKE_mask_shape_active(mask); + MaskObject *maskobj = BKE_mask_object_active(mask); - if (shape) { - BKE_mask_shape_remove(mask, shape); + if (maskobj) { + BKE_mask_object_remove(mask, maskobj); WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); } @@ -647,15 +647,15 @@ static int shape_remove_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -void MASK_OT_shape_remove(wmOperatorType *ot) +void MASK_OT_object_remove(wmOperatorType *ot) { /* identifiers */ - ot->name = "Remove Shape"; - ot->description = "Remove shape used for masking"; - ot->idname = "MASK_OT_shape_remove"; + ot->name = "Remove Mask Object"; + ot->description = "Remove mask object"; + ot->idname = "MASK_OT_object_remove"; /* api callbacks */ - ot->exec = shape_remove_exec; + ot->exec = maskobj_remove_exec; ot->poll = ED_maskediting_poll; /* flags */ @@ -676,7 +676,7 @@ typedef struct SlidePointData { float vec[3][3]; Mask *mask; - MaskShape *shape; + MaskObject *maskobj; MaskSpline *spline; MaskSplinePoint *point; MaskSplinePointUW *uw; @@ -692,7 +692,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) { Mask *mask = CTX_data_edit_mask(C); SlidePointData *customdata = NULL; - MaskShape *shape, *cv_shape, *feather_shape; + MaskObject *maskobj, *cv_maskobj, *feather_maskobj; MaskSpline *spline, *cv_spline, *feather_spline; MaskSplinePoint *point, *cv_point, *feather_point; MaskSplinePointUW *uw = NULL; @@ -704,13 +704,13 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) ED_mask_mouse_pos(C, event, co); ED_mask_size(C, &width, &height); - cv_point = find_nearest_point(C, mask, co, threshold, &cv_shape, &cv_spline, &is_handle, &cv_score); + cv_point = find_nearest_point(C, mask, co, threshold, &cv_maskobj, &cv_spline, &is_handle, &cv_score); - if (find_nearest_feather(C, mask, co, threshold, &feather_shape, &feather_spline, &feather_point, &uw, &feather_score)) { + if (find_nearest_feather(C, mask, co, threshold, &feather_maskobj, &feather_spline, &feather_point, &uw, &feather_score)) { if (slide_feather || !cv_point || feather_score < cv_score) { action = SLIDE_ACTION_FEATHER; - shape = feather_shape; + maskobj = feather_maskobj; spline = feather_spline; point = feather_point; } @@ -722,7 +722,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) else action = SLIDE_ACTION_POINT; - shape = cv_shape; + maskobj = cv_maskobj; spline = cv_spline; point = cv_point; } @@ -731,7 +731,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) customdata = MEM_callocN(sizeof(SlidePointData), "mask slide point data"); customdata->mask = mask; - customdata->shape = shape; + customdata->maskobj = maskobj; customdata->spline = spline; customdata->point = point; customdata->width = width; @@ -798,8 +798,8 @@ static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) mask_flush_selection(mask); } - slidedata->shape->act_spline = slidedata->spline; - slidedata->shape->act_point = slidedata->point; + slidedata->maskobj->act_spline = slidedata->spline; + slidedata->maskobj->act_point = slidedata->point; WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); @@ -999,7 +999,7 @@ void MASK_OT_select_all(wmOperatorType *ot) static int select_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - MaskShape *shape; + MaskObject *maskobj; MaskSpline *spline; MaskSplinePoint *point = NULL; float co[2]; @@ -1009,7 +1009,7 @@ static int select_exec(bContext *C, wmOperator *op) RNA_float_get_array(op->ptr, "location", co); - point = find_nearest_point(C, mask, co, threshold, &shape, &spline, &is_handle, NULL); + point = find_nearest_point(C, mask, co, threshold, &maskobj, &spline, &is_handle, NULL); if (point) { if (!extend) @@ -1022,8 +1022,8 @@ static int select_exec(bContext *C, wmOperator *op) spline_point_select(point, SEL_SELECT); } - shape->act_spline = spline; - shape->act_point = point; + maskobj->act_spline = spline; + maskobj->act_point = point; mask_flush_selection(mask); @@ -1032,14 +1032,14 @@ static int select_exec(bContext *C, wmOperator *op) else { MaskSplinePointUW *uw; - if (find_nearest_feather(C, mask, co, threshold, &shape, &spline, &point, &uw, NULL)) { + if (find_nearest_feather(C, mask, co, threshold, &maskobj, &spline, &point, &uw, NULL)) { if (!extend) toggle_selection_all(mask, SEL_DESELECT); uw->flag |= SELECT; - shape->act_spline = spline; - shape->act_point = point; + maskobj->act_spline = spline; + maskobj->act_point = point; mask_flush_selection(mask); @@ -1217,13 +1217,13 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) { - MaskShape *shape; + MaskObject *maskobj; MaskSpline *spline; MaskSplinePoint *point = NULL; const float threshold = 9; float tangent[2]; - if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &shape, &spline, &point, NULL, tangent)) { + if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &maskobj, &spline, &point, NULL, tangent)) { MaskSplinePoint *new_point_array, *new_point; int point_index = point - spline->points; @@ -1243,7 +1243,7 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) setup_vertex_point(C, mask, spline, new_point, co, tangent, NULL, TRUE); - shape->act_point = new_point; + maskobj->act_point = new_point; WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); @@ -1255,17 +1255,17 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) /* **** add extrude vertex **** */ -static void finSelectedSplinePoint(MaskShape *shape, MaskSpline **spline, MaskSplinePoint **point, short check_active) +static void finSelectedSplinePoint(MaskObject *maskobj, MaskSpline **spline, MaskSplinePoint **point, short check_active) { - MaskSpline *cur_spline = shape->splines.first; + MaskSpline *cur_spline = maskobj->splines.first; *spline = NULL; *point = NULL; if (check_active) { - if (shape->act_spline && shape->act_point) { - *spline = shape->act_spline; - *point = shape->act_point; + if (maskobj->act_spline && maskobj->act_point) { + *spline = maskobj->act_spline; + *point = maskobj->act_point; return; } } @@ -1298,30 +1298,30 @@ static void finSelectedSplinePoint(MaskShape *shape, MaskSpline **spline, MaskSp static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) { - MaskShape *shape; + MaskObject *maskobj; MaskSpline *spline; MaskSplinePoint *point; MaskSplinePoint *new_point = NULL, *ref_point = NULL; toggle_selection_all(mask, SEL_DESELECT); - shape = BKE_mask_shape_active(mask); + maskobj = BKE_mask_object_active(mask); - if (!shape) { - /* if there's no shape currently operationg on, create new one */ - shape = BKE_mask_shape_new(mask, ""); - mask->shapenr = mask->tot_shape - 1; + if (!maskobj) { + /* if there's no maskobj currently operationg on, create new one */ + maskobj = BKE_mask_object_new(mask, ""); + mask->act_maskobj = mask->tot_maskobj - 1; spline = NULL; point = NULL; } else { - finSelectedSplinePoint(shape, &spline, &point, TRUE); + finSelectedSplinePoint(maskobj, &spline, &point, TRUE); } if (!spline) { - /* no selected splines in actuve shape, create new spline */ - spline = BKE_mask_spline_add(shape); - shape->act_spline = spline; + /* no selected splines in active maskobj, create new spline */ + spline = BKE_mask_spline_add(maskobj); + maskobj->act_spline = spline; new_point = spline->points; } @@ -1351,13 +1351,13 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) ref_point = &spline->points[1]; } else { - spline = BKE_mask_spline_add(shape); - shape->act_spline = spline; + spline = BKE_mask_spline_add(maskobj); + maskobj->act_spline = spline; new_point = spline->points; } } - shape->act_point = new_point; + maskobj->act_point = new_point; setup_vertex_point(C, mask, spline, new_point, co, NULL, ref_point, FALSE); WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); @@ -1416,7 +1416,7 @@ void MASK_OT_add_vertex(wmOperatorType *ot) static int add_feather_vertex_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - MaskShape *shape; + MaskObject *maskobj; MaskSpline *spline; MaskSplinePoint *point = NULL; const float threshold = 9; @@ -1428,7 +1428,7 @@ static int add_feather_vertex_exec(bContext *C, wmOperator *op) if (point) return OPERATOR_FINISHED; - if (find_nearest_diff_point(C, mask, co, threshold, TRUE, &shape, &spline, &point, &u, NULL)) { + if (find_nearest_diff_point(C, mask, co, threshold, TRUE, &maskobj, &spline, &point, &u, NULL)) { float w = BKE_mask_point_weight(spline, point, u); BKE_mask_point_add_uw(point, u, w); @@ -1477,10 +1477,10 @@ void MASK_OT_add_feather_vertex(wmOperatorType *ot) static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); - MaskShape *shape = mask->shapes.first; + MaskObject *maskobj = mask->maskobjs.first; - while (shape) { - MaskSpline *spline = shape->splines.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { if (points_has_selection(spline->points, spline->tot_point)) @@ -1489,7 +1489,7 @@ static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); @@ -1553,10 +1553,10 @@ static void delete_feather_points(MaskSplinePoint *point) static int delete_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); - MaskShape *shape = mask->shapes.first; + MaskObject *maskobj = mask->maskobjs.first; - while (shape) { - MaskSpline *spline = shape->splines.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { int i, count = 0; @@ -1572,12 +1572,12 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) if (count == 0) { /* delete the whole spline */ - BLI_remlink(&shape->splines, spline); + BLI_remlink(&maskobj->splines, spline); BKE_mask_spline_free(spline); - if (spline == shape->act_spline) { - shape->act_spline = NULL; - shape->act_point = NULL; + if (spline == maskobj->act_spline) { + maskobj->act_spline = NULL; + maskobj->act_point = NULL; } } else { @@ -1590,8 +1590,8 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) MaskSplinePoint *point = &spline->points[i]; if (!MASKPOINT_ISSEL(point)) { - if (point == shape->act_point) - shape->act_point = &new_points[j]; + if (point == maskobj->act_point) + maskobj->act_point = &new_points[j]; delete_feather_points(point); @@ -1599,8 +1599,8 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) j++; } else { - if (point == shape->act_point) - shape->act_point = NULL; + if (point == maskobj->act_point) + maskobj->act_point = NULL; BKE_mask_point_free(point); } @@ -1616,7 +1616,7 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) spline = next_spline; } - shape = shape->next; + maskobj = maskobj->next; } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); @@ -1645,11 +1645,11 @@ void MASK_OT_delete(wmOperatorType *ot) static int set_handle_type_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - MaskShape *shape = mask->shapes.first; + MaskObject *maskobj = mask->maskobjs.first; int handle_type = RNA_enum_get(op->ptr, "type"); - while (shape) { - MaskSpline *spline = shape->splines.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; int i; while (spline) { @@ -1666,7 +1666,7 @@ static int set_handle_type_exec(bContext *C, wmOperator *op) spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 50d6beb0681..0a4b7aaeb01 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5943,15 +5943,15 @@ static void createTransMaskingData(bContext *C, TransInfo *t) { SpaceClip *sc = CTX_wm_space_clip(C); Mask *mask = CTX_data_edit_mask(C); - MaskShape *shape; + MaskObject *maskobj; TransData *td = NULL; TransData2D *td2d = NULL; TransDataMasking *tdm = NULL; /* count */ - shape = mask ? mask->shapes.first : NULL; - while (shape) { - MaskSpline *spline = shape->splines.first; + maskobj = mask ? mask->maskobjs.first : NULL; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { int i; @@ -5970,7 +5970,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t) spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } if (t->total == 0) @@ -5985,9 +5985,9 @@ static void createTransMaskingData(bContext *C, TransInfo *t) t->flag |= T_FREE_CUSTOMDATA; /* create data */ - shape = mask->shapes.first; - while (shape) { - MaskSpline *spline = shape->splines.first; + maskobj = mask->maskobjs.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { int i; @@ -6014,7 +6014,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t) spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } } diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index dbdde515804..7fb2196e82c 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -43,9 +43,9 @@ typedef struct Mask { ID id; struct AnimData *adt; - ListBase shapes; /* shapes which defines this mask */ - int shapenr; /* index of active shape */ - int tot_shape; /* total number of shapes */ + ListBase maskobjs; /* mask objects */ + int act_maskobj; /* index of active mask object */ + int tot_maskobj; /* total number of mask objects */ } Mask; typedef struct MaskParent { @@ -85,15 +85,15 @@ typedef struct MaskSpline { int weight_interp, pad; /* weight interpolation */ } MaskSpline; -typedef struct MaskShape { - struct MaskShape *next, *prev; +typedef struct MaskObject { + struct MaskObject *next, *prev; - char name[64]; /* name of the shape (64 = MAD_ID_NAME - 2) */ + char name[64]; /* name of the mask object (64 = MAD_ID_NAME - 2) */ - ListBase splines; /* list of splines which defines this shape */ + ListBase splines; /* list of splines which defines this mask object */ struct MaskSpline *act_spline; /* active spline */ struct MaskSplinePoint *act_point; /* active point */ -} MaskShape; +} MaskObject; /* MaskParent->flag */ #define MASK_PARENT_ACTIVE (1 << 0) diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 3d4a5a39dc2..864a7c31cef 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -93,106 +93,106 @@ static void rna_MaskParent_id_type_set(PointerRNA *ptr, int value) mpar->id = NULL; } -static void rna_Mask_shapes_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +static void rna_Mask_objects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Mask *mask = (Mask *)ptr->id.data; - rna_iterator_listbase_begin(iter, &mask->shapes, NULL); + rna_iterator_listbase_begin(iter, &mask->maskobjs, NULL); } -static int rna_Mask_active_shape_index_get(PointerRNA *ptr) +static int rna_Mask_object_active_index_get(PointerRNA *ptr) { Mask *mask = (Mask *)ptr->id.data; - return mask->shapenr; + return mask->act_maskobj; } -static void rna_Mask_active_shape_index_set(PointerRNA *ptr, int value) +static void rna_Mask_object_active_index_set(PointerRNA *ptr, int value) { Mask *mask = (Mask *)ptr->id.data; - mask->shapenr = value; + mask->act_maskobj = value; } -static void rna_Mask_active_shape_index_range(PointerRNA *ptr, int *min, int *max) +static void rna_Mask_object_active_index_range(PointerRNA *ptr, int *min, int *max) { Mask *mask = (Mask *)ptr->id.data; *min = 0; - *max = mask->tot_shape - 1; + *max = mask->tot_maskobj - 1; *max = MAX2(0, *max); } -static PointerRNA rna_Mask_active_shape_get(PointerRNA *ptr) +static PointerRNA rna_Mask_object_active_get(PointerRNA *ptr) { Mask *mask = (Mask *)ptr->id.data; - MaskShape *shape = BKE_mask_shape_active(mask); + MaskObject *maskobj = BKE_mask_object_active(mask); - return rna_pointer_inherit_refine(ptr, &RNA_MaskShape, shape); + return rna_pointer_inherit_refine(ptr, &RNA_MaskObject, maskobj); } -static void rna_Mask_active_shape_set(PointerRNA *ptr, PointerRNA value) +static void rna_Mask_object_active_set(PointerRNA *ptr, PointerRNA value) { Mask *mask = (Mask *)ptr->id.data; - MaskShape *shape = (MaskShape *)value.data; + MaskObject *maskobj = (MaskObject *)value.data; - BKE_mask_shape_active_set(mask, shape); + BKE_mask_object_active_set(mask, maskobj); } -static void rna_MaskShape_splines_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +static void rna_MaskObject_splines_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { - MaskShape *shape = (MaskShape *)ptr->data; + MaskObject *maskobj = (MaskObject *)ptr->data; - rna_iterator_listbase_begin(iter, &shape->splines, NULL); + rna_iterator_listbase_begin(iter, &maskobj->splines, NULL); } -void rna_MaskShape_name_set(PointerRNA *ptr, const char *value) +void rna_MaskObject_name_set(PointerRNA *ptr, const char *value) { Mask *mask = (Mask *)ptr->id.data; - MaskShape *shape = (MaskShape *)ptr->data; + MaskObject *maskobj = (MaskObject *)ptr->data; - BLI_strncpy(shape->name, value, sizeof(shape->name)); + BLI_strncpy(maskobj->name, value, sizeof(maskobj->name)); - BKE_mask_shape_unique_name(mask, shape); + BKE_mask_object_unique_name(mask, maskobj); } -static PointerRNA rna_MaskShape_active_spline_get(PointerRNA *ptr) +static PointerRNA rna_MaskObject_active_spline_get(PointerRNA *ptr) { - MaskShape *shape = (MaskShape *)ptr->data; + MaskObject *maskobj = (MaskObject *)ptr->data; - return rna_pointer_inherit_refine(ptr, &RNA_MaskSpline, shape->act_spline); + return rna_pointer_inherit_refine(ptr, &RNA_MaskSpline, maskobj->act_spline); } -static void rna_MaskShape_active_spline_set(PointerRNA *ptr, PointerRNA value) +static void rna_MaskObject_active_spline_set(PointerRNA *ptr, PointerRNA value) { - MaskShape *shape = (MaskShape *)ptr->data; + MaskObject *maskobj = (MaskObject *)ptr->data; MaskSpline *spline = (MaskSpline *)value.data; - int index = BLI_findindex(&shape->splines, spline); + int index = BLI_findindex(&maskobj->splines, spline); if (index >= 0) - shape->act_spline = spline; + maskobj->act_spline = spline; else - shape->act_spline = NULL; + maskobj->act_spline = NULL; } -static PointerRNA rna_MaskShape_active_spline_point_get(PointerRNA *ptr) +static PointerRNA rna_MaskObject_active_spline_point_get(PointerRNA *ptr) { - MaskShape *shape = (MaskShape *)ptr->data; + MaskObject *maskobj = (MaskObject *)ptr->data; - return rna_pointer_inherit_refine(ptr, &RNA_MaskSplinePoint, shape->act_point); + return rna_pointer_inherit_refine(ptr, &RNA_MaskSplinePoint, maskobj->act_point); } -static void rna_MaskShape_active_spline_point_set(PointerRNA *ptr, PointerRNA value) +static void rna_MaskObject_active_spline_point_set(PointerRNA *ptr, PointerRNA value) { - MaskShape *shape = (MaskShape *)ptr->data; - MaskSpline *spline = shape->splines.first; + MaskObject *maskobj = (MaskObject *)ptr->data; + MaskSpline *spline = maskobj->splines.first; MaskSplinePoint *point = (MaskSplinePoint *)value.data; - shape->act_point = NULL; + maskobj->act_point = NULL; while (spline) { if (point >= spline->points && point < spline->points + spline->tot_point) { - shape->act_point = point; + maskobj->act_point = point; break; } @@ -279,29 +279,29 @@ static void rna_MaskSplinePoint_handle_type_set(PointerRNA *ptr, int value) /* ** API ** */ -static MaskShape *rna_Mask_shape_new(Mask *mask, const char *name) +static MaskObject *rna_Mask_object_new(Mask *mask, const char *name) { - MaskShape *shape = BKE_mask_shape_new(mask, name); + MaskObject *maskobj = BKE_mask_object_new(mask, name); WM_main_add_notifier(NC_MASK|NA_EDITED, mask); - return shape; + return maskobj; } -void rna_Mask_shape_remove(Mask *mask, MaskShape *shape) +void rna_Mask_object_remove(Mask *mask, MaskObject *maskobj) { - BKE_mask_shape_remove(mask, shape); + BKE_mask_object_remove(mask, maskobj); WM_main_add_notifier(NC_MASK|NA_EDITED, mask); } -static void rna_MaskShape_spline_add(ID *id, MaskShape *shape, int number) +static void rna_MaskObject_spline_add(ID *id, MaskObject *maskobj, int number) { Mask *mask = (Mask*) id; int i; for (i = 0; i < number; i++) - BKE_mask_spline_add(shape); + BKE_mask_spline_add(maskobj); WM_main_add_notifier(NC_MASK|NA_EDITED, mask); } @@ -402,7 +402,7 @@ static void rna_def_maskSplinePoint(BlenderRNA *brna) rna_def_maskSplinePointUW(brna); srna = RNA_def_struct(brna, "MaskSplinePoint", NULL); - RNA_def_struct_ui_text(srna, "Mask Spline Point", "Single point in spline used for defining mash shape"); + RNA_def_struct_ui_text(srna, "Mask Spline Point", "Single point in spline used for defining mask"); /* Vector values */ prop = RNA_def_property(srna, "handle_left", PROP_FLOAT, PROP_TRANSLATION); @@ -447,34 +447,34 @@ static void rna_def_maskSplinePoint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Feather Points", "Points defining feather"); } -static void rna_def_maskSplines(BlenderRNA *brna) +static void rna_def_mask_splines(BlenderRNA *brna) { StructRNA *srna; FunctionRNA *func; PropertyRNA *prop; srna = RNA_def_struct(brna, "MaskSplines", NULL); - RNA_def_struct_sdna(srna, "MaskShape"); + RNA_def_struct_sdna(srna, "MaskObject"); RNA_def_struct_ui_text(srna, "Mask Splines", "Collection of masking splines"); - func = RNA_def_function(srna, "add", "rna_MaskShape_spline_add"); + func = RNA_def_function(srna, "add", "rna_MaskObject_spline_add"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Add a number of splines to mask shape"); - RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of splines to add to the shape", 0, INT_MAX); + RNA_def_function_ui_description(func, "Add a number of splines to mask object"); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of splines to add to the object", 0, INT_MAX); /* active spline */ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MaskSpline"); - RNA_def_property_pointer_funcs(prop, "rna_MaskShape_active_spline_get", "rna_MaskShape_active_spline_set", NULL, NULL); + RNA_def_property_pointer_funcs(prop, "rna_MaskObject_active_spline_get", "rna_MaskObject_active_spline_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); - RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking shape"); + RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking object"); /* active point */ prop = RNA_def_property(srna, "active_point", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MaskSplinePoint"); - RNA_def_property_pointer_funcs(prop, "rna_MaskShape_active_spline_point_get", "rna_MaskShape_active_spline_point_set", NULL, NULL); + RNA_def_property_pointer_funcs(prop, "rna_MaskObject_active_spline_point_get", "rna_MaskObject_active_spline_point_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); - RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking shape"); + RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking object"); } static void rna_def_maskSpline(BlenderRNA *brna) @@ -507,34 +507,34 @@ static void rna_def_maskSpline(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Mask_update_data"); } -static void rna_def_maskShape(BlenderRNA *brna) +static void rna_def_mask_object(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; rna_def_maskSpline(brna); - rna_def_maskSplines(brna); + rna_def_mask_splines(brna); - srna = RNA_def_struct(brna, "MaskShape", NULL); - RNA_def_struct_ui_text(srna, "Mask shape", "Single shape used for masking stuff"); + srna = RNA_def_struct(brna, "MaskObject", NULL); + RNA_def_struct_ui_text(srna, "Mask Object", "Single object used for masking pixels"); /* name */ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_ui_text(prop, "Name", "Unique name of shape"); - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MaskShape_name_set"); + RNA_def_property_ui_text(prop, "Name", "Unique name of object"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MaskObject_name_set"); RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); RNA_def_property_update(prop, 0, "rna_Mask_update_data"); RNA_def_struct_name_property(srna, prop); /* splines */ prop = RNA_def_property(srna, "splines", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_funcs(prop, "rna_MaskShape_splines_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_MaskObject_splines_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); RNA_def_property_struct_type(prop, "MaskSpline"); - RNA_def_property_ui_text(prop, "Splines", "Collection of splines which defines this shape"); + RNA_def_property_ui_text(prop, "Splines", "Collection of splines which defines this object"); RNA_def_property_srna(prop, "MaskSplines"); } -static void rna_def_maskShapes(BlenderRNA *brna, PropertyRNA *cprop) +static void rna_def_maskobjects(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; PropertyRNA *prop; @@ -542,27 +542,27 @@ static void rna_def_maskShapes(BlenderRNA *brna, PropertyRNA *cprop) FunctionRNA *func; PropertyRNA *parm; - RNA_def_property_srna(cprop, "MaskShapes"); - srna = RNA_def_struct(brna, "MaskShapes", NULL); + RNA_def_property_srna(cprop, "MaskObjects"); + srna = RNA_def_struct(brna, "MaskObjects", NULL); RNA_def_struct_sdna(srna, "Mask"); - RNA_def_struct_ui_text(srna, "Mask Shapes", "Collection of shapes used by mask"); + RNA_def_struct_ui_text(srna, "Mask Objects", "Collection of objects used by mask"); - func = RNA_def_function(srna, "new", "rna_Mask_shape_new"); - RNA_def_function_ui_description(func, "Add shape to this mask"); - RNA_def_string(func, "name", "", 0, "Name", "Name of new shape"); - parm = RNA_def_pointer(func, "shape", "MaskShape", "", "New mask shape"); + func = RNA_def_function(srna, "new", "rna_Mask_object_new"); + RNA_def_function_ui_description(func, "Add object to this mask"); + RNA_def_string(func, "name", "", 0, "Name", "Name of new object"); + parm = RNA_def_pointer(func, "object", "MaskObject", "", "New mask object"); RNA_def_function_return(func, parm); - func = RNA_def_function(srna, "remove", "rna_Mask_shape_remove"); - RNA_def_function_ui_description(func, "Remove shape from this mask"); - RNA_def_pointer(func, "shape", "MaskShape", "", "Shape to be removed"); + func = RNA_def_function(srna, "remove", "rna_Mask_object_remove"); + RNA_def_function_ui_description(func, "Remove object from this mask"); + RNA_def_pointer(func, "object", "MaskObject", "", "Shape to be removed"); /* active object */ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "MaskShape"); - RNA_def_property_pointer_funcs(prop, "rna_Mask_active_shape_get", "rna_Mask_active_shape_set", NULL, NULL); + RNA_def_property_struct_type(prop, "MaskObject"); + RNA_def_property_pointer_funcs(prop, "rna_Mask_object_active_get", "rna_Mask_object_active_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); - RNA_def_property_ui_text(prop, "Active Shape", "Active shape in this mask"); + RNA_def_property_ui_text(prop, "Active Shape", "Active object in this mask"); } static void rna_def_mask(BlenderRNA *brna) @@ -570,25 +570,25 @@ static void rna_def_mask(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - rna_def_maskShape(brna); + rna_def_mask_object(brna); srna = RNA_def_struct(brna, "Mask", "ID"); RNA_def_struct_ui_text(srna, "Mask", "Mask datablock defining mask for compositing"); RNA_def_struct_ui_icon(srna, ICON_MOD_MASK); - /* shapes */ - prop = RNA_def_property(srna, "shapes", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_funcs(prop, "rna_Mask_shapes_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); - RNA_def_property_struct_type(prop, "MaskShape"); - RNA_def_property_ui_text(prop, "Shapes", "Collection of shapes which defines this mask"); - rna_def_maskShapes(brna, prop); + /* mask objects */ + prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_Mask_objects_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_struct_type(prop, "MaskObject"); + RNA_def_property_ui_text(prop, "Objects", "Collection of objects which defines this mask"); + rna_def_maskobjects(brna, prop); - /* active shape index */ - prop = RNA_def_property(srna, "active_shape_index", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "shapenr"); + /* active maskobj index */ + prop = RNA_def_property(srna, "active_object_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "act_maskobj"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_funcs(prop, "rna_Mask_active_shape_index_get", "rna_Mask_active_shape_index_set", "rna_Mask_active_shape_index_range"); - RNA_def_property_ui_text(prop, "Active Shape Index", "Index of active shape in list of all mask's shapes"); + RNA_def_property_int_funcs(prop, "rna_Mask_object_active_index_get", "rna_Mask_object_active_index_set", "rna_Mask_object_active_index_range"); + RNA_def_property_ui_text(prop, "Active Shape Index", "Index of active object in list of all mask's objects"); } void RNA_def_mask(BlenderRNA *brna) diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c index a586824e6e1..2f7f48c5c4b 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mask.c +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -58,7 +58,7 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) Mask *mask = (Mask *)node->id; CompBuf *stackbuf; RenderData *rd = data; - MaskShape *shape = mask->shapes.first; + MaskObject *maskobj = mask->maskobjs.first; float *res; int sx, sy; @@ -84,9 +84,9 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE); res = stackbuf->rect; - shape = mask->shapes.first; - while (shape) { - MaskSpline *spline = shape->splines.first; + maskobj = mask->maskobjs.first; + while (maskobj) { + MaskSpline *spline = maskobj->splines.first; while (spline) { float *diff_points; @@ -123,7 +123,7 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) spline = spline->next; } - shape = shape->next; + maskobj = maskobj->next; } /* pass on output and free */ From ec142edaa02038875a329a5272cec8b94bb800bd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 May 2012 14:49:30 +0000 Subject: [PATCH 066/360] code cleanup: use for loops for mask/spline looping --- source/blender/blenkernel/intern/mask.c | 12 +- source/blender/blenloader/intern/readfile.c | 10 +- source/blender/blenloader/intern/writefile.c | 10 +- source/blender/editors/mask/mask_draw.c | 12 +- source/blender/editors/mask/mask_ops.c | 104 ++++++------------ .../editors/transform/transform_conversions.c | 10 +- source/blender/makesrna/intern/rna_mask.c | 6 +- .../composite/nodes/node_composite_mask.c | 11 +- 8 files changed, 53 insertions(+), 122 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index e3c2570ab93..1b6dabbf94c 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -957,13 +957,13 @@ void BKE_mask_calc_handles(Mask *mask) void BKE_mask_evaluate(Mask *mask, float ctime) { - MaskObject *maskobj = mask->maskobjs.first; + MaskObject *maskobj; - while (maskobj) { - MaskSpline *spline = maskobj->splines.first; + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; int i; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; BezTriple *bezt = &point->bezt; @@ -977,11 +977,7 @@ void BKE_mask_evaluate(Mask *mask, float ctime) add_v2_v2(bezt->vec[1], delta); add_v2_v2(bezt->vec[2], delta); } - - spline = spline->next; } - - maskobj = maskobj->next; } BKE_mask_calc_handles(mask); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d0b9808697f..17eabc3d7ac 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6282,8 +6282,7 @@ static void direct_link_mask(FileData *fd, Mask *mask) link_list(fd, &mask->maskobjs); - maskobj = mask->maskobjs.first; - while (maskobj) { + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; link_list(fd, &maskobj->splines); @@ -6306,8 +6305,6 @@ static void direct_link_mask(FileData *fd, Mask *mask) maskobj->act_spline = newdataadr(fd, maskobj->act_spline); maskobj->act_point = newdataadr(fd, maskobj->act_point); - - maskobj = maskobj->next; } } @@ -6328,8 +6325,7 @@ static void lib_link_mask(FileData *fd, Main *main) if (mask->adt) lib_link_animdata(fd, &mask->id, mask->adt); - maskobj = mask->maskobjs.first; - while (maskobj) { + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; spline = maskobj->splines.first; @@ -6346,8 +6342,6 @@ static void lib_link_mask(FileData *fd, Main *main) spline = spline->next; } - - maskobj = maskobj->next; } mask->id.flag -= LIB_NEEDLINK; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index a514a3283b1..7a924238c77 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2769,14 +2769,12 @@ static void write_masks(WriteData *wd, ListBase *idbase) if (mask->adt) write_animdata(wd, mask->adt); - maskobj = mask->maskobjs.first; - while (maskobj) { + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; writestruct(wd, DATA, "MaskObject", 1, maskobj); - spline = maskobj->splines.first; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; writestruct(wd, DATA, "MaskSpline", 1, spline); @@ -2788,11 +2786,7 @@ static void write_masks(WriteData *wd, ListBase *idbase) if (point->tot_uw) writestruct(wd, DATA, "MaskSplinePointUW", point->tot_uw, point->uw); } - - spline = spline->next; } - - maskobj = maskobj->next; } } diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 06f24c6fa8f..f4022581f2d 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -218,22 +218,18 @@ static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline) static void draw_maskobjs(Mask *mask) { - MaskObject *maskobj = mask->maskobjs.first; + MaskObject *maskobj; - while (maskobj) { - MaskSpline *spline = maskobj->splines.first; + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { /* draw curve itself first... */ draw_spline_curve(maskobj, spline); /* ...and then handles over the curve so they're nicely visible */ draw_spline_points(maskobj, spline); - - spline = spline->next; } - - maskobj = maskobj->next; } } diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 9b9dbcec7e5..7774af690d7 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -167,19 +167,16 @@ static int points_has_selection(MaskSplinePoint *points, int tot_point) static int mask_has_selection(Mask *mask) { - MaskObject *maskobj = mask->maskobjs.first; + MaskObject *maskobj; - while (maskobj) { - MaskSpline *spline = maskobj->splines.first; + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; - while (spline) { - if (points_has_selection(spline->points, spline->tot_point)) + for (spline = maskobj->splines.first; spline; spline = spline->next) { + if (points_has_selection(spline->points, spline->tot_point)) { return TRUE; - - spline = spline->next; + } } - - maskobj = maskobj->next; } return FALSE; @@ -187,7 +184,7 @@ static int mask_has_selection(Mask *mask) static void toggle_selection_all(Mask *mask, int action) { - MaskObject *maskobj = mask->maskobjs.first; + MaskObject *maskobj; if (action == SEL_TOGGLE) { if (mask_has_selection(mask)) @@ -196,10 +193,10 @@ static void toggle_selection_all(Mask *mask, int action) action = SEL_SELECT; } - while (maskobj) { - MaskSpline *spline = maskobj->splines.first; + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { @@ -207,11 +204,7 @@ static void toggle_selection_all(Mask *mask, int action) spline_point_select(point, action); } - - spline = spline->next; } - - maskobj = maskobj->next; } } @@ -234,11 +227,10 @@ static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; - maskobj = mask->maskobjs.first; - while (maskobj) { - MaskSpline *spline = maskobj->splines.first; + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { @@ -274,11 +266,7 @@ static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal is_handle = FALSE; } } - - spline = spline->next; } - - maskobj = maskobj->next; } if (len < threshold) { @@ -328,11 +316,10 @@ static int find_nearest_feather(bContext *C, Mask *mask, float normal_co[2], int co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; - maskobj = mask->maskobjs.first; - while (maskobj) { - MaskSpline *spline = maskobj->splines.first; + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i, tot_feather_point; float *feather_points, *fp; @@ -367,11 +354,7 @@ static int find_nearest_feather(bContext *C, Mask *mask, float normal_co[2], int } MEM_freeN(feather_points); - - spline = spline->next; } - - maskobj = maskobj->next; } if (len < threshold) { @@ -424,11 +407,10 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; - maskobj = mask->maskobjs.first; - while (maskobj) { - MaskSpline *spline = maskobj->splines.first; + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { @@ -484,11 +466,7 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], MEM_freeN(diff_points); } } - - spline = spline->next; } - - maskobj = maskobj->next; } if (point && dist < threshold) { @@ -526,11 +504,10 @@ static void mask_flush_selection(Mask *mask) { MaskObject *maskobj; - maskobj = mask->maskobjs.first; - while (maskobj) { - MaskSpline *spline = maskobj->splines.first; + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; spline->flag &= ~SELECT; @@ -552,11 +529,7 @@ static void mask_flush_selection(Mask *mask) } } } - - spline = spline->next; } - - maskobj = maskobj->next; } } @@ -1477,19 +1450,16 @@ void MASK_OT_add_feather_vertex(wmOperatorType *ot) static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj = mask->maskobjs.first; + MaskObject *maskobj; - while (maskobj) { - MaskSpline *spline = maskobj->splines.first; + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; - while (spline) { - if (points_has_selection(spline->points, spline->tot_point)) + for (spline = maskobj->splines.first; spline; spline = spline->next) { + if (points_has_selection(spline->points, spline->tot_point)) { spline->flag ^= MASK_SPLINE_CYCLIC; - - spline = spline->next; + } } - - maskobj = maskobj->next; } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); @@ -1553,9 +1523,9 @@ static void delete_feather_points(MaskSplinePoint *point) static int delete_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj = mask->maskobjs.first; + MaskObject *maskobj; - while (maskobj) { + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline = maskobj->splines.first; while (spline) { @@ -1615,8 +1585,6 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) spline = next_spline; } - - maskobj = maskobj->next; } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); @@ -1645,14 +1613,14 @@ void MASK_OT_delete(wmOperatorType *ot) static int set_handle_type_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj = mask->maskobjs.first; + MaskObject *maskobj; int handle_type = RNA_enum_get(op->ptr, "type"); - while (maskobj) { - MaskSpline *spline = maskobj->splines.first; + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; int i; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; @@ -1662,11 +1630,7 @@ static int set_handle_type_exec(bContext *C, wmOperator *op) bezt->h1 = bezt->h2 = handle_type; } } - - spline = spline->next; } - - maskobj = maskobj->next; } WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 0a4b7aaeb01..e8cec774a60 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5949,8 +5949,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t) TransDataMasking *tdm = NULL; /* count */ - maskobj = mask ? mask->maskobjs.first : NULL; - while (maskobj) { + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline = maskobj->splines.first; while (spline) { @@ -5969,8 +5968,6 @@ static void createTransMaskingData(bContext *C, TransInfo *t) spline = spline->next; } - - maskobj = maskobj->next; } if (t->total == 0) @@ -5985,8 +5982,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t) t->flag |= T_FREE_CUSTOMDATA; /* create data */ - maskobj = mask->maskobjs.first; - while (maskobj) { + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline = maskobj->splines.first; while (spline) { @@ -6013,8 +6009,6 @@ static void createTransMaskingData(bContext *C, TransInfo *t) spline = spline->next; } - - maskobj = maskobj->next; } } diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 864a7c31cef..53a6bc34c4a 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -185,19 +185,17 @@ static PointerRNA rna_MaskObject_active_spline_point_get(PointerRNA *ptr) static void rna_MaskObject_active_spline_point_set(PointerRNA *ptr, PointerRNA value) { MaskObject *maskobj = (MaskObject *)ptr->data; - MaskSpline *spline = maskobj->splines.first; + MaskSpline *spline; MaskSplinePoint *point = (MaskSplinePoint *)value.data; maskobj->act_point = NULL; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { if (point >= spline->points && point < spline->points + spline->tot_point) { maskobj->act_point = point; break; } - - spline = spline->next; } } diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c index 2f7f48c5c4b..93d1edd76e8 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mask.c +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -84,11 +84,10 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE); res = stackbuf->rect; - maskobj = mask->maskobjs.first; - while (maskobj) { - MaskSpline *spline = maskobj->splines.first; + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { float *diff_points; int tot_diff_point; @@ -119,11 +118,7 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) MEM_freeN(diff_points); } - - spline = spline->next; } - - maskobj = maskobj->next; } /* pass on output and free */ From e63040a263e2195bf042d599c3db005ca2f15abc Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Fri, 18 May 2012 19:17:55 +0000 Subject: [PATCH 067/360] Tomato Branch: * Fix for msvc, it needs stdio header for the NULL keyword. --- intern/raskter/raskter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index f9c2f851f6e..cf8d76372e7 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -28,6 +28,7 @@ * \ingroup RASKTER */ +#include #include #include "raskter.h" From c5dd7879330500365c36f9b4d7af23608a2c3a8b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 18 May 2012 19:22:50 +0000 Subject: [PATCH 068/360] No need to invert brute and normalization flags in rna. Also remove currently unused update callback. --- source/blender/blenkernel/intern/tracking.c | 9 +++++++-- source/blender/makesrna/intern/rna_tracking.c | 19 ++++++------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 2456411c2c2..7ac687e3beb 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1734,8 +1734,13 @@ int BKE_tracking_next(MovieTrackingContext *context) /* Configure the tracker */ options.motion_model = track->motion_model; - options.use_brute = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) == 0); - options.use_normalization = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) == 0); + + options.use_brute = + ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) != 0); + + options.use_normalization = + ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) != 0); + options.num_iterations = 50; options.minimum_correlation = track->minimum_correlation; options.sigma = 0.9; diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 565655ccf37..52cb9f2f409 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -195,13 +195,6 @@ static void rna_trackingTrack_select_set(PointerRNA *ptr, int value) } } -static void rna_tracking_trackerPattern_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - MovieTrackingTrack *track = (MovieTrackingTrack *)ptr->data; - - BKE_tracking_clamp_track(track, CLAMP_PAT_DIM); -} - static void rna_tracking_trackerSearch_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { MovieTrackingTrack *track = (MovieTrackingTrack *)ptr->data; @@ -621,14 +614,14 @@ static void rna_def_trackingSettings(BlenderRNA *brna) /* use_brute */ prop = RNA_def_property(srna, "default_use_brute", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); + RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation-only initialization when tracking"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); /* default use_normalization */ prop = RNA_def_property(srna, "default_use_normalization", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); - RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking. Slower."); + RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); + RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking. Slower"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); /* default minmal correlation */ @@ -932,16 +925,16 @@ static void rna_def_trackingTrack(BlenderRNA *brna) /* use_brute */ prop = RNA_def_property(srna, "use_brute", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); + RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation only pre-track before refinement"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); /* use_brute */ prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); + RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking. Slower."); + RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking. Slower"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); /* markers */ From c72298ea19b92ac8674bef8804592d4de8f53a70 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Fri, 18 May 2012 20:04:43 +0000 Subject: [PATCH 069/360] Remove an unnecessary template<> line in libmv. Convert debug logs to LG. --- extern/libmv/libmv/tracking/track_region.cc | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index 6fad3f7af3f..62cc43205d0 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -105,7 +105,6 @@ struct AutoDiff { // Sample the image and gradient when the coordinates are jets, applying the // jacobian appropriately to propagate the derivatives from the coordinates. -template<> template struct AutoDiff > { static ceres::Jet Sample(const FloatImage &image_and_gradient, @@ -353,8 +352,8 @@ class WarpCostFunctor { } *src_mean /= T(num_samples); *dst_mean /= T(num_samples); - std::cout << "Normalization for src:\n" << *src_mean << "\n"; - std::cout << "Normalization for dst:\n" << *dst_mean << "\n"; + LG << "Normalization for src:" << *src_mean; + LG << "Normalization for dst:" << *dst_mean; } // TODO(keir): Consider also computing the cost here. @@ -591,9 +590,9 @@ struct TranslationRotationWarp { Mat2 R = OrthogonalProcrustes(correlation_matrix); parameters[2] = atan2(R(1, 0), R(0, 0)); - std::cout << "correlation_matrix:\n" << correlation_matrix << "\n"; - std::cout << "R:\n" << R << "\n"; - std::cout << "theta:" << parameters[2] << "\n"; + LG << "Correlation_matrix:\n" << correlation_matrix; + LG << "R:\n" << R; + LG << "Theta:" << parameters[2]; } // The strange way of parameterizing the translation and rotation is to make @@ -656,11 +655,12 @@ struct TranslationRotationScaleWarp { correlation_matrix += q1.CornerRelativeToCentroid(i) * q2.CornerRelativeToCentroid(i).transpose(); } - std::cout << "correlation_matrix:\n" << correlation_matrix << "\n"; Mat2 R = OrthogonalProcrustes(correlation_matrix); - std::cout << "R:\n" << R << "\n"; parameters[3] = atan2(R(1, 0), R(0, 0)); - std::cout << "theta:" << parameters[3] << "\n"; + + LG << "Correlation_matrix:\n" << correlation_matrix; + LG << "R:\n" << R; + LG << "Theta:" << parameters[3]; } // The strange way of parameterizing the translation and rotation is to make @@ -741,8 +741,8 @@ struct AffineWarp { parameters[4] = a[2]; parameters[5] = a[3]; - std::cout << "a:" << a.transpose() << "\n"; - std::cout << "t:" << t.transpose() << "\n"; + LG << "a:" << a.transpose(); + LG << "t:" << t.transpose(); } // See comments in other parameterizations about why the centroid is used. From ca446f090bb1347e4855cf941166340d2f024668 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 19 May 2012 16:55:20 +0000 Subject: [PATCH 070/360] Fix aspect ratio correction for translating motion tracking data Still has got some issues when translating masks. --- source/blender/editors/transform/transform.c | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index d06de6be3ae..480edf2d855 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -164,6 +164,7 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) View2D *v2d = t->view; float divx, divy; float mulx, muly; + float aspx = 1.0f, aspy = 1.0f; divx = v2d->mask.xmax-v2d->mask.xmin; divy = v2d->mask.ymax-v2d->mask.ymin; @@ -181,13 +182,16 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) r_vec[1] = muly * (dy) / divy; r_vec[2] = 0.0f; - /* TODO - NOT WORKING, this isnt so bad since its only display aspect */ - if (t->options & CTX_MASK) { - float aspx, aspy; - ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy); - r_vec[0] *= aspx; - r_vec[1] *= aspy; + if (t->options & CTX_MOVIECLIP) { + ED_space_clip_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy); } + else if (t->options & CTX_MASK) { + /* TODO - NOT WORKING, this isnt so bad since its only display aspect */ + ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy); + } + + r_vec[0] *= aspx; + r_vec[1] *= aspy; } else { printf("%s: called in an invalid context\n", __func__); @@ -349,21 +353,17 @@ void removeAspectRatio(TransInfo *t, float vec[2]) else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) { if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { SpaceClip *sc = t->sa->spacedata.first; - float aspx, aspy; + float aspx = 1.0f, aspy = 1.0f; if (t->options & CTX_MOVIECLIP) { ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); - - vec[0] *= aspx; - vec[1] *= aspy; } else if (t->options & CTX_MASK) { - ED_space_clip_aspect(sc, &aspx, &aspy); ED_space_clip_mask_aspect(sc, &aspx, &aspy); - - vec[0] *= aspx; - vec[1] *= aspy; } + + vec[0] *= aspx; + vec[1] *= aspy; } } } From 130e7ab6f43a8e358ab7e4d85402f2d6af4b623a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 21 May 2012 09:19:08 +0000 Subject: [PATCH 071/360] Move search area form track to marker structure This allows different markers has different size of search area which makes it possible to scale search area when doing planar tracking. Made changes to all related areas such as transformation, tracking, finally ported marker clamping function, added python bindings for changed search area and added python API for pattern corners. TODO: It's still possible to make marker's center go outside of pattern corners when translating pattern area or rotating it around median point. --- source/blender/blenkernel/BKE_tracking.h | 5 +- source/blender/blenkernel/intern/tracking.c | 140 +++++++----------- source/blender/blenloader/intern/readfile.c | 5 + .../blender/editors/space_clip/clip_buttons.c | 81 +++++----- source/blender/editors/space_clip/clip_draw.c | 28 ++-- .../blender/editors/space_clip/tracking_ops.c | 34 ++--- .../editors/transform/transform_conversions.c | 26 ++-- .../editors/transform/transform_generics.c | 13 +- source/blender/makesdna/DNA_tracking_types.h | 23 ++- source/blender/makesrna/intern/rna_tracking.c | 78 ++++++---- 10 files changed, 218 insertions(+), 215 deletions(-) diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 4b94fcb7260..40a023101ba 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -48,7 +48,7 @@ struct Object; struct Scene; void BKE_tracking_init_settings(struct MovieTracking *tracking); -void BKE_tracking_clamp_track(struct MovieTrackingTrack *track, int event); +void BKE_tracking_clamp_marker(struct MovieTrackingMarker *marker, int event); void BKE_tracking_track_flag(struct MovieTrackingTrack *track, int area, int flag, int clear); struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, struct ListBase *tracksbase, @@ -76,7 +76,8 @@ struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTra float pos[2], int origin[2]); struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker); -struct ImBuf *BKE_tracking_track_mask_get(struct MovieTracking *tracking, struct MovieTrackingTrack *track, int width, int height); +struct ImBuf *BKE_tracking_track_mask_get(struct MovieTracking *tracking, struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker, int width, int height); void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 7ac687e3beb..7df10aa679c 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -104,11 +104,10 @@ static void marker_unified_to_frame_pixel_coordinates(const ImBuf *ibuf, const M unified_to_pixel(ibuf, frame_pixel_coords, frame_pixel_coords); } -static void get_search_origin_frame_pixel(const ImBuf *ibuf, const MovieTrackingTrack *track, - const MovieTrackingMarker *marker, float frame_pixel[2]) +static void get_search_origin_frame_pixel(const ImBuf *ibuf, const MovieTrackingMarker *marker, float frame_pixel[2]) { /* Get the lower left coordinate of the search window and snap to pixel coordinates */ - marker_unified_to_frame_pixel_coordinates(ibuf, marker, track->search_min, frame_pixel); + marker_unified_to_frame_pixel_coordinates(ibuf, marker, marker->search_min, frame_pixel); frame_pixel[0] = (int)frame_pixel[0]; frame_pixel[1] = (int)frame_pixel[1]; } @@ -120,26 +119,24 @@ static void pixel_to_unified(const ImBuf *ibuf, const float pixel_coords[2], flo unified_coords[1] = pixel_coords[1] / ibuf->y; } -static void marker_unified_to_search_pixel(const ImBuf *ibuf, const MovieTrackingTrack *track, - const MovieTrackingMarker *marker, const float marker_unified[2], - float search_pixel[2]) +static void marker_unified_to_search_pixel(const ImBuf *ibuf, const MovieTrackingMarker *marker, + const float marker_unified[2], float search_pixel[2]) { float frame_pixel[2]; float search_origin_frame_pixel[2]; marker_unified_to_frame_pixel_coordinates(ibuf, marker, marker_unified, frame_pixel); - get_search_origin_frame_pixel(ibuf, track, marker, search_origin_frame_pixel); + get_search_origin_frame_pixel(ibuf, marker, search_origin_frame_pixel); sub_v2_v2v2(search_pixel, frame_pixel, search_origin_frame_pixel); } -static void search_pixel_to_marker_unified(const ImBuf *ibuf, const MovieTrackingTrack *track, - const MovieTrackingMarker *marker, const float search_pixel[2], - float marker_unified[2]) +static void search_pixel_to_marker_unified(const ImBuf *ibuf, const MovieTrackingMarker *marker, + const float search_pixel[2], float marker_unified[2]) { float frame_unified[2]; float search_origin_frame_pixel[2]; - get_search_origin_frame_pixel(ibuf, track, marker, search_origin_frame_pixel); + get_search_origin_frame_pixel(ibuf, marker, search_origin_frame_pixel); add_v2_v2v2(frame_unified, search_pixel, search_origin_frame_pixel); pixel_to_unified(ibuf, frame_unified, frame_unified); @@ -173,34 +170,18 @@ void BKE_tracking_init_settings(MovieTracking *tracking) BKE_tracking_new_object(tracking, "Camera"); } -void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) +void BKE_tracking_clamp_marker(MovieTrackingMarker *marker, int event) { int a; float pat_min[2], pat_max[2]; - float eff_pat_min[2], eff_pat_max[2]; - /* XXX: currently search area is global, pattern size is per-marker, so we'll need to - * find maximal size of pattern to clamp search size nicely - */ - INIT_MINMAX2(pat_min, pat_max); - - for (a = 0; a < track->markersnr; a++) { - float cur_pat_min[2], cur_pat_max[2]; - - BKE_tracking_marker_pattern_minmax(&track->markers[a], cur_pat_min, cur_pat_max); - - DO_MINMAX2(cur_pat_min, pat_min, pat_max); - DO_MINMAX2(cur_pat_max, pat_min, pat_max); - } - - copy_v2_v2(eff_pat_min, pat_min); - copy_v2_v2(eff_pat_max, pat_max); + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); if (event == CLAMP_PAT_DIM) { for (a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ - track->search_min[a] = MIN2(eff_pat_min[a], track->search_min[a]); - track->search_max[a] = MAX2(eff_pat_max[a], track->search_max[a]); + marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]); + marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]); } } else if (event == CLAMP_PAT_POS) { @@ -208,44 +189,40 @@ void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) sub_v2_v2v2(dim, pat_max, pat_min); -#if 0 - /* XXX: needs porting, but we need to know marker here, will be ported after a bit - * more global refactoring - */ for (a = 0; a < 2; a++) { + int b; /* pattern shouldn't be moved outside of search */ - if (eff_pat_min[a] < track->search_min[a]) { - track->pat_min[a] = track->search_min[a] - (eff_pat_min[a] - pat_min[a]); - track->pat_max[a] = track->pat_min[a] + dim[a]; + if (pat_min[a] < marker->search_min[a]) { + for (b = 0; b < 4; b++) + marker->pattern_corners[b][a] += marker->search_min[a] - pat_min[a]; } - if (eff_pat_max[a] > track->search_max[a]) { - track->pat_max[a] = track->search_max[a] - (eff_pat_max[a] - pat_max[a]); - track->pat_min[a] = track->pat_max[a] - dim[a]; + if (pat_max[a] > marker->search_max[a]) { + for (b = 0; b < 4; b++) + marker->pattern_corners[b][a] -= pat_max[a] - marker->search_max[a]; } } -#endif } else if (event == CLAMP_SEARCH_DIM) { for (a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ - track->search_min[a] = MIN2(eff_pat_min[a], track->search_min[a]); - track->search_max[a] = MAX2(eff_pat_max[a], track->search_max[a]); + marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]); + marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]); } } else if (event == CLAMP_SEARCH_POS) { float dim[2]; - sub_v2_v2v2(dim, track->search_max, track->search_min); + sub_v2_v2v2(dim, marker->search_max, marker->search_min); for (a = 0; a < 2; a++) { /* search shouldn't be moved inside pattern */ - if (track->search_min[a] > eff_pat_min[a]) { - track->search_min[a] = eff_pat_min[a]; - track->search_max[a] = track->search_min[a] + dim[a]; + if (marker->search_min[a] > pat_min[a]) { + marker->search_min[a] = pat_min[a]; + marker->search_max[a] = marker->search_min[a] + dim[a]; } - if (track->search_max[a] < eff_pat_max[a]) { - track->search_max[a] = eff_pat_max[a]; - track->search_min[a] = track->search_max[a] - dim[a]; + if (marker->search_max[a] < pat_max[a]) { + marker->search_max[a] = pat_max[a]; + marker->search_min[a] = marker->search_max[a] - dim[a]; } } } @@ -253,8 +230,8 @@ void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) float dim[2]; sub_v2_v2v2(dim, pat_max, pat_min); for (a = 0; a < 2; a++) { - track->search_min[a] = pat_min[a]; - track->search_max[a] = pat_max[a]; + marker->search_min[a] = pat_min[a]; + marker->search_max[a] = pat_max[a]; } } } @@ -324,8 +301,8 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tr negate_v2_v2(marker.pattern_corners[2], marker.pattern_corners[0]); negate_v2_v2(marker.pattern_corners[3], marker.pattern_corners[1]); - copy_v2_v2(track->search_max, search); - negate_v2_v2(track->search_min, search); + copy_v2_v2(marker.search_max, search); + negate_v2_v2(marker.search_min, search); BKE_tracking_insert_marker(track, &marker); @@ -1276,13 +1253,13 @@ ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mov int x, y, w, h; float search_origin[2]; - get_search_origin_frame_pixel(ibuf, track, marker, search_origin); + get_search_origin_frame_pixel(ibuf, marker, search_origin); x = search_origin[0]; y = search_origin[1]; - w = (track->search_max[0] - track->search_min[0]) * ibuf->x; - h = (track->search_max[1] - track->search_min[1]) * ibuf->y; + w = (marker->search_max[0] - marker->search_min[0]) * ibuf->x; + h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y; searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); searchibuf->profile = ibuf->profile; @@ -1319,7 +1296,7 @@ static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track) return NULL; } -static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTrackingTrack *track, +static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTrackingMarker *marker, bGPDlayer *layer, ImBuf *ibuf, int width, int height) { bGPDframe *frame = layer->frames.first; @@ -1342,8 +1319,8 @@ static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTra "track mask rasterization points"); for (i = 0; i < stroke->totpoints; i++, fp += 2) { - fp[0] = stroke_points[i].x * width / ibuf->x - track->search_min[0]; - fp[1] = stroke_points[i].y * height * aspy / ibuf->x - track->search_min[1]; + fp[0] = stroke_points[i].x * width / ibuf->x - marker->search_min[0]; + fp[1] = stroke_points[i].y * height * aspy / ibuf->x - marker->search_min[1]; } PLX_raskterize(mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y); @@ -1374,19 +1351,20 @@ static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTra IMB_rect_from_float(ibuf); } -ImBuf *BKE_tracking_track_mask_get(MovieTracking *tracking, MovieTrackingTrack *track, int width, int height) +ImBuf *BKE_tracking_track_mask_get(MovieTracking *tracking, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int width, int height) { ImBuf *ibuf; bGPDlayer *layer = track_mask_gpencil_layer_get(track); int mask_width, mask_height; - mask_width = (track->search_max[0] - track->search_min[0]) * width; - mask_height = (track->search_max[1] - track->search_min[1]) * height; + mask_width = (marker->search_max[0] - marker->search_min[0]) * width; + mask_height = (marker->search_max[1] - marker->search_min[1]) * height; ibuf = IMB_allocImBuf(mask_width, mask_height, 32, IB_rect | IB_rectfloat); if (layer) { - track_mask_gpencil_layer_rasterize(tracking, track, layer, ibuf, width, height); + track_mask_gpencil_layer_rasterize(tracking, marker, layer, ibuf, width, height); } else { float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; @@ -1459,8 +1437,7 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT * This function puts those 5 points into the appropriate frame for tracking * (the "search" coordinate frame). */ -static void get_marker_coords_for_tracking(const ImBuf *ibuf, const MovieTrackingTrack *track, - const MovieTrackingMarker *marker, +static void get_marker_coords_for_tracking(const ImBuf *ibuf, const MovieTrackingMarker *marker, double search_pixel_x[5], double search_pixel_y[5]) { int i; @@ -1469,23 +1446,22 @@ static void get_marker_coords_for_tracking(const ImBuf *ibuf, const MovieTrackin /* Convert the corners into search space coordinates. */ for (i = 0; i < 4; i++) { - marker_unified_to_search_pixel(ibuf, track, marker, marker->pattern_corners[i], pixel_coords); + marker_unified_to_search_pixel(ibuf, marker, marker->pattern_corners[i], pixel_coords); search_pixel_x[i] = pixel_coords[0]; search_pixel_y[i] = pixel_coords[1]; } /* Convert the center position (aka "pos"); this is the origin */ unified_coords[0] = 0.0; unified_coords[1] = 0.0; - marker_unified_to_search_pixel(ibuf, track, marker, unified_coords, pixel_coords); + marker_unified_to_search_pixel(ibuf, marker, unified_coords, pixel_coords); search_pixel_x[4] = pixel_coords[0]; search_pixel_y[4] = pixel_coords[1]; } /* Inverse of above. */ -static void set_marker_coords_from_tracking(const ImBuf *ibuf, const MovieTrackingTrack *track, - MovieTrackingMarker *marker, const double search_pixel_x[5], - const double search_pixel_y[5]) +static void set_marker_coords_from_tracking(const ImBuf *ibuf, MovieTrackingMarker *marker, + const double search_pixel_x[5], const double search_pixel_y[5]) { int i; float marker_unified[2]; @@ -1495,13 +1471,13 @@ static void set_marker_coords_from_tracking(const ImBuf *ibuf, const MovieTracki for (i = 0; i < 4; i++) { search_pixel[0] = search_pixel_x[i]; search_pixel[1] = search_pixel_y[i]; - search_pixel_to_marker_unified(ibuf, track, marker, search_pixel, marker->pattern_corners[i]); + search_pixel_to_marker_unified(ibuf, marker, search_pixel, marker->pattern_corners[i]); } /* Convert the center position (aka "pos"); this is the origin */ search_pixel[0] = search_pixel_x[4]; search_pixel[1] = search_pixel_y[4]; - search_pixel_to_marker_unified(ibuf, track, marker, search_pixel, marker_unified); + search_pixel_to_marker_unified(ibuf, marker, search_pixel, marker_unified); /* If the tracker tracked nothing, then "marker_unified" would be zero. * Otherwise, the entire patch shifted, and that delta should be applied to @@ -1727,9 +1703,10 @@ int BKE_tracking_next(MovieTrackingContext *context) IMB_freeImBuf(reference_ibuf); } - /* XXX: for now, the width & height always match because the - * settings are per-track. This will change soon and in that - * case different sizes must be used */ + /* for now track to the same search area dimension as marker has got for current frame + * will make all tracked markers in currently tracked segment have the same search area + * size, but it's quite close to what is actually needed + */ patch_new = get_search_floatbuf(destination_ibuf, track, marker, &width, &height); /* Configure the tracker */ @@ -1746,11 +1723,8 @@ int BKE_tracking_next(MovieTrackingContext *context) options.sigma = 0.9; /* Convert the marker corners and center into pixel coordinates in the search/destination images. */ - get_marker_coords_for_tracking(destination_ibuf, track, &track_context->marker, - src_pixel_x, src_pixel_y); - - get_marker_coords_for_tracking(destination_ibuf, track, marker, - dst_pixel_x, dst_pixel_y); + get_marker_coords_for_tracking(destination_ibuf, &track_context->marker, src_pixel_x, src_pixel_y); + get_marker_coords_for_tracking(destination_ibuf, marker, dst_pixel_x, dst_pixel_y); /* Run the tracker! */ tracked = libmv_trackRegion(&options, @@ -1765,7 +1739,7 @@ int BKE_tracking_next(MovieTrackingContext *context) if (tracked && !onbound) { memset(&marker_new, 0, sizeof(marker_new)); marker_new = *marker; - set_marker_coords_from_tracking(destination_ibuf, track, &marker_new, dst_pixel_x, dst_pixel_y); + set_marker_coords_from_tracking(destination_ibuf, &marker_new, dst_pixel_x, dst_pixel_y); marker_new.flag |= MARKER_TRACKED; marker_new.framenr = nextfra; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 17465e84a50..3b6b888b7d8 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7633,6 +7633,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main) marker->pattern_corners[3][0] = track->pat_min[0]; marker->pattern_corners[3][1] = track->pat_max[1]; } + + if (is_zero_v2(marker->search_min) && is_zero_v2(marker->search_max)) { + copy_v2_v2(marker->search_min, track->search_min); + copy_v2_v2(marker->search_max, track->search_max); + } } track = track->next; diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 1f5e838f073..5b2c3530aa4 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -190,9 +190,9 @@ typedef struct { int framenr; /* current frame number */ float marker_pos[2]; /* position of marker in pixel coords */ - float track_pat[2]; /* position and dimensions of marker pattern in pixel coords */ + float marker_pat[2]; /* position and dimensions of marker pattern in pixel coords */ float track_offset[2]; /* offset of "parenting" point */ - float track_search_pos[2], track_search[2]; /* position and dimensions of marker search in pixel coords */ + float marker_search_pos[2], marker_search[2]; /* position and dimensions of marker search in pixel coords */ int marker_flag; /* marker's flags */ } MarkerUpdateCb; @@ -240,67 +240,62 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event) } else if (event == B_MARKER_PAT_DIM) { float dim[2], pat_dim[2], pat_min[2], pat_max[2]; + float scale_x, scale_y; + int a; BKE_tracking_marker_pattern_minmax(cb->marker, pat_min, pat_max); sub_v2_v2v2(pat_dim, pat_max, pat_min); - dim[0] = cb->track_pat[0] / width; - dim[1] = cb->track_pat[1] / height; + dim[0] = cb->marker_pat[0] / width; + dim[1] = cb->marker_pat[1] / height; - sub_v2_v2(dim, pat_dim); - mul_v2_fl(dim, 0.5f); + scale_x = dim[0] / pat_dim[0]; + scale_y = dim[1] / pat_dim[1]; - cb->marker->pattern_corners[0][0] -= dim[0]; - cb->marker->pattern_corners[0][1] -= dim[1]; + for (a = 0; a < 4; a++) { + cb->marker->pattern_corners[a][0] *= scale_x; + cb->marker->pattern_corners[a][1] *= scale_y; + } - cb->marker->pattern_corners[1][0] += dim[0]; - cb->marker->pattern_corners[1][1] -= dim[1]; - - cb->marker->pattern_corners[2][0] += dim[0]; - cb->marker->pattern_corners[2][1] += dim[1]; - - cb->marker->pattern_corners[3][0] -= dim[0]; - cb->marker->pattern_corners[3][1] += dim[1]; - - BKE_tracking_clamp_track(cb->track, CLAMP_PAT_DIM); + BKE_tracking_clamp_marker(cb->marker, CLAMP_PAT_DIM); ok = TRUE; } else if (event == B_MARKER_SEARCH_POS) { float delta[2], side[2]; - sub_v2_v2v2(side, cb->track->search_max, cb->track->search_min); + sub_v2_v2v2(side, cb->marker->search_max, cb->marker->search_min); mul_v2_fl(side, 0.5f); - delta[0] = cb->track_search_pos[0] / width; - delta[1] = cb->track_search_pos[1] / height; + delta[0] = cb->marker_search_pos[0] / width; + delta[1] = cb->marker_search_pos[1] / height; - sub_v2_v2v2(cb->track->search_min, delta, side); - add_v2_v2v2(cb->track->search_max, delta, side); + sub_v2_v2v2(cb->marker->search_min, delta, side); + add_v2_v2v2(cb->marker->search_max, delta, side); - BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_POS); + BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_POS); ok = TRUE; } else if (event == B_MARKER_SEARCH_DIM) { float dim[2], search_dim[2]; - sub_v2_v2v2(search_dim, cb->track->search_max, cb->track->search_min); + sub_v2_v2v2(search_dim, cb->marker->search_max, cb->marker->search_min); - dim[0] = cb->track_search[0] / width; - dim[1] = cb->track_search[1] / height; + dim[0] = cb->marker_search[0] / width; + dim[1] = cb->marker_search[1] / height; sub_v2_v2(dim, search_dim); mul_v2_fl(dim, 0.5f); - cb->track->search_min[0] -= dim[0]; - cb->track->search_min[1] -= dim[1]; + cb->marker->search_min[0] -= dim[0]; + cb->marker->search_min[1] -= dim[1]; - cb->track->search_max[0] += dim[0]; - cb->track->search_max[1] += dim[1]; + cb->marker->search_max[0] += dim[0]; + cb->marker->search_max[1] += dim[1]; - BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_DIM); + BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_DIM); ok = TRUE; } @@ -413,15 +408,15 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); sub_v2_v2v2(pat_dim, pat_max, pat_min); - sub_v2_v2v2(search_dim, track->search_max, track->search_min); + sub_v2_v2v2(search_dim, marker->search_max, marker->search_min); - add_v2_v2v2(search_pos, track->search_max, track->search_min); + add_v2_v2v2(search_pos, marker->search_max, marker->search_min); mul_v2_fl(search_pos, 0.5); to_pixel_space(cb->marker_pos, marker->pos, width, height); - to_pixel_space(cb->track_pat, pat_dim, width, height); - to_pixel_space(cb->track_search, search_dim, width, height); - to_pixel_space(cb->track_search_pos, search_pos, width, height); + to_pixel_space(cb->marker_pat, pat_dim, width, height); + to_pixel_space(cb->marker_search, search_dim, width, height); + to_pixel_space(cb->marker_search_pos, search_pos, width, height); to_pixel_space(cb->track_offset, track->offset, width, height); cb->marker_flag = marker->flag; @@ -457,19 +452,19 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P -10*height, 10.0*height, step, digits, "Y-offset to parenting point"); uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->track_pat[0], 3.0f, + uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->marker_pat[0], 3.0f, 10.0*width, step, digits, "Width of marker's pattern in screen coordinates"); - uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->track_pat[1], 3.0f, + uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->marker_pat[1], 3.0f, 10.0*height, step, digits, "Height of marker's pattern in screen coordinates"); uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->track_search_pos[0], + uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->marker_search_pos[0], -width, width, step, digits, "X-position of search at frame relative to marker's position"); - uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->track_search_pos[1], + uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->marker_search_pos[1], -height, height, step, digits, "X-position of search at frame relative to marker's position"); - uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->track_search[0], 3.0f, + uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->marker_search[0], 3.0f, 10.0*width, step, digits, "Width of marker's search in screen soordinates"); - uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->track_search[1], 3.0f, + uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->marker_search[1], 3.0f, 10.0*height, step, digits, "Height of marker's search in screen soordinates"); uiBlockEndAlign(block); diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index a06da289326..d654dc9cc77 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -485,10 +485,10 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0); if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) { glBegin(GL_LINE_LOOP); - glVertex2f(track->search_min[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_max[1]); - glVertex2f(track->search_min[0], track->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_max[1]); glEnd(); } glPopMatrix(); @@ -661,10 +661,10 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } glBegin(GL_LINE_LOOP); - glVertex2f(track->search_min[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_max[1]); - glVertex2f(track->search_min[0], track->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_max[1]); glEnd(); } @@ -761,8 +761,8 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo patdx = MIN2(dx * 2.0f / 3.0f, side / 6.0f); patdy = MIN2(dy * 2.0f / 3.0f, side * width / height / 6.0f); - searchdx = MIN2(dx, (track->search_max[0] - track->search_min[0]) / 6.0f); - searchdy = MIN2(dy, (track->search_max[1] - track->search_min[1]) / 6.0f); + searchdx = MIN2(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f); + searchdy = MIN2(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f); px[0] = 1.0f / sc->zoom / width / sc->scale; px[1] = 1.0f / sc->zoom / height / sc->scale; @@ -776,10 +776,10 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo } /* search offset square */ - draw_marker_slide_square(track->search_min[0], track->search_max[1], searchdx, searchdy, outline, px); + draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px); /* search re-sizing triangle */ - draw_marker_slide_triangle(track->search_max[0], track->search_min[1], searchdx, searchdy, outline, px); + draw_marker_slide_triangle(marker->search_max[0], marker->search_min[1], searchdx, searchdy, outline, px); } if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) { @@ -848,8 +848,8 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) { - dx = track->search_min[0]; - dy = track->search_min[1]; + dx = marker->search_min[0]; + dy = marker->search_min[1]; } else if (sc->flag & SC_SHOW_MARKER_PATTERN) { float pat_min[2], pat_max[2]; diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index b072b7475ac..4b37a17f26f 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -310,8 +310,8 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra } } else if (area == TRACK_AREA_SEARCH) { - data->min = track->search_min; - data->max = track->search_max; + data->min = marker->search_min; + data->max = marker->search_max; } if ((area == TRACK_AREA_SEARCH) || @@ -338,7 +338,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra return data; } -static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, +static int mouse_on_corner(SpaceClip *sc, MovieTrackingMarker *marker, int area, float co[2], int corner, int width, int height) { int inside = 0; @@ -347,8 +347,8 @@ static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTracki float crn[2], dx, dy, tdx, tdy; if (area == TRACK_AREA_SEARCH) { - copy_v2_v2(min, track->search_min); - copy_v2_v2(max, track->search_max); + copy_v2_v2(min, marker->search_min); + copy_v2_v2(max, marker->search_max); } else { BKE_tracking_marker_pattern_minmax(marker, min, max); @@ -512,11 +512,11 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) } if (sc->flag & SC_SHOW_MARKER_SEARCH) { - if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 1, width, height)) { + if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 1, width, height)) { customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, SLIDE_ACTION_OFFSET, width, height); } - else if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 0, width, height)) { + else if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 0, width, height)) { customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, SLIDE_ACTION_SIZE, width, height); } @@ -534,12 +534,12 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) } } else { - if (mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 1, width, height)) { + if (mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 1, width, height)) { customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, SLIDE_ACTION_OFFSET, width, height); } - if (!customdata && mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 0, width, height)) { + if (!customdata && mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 0, width, height)) { customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, SLIDE_ACTION_SIZE, width, height); } @@ -698,9 +698,9 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_DIM); + BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_DIM); else - BKE_tracking_clamp_track(data->track, CLAMP_PAT_DIM); + BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM); } else if (data->action == SLIDE_ACTION_OFFSET) { float d[2] = {dx, dy}; @@ -719,7 +719,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_POS); + BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_POS); } else if (data->action == SLIDE_ACTION_POS) { if (data->scale) { @@ -750,7 +750,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } /* currently only patterns are allowed to have such combination of event and data */ - BKE_tracking_clamp_track(data->track, CLAMP_PAT_DIM); + BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM); } } @@ -846,16 +846,16 @@ static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *trac BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - epsx = MIN4(pat_min[0] - track->search_min[0], track->search_max[0] - pat_max[0], + epsx = MIN4(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0], fabsf(pat_min[0]), fabsf(pat_max[0])) / 2; - epsy = MIN4(pat_min[1] - track->search_min[1], track->search_max[1] - pat_max[1], + epsy = MIN4(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1], fabsf(pat_min[1]), fabsf(pat_max[1])) / 2; epsx = MAX2(epsx, 2.0f / width); epsy = MAX2(epsy, 2.0f / height); if (sc->flag & SC_SHOW_MARKER_SEARCH) { - if (mouse_on_rect(co, marker->pos, track->search_min, track->search_max, epsx, epsy)) + if (mouse_on_rect(co, marker->pos, marker->search_min, marker->search_max, epsx, epsy)) return TRACK_AREA_SEARCH; } @@ -929,7 +929,7 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbas /* distance to search boundbox */ if (sc->flag & SC_SHOW_MARKER_SEARCH && TRACK_VIEW_SELECTED(sc, cur)) - d3 = dist_to_rect(co, marker->pos, cur->search_min, cur->search_max); + d3 = dist_to_rect(co, marker->pos, marker->search_min, marker->search_max); /* choose minimal distance. useful for cases of overlapped markers. */ dist = MIN3(d1, d2, d3); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index e8cec774a60..e40a051546d 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5456,7 +5456,7 @@ static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d, MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, sc->user.framenr); tdt->flag = marker->flag; - marker->flag &= ~(MARKER_DISABLED|MARKER_TRACKED); + marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED); markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT, track->offset, marker->pos, track->offset, aspx, aspy); @@ -5477,10 +5477,10 @@ static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d, if (track->search_flag & SELECT) { markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH, - track->search_min, marker->pos, NULL, aspx, aspy); + marker->search_min, marker->pos, NULL, aspx, aspy); markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH, - track->search_max, marker->pos, NULL, aspx, aspy); + marker->search_max, marker->pos, NULL, aspx, aspy); } } @@ -5556,18 +5556,16 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) td2d++; tdt++; - if ((marker->flag & MARKER_DISABLED) == 0) { - if (track->flag & SELECT) { - td++; - td2d++; - tdt++; - } + if (track->flag & SELECT) { + td++; + td2d++; + tdt++; + } - if (track->pat_flag & SELECT) { - td += 4; - td2d += 4; - tdt += 4; - } + if (track->pat_flag & SELECT) { + td += 4; + td2d += 4; + tdt += 4; } if (track->search_flag & SELECT) { diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index e3ca0957c25..b404c4ef669 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -642,27 +642,30 @@ static void recalcData_spaceclip(TransInfo *t) MovieClip *clip = ED_space_clip(sc); ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; + int framenr = sc->user.framenr; flushTransTracking(t); track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + if (t->mode == TFM_TRANSLATION) { if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_track(track, CLAMP_PAT_POS); + BKE_tracking_clamp_marker(marker, CLAMP_PAT_POS); if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) - BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS); + BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_POS); } else if (t->mode == TFM_RESIZE) { if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_track(track, CLAMP_PAT_DIM); + BKE_tracking_clamp_marker(marker, CLAMP_PAT_DIM); if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) - BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); + BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_DIM); } else if (t->mode == TFM_ROTATION) { if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_track(track, CLAMP_PAT_DIM); + BKE_tracking_clamp_marker(marker, CLAMP_PAT_POS); } } diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index a720a14fdcb..c5b0174a3c9 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -81,11 +81,16 @@ typedef struct MovieTrackingMarker { * | | | * | (0) --- (1) * +-------------> X - * - * the coordinates are stored relative to pos. + * + * the coordinates are stored relative to pos. */ float pattern_corners[4][2]; + /* positions of left-bottom and right-top corners of search area (in unified 0..1 units, + * relative to marker->pos + */ + float search_min[2], search_max[2]; + int framenr; /* number of frame marker is associated with */ int flag; /* Marker's flag (alive, ...) */ } MovieTrackingMarker; @@ -97,11 +102,17 @@ typedef struct MovieTrackingTrack { /* ** setings ** */ - /* positions of left-bottom and right-top corners of pattern (in unified 0..1 units, relative to marker->pos) */ - float pat_min[2], pat_max[2] DNA_DEPRECATED; + /* positions of left-bottom and right-top corners of pattern (in unified 0..1 units, + * relative to marker->pos) + * moved to marker's corners since planar tracking implementation + */ + float pat_min[2] DNA_DEPRECATED, pat_max[2] DNA_DEPRECATED; - /* positions of left-bottom and right-top corners of search area (in unified 0..1 units, relative to marker->pos */ - float search_min[2], search_max[2]; + /* positions of left-bottom and right-top corners of search area (in unified 0..1 units, + * relative to marker->pos + * moved to marker since affine tracking implementation + */ + float search_min[2] DNA_DEPRECATED, search_max[2] DNA_DEPRECATED; float offset[2]; /* offset to "parenting" point */ diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 52cb9f2f409..dcbe52c3531 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -195,13 +195,6 @@ static void rna_trackingTrack_select_set(PointerRNA *ptr, int value) } } -static void rna_tracking_trackerSearch_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - MovieTrackingTrack *track = (MovieTrackingTrack *)ptr->data; - - BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); -} - static char *rna_trackingCamera_path(PointerRNA *UNUSED(ptr)) { return BLI_sprintfN("tracking.camera"); @@ -361,6 +354,20 @@ static void rna_trackingMarker_frame_set(PointerRNA *ptr, int value) } } +static void rna_tracking_markerPattern_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + MovieTrackingMarker *marker = (MovieTrackingMarker *)ptr->data; + + BKE_tracking_clamp_marker(marker, CLAMP_PAT_DIM); +} + +static void rna_tracking_markerSearch_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + MovieTrackingMarker *marker = (MovieTrackingMarker *)ptr->data; + + BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_DIM); +} + /* API */ static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, int frame, int number) @@ -467,6 +474,7 @@ static EnumPropertyItem pattern_match_items[] = { {0, NULL, 0, NULL, NULL}}; static int rna_matrix_dimsize_4x4[] = {4, 4}; +static int rna_matrix_dimsize_4x2[] = {4, 2}; static void rna_def_trackingSettings(BlenderRNA *brna) { @@ -797,6 +805,38 @@ static void rna_def_trackingMarker(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", MARKER_DISABLED); RNA_def_property_ui_text(prop, "Mode", "Is marker muted for current frame"); RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + + /* pattern */ + prop = RNA_def_property(srna, "pattern_corners", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "pattern_corners"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x2); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_ui_text(prop, "Pattern Corners", + "Array of coordinates which represents patter's corners in " + " normalized coordinates relative to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_markerPattern_update"); + + /* search */ + prop = RNA_def_property(srna, "search_min", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_float_sdna(prop, NULL, "search_min"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Search Min", + "Left-bottom corner of search area in normalized coordinates relative " + "to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_markerSearch_update"); + + prop = RNA_def_property(srna, "search_max", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_float_sdna(prop, NULL, "search_max"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Search Max", + "Right-bottom corner of search area in normalized coordinates relative " + "to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_markerSearch_update"); } static void rna_def_trackingMarkers(BlenderRNA *brna, PropertyRNA *cprop) @@ -857,30 +897,6 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); RNA_def_struct_name_property(srna, prop); - /* Pattern */ - /* XXX The four pattern corners are not exported to rna yet */ - - /* Search */ - prop = RNA_def_property(srna, "search_min", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_array(prop, 2); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); - RNA_def_property_float_sdna(prop, NULL, "search_min"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Search Min", - "Left-bottom corner of search area in normalized coordinates relative " - "to marker position"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerSearch_update"); - - prop = RNA_def_property(srna, "search_max", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_array(prop, 2); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); - RNA_def_property_float_sdna(prop, NULL, "search_max"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Search Max", - "Right-bottom corner of search area in normalized coordinates relative " - "to marker position"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerSearch_update"); - /* limit frames */ prop = RNA_def_property(srna, "frames_limit", PROP_INT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); From ebd87e18dfdde9d80bbbe6b74c93535bcad46f8f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 21 May 2012 11:09:53 +0000 Subject: [PATCH 072/360] mask parenting operator, and clear parenting. (Ctrl+P, Alt+P) - also use offset now with parenting. - draw line from point to parent. --- source/blender/blenkernel/intern/mask.c | 5 +- source/blender/editors/mask/CMakeLists.txt | 1 + source/blender/editors/mask/mask_draw.c | 32 +++ source/blender/editors/mask/mask_editor.c | 8 + source/blender/editors/mask/mask_intern.h | 4 + .../blender/editors/mask/mask_relationships.c | 182 ++++++++++++++++++ 6 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 source/blender/editors/mask/mask_relationships.c diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 1b6dabbf94c..70a83dd5104 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -757,7 +757,7 @@ void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_c } } -static void evaluate_mask_parent(MaskParent *parent, float ctime, float co[2]) +static void evaluate_mask_parent(MaskParent *parent, float ctime, float r_co[2]) { if (!parent) return; @@ -779,7 +779,8 @@ static void evaluate_mask_parent(MaskParent *parent, float ctime, float co[2]) if (track) { MovieTrackingMarker *marker = BKE_tracking_get_marker(track, ctime); - BKE_mask_coord_from_movieclip(clip, &user, co, marker->pos); + BKE_mask_coord_from_movieclip(clip, &user, r_co, marker->pos); + add_v2_v2(r_co, parent->offset); } } } diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt index fc1d2f4be6b..b71b014b628 100644 --- a/source/blender/editors/mask/CMakeLists.txt +++ b/source/blender/editors/mask/CMakeLists.txt @@ -40,6 +40,7 @@ set(SRC mask_draw.c mask_editor.c mask_ops.c + mask_relationships.c mask_intern.h ) diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index f4022581f2d..7077450c807 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -62,6 +62,36 @@ static void set_spline_color(MaskObject *maskobj, MaskSpline *spline) } } +static void draw_spline_parents(MaskObject *UNUSED(maskobj), MaskSpline *spline) +{ + int i; + + if (!spline->tot_point) + return; + + glColor3ub(0, 0, 0); + glEnable(GL_LINE_STIPPLE); + glLineStipple(1, 0xAAAA); + + glBegin(GL_LINES); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (point->parent.flag & MASK_PARENT_ACTIVE) { + glVertex2f(point->bezt.vec[1][0], + point->bezt.vec[1][1]); + + glVertex2f(point->bezt.vec[1][0] - point->parent.offset[0], + point->bezt.vec[1][1] - point->parent.offset[1]); + } + } + + glEnd(); + + glDisable(GL_LINE_STIPPLE); +} + /* return non-zero if spline is selected */ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) { @@ -227,6 +257,8 @@ static void draw_maskobjs(Mask *mask) /* draw curve itself first... */ draw_spline_curve(maskobj, spline); + draw_spline_parents(maskobj, spline); + /* ...and then handles over the curve so they're nicely visible */ draw_spline_points(maskobj, spline); } diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index e8311935d86..29c04587539 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -163,6 +163,10 @@ void ED_operatortypes_mask(void) WM_operatortype_append(MASK_OT_slide_point); WM_operatortype_append(MASK_OT_cyclic_toggle); WM_operatortype_append(MASK_OT_handle_type_set); + + /* relationships */ + WM_operatortype_append(MASK_OT_parent_set); + WM_operatortype_append(MASK_OT_parent_clear); } void ED_keymap_mask(wmKeyConfig *keyconf) @@ -196,6 +200,10 @@ void ED_keymap_mask(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MASK_OT_slide_point", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MASK_OT_handle_type_set", VKEY, KM_PRESS, 0, 0); + /* relationships */ + WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_ALT, 0); + transform_keymap_for_space(keyconf, keymap, SPACE_CLIP); } diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index 163239eade7..3ea0f4bce2b 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -56,6 +56,10 @@ void MASK_OT_delete(struct wmOperatorType *ot); void MASK_OT_handle_type_set(struct wmOperatorType *ot); +/* mask_relationships.c */ +void MASK_OT_parent_set(struct wmOperatorType *ot); +void MASK_OT_parent_clear(struct wmOperatorType *ot); + /* mask_editor.c */ int ED_maskediting_poll(struct bContext *C); int ED_maskediting_mask_poll(struct bContext *C); diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c new file mode 100644 index 00000000000..d60a4f9a3ba --- /dev/null +++ b/source/blender/editors/mask/mask_relationships.c @@ -0,0 +1,182 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_ops.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" +#include "BKE_tracking.h" + +#include "DNA_mask_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" +#include "ED_clip.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "mask_intern.h" /* own include */ + +static int mask_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskObject *maskobj; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + int i; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL(point)) { + point->parent.flag &= ~MASK_PARENT_ACTIVE; + } + } + } + } + + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; +} + +void MASK_OT_parent_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Parent"; + ot->description = "Clear the masks parenting"; + ot->idname = "MASK_OT_parent_clear"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = mask_parent_clear_exec; + + ot->poll = ED_operator_object_active_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskObject *maskobj; + + /* parent info */ + SpaceClip *sc; + MovieClip *clip; + MovieTrackingTrack *track; + MovieTrackingMarker *marker; + MovieTrackingObject *tracking; + /* done */ + + float parmask_pos[2]; + + if ((NULL == (sc = CTX_wm_space_clip(C))) || + (NULL == (clip = sc->clip)) || + (NULL == (track = clip->tracking.act_track)) || + (NULL == (marker = BKE_tracking_get_marker(track, sc->user.framenr))) || + (NULL == (tracking = BKE_tracking_active_object(&clip->tracking)))) + { + return OPERATOR_CANCELLED; + } + + BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker->pos); + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + int i; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL(point)) { + BezTriple *bezt = &point->bezt; + float tvec[2]; + + point->parent.id_type = ID_MC; + point->parent.id = &clip->id; + strcpy(point->parent.parent, tracking->name); + strcpy(point->parent.sub_parent, track->name); + + point->parent.flag |= MASK_PARENT_ACTIVE; + + sub_v2_v2v2(tvec, parmask_pos, bezt->vec[1]); + + add_v2_v2(bezt->vec[0], tvec); + add_v2_v2(bezt->vec[1], tvec); + add_v2_v2(bezt->vec[2], tvec); + + negate_v2_v2(point->parent.offset, tvec); + } + } + } + } + + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; +} + +/** based on #OBJECT_OT_parent_set */ +void MASK_OT_parent_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Make Parent"; + ot->description = "Set the masks parenting"; + ot->idname = "MASK_OT_parent_set"; + + /* api callbacks */ + //ot->invoke = mask_parent_set_invoke; + ot->exec = mask_parent_set_exec; + + ot->poll = ED_operator_object_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} From 2d613b050b8fe67c3b2f6e7f500f3078001b26ec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 21 May 2012 13:42:58 +0000 Subject: [PATCH 073/360] clip/mask parenting from previous commit - clear parent wasnt working - selecting tracks now works when mask editing --- source/blender/editors/mask/mask_editor.c | 8 +++++++- source/blender/editors/mask/mask_ops.c | 4 ++++ source/blender/editors/mask/mask_relationships.c | 1 - source/blender/editors/space_clip/space_clip.c | 8 ++++---- source/blender/editors/space_clip/tracking_ops.c | 3 ++- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index 29c04587539..eaeb0ab9b7f 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -195,6 +195,12 @@ void ED_keymap_mask(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + /* select clip while in maker view, + * this matches View3D functionality where you can select an + * object while in editmode to allow vertex parenting */ + kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + /* shape */ WM_keymap_add_item(keymap, "MASK_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MASK_OT_slide_point", LEFTMOUSE, KM_PRESS, 0, 0); @@ -202,7 +208,7 @@ void ED_keymap_mask(wmKeyConfig *keyconf) /* relationships */ WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "MASK_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0); transform_keymap_for_space(keyconf, keymap, SPACE_CLIP); } diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 7774af690d7..d073bd08cef 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1001,6 +1001,8 @@ static int select_exec(bContext *C, wmOperator *op) mask_flush_selection(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; } else { MaskSplinePointUW *uw; @@ -1017,6 +1019,8 @@ static int select_exec(bContext *C, wmOperator *op) mask_flush_selection(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; } } diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index d60a4f9a3ba..07b4508b383 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -91,7 +91,6 @@ void MASK_OT_parent_clear(wmOperatorType *ot) ot->idname = "MASK_OT_parent_clear"; /* api callbacks */ - ot->invoke = WM_menu_invoke; ot->exec = mask_parent_clear_exec; ot->poll = ED_operator_object_active_editable; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 8e92a9198b1..c6d35b03468 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -556,7 +556,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) /* ******** Hotkeys avalaible for main region only ******** */ keymap = WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0); - +// keymap->poll = ED_space_clip_tracking_poll; /* ** View/navigation ** */ WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); @@ -1048,14 +1048,14 @@ static void clip_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); /* own keymap */ + keymap= WM_keymap_find(wm->defaultconf, "Mask Editor", 0, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + keymap = WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); keymap = WM_keymap_find(wm->defaultconf, "Clip Editor", SPACE_CLIP, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - - keymap= WM_keymap_find(wm->defaultconf, "Mask Editor", 0, 0); - WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } static void clip_main_area_draw(const bContext *C, ARegion *ar) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 4b37a17f26f..6d34994e081 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1039,7 +1039,8 @@ void CLIP_OT_select(wmOperatorType *ot) /* api callbacks */ ot->exec = select_exec; ot->invoke = select_invoke; - ot->poll = ED_space_clip_tracking_poll; + //ot->poll = ED_space_clip_tracking_poll; // so mask view can Ctrl+RMB markers + ot->poll = ED_space_clip_view_clip_poll; /* flags */ ot->flag = OPTYPE_UNDO; From 857444d7beeb91a9d2aaee9530fd778b4cd274f7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 22 May 2012 10:48:29 +0000 Subject: [PATCH 074/360] move select operations into their own file --- source/blender/editors/mask/CMakeLists.txt | 1 + source/blender/editors/mask/mask_intern.h | 24 +- source/blender/editors/mask/mask_ops.c | 286 ++-------------- .../blender/editors/mask/mask_relationships.c | 2 +- source/blender/editors/mask/mask_select.c | 304 ++++++++++++++++++ 5 files changed, 346 insertions(+), 271 deletions(-) create mode 100644 source/blender/editors/mask/mask_select.c diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt index b71b014b628..55c31e35536 100644 --- a/source/blender/editors/mask/CMakeLists.txt +++ b/source/blender/editors/mask/CMakeLists.txt @@ -41,6 +41,7 @@ set(SRC mask_editor.c mask_ops.c mask_relationships.c + mask_select.c mask_intern.h ) diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index 3ea0f4bce2b..623ef5fd533 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -47,19 +47,37 @@ void MASK_OT_add_vertex(struct wmOperatorType *ot); void MASK_OT_add_feather_vertex(struct wmOperatorType *ot); void MASK_OT_cyclic_toggle(struct wmOperatorType *ot); -void MASK_OT_select(struct wmOperatorType *ot); -void MASK_OT_select_all(struct wmOperatorType *ot); - void MASK_OT_slide_point(struct wmOperatorType *ot); void MASK_OT_delete(struct wmOperatorType *ot); void MASK_OT_handle_type_set(struct wmOperatorType *ot); +int ED_mask_feather_find_nearest( + struct bContext *C, struct Mask *mask, float normal_co[2], int threshold, + struct MaskObject **maskobj_r, struct MaskSpline **spline_r, struct MaskSplinePoint **point_r, + struct MaskSplinePointUW **uw_r, float *score); + +struct MaskSplinePoint *ED_mask_point_find_nearest( + struct bContext *C, struct Mask *mask, float normal_co[2], int threshold, + struct MaskObject **maskobj_r, struct MaskSpline **spline_r, int *is_handle_r, + float *score); + /* mask_relationships.c */ void MASK_OT_parent_set(struct wmOperatorType *ot); void MASK_OT_parent_clear(struct wmOperatorType *ot); +/* mask_select.c */ +void MASK_OT_select(struct wmOperatorType *ot); +void MASK_OT_select_all(struct wmOperatorType *ot); + +int ED_mask_spline_select_check(struct MaskSplinePoint *points, int tot_point); +int ED_mask_select_check(struct Mask *mask); +void ED_mask_point_select(struct MaskSplinePoint *point, int action); + +void ED_mask_select_toggle_all(struct Mask *mask, int action); +void ED_mask_select_flush_all(struct Mask *mask); + /* mask_editor.c */ int ED_maskediting_poll(struct bContext *C); int ED_maskediting_mask_poll(struct bContext *C); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index d073bd08cef..4054814604e 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -57,38 +57,6 @@ /******************** utility functions *********************/ -static void spline_point_select(MaskSplinePoint *point, int action) -{ - int i; - - switch (action) { - case SEL_SELECT: - MASKPOINT_SEL(point); - break; - case SEL_DESELECT: - MASKPOINT_DESEL(point); - break; - case SEL_INVERT: - MASKPOINT_INVSEL(point); - break; - } - - for (i = 0; i < point->tot_uw; i++) { - switch (action) { - case SEL_SELECT: - point->uw[i].flag |= SELECT; - break; - case SEL_DESELECT: - point->uw[i].flag &= ~SELECT; - break; - case SEL_INVERT: - point->uw[i].flag ^= SELECT; - break; - } - } -} - - static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, float start_u, const float co[2]) { const float proj_eps = 1e-3; @@ -151,66 +119,9 @@ static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, fl return u; } -static int points_has_selection(MaskSplinePoint *points, int tot_point) -{ - int i; - - for (i = 0; i < tot_point; i++) { - MaskSplinePoint *point = &points[i]; - - if (MASKPOINT_ISSEL(point)) - return TRUE; - } - - return FALSE; -} - -static int mask_has_selection(Mask *mask) -{ - MaskObject *maskobj; - - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskSpline *spline; - - for (spline = maskobj->splines.first; spline; spline = spline->next) { - if (points_has_selection(spline->points, spline->tot_point)) { - return TRUE; - } - } - } - - return FALSE; -} - -static void toggle_selection_all(Mask *mask, int action) -{ - MaskObject *maskobj; - - if (action == SEL_TOGGLE) { - if (mask_has_selection(mask)) - action = SEL_DESELECT; - else - action = SEL_SELECT; - } - - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskSpline *spline; - - for (spline = maskobj->splines.first; spline; spline = spline->next) { - int i; - - for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; - - spline_point_select(point, action); - } - } - } -} - -static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal_co[2], int threshold, - MaskObject **maskobj_r, MaskSpline **spline_r, int *is_handle_r, - float *score) +MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float normal_co[2], int threshold, + MaskObject **maskobj_r, MaskSpline **spline_r, int *is_handle_r, + float *score) { MaskObject *maskobj; MaskObject *point_maskobj = NULL; @@ -297,9 +208,9 @@ static MaskSplinePoint *find_nearest_point(bContext *C, Mask *mask, float normal return NULL; } -static int find_nearest_feather(bContext *C, Mask *mask, float normal_co[2], int threshold, - MaskObject **maskobj_r, MaskSpline **spline_r, MaskSplinePoint **point_r, - MaskSplinePointUW **uw_r, float *score) +int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], int threshold, + MaskObject **maskobj_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + MaskSplinePointUW **uw_r, float *score) { MaskObject *maskobj, *point_maskobj = NULL; MaskSpline *point_spline = NULL; @@ -500,39 +411,6 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], return FALSE; } -static void mask_flush_selection(Mask *mask) -{ - MaskObject *maskobj; - - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskSpline *spline; - - for (spline = maskobj->splines.first; spline; spline = spline->next) { - int i; - - spline->flag &= ~SELECT; - - for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *cur_point = &spline->points[i]; - - if (MASKPOINT_ISSEL(cur_point)) { - spline->flag |= SELECT; - } - else { - int j; - - for (j = 0; j < cur_point->tot_uw; j++) { - if (cur_point->uw[j].flag & SELECT) { - spline->flag |= SELECT; - break; - } - } - } - } - } - } -} - /******************** create new mask *********************/ static int mask_new_exec(bContext *C, wmOperator *op) @@ -677,9 +555,9 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) ED_mask_mouse_pos(C, event, co); ED_mask_size(C, &width, &height); - cv_point = find_nearest_point(C, mask, co, threshold, &cv_maskobj, &cv_spline, &is_handle, &cv_score); + cv_point = ED_mask_point_find_nearest(C, mask, co, threshold, &cv_maskobj, &cv_spline, &is_handle, &cv_score); - if (find_nearest_feather(C, mask, co, threshold, &feather_maskobj, &feather_spline, &feather_point, &uw, &feather_score)) { + if (ED_mask_feather_find_nearest(C, mask, co, threshold, &feather_maskobj, &feather_spline, &feather_point, &uw, &feather_score)) { if (slide_feather || !cv_point || feather_score < cv_score) { action = SLIDE_ACTION_FEATHER; @@ -756,19 +634,19 @@ static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) if (slidedata->uw) { if ((slidedata->uw->flag & SELECT) == 0) { - toggle_selection_all(mask, SEL_DESELECT); + ED_mask_select_toggle_all(mask, SEL_DESELECT); slidedata->uw->flag |= SELECT; - mask_flush_selection(mask); + ED_mask_select_flush_all(mask); } } else if (!MASKPOINT_ISSEL(slidedata->point)) { - toggle_selection_all(mask, SEL_DESELECT); + ED_mask_select_toggle_all(mask, SEL_DESELECT); - spline_point_select(slidedata->point, SEL_SELECT); + ED_mask_point_select(slidedata->point, SEL_SELECT); - mask_flush_selection(mask); + ED_mask_select_flush_all(mask); } slidedata->maskobj->act_spline = slidedata->spline; @@ -934,132 +812,6 @@ void MASK_OT_slide_point(wmOperatorType *ot) RNA_def_boolean(ot->srna, "slide_feather", 0, "Slide Feather", "First try to slide slide feather instead of vertex"); } -/******************** toggle selection *********************/ - -static int select_all_exec(bContext *C, wmOperator *op) -{ - Mask *mask = CTX_data_edit_mask(C); - int action = RNA_enum_get(op->ptr, "action"); - - toggle_selection_all(mask, action); - mask_flush_selection(mask); - - WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); - - return OPERATOR_FINISHED; -} - -void MASK_OT_select_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select or Deselect All"; - ot->description = "Change selection of all curve points"; - ot->idname = "MASK_OT_select_all"; - - /* api callbacks */ - ot->exec = select_all_exec; - ot->poll = ED_maskediting_mask_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - WM_operator_properties_select_all(ot); -} - -/******************** select *********************/ - -static int select_exec(bContext *C, wmOperator *op) -{ - Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; - MaskSpline *spline; - MaskSplinePoint *point = NULL; - float co[2]; - int extend = RNA_boolean_get(op->ptr, "extend"); - int is_handle = 0; - const float threshold = 19; - - RNA_float_get_array(op->ptr, "location", co); - - point = find_nearest_point(C, mask, co, threshold, &maskobj, &spline, &is_handle, NULL); - - if (point) { - if (!extend) - toggle_selection_all(mask, SEL_DESELECT); - - if (is_handle) { - MASKPOINT_HANDLE_SEL(point); - } - else { - spline_point_select(point, SEL_SELECT); - } - - maskobj->act_spline = spline; - maskobj->act_point = point; - - mask_flush_selection(mask); - - WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); - - return OPERATOR_FINISHED; - } - else { - MaskSplinePointUW *uw; - - if (find_nearest_feather(C, mask, co, threshold, &maskobj, &spline, &point, &uw, NULL)) { - if (!extend) - toggle_selection_all(mask, SEL_DESELECT); - - uw->flag |= SELECT; - - maskobj->act_spline = spline; - maskobj->act_point = point; - - mask_flush_selection(mask); - - WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); - - return OPERATOR_FINISHED; - } - } - - return OPERATOR_PASS_THROUGH; -} - -static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - float co[2]; - - ED_mask_mouse_pos(C, event, co); - - RNA_float_set_array(op->ptr, "location", co); - - return select_exec(C, op); -} - -void MASK_OT_select(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select"; - ot->description = "Select spline points"; - ot->idname = "MASK_OT_select"; - - /* api callbacks */ - ot->exec = select_exec; - ot->invoke = select_invoke; - ot->poll = ED_maskediting_mask_poll; - - /* flags */ - ot->flag = OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "extend", 0, - "Extend", "Extend selection rather than clearing the existing selection"); - RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, - "Location", "Location of vertex in normalized space", -1.0f, 1.0f); -} - /******************** add vertex *********************/ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point, @@ -1187,7 +939,7 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask /* select new point */ MASKPOINT_SEL(new_point); - mask_flush_selection(mask); + ED_mask_select_flush_all(mask); } /* **** add subdivide vertex **** */ @@ -1204,7 +956,7 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) MaskSplinePoint *new_point_array, *new_point; int point_index = point - spline->points; - toggle_selection_all(mask, SEL_DESELECT); + ED_mask_select_toggle_all(mask, SEL_DESELECT); new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); @@ -1280,7 +1032,7 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) MaskSplinePoint *point; MaskSplinePoint *new_point = NULL, *ref_point = NULL; - toggle_selection_all(mask, SEL_DESELECT); + ED_mask_select_toggle_all(mask, SEL_DESELECT); maskobj = BKE_mask_object_active(mask); @@ -1401,7 +1153,7 @@ static int add_feather_vertex_exec(bContext *C, wmOperator *op) RNA_float_get_array(op->ptr, "location", co); - point = find_nearest_point(C, mask, co, threshold, NULL, NULL, NULL, NULL); + point = ED_mask_point_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL); if (point) return OPERATOR_FINISHED; @@ -1460,7 +1212,7 @@ static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) MaskSpline *spline; for (spline = maskobj->splines.first; spline; spline = spline->next) { - if (points_has_selection(spline->points, spline->tot_point)) { + if (ED_mask_spline_select_check(spline->points, spline->tot_point)) { spline->flag ^= MASK_SPLINE_CYCLIC; } } @@ -1584,7 +1336,7 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) spline->points = new_points; spline->tot_point = j; - mask_flush_selection(mask); + ED_mask_select_flush_all(mask); } spline = next_spline; diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index 07b4508b383..136376336d8 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/mask/mask_ops.c +/** \file blender/editors/mask/mask_relationshops.c * \ingroup edmask */ diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c new file mode 100644 index 00000000000..672ea96778c --- /dev/null +++ b/source/blender/editors/mask/mask_select.c @@ -0,0 +1,304 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_select.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" +#include "ED_clip.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "mask_intern.h" /* own include */ + +int ED_mask_spline_select_check(MaskSplinePoint *points, int tot_point) +{ + int i; + + for (i = 0; i < tot_point; i++) { + MaskSplinePoint *point = &points[i]; + + if (MASKPOINT_ISSEL(point)) + return TRUE; + } + + return FALSE; +} + +int ED_mask_select_check(Mask *mask) +{ + MaskObject *maskobj; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline->points, spline->tot_point)) { + return TRUE; + } + } + } + + return FALSE; +} + +void ED_mask_point_select(MaskSplinePoint *point, int action) +{ + int i; + + switch (action) { + case SEL_SELECT: + MASKPOINT_SEL(point); + break; + case SEL_DESELECT: + MASKPOINT_DESEL(point); + break; + case SEL_INVERT: + MASKPOINT_INVSEL(point); + break; + } + + for (i = 0; i < point->tot_uw; i++) { + switch (action) { + case SEL_SELECT: + point->uw[i].flag |= SELECT; + break; + case SEL_DESELECT: + point->uw[i].flag &= ~SELECT; + break; + case SEL_INVERT: + point->uw[i].flag ^= SELECT; + break; + } + } +} + + +void ED_mask_select_toggle_all(Mask *mask, int action) +{ + MaskObject *maskobj; + + if (action == SEL_TOGGLE) { + if (ED_mask_select_check(mask)) + action = SEL_DESELECT; + else + action = SEL_SELECT; + } + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + ED_mask_point_select(point, action); + } + } + } +} + +void ED_mask_select_flush_all(Mask *mask) +{ + MaskObject *maskobj; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + int i; + + spline->flag &= ~SELECT; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *cur_point = &spline->points[i]; + + if (MASKPOINT_ISSEL(cur_point)) { + spline->flag |= SELECT; + } + else { + int j; + + for (j = 0; j < cur_point->tot_uw; j++) { + if (cur_point->uw[j].flag & SELECT) { + spline->flag |= SELECT; + break; + } + } + } + } + } + } +} + +/******************** toggle selection *********************/ + +static int select_all_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + int action = RNA_enum_get(op->ptr, "action"); + + ED_mask_select_toggle_all(mask, action); + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_select_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select or Deselect All"; + ot->description = "Change selection of all curve points"; + ot->idname = "MASK_OT_select_all"; + + /* api callbacks */ + ot->exec = select_all_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_select_all(ot); +} + +/******************** select *********************/ + +static int select_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskObject *maskobj; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + float co[2]; + int extend = RNA_boolean_get(op->ptr, "extend"); + int is_handle = 0; + const float threshold = 19; + + RNA_float_get_array(op->ptr, "location", co); + + point = ED_mask_point_find_nearest(C, mask, co, threshold, &maskobj, &spline, &is_handle, NULL); + + if (point) { + if (!extend) + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + if (is_handle) { + MASKPOINT_HANDLE_SEL(point); + } + else { + ED_mask_point_select(point, SEL_SELECT); + } + + maskobj->act_spline = spline; + maskobj->act_point = point; + + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + else { + MaskSplinePointUW *uw; + + if (ED_mask_feather_find_nearest(C, mask, co, threshold, &maskobj, &spline, &point, &uw, NULL)) { + if (!extend) + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + uw->flag |= SELECT; + + maskobj->act_spline = spline; + maskobj->act_point = point; + + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + } + + return OPERATOR_PASS_THROUGH; +} + +static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return select_exec(C, op); +} + +void MASK_OT_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select"; + ot->description = "Select spline points"; + ot->idname = "MASK_OT_select"; + + /* api callbacks */ + ot->exec = select_exec; + ot->invoke = select_invoke; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "extend", 0, + "Extend", "Extend selection rather than clearing the existing selection"); + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} From e76812a1d7490b01066c0f751d5311b58825ffd8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 23 May 2012 12:15:12 +0000 Subject: [PATCH 075/360] fix for crash selecting curve pointsx --- source/blender/editors/mask/mask_select.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 672ea96778c..f1ee620e2ce 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -254,7 +254,8 @@ static int select_exec(bContext *C, wmOperator *op) if (!extend) ED_mask_select_toggle_all(mask, SEL_DESELECT); - uw->flag |= SELECT; + if (uw) + uw->flag |= SELECT; maskobj->act_spline = spline; maskobj->act_point = point; From 3e1df2d12ebb319c0d12d2511d1a728667b5e45e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 May 2012 13:31:36 +0000 Subject: [PATCH 076/360] shapekeys for masks - this doesnt use existing shapekey code however. --- source/blender/blenkernel/BKE_mask.h | 21 +- source/blender/blenkernel/intern/mask.c | 275 ++++++++++++++++++- source/blender/blenkernel/intern/scene.c | 4 +- source/blender/blenloader/intern/readfile.c | 10 +- source/blender/blenloader/intern/writefile.c | 6 + source/blender/editors/mask/CMakeLists.txt | 1 + source/blender/editors/mask/mask_editor.c | 8 + source/blender/editors/mask/mask_intern.h | 4 + source/blender/editors/mask/mask_shapekey.c | 130 +++++++++ source/blender/makesdna/DNA_mask_types.h | 13 + 10 files changed, 459 insertions(+), 13 deletions(-) create mode 100755 source/blender/editors/mask/mask_shapekey.c diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 361de2c38ce..e09aa9d8355 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -31,6 +31,7 @@ struct Main; struct Mask; struct MaskParent; struct MaskObject; +struct MaskObjectShape; struct MaskSpline; struct MaskSplinePoint; struct MaskSplinePointUW; @@ -83,8 +84,8 @@ void BKE_mask_coord_to_movieclip(struct MovieClip *clip, struct MovieClipUser *u /* parenting */ -void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime); -void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene); +void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime, const int do_newframe); +void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene, const int do_newframe); void BKE_mask_parent_init(struct MaskParent *parent); void BKE_mask_calc_handle_adjacent_length(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point); void BKE_mask_calc_handle_point(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point); @@ -93,6 +94,22 @@ void BKE_mask_get_handle_point_adjacent(struct Mask *mask, struct MaskSpline *sp struct MaskSplinePoint **r_point_prev, struct MaskSplinePoint **r_point_next); void BKE_mask_calc_handles(struct Mask *mask); +/* animation */ +int BKE_mask_object_shape_totvert(struct MaskObject *maskobj); +void BKE_mask_object_shape_from_mask(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape); +void BKE_mask_object_shape_to_mask(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape); +void BKE_mask_object_shape_to_mask_interp(struct MaskObject *maskobj, + struct MaskObjectShape *maskobj_shape_a, + struct MaskObjectShape *maskobj_shape_b, + const float fac); +struct MaskObjectShape *BKE_mask_object_shape_find_frame(struct MaskObject *maskobj, int frame); +int BKE_mask_object_shape_find_frame_range(struct MaskObject *maskobj, int frame, + struct MaskObjectShape **r_maskobj_shape_a, + struct MaskObjectShape **r_maskobj_shape_b); +struct MaskObjectShape *BKE_mask_object_shape_varify_frame(struct MaskObject *maskobj, int frame); +void BKE_mask_object_shape_unlink(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape); +void BKE_mask_object_shape_sort(struct MaskObject *maskobj); + #define MASKPOINT_ISSEL(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT) #define MASKPOINT_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 #define MASKPOINT_DESEL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 70a83dd5104..56bf90499e5 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -662,10 +662,20 @@ void BKE_mask_spline_free(MaskSpline *spline) MEM_freeN(spline); } +void BKE_mask_object_shape_free(MaskObjectShape *maskobj_shape) +{ + MEM_freeN(maskobj_shape->data); + + MEM_freeN(maskobj_shape); +} + void BKE_mask_object_free(MaskObject *maskobj) { - MaskSpline *spline = maskobj->splines.first; + MaskSpline *spline; + MaskObjectShape *maskobj_shape; + /* free splines */ + spline = maskobj->splines.first; while (spline) { MaskSpline *next_spline = spline->next; @@ -675,6 +685,17 @@ void BKE_mask_object_free(MaskObject *maskobj) spline = next_spline; } + /* free animation data */ + maskobj_shape = maskobj->splines_shapes.first; + while (maskobj_shape) { + MaskObjectShape *next_maskobj_shape = maskobj_shape->next; + + BLI_remlink(&maskobj->splines_shapes, maskobj_shape); + BKE_mask_object_shape_free(maskobj_shape); + + maskobj_shape = next_maskobj_shape; + } + MEM_freeN(maskobj); } @@ -956,7 +977,7 @@ void BKE_mask_calc_handles(Mask *mask) } } -void BKE_mask_evaluate(Mask *mask, float ctime) +void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) { MaskObject *maskobj; @@ -964,6 +985,40 @@ void BKE_mask_evaluate(Mask *mask, float ctime) MaskSpline *spline; int i; + /* animation if available */ + if (do_newframe) { + MaskObjectShape *maskobj_shape_a; + MaskObjectShape *maskobj_shape_b; + int found; + + if ((found = BKE_mask_object_shape_find_frame_range(maskobj, (int)ctime, + &maskobj_shape_a, &maskobj_shape_b))) + { + if (found == 1) { +#if 0 + printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_countlist(&maskobj->splines_shapes), + maskobj_shape_a->frame); +#endif + + BKE_mask_object_shape_to_mask(maskobj, maskobj_shape_a); + } + else if (found == 2) { + float w = maskobj_shape_b->frame - maskobj_shape_a->frame; +#if 0 + printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_countlist(&maskobj->splines_shapes), + maskobj_shape_a->frame, maskobj_shape_b->frame); +#endif + BKE_mask_object_shape_to_mask_interp(maskobj, maskobj_shape_a, maskobj_shape_b, + (ctime - maskobj_shape_a->frame) / w); + } + else { + /* always fail, should never happen */ + BLI_assert(found == 2); + } + } + } + /* animation done... */ + for (spline = maskobj->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; @@ -984,22 +1039,22 @@ void BKE_mask_evaluate(Mask *mask, float ctime) BKE_mask_calc_handles(mask); } -void BKE_mask_evaluate_all_masks(Main *bmain, float ctime) +void BKE_mask_evaluate_all_masks(Main *bmain, float ctime, const int do_newframe) { Mask *mask; for (mask = bmain->mask.first; mask; mask = mask->id.next) { - BKE_mask_evaluate(mask, ctime); + BKE_mask_evaluate(mask, ctime, do_newframe); } } -void BKE_mask_update_scene(Main *bmain, Scene *scene) +void BKE_mask_update_scene(Main *bmain, Scene *scene, const int do_newframe) { Mask *mask; for (mask = bmain->mask.first; mask; mask = mask->id.next) { if (mask->id.flag & LIB_ID_RECALC) { - BKE_mask_evaluate_all_masks(bmain, CFRA); + BKE_mask_evaluate_all_masks(bmain, CFRA, do_newframe); } } } @@ -1008,3 +1063,211 @@ void BKE_mask_parent_init(MaskParent *parent) { parent->id_type = ID_MC; } + + +/* *** own animation/shapekey implimentation *** + * BKE_mask_object_shape_XXX */ + +int BKE_mask_object_shape_totvert(MaskObject *maskobj) +{ + int tot = 0; + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + tot += spline->tot_point; + } + + return tot; +} + +/* these functions match. copy is swapped */ +void BKE_mask_object_shape_from_mask(MaskObject *maskobj, MaskObjectShape *maskobj_shape) +{ + int tot = BKE_mask_object_shape_totvert(maskobj); + + if (maskobj_shape->tot_vert == tot) { + float *fp = maskobj_shape->data; + + MaskSpline *spline; + for (spline = maskobj->splines.first; spline; spline = spline->next) { + int i; + for (i = 0; i < spline->tot_point; i++) { + BezTriple *bezt = &spline->points[i].bezt; + /* *** BKE_mask_object_shape_to_mask - swapped *** */ + copy_v2_v2(fp, bezt->vec[0]); fp += 2; + copy_v2_v2(fp, bezt->vec[1]); fp += 2; + copy_v2_v2(fp, bezt->vec[2]); fp += 2; + fp[0] = bezt->weight; + fp[1] = bezt->radius; fp += 2; + } + } + } + else { + printf("%s: vert mismatch %d != %d\n", __func__, maskobj_shape->tot_vert, tot); + } +} + +void BKE_mask_object_shape_to_mask(MaskObject *maskobj, MaskObjectShape *maskobj_shape) +{ + int tot = BKE_mask_object_shape_totvert(maskobj); + + if (maskobj_shape->tot_vert == tot) { + float *fp = maskobj_shape->data; + + MaskSpline *spline; + for (spline = maskobj->splines.first; spline; spline = spline->next) { + int i; + for (i = 0; i < spline->tot_point; i++) { + BezTriple *bezt = &spline->points[i].bezt; + /* *** BKE_mask_object_shape_from_mask - swapped *** */ + copy_v2_v2(bezt->vec[0], fp); fp += 2; + copy_v2_v2(bezt->vec[1], fp); fp += 2; + copy_v2_v2(bezt->vec[2], fp); fp += 2; + bezt->weight = fp[0]; + bezt->radius = fp[1]; fp += 2; + } + } + } + else { + printf("%s: vert mismatch %d != %d\n", __func__, maskobj_shape->tot_vert, tot); + } +} + +BLI_INLINE void interp_v2_v2v2_flfl(float target[2], const float a[2], const float b[2], + const float t, const float s) +{ + target[0] = s * a[0] + t * b[0]; + target[1] = s * a[1] + t * b[1]; +} + +/* linear interpolation only */ +void BKE_mask_object_shape_to_mask_interp(MaskObject *maskobj, + MaskObjectShape *maskobj_shape_a, + MaskObjectShape *maskobj_shape_b, + const float fac) +{ + int tot = BKE_mask_object_shape_totvert(maskobj); + printf("%.6f\n", fac); + if (maskobj_shape_a->tot_vert == tot && maskobj_shape_b->tot_vert == tot) { + float *fp_a = maskobj_shape_a->data; + float *fp_b = maskobj_shape_b->data; + const float ifac = 1.0f - fac; + + MaskSpline *spline; + for (spline = maskobj->splines.first; spline; spline = spline->next) { + int i; + for (i = 0; i < spline->tot_point; i++) { + BezTriple *bezt = &spline->points[i].bezt; + /* *** BKE_mask_object_shape_from_mask - swapped *** */ + interp_v2_v2v2_flfl(bezt->vec[0], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2; + interp_v2_v2v2_flfl(bezt->vec[1], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2; + interp_v2_v2v2_flfl(bezt->vec[2], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2; + bezt->weight = (fp_a[0] * ifac) + (fp_b[0] * fac); + bezt->radius = (fp_a[1] * ifac) + (fp_b[1] * fac); fp_a += 2; fp_b += 2; + } + } + } + else { + printf("%s: vert mismatch %d != %d != %d\n", + __func__, maskobj_shape_a->tot_vert, maskobj_shape_b->tot_vert, tot); + } +} + +MaskObjectShape *BKE_mask_object_shape_find_frame(MaskObject *maskobj, int frame) +{ + MaskObjectShape *maskobj_shape; + + for (maskobj_shape = maskobj->splines_shapes.first; + maskobj_shape; + maskobj_shape = maskobj_shape->next) + { + if (frame == maskobj_shape->frame) { + return maskobj_shape; + } + else if (frame > maskobj_shape->frame) { + break; + } + } + + return NULL; +} + +/* when returning 2 - the frame isnt found but before/after frames are */ +int BKE_mask_object_shape_find_frame_range(MaskObject *maskobj, int frame, + MaskObjectShape **r_maskobj_shape_a, + MaskObjectShape **r_maskobj_shape_b) +{ + MaskObjectShape *maskobj_shape; + + for (maskobj_shape = maskobj->splines_shapes.first; + maskobj_shape; + maskobj_shape = maskobj_shape->next) + { + if (frame == maskobj_shape->frame) { + *r_maskobj_shape_a = maskobj_shape; + *r_maskobj_shape_b = NULL; + return 1; + } + else if (frame < maskobj_shape->frame) { + if (maskobj_shape->prev) { + *r_maskobj_shape_a = maskobj_shape->prev; + *r_maskobj_shape_b = maskobj_shape; + return 2; + } + else { + *r_maskobj_shape_a = maskobj_shape; + *r_maskobj_shape_b = NULL; + return 1; + } + } + } + + *r_maskobj_shape_a = NULL; + *r_maskobj_shape_b = NULL; + + return 0; +} + +MaskObjectShape *BKE_mask_object_shape_varify_frame(MaskObject *maskobj, int frame) +{ + MaskObjectShape *maskobj_shape; + + maskobj_shape = BKE_mask_object_shape_find_frame(maskobj, frame); + + if (maskobj_shape == NULL) { + int tot_vert = BKE_mask_object_shape_totvert(maskobj); + + maskobj_shape = MEM_mallocN(sizeof(MaskObjectShape), __func__); + maskobj_shape->frame = frame; + maskobj_shape->tot_vert = tot_vert; + maskobj_shape->data = MEM_mallocN(tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); + + BLI_addtail(&maskobj->splines_shapes, maskobj_shape); + + BKE_mask_object_shape_sort(maskobj); + } + + return maskobj_shape; +} + +void BKE_mask_object_shape_unlink(MaskObject *maskobj, MaskObjectShape *maskobj_shape) +{ + BLI_remlink(&maskobj->splines_shapes, maskobj_shape); + + BKE_mask_object_shape_free(maskobj_shape); +} + +static int mask_object_shape_sort_cb(void *maskobj_shape_a_ptr, void *maskobj_shape_b_ptr) +{ + MaskObjectShape *maskobj_shape_a = (MaskObjectShape *)maskobj_shape_a_ptr; + MaskObjectShape *maskobj_shape_b = (MaskObjectShape *)maskobj_shape_b_ptr; + + if (maskobj_shape_a->frame < maskobj_shape_b->frame) return -1; + else if (maskobj_shape_a->frame > maskobj_shape_b->frame) return 1; + else return 0; +} + +void BKE_mask_object_shape_sort(MaskObject *maskobj) +{ + BLI_sortlist(&maskobj->splines_shapes, mask_object_shape_sort_cb); +} diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index ee791ff0a0a..752203a5453 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1004,7 +1004,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen sound_update_scene(scene); /* update masking curves */ - BKE_mask_update_scene(bmain, scene); + BKE_mask_update_scene(bmain, scene, FALSE); } /* this is called in main loop, doing tagged updates before redraw */ @@ -1075,7 +1075,7 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) * so don't call within 'scene_update_tagged_recursive' */ DAG_scene_update_flags(bmain, sce, lay, TRUE); // only stuff that moves or needs display still - BKE_mask_evaluate_all_masks(bmain, ctime); + BKE_mask_evaluate_all_masks(bmain, ctime, TRUE); /* All 'standard' (i.e. without any dependencies) animation is handled here, * with an 'local' to 'macro' order of evaluation. This should ensure that diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index edea4ccab5b..4ea7da44f11 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6197,11 +6197,11 @@ static void direct_link_mask(FileData *fd, Mask *mask) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; + MaskObjectShape *maskobj_shape; link_list(fd, &maskobj->splines); - spline = maskobj->splines.first; - while (spline) { + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; spline->points = newdataadr(fd, spline->points); @@ -6212,8 +6212,12 @@ static void direct_link_mask(FileData *fd, Mask *mask) if (point->tot_uw) point->uw = newdataadr(fd, point->uw); } + } - spline = spline->next; + link_list(fd, &maskobj->splines_shapes); + + for (maskobj_shape = maskobj->splines_shapes.first; maskobj_shape; maskobj_shape = maskobj_shape->next) { + maskobj_shape->data = newdataadr(fd, maskobj_shape->data); } maskobj->act_spline = newdataadr(fd, maskobj->act_spline); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 29cfd7f7f5c..7c9945ef517 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2771,6 +2771,7 @@ static void write_masks(WriteData *wd, ListBase *idbase) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; + MaskObjectShape *maskobj_shape; writestruct(wd, DATA, "MaskObject", 1, maskobj); @@ -2787,6 +2788,11 @@ static void write_masks(WriteData *wd, ListBase *idbase) writestruct(wd, DATA, "MaskSplinePointUW", point->tot_uw, point->uw); } } + + for (maskobj_shape = maskobj->splines_shapes.first; maskobj_shape; maskobj_shape = maskobj_shape->next) { + writestruct(wd, DATA, "MaskObjectShape", 1, maskobj_shape); + writedata(wd, DATA, maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, maskobj_shape->data); + } } } diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt index 55c31e35536..e6f26e32c06 100644 --- a/source/blender/editors/mask/CMakeLists.txt +++ b/source/blender/editors/mask/CMakeLists.txt @@ -42,6 +42,7 @@ set(SRC mask_ops.c mask_relationships.c mask_select.c + mask_shapekey.c mask_intern.h ) diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index eaeb0ab9b7f..749c2c0237e 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -167,6 +167,10 @@ void ED_operatortypes_mask(void) /* relationships */ WM_operatortype_append(MASK_OT_parent_set); WM_operatortype_append(MASK_OT_parent_clear); + + /* shapekeys */ + WM_operatortype_append(MASK_OT_shape_key_insert); + WM_operatortype_append(MASK_OT_shape_key_clear); } void ED_keymap_mask(wmKeyConfig *keyconf) @@ -210,6 +214,10 @@ void ED_keymap_mask(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "MASK_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "MASK_OT_shape_key_insert", IKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_shape_key_clear", IKEY, KM_PRESS, KM_ALT, 0); + + transform_keymap_for_space(keyconf, keymap, SPACE_CLIP); } diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index 623ef5fd533..fee4b63529d 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -88,4 +88,8 @@ void ED_mask_aspect(struct bContext *C, float *aspx, float *aspy); void ED_mask_pixelspace_factor(struct bContext *C, float *scalex, float *scaley); void ED_mask_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]); +/* mask_shapekey.c */ +void MASK_OT_shape_key_insert(struct wmOperatorType *ot); +void MASK_OT_shape_key_clear(struct wmOperatorType *ot); + #endif /* __MASK_INTERN_H__ */ diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c new file mode 100755 index 00000000000..80ba605fe72 --- /dev/null +++ b/source/blender/editors/mask/mask_shapekey.c @@ -0,0 +1,130 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_shapekey.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "DNA_mask_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" +#include "ED_clip.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "mask_intern.h" /* own include */ + +static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + const int frame = CFRA; + Mask *mask = CTX_data_edit_mask(C); + MaskObject *maskobj; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskObjectShape *maskobj_shape; + + maskobj_shape = BKE_mask_object_shape_varify_frame(maskobj, frame); + BKE_mask_object_shape_from_mask(maskobj, maskobj_shape); + } + + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; +} + +void MASK_OT_shape_key_insert(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Insert Shape Key"; + ot->description = ""; + ot->idname = "MASK_OT_shape_key_insert"; + + /* api callbacks */ + ot->exec = mask_shape_key_insert_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + const int frame = CFRA; + Mask *mask = CTX_data_edit_mask(C); + MaskObject *maskobj; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskObjectShape *maskobj_shape; + + maskobj_shape = BKE_mask_object_shape_find_frame(maskobj, frame); + + if (maskobj_shape) { + BKE_mask_object_shape_unlink(maskobj, maskobj_shape); + } + } + + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; +} + +void MASK_OT_shape_key_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Shape Key"; + ot->description = ""; + ot->idname = "MASK_OT_shape_key_clear"; + + /* api callbacks */ + ot->exec = mask_shape_key_clear_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index 7fb2196e82c..9f163adc77b 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -85,12 +85,23 @@ typedef struct MaskSpline { int weight_interp, pad; /* weight interpolation */ } MaskSpline; +/* one per frame */ +typedef struct MaskObjectShape { + struct MaskObjectShape *next, *prev; + + float *data; /* u coordinate along spline segment and weight of this point */ + int tot_vert; /* to ensure no buffer overruns's: alloc size is (tot_vert * MASK_OBJECT_SHAPE_ELEM_SIZE) */ + int frame; /* different flags of this point */ +} MaskObjectShape; + typedef struct MaskObject { struct MaskObject *next, *prev; char name[64]; /* name of the mask object (64 = MAD_ID_NAME - 2) */ ListBase splines; /* list of splines which defines this mask object */ + ListBase splines_shapes; + struct MaskSpline *act_spline; /* active spline */ struct MaskSplinePoint *act_point; /* active point */ } MaskObject; @@ -105,4 +116,6 @@ typedef struct MaskObject { #define MASK_SPLINE_INTERP_LINEAR 1 #define MASK_SPLINE_INTERP_EASE 2 +#define MASK_OBJECT_SHAPE_ELEM_SIZE 8 /* 3x 2D points + weight + radius == 8 */ + #endif // __DNA_MASK_TYPES_H__ From 3305674bb5615b959bc5dfa73dab7e9783849081 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 24 May 2012 14:01:00 +0000 Subject: [PATCH 077/360] Port mask node to new compositor system Works in the same way as double edge node -- not actually multithreaded but currently it's fast enough to be used in such way. In the future it might be changed in some way. Move actual mask rasterization code to BKE so it's resued by old compositor system and new compositor. Also in the future it might be used to display mask preview in mask editor. --- source/blender/blenkernel/BKE_mask.h | 3 + source/blender/blenkernel/intern/mask.c | 45 +++++++ source/blender/compositor/CMakeLists.txt | 5 + .../compositor/intern/COM_Converter.cpp | 4 + .../blender/compositor/nodes/COM_MaskNode.cpp | 65 +++++++++++ .../blender/compositor/nodes/COM_MaskNode.h | 38 ++++++ .../operations/COM_MaskOperation.cpp | 110 ++++++++++++++++++ .../compositor/operations/COM_MaskOperation.h | 66 +++++++++++ source/blender/nodes/CMakeLists.txt | 1 - .../composite/nodes/node_composite_mask.c | 40 +------ 10 files changed, 337 insertions(+), 40 deletions(-) create mode 100644 source/blender/compositor/nodes/COM_MaskNode.cpp create mode 100644 source/blender/compositor/nodes/COM_MaskNode.h create mode 100644 source/blender/compositor/operations/COM_MaskOperation.cpp create mode 100644 source/blender/compositor/operations/COM_MaskOperation.h diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index e09aa9d8355..21be180b05f 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -110,6 +110,9 @@ struct MaskObjectShape *BKE_mask_object_shape_varify_frame(struct MaskObject *ma void BKE_mask_object_shape_unlink(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape); void BKE_mask_object_shape_sort(struct MaskObject *maskobj); +/* rasterization */ +void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer); + #define MASKPOINT_ISSEL(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT) #define MASKPOINT_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 #define MASKPOINT_DESEL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 56bf90499e5..ea2acc4dbd3 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -55,6 +55,8 @@ #include "BKE_movieclip.h" #include "BKE_utildefines.h" +#include "raskter.h" + /* mask objects */ MaskObject *BKE_mask_object_new(Mask *mask, const char *name) @@ -1271,3 +1273,46 @@ void BKE_mask_object_shape_sort(MaskObject *maskobj) { BLI_sortlist(&maskobj->splines_shapes, mask_object_shape_sort_cb); } + +/* rasterization */ +void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) +{ + MaskObject *maskobj; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + float *diff_points; + int tot_diff_point; + + diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); + + /* TODO, make this optional! */ + if (width != height) { + float *fp; + int i; + float asp; + + if (width < height) { + fp = &diff_points[0]; + asp = (float)width / (float)height; + } + else { + fp = &diff_points[1]; + asp = (float)height / (float)width; + } + + for (i = 0; i < tot_diff_point; i++, fp += 2) { + (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; + } + } + + if (tot_diff_point) { + PLX_raskterize(diff_points, tot_diff_point, buffer, width, height); + + MEM_freeN(diff_points); + } + } + } +} diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 3230c0ec33d..5e778d4d03b 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -134,6 +134,8 @@ set(SRC nodes/COM_MovieClipNode.h nodes/COM_OutputFileNode.cpp nodes/COM_OutputFileNode.h + nodes/COM_MaskNode.cpp + nodes/COM_MaskNode.h # output nodes nodes/COM_CompositorNode.cpp @@ -603,6 +605,9 @@ operations/COM_ConvertDepthToRadiusOperation.cpp operations/COM_AntiAliasOperation.cpp operations/COM_AntiAliasOperation.h + + operations/COM_MaskOperation.cpp + operations/COM_MaskOperation.h ) blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 3cb297801ca..dc6409e7b86 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -111,6 +111,7 @@ #include "COM_DefocusNode.h" #include "COM_DoubleEdgeMaskNode.h" #include "COM_CropNode.h" +#include "COM_MaskNode.h" Node *Converter::convert(bNode *bNode) { @@ -347,6 +348,9 @@ case CMP_NODE_OUTPUT_FILE: case CMP_NODE_CROP: node = new CropNode(bNode); break; + case CMP_NODE_MASK: + node = new MaskNode(bNode); + break; /* not inplemented yet */ default: node = new MuteNode(bNode); diff --git a/source/blender/compositor/nodes/COM_MaskNode.cpp b/source/blender/compositor/nodes/COM_MaskNode.cpp new file mode 100644 index 00000000000..991c3f75e05 --- /dev/null +++ b/source/blender/compositor/nodes/COM_MaskNode.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_MaskNode.h" +#include "COM_ExecutionSystem.h" +#include "COM_MaskOperation.h" + +extern "C" { + #include "DNA_mask_types.h" +} + +MaskNode::MaskNode(bNode *editorNode): Node(editorNode) +{ +} + +void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +{ + const RenderData *data = &context->getScene()->r; + + InputSocket *inputImage = this->getInputSocket(0); + OutputSocket *outputMask = this->getOutputSocket(0); + + bNode *editorNode = this->getbNode(); + Mask *mask = (Mask *)editorNode->id; + + // always connect the output image + MaskOperation *operation = new MaskOperation(); + + if (inputImage->isConnected()) { + inputImage->relinkConnections(operation->getInputSocket(0), 0, graph); + } + else { + operation->setMaskWidth(data->xsch * data->size / 100.0f); + operation->setMaskHeight(data->ysch * data->size / 100.0f); + } + + if (outputMask->isConnected()) { + outputMask->relinkConnections(operation->getOutputSocket()); + } + + operation->setMask(mask); + operation->setFramenumber(context->getFramenumber()); + + graph->addOperation(operation); +} diff --git a/source/blender/compositor/nodes/COM_MaskNode.h b/source/blender/compositor/nodes/COM_MaskNode.h new file mode 100644 index 00000000000..9d2ea1889d9 --- /dev/null +++ b/source/blender/compositor/nodes/COM_MaskNode.h @@ -0,0 +1,38 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_Node.h" +#include "DNA_node_types.h" + +/** + * @brief MaskNode + * @ingroup Node + */ +class MaskNode : public Node { + + +public: + MaskNode(bNode *editorNode); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); + +}; diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp new file mode 100644 index 00000000000..7c71e884e5c --- /dev/null +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -0,0 +1,110 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_MaskOperation.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "DNA_scene_types.h" + +extern "C" { + #include "BKE_mask.h" +} + +MaskOperation::MaskOperation(): NodeOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->mask = NULL; + this->maskWidth = 0; + this->maskHeight = 0; + this->framenumber = 0; + this->rasterizedMask = NULL; + setComplex(true); +} + +void MaskOperation::initExecution() +{ + initMutex(); + this->rasterizedMask = NULL; +} + +void MaskOperation::deinitExecution() +{ + if (this->rasterizedMask) { + MEM_freeN(rasterizedMask); + this->rasterizedMask = NULL; + } +} + +void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + if (this->rasterizedMask) + return this->rasterizedMask; + + BLI_mutex_lock(getMutex()); + if (this->rasterizedMask == NULL) { + int width = this->getWidth(); + int height = this->getHeight(); + + this->rasterizedMask = (float *)MEM_callocN(sizeof(float) * width * height, "rasterized mask"); + BKE_mask_rasterize(mask, width, height, this->rasterizedMask); + } + BLI_mutex_unlock(getMutex()); + + return this->rasterizedMask; +} + +void MaskOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) +{ + if (maskWidth == 0 || maskHeight == 0) { + NodeOperation::determineResolution(resolution, preferredResolution); + } + else { + unsigned int nr[2]; + + nr[0] = maskWidth; + nr[1] = maskHeight; + + NodeOperation::determineResolution(resolution, nr); + + resolution[0] = maskWidth; + resolution[1] = maskHeight; + } +} + +void MaskOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + float *buffer = (float*) data; + int index = (y * this->getWidth() + x); + + color[0] = buffer[index]; + color[1] = buffer[index]; + color[2] = buffer[index]; + color[3] = 1.0f; +} + + diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h new file mode 100644 index 00000000000..9f2c7f53f56 --- /dev/null +++ b/source/blender/compositor/operations/COM_MaskOperation.h @@ -0,0 +1,66 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + + +#ifndef _COM_MaskOperation_h +#define _COM_MaskOperation_h + +#include "COM_NodeOperation.h" +#include "DNA_scene_types.h" +#include "DNA_mask_types.h" +#include "BLI_listbase.h" +#include "IMB_imbuf_types.h" + +/** + * Class with implementation of mask rasterization + */ +class MaskOperation : public NodeOperation { +protected: + Mask *mask; + int maskWidth; + int maskHeight; + int framenumber; + float *rasterizedMask; + + /** + * Determine the output resolution. The resolution is retrieved from the Renderer + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + +public: + MaskOperation(); + + void initExecution(); + void deinitExecution(); + + void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + void setMask(Mask *mask) {this->mask = mask;} + void setMaskWidth(int width) {this->maskWidth = width;} + void setMaskHeight(int height) {this->maskHeight = height;} + void setFramenumber(int framenumber) {this->framenumber = framenumber;} + + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); +}; + +#endif diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 358abb08ba4..5e36f90f217 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -35,7 +35,6 @@ set(INC ../makesrna ../render/extern/include ../../../intern/guardedalloc - ../../../intern/raskter ../compositor ) diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c index 93d1edd76e8..c90c7918660 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mask.c +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -36,8 +36,6 @@ #include "BKE_mask.h" -// XXX: ... -#include "../../../../intern/raskter/raskter.h" #include "node_composite_util.h" /* **************** Translate ******************** */ @@ -58,7 +56,6 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) Mask *mask = (Mask *)node->id; CompBuf *stackbuf; RenderData *rd = data; - MaskObject *maskobj = mask->maskobjs.first; float *res; int sx, sy; @@ -84,42 +81,7 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE); res = stackbuf->rect; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskSpline *spline; - - for (spline = maskobj->splines.first; spline; spline = spline->next) { - float *diff_points; - int tot_diff_point; - - diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); - - /* TODO, make this optional! */ - if (sx != sy) { - float *fp; - int i; - float asp; - - if (sx < sy) { - fp = &diff_points[0]; - asp = (float)sx / (float)sy; - } - else { - fp = &diff_points[1]; - asp = (float)sy / (float)sx; - } - - for (i = 0; i < tot_diff_point; i++, fp += 2) { - (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; - } - } - - if (tot_diff_point) { - PLX_raskterize(diff_points, tot_diff_point, res, sx, sy); - - MEM_freeN(diff_points); - } - } - } + BKE_mask_rasterize(mask, sx, sy, res); /* pass on output and free */ out[0]->data = stackbuf; From a8a855ecd7be7a695a67308f20c07332bce768db Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 May 2012 14:06:10 +0000 Subject: [PATCH 078/360] fix for incorrect range function args. --- source/blender/makesrna/intern/rna_mask.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 53a6bc34c4a..1345011cd7e 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -114,13 +114,16 @@ static void rna_Mask_object_active_index_set(PointerRNA *ptr, int value) mask->act_maskobj = value; } -static void rna_Mask_object_active_index_range(PointerRNA *ptr, int *min, int *max) +static void rna_Mask_object_active_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) { Mask *mask = (Mask *)ptr->id.data; *min = 0; *max = mask->tot_maskobj - 1; *max = MAX2(0, *max); + + *softmin = *min; + *softmax = *max; } static PointerRNA rna_Mask_object_active_get(PointerRNA *ptr) From ebd39522d89a6f5d1b5ae58342cb1a3b28ebd714 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 May 2012 15:29:50 +0000 Subject: [PATCH 079/360] fix bug in own recent edits - shape key insertion --- source/blender/blenkernel/intern/mask.c | 15 +++++++++++- source/blender/editors/mask/mask_shapekey.c | 26 ++++++++++++++++----- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index ea2acc4dbd3..5e9d659c68a 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1186,7 +1186,7 @@ MaskObjectShape *BKE_mask_object_shape_find_frame(MaskObject *maskobj, int frame if (frame == maskobj_shape->frame) { return maskobj_shape; } - else if (frame > maskobj_shape->frame) { + else if (frame < maskobj_shape->frame) { break; } } @@ -1249,6 +1249,19 @@ MaskObjectShape *BKE_mask_object_shape_varify_frame(MaskObject *maskobj, int fra BKE_mask_object_shape_sort(maskobj); } +#if 0 + { + MaskObjectShape *maskobj_shape; + int i = 0; + for (maskobj_shape = maskobj->splines_shapes.first; + maskobj_shape; + maskobj_shape = maskobj_shape->next) + { + printf("mask %d, %d\n", i++, maskobj_shape->frame); + } + } +#endif + return maskobj_shape; } diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c index 80ba605fe72..c80ca979077 100755 --- a/source/blender/editors/mask/mask_shapekey.c +++ b/source/blender/editors/mask/mask_shapekey.c @@ -62,18 +62,25 @@ static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op)) const int frame = CFRA; Mask *mask = CTX_data_edit_mask(C); MaskObject *maskobj; + int change = FALSE; for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskObjectShape *maskobj_shape; maskobj_shape = BKE_mask_object_shape_varify_frame(maskobj, frame); BKE_mask_object_shape_from_mask(maskobj, maskobj_shape); + change = TRUE; } - WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); - DAG_id_tag_update(&mask->id, 0); + if (change) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } } void MASK_OT_shape_key_insert(wmOperatorType *ot) @@ -97,6 +104,7 @@ static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) const int frame = CFRA; Mask *mask = CTX_data_edit_mask(C); MaskObject *maskobj; + int change = FALSE; for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskObjectShape *maskobj_shape; @@ -105,13 +113,19 @@ static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) if (maskobj_shape) { BKE_mask_object_shape_unlink(maskobj, maskobj_shape); + change = TRUE; } } - WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); - DAG_id_tag_update(&mask->id, 0); + if (change) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } } void MASK_OT_shape_key_clear(wmOperatorType *ot) From afe2def93cbeb164c4c0a6b97d97b580936b9429 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 May 2012 19:16:08 +0000 Subject: [PATCH 080/360] adding new keyframes now updates existing shapekeys --- source/blender/blenkernel/BKE_mask.h | 5 + source/blender/blenkernel/intern/mask.c | 126 +++++++++++++++++++++--- source/blender/editors/mask/mask_ops.c | 17 ++++ 3 files changed, 134 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 21be180b05f..7745eb0b972 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -110,6 +110,11 @@ struct MaskObjectShape *BKE_mask_object_shape_varify_frame(struct MaskObject *ma void BKE_mask_object_shape_unlink(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape); void BKE_mask_object_shape_sort(struct MaskObject *maskobj); +int BKE_mask_object_shape_spline_index(struct MaskObject *maskobj, int index, + struct MaskSpline **r_maskobj_shape, int *r_index); +void BKE_mask_object_shape_changed_add(struct MaskObject *maskobj, int index, + int do_init, int do_init_interpolate); + /* rasterization */ void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 5e9d659c68a..c09947ef540 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1082,6 +1082,24 @@ int BKE_mask_object_shape_totvert(MaskObject *maskobj) return tot; } +static void mask_object_shape_from_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE]) +{ + copy_v2_v2(&fp[0], bezt->vec[0]); + copy_v2_v2(&fp[2], bezt->vec[1]); + copy_v2_v2(&fp[4], bezt->vec[2]); + fp[6] = bezt->weight; + fp[7] = bezt->radius; +} + +static void mask_object_shape_to_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE]) +{ + copy_v2_v2(bezt->vec[0], &fp[0]); + copy_v2_v2(bezt->vec[1], &fp[2]); + copy_v2_v2(bezt->vec[2], &fp[4]); + bezt->weight = fp[6]; + bezt->radius = fp[7]; +} + /* these functions match. copy is swapped */ void BKE_mask_object_shape_from_mask(MaskObject *maskobj, MaskObjectShape *maskobj_shape) { @@ -1094,13 +1112,8 @@ void BKE_mask_object_shape_from_mask(MaskObject *maskobj, MaskObjectShape *masko for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { - BezTriple *bezt = &spline->points[i].bezt; - /* *** BKE_mask_object_shape_to_mask - swapped *** */ - copy_v2_v2(fp, bezt->vec[0]); fp += 2; - copy_v2_v2(fp, bezt->vec[1]); fp += 2; - copy_v2_v2(fp, bezt->vec[2]); fp += 2; - fp[0] = bezt->weight; - fp[1] = bezt->radius; fp += 2; + mask_object_shape_from_mask_point(&spline->points[i].bezt, fp); + fp += MASK_OBJECT_SHAPE_ELEM_SIZE; } } } @@ -1120,13 +1133,8 @@ void BKE_mask_object_shape_to_mask(MaskObject *maskobj, MaskObjectShape *maskobj for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { - BezTriple *bezt = &spline->points[i].bezt; - /* *** BKE_mask_object_shape_from_mask - swapped *** */ - copy_v2_v2(bezt->vec[0], fp); fp += 2; - copy_v2_v2(bezt->vec[1], fp); fp += 2; - copy_v2_v2(bezt->vec[2], fp); fp += 2; - bezt->weight = fp[0]; - bezt->radius = fp[1]; fp += 2; + mask_object_shape_to_mask_point(&spline->points[i].bezt, fp); + fp += MASK_OBJECT_SHAPE_ELEM_SIZE; } } } @@ -1287,6 +1295,96 @@ void BKE_mask_object_shape_sort(MaskObject *maskobj) BLI_sortlist(&maskobj->splines_shapes, mask_object_shape_sort_cb); } +int BKE_mask_object_shape_spline_index(MaskObject *maskobj, int index, + MaskSpline **r_maskobj_shape, int *r_index) +{ + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + if (index < spline->tot_point) { + *r_maskobj_shape = spline; + *r_index = index; + return TRUE; + } + index -= spline->tot_point; + } + + return FALSE; +} + +/* when a now points added - resize all shapekey array */ +void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, + int do_init, int do_init_interpolate) +{ + MaskObjectShape *maskobj_shape; + + for (maskobj_shape = maskobj->splines_shapes.first; + maskobj_shape; + maskobj_shape = maskobj_shape->next) + { + /* spline index from maskobj */ + MaskSpline *spline; + int spline_point_index; + + float *data_resized; + + if (BKE_mask_object_shape_spline_index(maskobj, index, + &spline, &spline_point_index)) + { + maskobj_shape->tot_vert++; + data_resized = MEM_mallocN(maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); + if (index > 0) { + memcpy(data_resized, + maskobj_shape->data, + index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + + if (do_init) { + if (do_init_interpolate) { + /* TODO */ + } + else { + mask_object_shape_from_mask_point(&spline->points[spline_point_index].bezt, &data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE]); + } + } + else { + memset(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE], + 0, + sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + + if (index != maskobj_shape->tot_vert - 1) { + memcpy(&data_resized[(index + 1) * MASK_OBJECT_SHAPE_ELEM_SIZE], + maskobj_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), + (maskobj_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + + MEM_freeN(maskobj_shape->data); + maskobj_shape->data = data_resized; + } + } +} + +/* move array to account for removed point */ +#if 0 +void BKE_mask_object_shape_changed_remove(MaskObject *maskobj, int index) +{ + MaskObjectShape *maskobj_shape; + + for (maskobj_shape = maskobj->splines_shapes.first; + maskobj_shape; + maskobj_shape = maskobj_shape->next) + { + if (frame == maskobj_shape->frame) { + return maskobj_shape; + } + else if (frame < maskobj_shape->frame) { + break; + } + } +} +#endif + /* rasterization */ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) { diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 4054814604e..e67a47abdef 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -972,6 +972,23 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) setup_vertex_point(C, mask, spline, new_point, co, tangent, NULL, TRUE); + + { + + /* this block could be a function */ + MaskSpline *spline_iter; + int i_abs = 0; + for (spline_iter = maskobj->splines.first; + spline_iter && spline_iter != spline; + spline_iter = spline_iter->next, i_abs += spline_iter->tot_point) + { + /* pass */ + } + + /* TODO - we could pass the spline! */ + BKE_mask_object_shape_changed_add(maskobj, i_abs + point_index + 1, TRUE, FALSE); + } + maskobj->act_point = new_point; WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); From 139c92e7eb69ba03441faeb7e67b84d60488a199 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 May 2012 09:06:15 +0000 Subject: [PATCH 081/360] new points now have their animated locations applied all non-active keys. --- source/blender/blenkernel/intern/mask.c | 90 +++++++++++++++++++------ source/blender/editors/mask/mask_ops.c | 2 +- 2 files changed, 71 insertions(+), 21 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index c09947ef540..4a91de8cf6d 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1157,7 +1157,6 @@ void BKE_mask_object_shape_to_mask_interp(MaskObject *maskobj, const float fac) { int tot = BKE_mask_object_shape_totvert(maskobj); - printf("%.6f\n", fac); if (maskobj_shape_a->tot_vert == tot && maskobj_shape_b->tot_vert == tot) { float *fp_a = maskobj_shape_a->data; float *fp_b = maskobj_shape_b->data; @@ -1312,25 +1311,70 @@ int BKE_mask_object_shape_spline_index(MaskObject *maskobj, int index, return FALSE; } +/* basic 2D interpolation functions, could make more comprehensive later */ +static void interp_weights_uv_v2_calc(float r_uv[2], const float pt[2], const float pt_a[2], const float pt_b[2]) +{ + float pt_on_line[2]; + r_uv[0] = closest_to_line_v2(pt_on_line, pt, pt_a, pt_b); + r_uv[1] = (len_v2v2(pt_on_line, pt) / len_v2v2(pt_a, pt_b)) * + ((line_point_side_v2(pt_a, pt_b, pt) < 0.0f) ? -1.0 : 1.0); /* this line only sets the sign */ +} + + +static void interp_weights_uv_v2_apply(const float uv[2], float r_pt[2], const float pt_a[2], const float pt_b[2]) +{ + const float dvec[2] = {pt_b[0] - pt_a[0], + pt_b[1] - pt_a[1]}; + + /* u */ + madd_v2_v2v2fl(r_pt, pt_a, dvec, uv[0]); + + /* v */ + r_pt[0] += -dvec[1] * uv[1]; + r_pt[1] += dvec[0] * uv[1]; +} + /* when a now points added - resize all shapekey array */ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, int do_init, int do_init_interpolate) { MaskObjectShape *maskobj_shape; - for (maskobj_shape = maskobj->splines_shapes.first; - maskobj_shape; - maskobj_shape = maskobj_shape->next) + /* spline index from maskobj */ + MaskSpline *spline; + int spline_point_index; + + if (BKE_mask_object_shape_spline_index(maskobj, index, + &spline, &spline_point_index)) { - /* spline index from maskobj */ - MaskSpline *spline; - int spline_point_index; + /* for interpolation */ + /* TODO - assumes closed curve for now */ + float uv[3][2]; /* 3x 2D handles */ + const int pi_curr = spline_point_index; + const int pi_prev = ((spline_point_index - 1) + spline->tot_point) % spline->tot_point; + const int pi_next = (spline_point_index + 1) % spline->tot_point; - float *data_resized; + const int index_offset = index - spline_point_index; + /* const int pi_curr_abs = index; */ + const int pi_prev_abs = pi_prev + index_offset; + const int pi_next_abs = pi_next + index_offset; - if (BKE_mask_object_shape_spline_index(maskobj, index, - &spline, &spline_point_index)) + int i; + if (do_init_interpolate) { + for (i = 0; i < 3; i++) { + interp_weights_uv_v2_calc(uv[i], + spline->points[pi_curr].bezt.vec[i], + spline->points[pi_prev].bezt.vec[i], + spline->points[pi_next].bezt.vec[i]); + } + } + + for (maskobj_shape = maskobj->splines_shapes.first; + maskobj_shape; + maskobj_shape = maskobj_shape->next) { + float *data_resized; + maskobj_shape->tot_vert++; data_resized = MEM_mallocN(maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); if (index > 0) { @@ -1339,12 +1383,24 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } + if (index != maskobj_shape->tot_vert - 1) { + memcpy(&data_resized[(index + 1) * MASK_OBJECT_SHAPE_ELEM_SIZE], + maskobj_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), + (maskobj_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + if (do_init) { + float *fp = &data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE]; + + mask_object_shape_from_mask_point(&spline->points[spline_point_index].bezt, fp); + if (do_init_interpolate) { - /* TODO */ - } - else { - mask_object_shape_from_mask_point(&spline->points[spline_point_index].bezt, &data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE]); + for (i = 0; i < 3; i++) { + interp_weights_uv_v2_apply(uv[i], + &fp[i * 2], + &data_resized[(pi_prev_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)], + &data_resized[(pi_next_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)]); + } } } else { @@ -1353,12 +1409,6 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } - if (index != maskobj_shape->tot_vert - 1) { - memcpy(&data_resized[(index + 1) * MASK_OBJECT_SHAPE_ELEM_SIZE], - maskobj_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), - (maskobj_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); - } - MEM_freeN(maskobj_shape->data); maskobj_shape->data = data_resized; } diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index e67a47abdef..8f8be8fefc1 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -986,7 +986,7 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) } /* TODO - we could pass the spline! */ - BKE_mask_object_shape_changed_add(maskobj, i_abs + point_index + 1, TRUE, FALSE); + BKE_mask_object_shape_changed_add(maskobj, i_abs + point_index + 1, TRUE, TRUE); } maskobj->act_point = new_point; From c6e0d24d02bbbeefdd9010e7f99f4d95185f4c61 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 May 2012 10:04:10 +0000 Subject: [PATCH 082/360] add auto-key for masks --- .../editors/transform/transform_conversions.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 0be2967d54b..7cc8b479517 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4910,6 +4910,20 @@ void special_aftertrans_update(bContext *C, TransInfo *t) nodeUpdateID(t->scene->nodetree, &mask->id); WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); } + + /* TODO - dont key all masks... */ + if (IS_AUTOKEY_ON(t->scene)) { + MaskObject *maskobj; + Scene *scene = t->scene; + int frame = CFRA; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskObjectShape *maskobj_shape; + + maskobj_shape = BKE_mask_object_shape_varify_frame(maskobj, frame); + BKE_mask_object_shape_from_mask(maskobj, maskobj_shape); + } + } } } else if (t->spacetype == SPACE_ACTION) { From e70316f3b26f89d775b5ee27e382cadb28ab0fc4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 May 2012 11:41:42 +0000 Subject: [PATCH 083/360] fix for crash in auto ketframe. --- source/blender/blenkernel/intern/mask.c | 64 ++++++++++++++----------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 4a91de8cf6d..c9aaa2563aa 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1347,6 +1347,9 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, if (BKE_mask_object_shape_spline_index(maskobj, index, &spline, &spline_point_index)) { + /* sanity check */ + int tot = BKE_mask_object_shape_totvert(maskobj); + /* for interpolation */ /* TODO - assumes closed curve for now */ float uv[3][2]; /* 3x 2D handles */ @@ -1373,44 +1376,49 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, maskobj_shape; maskobj_shape = maskobj_shape->next) { - float *data_resized; + if (tot == maskobj_shape->tot_vert) { + float *data_resized; - maskobj_shape->tot_vert++; - data_resized = MEM_mallocN(maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); - if (index > 0) { - memcpy(data_resized, - maskobj_shape->data, - index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); - } + maskobj_shape->tot_vert++; + data_resized = MEM_mallocN(maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); + if (index > 0) { + memcpy(data_resized, + maskobj_shape->data, + index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } - if (index != maskobj_shape->tot_vert - 1) { - memcpy(&data_resized[(index + 1) * MASK_OBJECT_SHAPE_ELEM_SIZE], - maskobj_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), - (maskobj_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); - } + if (index != maskobj_shape->tot_vert - 1) { + memcpy(&data_resized[(index + 1) * MASK_OBJECT_SHAPE_ELEM_SIZE], + maskobj_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), + (maskobj_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } - if (do_init) { - float *fp = &data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE]; + if (do_init) { + float *fp = &data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE]; - mask_object_shape_from_mask_point(&spline->points[spline_point_index].bezt, fp); + mask_object_shape_from_mask_point(&spline->points[spline_point_index].bezt, fp); - if (do_init_interpolate) { - for (i = 0; i < 3; i++) { - interp_weights_uv_v2_apply(uv[i], - &fp[i * 2], - &data_resized[(pi_prev_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)], - &data_resized[(pi_next_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)]); + if (do_init_interpolate) { + for (i = 0; i < 3; i++) { + interp_weights_uv_v2_apply(uv[i], + &fp[i * 2], + &data_resized[(pi_prev_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)], + &data_resized[(pi_next_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)]); + } } } + else { + memset(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE], + 0, + sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + + MEM_freeN(maskobj_shape->data); + maskobj_shape->data = data_resized; } else { - memset(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE], - 0, - sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + printf("%s: vert mismatch %d != %d\n", __func__, maskobj_shape->tot_vert, tot); } - - MEM_freeN(maskobj_shape->data); - maskobj_shape->data = data_resized; } } } From 94fc1f5f4a9a33cb78ef095b3534448655b7fb3c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 May 2012 11:51:56 +0000 Subject: [PATCH 084/360] fix error in prev commit --- source/blender/blenkernel/intern/mask.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index c9aaa2563aa..eacdaeabd1e 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1348,7 +1348,7 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, &spline, &spline_point_index)) { /* sanity check */ - int tot = BKE_mask_object_shape_totvert(maskobj); + int tot = BKE_mask_object_shape_totvert(maskobj) - 1; /* for interpolation */ /* TODO - assumes closed curve for now */ From bb97cf31dee09b87c3ef634ee4fb86b6295ad045 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 May 2012 12:06:10 +0000 Subject: [PATCH 085/360] print frame bumbers when printing shapes that mismatch --- source/blender/blenkernel/intern/mask.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index eacdaeabd1e..55ea4173491 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1118,7 +1118,8 @@ void BKE_mask_object_shape_from_mask(MaskObject *maskobj, MaskObjectShape *masko } } else { - printf("%s: vert mismatch %d != %d\n", __func__, maskobj_shape->tot_vert, tot); + printf("%s: vert mismatch %d != %d (frame %d)\n", + __func__, maskobj_shape->tot_vert, tot, maskobj_shape->frame); } } @@ -1139,7 +1140,8 @@ void BKE_mask_object_shape_to_mask(MaskObject *maskobj, MaskObjectShape *maskobj } } else { - printf("%s: vert mismatch %d != %d\n", __func__, maskobj_shape->tot_vert, tot); + printf("%s: vert mismatch %d != %d (frame %d)\n", + __func__, maskobj_shape->tot_vert, tot, maskobj_shape->frame); } } @@ -1177,8 +1179,9 @@ void BKE_mask_object_shape_to_mask_interp(MaskObject *maskobj, } } else { - printf("%s: vert mismatch %d != %d != %d\n", - __func__, maskobj_shape_a->tot_vert, maskobj_shape_b->tot_vert, tot); + printf("%s: vert mismatch %d != %d != %d (frame %d - %d)\n", + __func__, maskobj_shape_a->tot_vert, maskobj_shape_b->tot_vert, tot, + maskobj_shape_a->frame, maskobj_shape_b->frame); } } @@ -1417,7 +1420,8 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, maskobj_shape->data = data_resized; } else { - printf("%s: vert mismatch %d != %d\n", __func__, maskobj_shape->tot_vert, tot); + printf("%s: vert mismatch %d != %d (frame %d)\n", + __func__, maskobj_shape->tot_vert, tot, maskobj_shape->frame); } } } From b230ebf726a0823a632fd70f5c04f3d0ec8c9898 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 May 2012 12:48:24 +0000 Subject: [PATCH 086/360] mask slide now auto-keys --- source/blender/blenkernel/intern/mask.c | 54 +++++++++++++------ source/blender/editors/include/ED_mask.h | 3 ++ source/blender/editors/mask/mask_ops.c | 8 +++ source/blender/editors/mask/mask_shapekey.c | 16 ++++++ .../editors/transform/transform_conversions.c | 9 +--- 5 files changed, 65 insertions(+), 25 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 55ea4173491..bc9629176cc 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1351,6 +1351,7 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, &spline, &spline_point_index)) { /* sanity check */ + /* the point has already been removed in this array so subtract one when comparing with the shapes */ int tot = BKE_mask_object_shape_totvert(maskobj) - 1; /* for interpolation */ @@ -1376,8 +1377,8 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, } for (maskobj_shape = maskobj->splines_shapes.first; - maskobj_shape; - maskobj_shape = maskobj_shape->next) + maskobj_shape; + maskobj_shape = maskobj_shape->next) { if (tot == maskobj_shape->tot_vert) { float *data_resized; @@ -1386,14 +1387,14 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, data_resized = MEM_mallocN(maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); if (index > 0) { memcpy(data_resized, - maskobj_shape->data, - index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + maskobj_shape->data, + index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } if (index != maskobj_shape->tot_vert - 1) { memcpy(&data_resized[(index + 1) * MASK_OBJECT_SHAPE_ELEM_SIZE], - maskobj_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), - (maskobj_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + maskobj_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), + (maskobj_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } if (do_init) { @@ -1404,16 +1405,16 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, if (do_init_interpolate) { for (i = 0; i < 3; i++) { interp_weights_uv_v2_apply(uv[i], - &fp[i * 2], - &data_resized[(pi_prev_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)], - &data_resized[(pi_next_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)]); + &fp[i * 2], + &data_resized[(pi_prev_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)], + &data_resized[(pi_next_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)]); } } } else { memset(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE], - 0, - sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + 0, + sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } MEM_freeN(maskobj_shape->data); @@ -1428,24 +1429,43 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, } /* move array to account for removed point */ -#if 0 void BKE_mask_object_shape_changed_remove(MaskObject *maskobj, int index) { MaskObjectShape *maskobj_shape; + /* the point has already been removed in this array so add one when comparing with the shapes */ + int tot = BKE_mask_object_shape_totvert(maskobj) + 1; + for (maskobj_shape = maskobj->splines_shapes.first; maskobj_shape; maskobj_shape = maskobj_shape->next) { - if (frame == maskobj_shape->frame) { - return maskobj_shape; + if (tot == maskobj_shape->tot_vert) { + float *data_resized; + + maskobj_shape->tot_vert--; + data_resized = MEM_mallocN(maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); + if (index > 0) { + memcpy(data_resized, + maskobj_shape->data, + (index - 1) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + + if (index != maskobj_shape->tot_vert - 1) { + memcpy(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE], + maskobj_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), + (maskobj_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + + MEM_freeN(maskobj_shape->data); + maskobj_shape->data = data_resized; } - else if (frame < maskobj_shape->frame) { - break; + else { + printf("%s: vert mismatch %d != %d (frame %d)\n", + __func__, maskobj_shape->tot_vert, tot, maskobj_shape->frame); } } } -#endif /* rasterization */ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h index 01495561912..ed1d2ba688e 100644 --- a/source/blender/editors/include/ED_mask.h +++ b/source/blender/editors/include/ED_mask.h @@ -41,4 +41,7 @@ void ED_operatormacros_mask(void); /* mask_draw.c */ void ED_mask_draw(const bContext *C); +/* mask_shapekey.c */ +int ED_mask_object_shape_auto_key_all(struct Mask *mask, const int frame); + #endif /* ED_TEXT_H */ diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 8f8be8fefc1..e52d673ad9e 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -40,6 +40,7 @@ #include "BKE_depsgraph.h" #include "BKE_mask.h" +#include "DNA_scene_types.h" #include "DNA_mask_types.h" #include "DNA_object_types.h" /* SELECT */ @@ -49,6 +50,7 @@ #include "ED_screen.h" #include "ED_mask.h" #include "ED_clip.h" +#include "ED_keyframing.h" #include "RNA_access.h" #include "RNA_define.h" @@ -770,8 +772,14 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: if (event->val == KM_RELEASE) { + Scene *scene = CTX_data_scene(C); + free_slide_point_data(op->customdata); + if (IS_AUTOKEY_ON(scene)) { + ED_mask_object_shape_auto_key_all(data->mask, CFRA); + } + WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); DAG_id_tag_update(&data->mask->id, 0); diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c index c80ca979077..7a91fbeed13 100755 --- a/source/blender/editors/mask/mask_shapekey.c +++ b/source/blender/editors/mask/mask_shapekey.c @@ -142,3 +142,19 @@ void MASK_OT_shape_key_clear(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +int ED_mask_object_shape_auto_key_all(Mask *mask, const int frame) +{ + MaskObject *maskobj; + int change = FALSE; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskObjectShape *maskobj_shape; + + maskobj_shape = BKE_mask_object_shape_varify_frame(maskobj, frame); + BKE_mask_object_shape_from_mask(maskobj, maskobj_shape); + change = TRUE; + } + + return change; +} diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 7cc8b479517..875e9e4a63f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4913,16 +4913,9 @@ void special_aftertrans_update(bContext *C, TransInfo *t) /* TODO - dont key all masks... */ if (IS_AUTOKEY_ON(t->scene)) { - MaskObject *maskobj; Scene *scene = t->scene; - int frame = CFRA; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskObjectShape *maskobj_shape; - - maskobj_shape = BKE_mask_object_shape_varify_frame(maskobj, frame); - BKE_mask_object_shape_from_mask(maskobj, maskobj_shape); - } + ED_mask_object_shape_auto_key_all(mask, CFRA); } } } From 6fa349f85e8feff90ba00a52b3669e28ea09c223 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 May 2012 15:20:29 +0000 Subject: [PATCH 087/360] support for deleting splines and points while maintaining animation --- source/blender/blenkernel/BKE_mask.h | 2 ++ source/blender/blenkernel/intern/mask.c | 19 ++++++++++--------- source/blender/editors/mask/mask_ops.c | 13 +++++++++++-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 7745eb0b972..fb9db2fcf98 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -115,6 +115,8 @@ int BKE_mask_object_shape_spline_index(struct MaskObject *maskobj, int index, void BKE_mask_object_shape_changed_add(struct MaskObject *maskobj, int index, int do_init, int do_init_interpolate); +void BKE_mask_object_shape_changed_remove(struct MaskObject *maskobj, int index, int count); + /* rasterization */ void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index bc9629176cc..146b67bd15c 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1428,33 +1428,34 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, } } + /* move array to account for removed point */ -void BKE_mask_object_shape_changed_remove(MaskObject *maskobj, int index) +void BKE_mask_object_shape_changed_remove(MaskObject *maskobj, int index, int count) { MaskObjectShape *maskobj_shape; /* the point has already been removed in this array so add one when comparing with the shapes */ - int tot = BKE_mask_object_shape_totvert(maskobj) + 1; + int tot = BKE_mask_object_shape_totvert(maskobj); for (maskobj_shape = maskobj->splines_shapes.first; maskobj_shape; maskobj_shape = maskobj_shape->next) { - if (tot == maskobj_shape->tot_vert) { + if (tot == maskobj_shape->tot_vert - count) { float *data_resized; - maskobj_shape->tot_vert--; + maskobj_shape->tot_vert -= count; data_resized = MEM_mallocN(maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); if (index > 0) { memcpy(data_resized, maskobj_shape->data, - (index - 1) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } - if (index != maskobj_shape->tot_vert - 1) { + if (index != maskobj_shape->tot_vert) { memcpy(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE], - maskobj_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), - (maskobj_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + maskobj_shape->data + ((index + count) * MASK_OBJECT_SHAPE_ELEM_SIZE), + (maskobj_shape->tot_vert - index) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } MEM_freeN(maskobj_shape->data); @@ -1462,7 +1463,7 @@ void BKE_mask_object_shape_changed_remove(MaskObject *maskobj, int index) } else { printf("%s: vert mismatch %d != %d (frame %d)\n", - __func__, maskobj_shape->tot_vert, tot, maskobj_shape->frame); + __func__, maskobj_shape->tot_vert - count, tot, maskobj_shape->frame); } } } diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index e52d673ad9e..69befc16b87 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1305,11 +1305,13 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); MaskObject *maskobj; + int mask_object_shape_ofs = 0; for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline = maskobj->splines.first; while (spline) { + const int tot_point_orig = spline->tot_point; int i, count = 0; MaskSpline *next_spline = spline->next; @@ -1322,6 +1324,7 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) } if (count == 0) { + /* delete the whole spline */ BLI_remlink(&maskobj->splines, spline); BKE_mask_spline_free(spline); @@ -1330,6 +1333,8 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) maskobj->act_spline = NULL; maskobj->act_point = NULL; } + + BKE_mask_object_shape_changed_remove(maskobj, mask_object_shape_ofs, tot_point_orig); } else { MaskSplinePoint *new_points; @@ -1337,7 +1342,7 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) new_points = MEM_callocN(count * sizeof(MaskSplinePoint), "deleteMaskPoints"); - for (i = 0, j = 0; i < spline->tot_point; i++) { + for (i = 0, j = 0; i < tot_point_orig; i++) { MaskSplinePoint *point = &spline->points[i]; if (!MASKPOINT_ISSEL(point)) { @@ -1354,12 +1359,16 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) maskobj->act_point = NULL; BKE_mask_point_free(point); + spline->tot_point--; + + BKE_mask_object_shape_changed_remove(maskobj, mask_object_shape_ofs + j, 1); } } + mask_object_shape_ofs += spline->tot_point; + MEM_freeN(spline->points); spline->points = new_points; - spline->tot_point = j; ED_mask_select_flush_all(mask); } From 10c6a8ce1a803f5d1dacedf3a4030394b5a16e7f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 May 2012 17:44:37 +0000 Subject: [PATCH 088/360] fix for adding/removing spline items with multiple splines in a mask-object --- source/blender/blenkernel/BKE_mask.h | 4 ++++ source/blender/blenkernel/intern/mask.c | 24 +++++++++++++++++++----- source/blender/editors/mask/mask_ops.c | 25 +++++++++---------------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index fb9db2fcf98..21c053e259b 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -110,6 +110,10 @@ struct MaskObjectShape *BKE_mask_object_shape_varify_frame(struct MaskObject *ma void BKE_mask_object_shape_unlink(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape); void BKE_mask_object_shape_sort(struct MaskObject *maskobj); +int BKE_mask_object_shape_spline_from_index(struct MaskObject *maskobj, int index, + struct MaskSpline **r_maskobj_shape, int *r_index); +int BKE_mask_object_shape_spline_to_index(struct MaskObject *maskobj, struct MaskSpline *spline); + int BKE_mask_object_shape_spline_index(struct MaskObject *maskobj, int index, struct MaskSpline **r_maskobj_shape, int *r_index); void BKE_mask_object_shape_changed_add(struct MaskObject *maskobj, int index, diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 146b67bd15c..e5ac03561ad 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1297,8 +1297,8 @@ void BKE_mask_object_shape_sort(MaskObject *maskobj) BLI_sortlist(&maskobj->splines_shapes, mask_object_shape_sort_cb); } -int BKE_mask_object_shape_spline_index(MaskObject *maskobj, int index, - MaskSpline **r_maskobj_shape, int *r_index) +int BKE_mask_object_shape_spline_from_index(MaskObject *maskobj, int index, + MaskSpline **r_maskobj_shape, int *r_index) { MaskSpline *spline; @@ -1314,6 +1314,20 @@ int BKE_mask_object_shape_spline_index(MaskObject *maskobj, int index, return FALSE; } +int BKE_mask_object_shape_spline_to_index(MaskObject *maskobj, MaskSpline *spline) +{ + MaskSpline *spline_iter; + int i_abs = 0; + for (spline_iter = maskobj->splines.first; + spline_iter && spline_iter != spline; + i_abs += spline_iter->tot_point, spline_iter = spline_iter->next) + { + /* pass */ + } + + return i_abs; +} + /* basic 2D interpolation functions, could make more comprehensive later */ static void interp_weights_uv_v2_calc(float r_uv[2], const float pt[2], const float pt_a[2], const float pt_b[2]) { @@ -1347,8 +1361,8 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, MaskSpline *spline; int spline_point_index; - if (BKE_mask_object_shape_spline_index(maskobj, index, - &spline, &spline_point_index)) + if (BKE_mask_object_shape_spline_from_index(maskobj, index, + &spline, &spline_point_index)) { /* sanity check */ /* the point has already been removed in this array so subtract one when comparing with the shapes */ @@ -1402,7 +1416,7 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, mask_object_shape_from_mask_point(&spline->points[spline_point_index].bezt, fp); - if (do_init_interpolate) { + if (do_init_interpolate && spline->tot_point > 2) { for (i = 0; i < 3; i++) { interp_weights_uv_v2_apply(uv[i], &fp[i * 2], diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 69befc16b87..ba027a47802 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -980,22 +980,8 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) setup_vertex_point(C, mask, spline, new_point, co, tangent, NULL, TRUE); - - { - - /* this block could be a function */ - MaskSpline *spline_iter; - int i_abs = 0; - for (spline_iter = maskobj->splines.first; - spline_iter && spline_iter != spline; - spline_iter = spline_iter->next, i_abs += spline_iter->tot_point) - { - /* pass */ - } - - /* TODO - we could pass the spline! */ - BKE_mask_object_shape_changed_add(maskobj, i_abs + point_index + 1, TRUE, TRUE); - } + /* TODO - we could pass the spline! */ + BKE_mask_object_shape_changed_add(maskobj, BKE_mask_object_shape_spline_to_index(maskobj, spline) + point_index + 1, TRUE, TRUE); maskobj->act_point = new_point; @@ -1114,6 +1100,13 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) maskobj->act_point = new_point; setup_vertex_point(C, mask, spline, new_point, co, NULL, ref_point, FALSE); + + { + //int point_index = (((int)(new_point - spline->points) + 1) % spline->tot_point); + int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); + BKE_mask_object_shape_changed_add(maskobj, BKE_mask_object_shape_spline_to_index(maskobj, spline) + point_index, TRUE, TRUE); + } + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return TRUE; From 3595db735057b9153463ccdf4b568d6fdc9798f0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 26 May 2012 23:18:07 +0000 Subject: [PATCH 089/360] draw the mask keyframes in the clip view --- source/blender/editors/space_clip/clip_draw.c | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index c0ac262d996..337b21465a3 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -33,12 +33,14 @@ #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" /* SELECT */ +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" #include "BKE_context.h" #include "BKE_movieclip.h" #include "BKE_tracking.h" +#include "BKE_mask.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -194,6 +196,32 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc glRecti(x, 0, x + framelen, 8); clip_draw_curfra_label(sc, x, 8.0f); + + /* movie clip animation */ + if ((sc->mode == SC_MODE_MASKEDITING) && sc->mask) { + MaskObject *maskobj = BKE_mask_object_active(sc->mask); + if (maskobj) { + MaskObjectShape *maskobj_shape; + + glColor4ub(255, 255, 0, 96); + glBegin(GL_LINES); + + for (maskobj_shape = maskobj->splines_shapes.first; + maskobj_shape; + maskobj_shape = maskobj_shape->next) + { + i = maskobj_shape->frame; + + /* glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 4); */ + + /* use a line so we always see the keyframes */ + glVertex2i((i - sfra) * framelen, 0); + glVertex2i((i - sfra) * framelen, 4); + } + + glEnd(); + } + } } static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar) From e7ba0100c7d9254e2220ef6ca484883db40910bd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 27 May 2012 10:35:12 +0000 Subject: [PATCH 090/360] tweaks to frame drawing from sebastian-k --- source/blender/editors/space_clip/clip_draw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 337b21465a3..fd47bc376c7 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -203,7 +203,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc if (maskobj) { MaskObjectShape *maskobj_shape; - glColor4ub(255, 255, 0, 96); + glColor4ub(255, 175, 0, 255); glBegin(GL_LINES); for (maskobj_shape = maskobj->splines_shapes.first; @@ -216,7 +216,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc /* use a line so we always see the keyframes */ glVertex2i((i - sfra) * framelen, 0); - glVertex2i((i - sfra) * framelen, 4); + glVertex2i((i - sfra) * framelen, (i == CFRA) ? 22 : 10); } glEnd(); From 1edf40594d3d693ec0d67173604641b7ad8740b8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 27 May 2012 12:59:16 +0000 Subject: [PATCH 091/360] up-down arrow keys now jump between mask keyframes (when in the mask view). --- .../editors/animation/keyframes_draw.c | 68 +++++++++++++++++++ .../editors/include/ED_keyframes_draw.h | 4 ++ source/blender/editors/screen/screen_ops.c | 14 +++- source/blender/makesdna/DNA_mask_types.h | 2 + 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index cb7dc7ac206..579527dfc56 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -60,6 +60,7 @@ #include "DNA_speaker_types.h" #include "DNA_world_types.h" #include "DNA_gpencil_types.h" +#include "DNA_mask_types.h" #include "BKE_key.h" #include "BKE_material.h" @@ -184,6 +185,50 @@ static void nupdate_ak_gpframe(void *node, void *data) ak->modified += 1; } +/* ......... */ + +/* Comparator callback used for ActKeyColumns and GPencil frame */ +static short compare_ak_maskobjshape(void *node, void *data) +{ + ActKeyColumn *ak = (ActKeyColumn *)node; + MaskObjectShape *maskobj_shape = (MaskObjectShape *)data; + + if (maskobj_shape->frame < ak->cfra) + return -1; + else if (maskobj_shape->frame > ak->cfra) + return 1; + else + return 0; +} + +/* New node callback used for building ActKeyColumns from GPencil frames */ +static DLRBT_Node *nalloc_ak_maskobjshape(void *data) +{ + ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF"); + MaskObjectShape *maskobj_shape = (MaskObjectShape *)data; + + /* store settings based on state of BezTriple */ + ak->cfra = maskobj_shape->frame; + ak->sel = (maskobj_shape->flag & SELECT) ? SELECT : 0; + + /* set 'modified', since this is used to identify long keyframes */ + ak->modified = 1; + + return (DLRBT_Node *)ak; +} + +/* Node updater callback used for building ActKeyColumns from GPencil frames */ +static void nupdate_ak_maskobjshape(void *node, void *data) +{ + ActKeyColumn *ak = (ActKeyColumn *)node; + MaskObjectShape *maskobj_shape = (MaskObjectShape *)data; + + /* set selection status and 'touched' status */ + if (maskobj_shape->flag & SELECT) ak->sel = SELECT; + ak->modified += 1; +} + + /* --------------- */ /* Add the given BezTriple to the given 'list' of Keyframes */ @@ -204,6 +249,15 @@ static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf) BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf); } +/* Add the given MaskObjectShape Frame to the given 'list' of Keyframes */ +static void add_maskobj_to_keycolumns_list(DLRBT_Tree *keys, MaskObjectShape *maskobj_shape) +{ + if (ELEM(NULL, keys, maskobj_shape)) + return; + else + BLI_dlrbTree_add(keys, compare_ak_maskobjshape, nalloc_ak_maskobjshape, nupdate_ak_maskobjshape, maskobj_shape); +} + /* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */ /* maximum size of default buffer for BezTriple columns */ @@ -940,3 +994,17 @@ void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys) } } +void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskObject *maskobj, DLRBT_Tree *keys) +{ + MaskObjectShape *maskobj_shape; + + if (maskobj && keys) { + for (maskobj_shape = maskobj->splines_shapes.first; + maskobj_shape; + maskobj_shape = maskobj_shape->next) + { + add_maskobj_to_keycolumns_list(keys, maskobj_shape); + } + } +} + diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index cd64427de78..d90b5648c23 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -42,6 +42,7 @@ struct bActionGroup; struct Object; struct ListBase; struct bGPDlayer; +struct MaskObject; struct Scene; struct View2D; struct DLRBT_Tree; @@ -139,6 +140,9 @@ void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, struct /* Grease Pencil Layer */ // XXX not restored void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys); +/* Mask */ +// XXX not restored +void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskObject *maskobj, struct DLRBT_Tree *keys); /* ActKeyColumn API ---------------- */ /* Comparator callback used for ActKeyColumns and cframe float-value pointer */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index becb82767e9..7caff30807d 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -46,6 +46,7 @@ #include "DNA_scene_types.h" #include "DNA_meta_types.h" #include "DNA_mesh_types.h" +#include "DNA_mask_types.h" #include "DNA_userdef_types.h" #include "BKE_context.h" @@ -59,6 +60,7 @@ #include "BKE_screen.h" #include "BKE_tessmesh.h" #include "BKE_sound.h" +#include "BKE_mask.h" #include "WM_api.h" #include "WM_types.h" @@ -1945,7 +1947,17 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) if (ob) ob_to_keylist(&ads, ob, &keys, NULL); - + + { + SpaceClip *sc = CTX_wm_space_clip(C); + if (sc) { + if ((sc->mode == SC_MODE_MASKEDITING) && sc->mask) { + MaskObject *maskobj = BKE_mask_object_active(sc->mask); + mask_to_keylist(&ads, maskobj, &keys); + } + } + } + /* build linked-list for searching */ BLI_dlrbTree_linkedlist_sync(&keys); diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index 9f163adc77b..441b15a8aa9 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -92,6 +92,8 @@ typedef struct MaskObjectShape { float *data; /* u coordinate along spline segment and weight of this point */ int tot_vert; /* to ensure no buffer overruns's: alloc size is (tot_vert * MASK_OBJECT_SHAPE_ELEM_SIZE) */ int frame; /* different flags of this point */ + char flag; + char pad[7]; } MaskObjectShape; typedef struct MaskObject { From aab3f71b9db40f9d5b14ae86727bb64c2de3d827 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 27 May 2012 16:59:36 +0000 Subject: [PATCH 092/360] Fix threading issue with Mask node --- source/blender/compositor/operations/COM_MaskOperation.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index 7c71e884e5c..e6456e73be3 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -69,9 +69,12 @@ void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers if (this->rasterizedMask == NULL) { int width = this->getWidth(); int height = this->getHeight(); + float *buffer; - this->rasterizedMask = (float *)MEM_callocN(sizeof(float) * width * height, "rasterized mask"); - BKE_mask_rasterize(mask, width, height, this->rasterizedMask); + buffer = (float *)MEM_callocN(sizeof(float) * width * height, "rasterized mask"); + BKE_mask_rasterize(mask, width, height, buffer); + + this->rasterizedMask = buffer; } BLI_mutex_unlock(getMutex()); From 8fb7b4073ec0f73d41e2d0dc0325c699d8067b86 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 28 May 2012 05:37:16 +0000 Subject: [PATCH 093/360] make selection operator follow mesh selection options from trunk. --- source/blender/blenkernel/BKE_mask.h | 4 + source/blender/blenkernel/intern/mask.c | 32 ++++++++ source/blender/editors/mask/mask_editor.c | 11 ++- source/blender/editors/mask/mask_intern.h | 3 +- source/blender/editors/mask/mask_ops.c | 2 +- source/blender/editors/mask/mask_select.c | 89 +++++++++++++---------- 6 files changed, 97 insertions(+), 44 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 21c053e259b..9c944a98564 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -73,6 +73,9 @@ float BKE_mask_point_weight(struct MaskSpline *spline, struct MaskSplinePoint *p struct MaskSplinePointUW *BKE_mask_point_sort_uw(struct MaskSplinePoint *point, struct MaskSplinePointUW *uw); void BKE_mask_point_add_uw(struct MaskSplinePoint *point, float u, float w); +void BKE_mask_point_select_set(struct MaskSplinePoint *point, int select); +void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, int select); + /* general */ struct Mask *BKE_mask_new(const char *name); @@ -134,5 +137,6 @@ void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer) #define MASKPOINT_HANDLE_ONLY_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) && (((p)->bezt.f2 & SELECT) == 0) ) #define MASKPOINT_HANDLE_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) ) #define MASKPOINT_HANDLE_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 +#define MASKPOINT_HANDLE_DESEL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 #endif diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index e5ac03561ad..ec01f303bae 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -41,6 +41,7 @@ #include "DNA_mask_types.h" #include "DNA_scene_types.h" +#include "DNA_object_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_movieclip_types.h" @@ -618,6 +619,37 @@ void BKE_mask_point_add_uw(MaskSplinePoint *point, float u, float w) BKE_mask_point_sort_uw(point, &point->uw[point->tot_uw - 1]); } +void BKE_mask_point_select_set(MaskSplinePoint *point, int select) +{ + int i; + + if (select) { + MASKPOINT_SEL(point); + } + else { + MASKPOINT_DESEL(point); + } + + for (i = 0; i < point->tot_uw; i++) { + if (select) { + point->uw[i].flag |= SELECT; + } + else { + point->uw[i].flag &= ~SELECT; + } + } +} + +void BKE_mask_point_select_set_handle(MaskSplinePoint *point, int select) +{ + if (select) { + MASKPOINT_HANDLE_SEL(point); + } + else { + MASKPOINT_HANDLE_DESEL(point); + } +} + /* only mask block itself */ static Mask *mask_alloc(const char *name) { diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index 749c2c0237e..0290934cf9a 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -189,10 +189,15 @@ void ED_keymap_mask(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MASK_OT_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MASK_OT_delete", DELKEY, KM_PRESS, 0, 0); - /* select */ - WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + /* selection */ + kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + RNA_boolean_set(kmi->ptr, "toggle", FALSE); kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + RNA_boolean_set(kmi->ptr, "toggle", TRUE); kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", AKEY, KM_PRESS, 0, 0); RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index fee4b63529d..d6392b07a80 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -73,7 +73,8 @@ void MASK_OT_select_all(struct wmOperatorType *ot); int ED_mask_spline_select_check(struct MaskSplinePoint *points, int tot_point); int ED_mask_select_check(struct Mask *mask); -void ED_mask_point_select(struct MaskSplinePoint *point, int action); +void ED_mask_point_select_set(struct MaskSplinePoint *point, int action); +void ED_mask_point_select_set_handle(struct MaskSplinePoint *point, int select); void ED_mask_select_toggle_all(struct Mask *mask, int action); void ED_mask_select_flush_all(struct Mask *mask); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index ba027a47802..365b3fc31c7 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -646,7 +646,7 @@ static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) else if (!MASKPOINT_ISSEL(slidedata->point)) { ED_mask_select_toggle_all(mask, SEL_DESELECT); - ED_mask_point_select(slidedata->point, SEL_SELECT); + BKE_mask_point_select_set(slidedata->point, TRUE); ED_mask_select_flush_all(mask); } diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index f1ee620e2ce..67df1d458db 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -86,38 +86,6 @@ int ED_mask_select_check(Mask *mask) return FALSE; } -void ED_mask_point_select(MaskSplinePoint *point, int action) -{ - int i; - - switch (action) { - case SEL_SELECT: - MASKPOINT_SEL(point); - break; - case SEL_DESELECT: - MASKPOINT_DESEL(point); - break; - case SEL_INVERT: - MASKPOINT_INVSEL(point); - break; - } - - for (i = 0; i < point->tot_uw; i++) { - switch (action) { - case SEL_SELECT: - point->uw[i].flag |= SELECT; - break; - case SEL_DESELECT: - point->uw[i].flag &= ~SELECT; - break; - case SEL_INVERT: - point->uw[i].flag ^= SELECT; - break; - } - } -} - - void ED_mask_select_toggle_all(Mask *mask, int action) { MaskObject *maskobj; @@ -138,7 +106,7 @@ void ED_mask_select_toggle_all(Mask *mask, int action) for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; - ED_mask_point_select(point, action); + BKE_mask_point_select_set(point, (action == SEL_SELECT) ? TRUE : FALSE); } } } @@ -219,7 +187,10 @@ static int select_exec(bContext *C, wmOperator *op) MaskSpline *spline; MaskSplinePoint *point = NULL; float co[2]; - int extend = RNA_boolean_get(op->ptr, "extend"); + short extend = RNA_boolean_get(op->ptr, "extend"); + short deselect = RNA_boolean_get(op->ptr, "deselect"); + short toggle = RNA_boolean_get(op->ptr, "toggle"); + int is_handle = 0; const float threshold = 19; @@ -228,14 +199,52 @@ static int select_exec(bContext *C, wmOperator *op) point = ED_mask_point_find_nearest(C, mask, co, threshold, &maskobj, &spline, &is_handle, NULL); if (point) { - if (!extend) + if (extend == 0 && deselect == 0 && toggle == 0) ED_mask_select_toggle_all(mask, SEL_DESELECT); if (is_handle) { - MASKPOINT_HANDLE_SEL(point); + if (extend) { + maskobj->act_spline = spline; + maskobj->act_point = point; + + BKE_mask_point_select_set_handle(point, TRUE); + } + else if (deselect) { + BKE_mask_point_select_set_handle(point, FALSE); + } + else { + maskobj->act_spline = spline; + maskobj->act_point = point; + + if (!MASKPOINT_HANDLE_ISSEL(point)) { + BKE_mask_point_select_set_handle(point, TRUE); + } + else if (toggle) { + BKE_mask_point_select_set_handle(point, FALSE); + } + } } else { - ED_mask_point_select(point, SEL_SELECT); + if (extend) { + maskobj->act_spline = spline; + maskobj->act_point = point; + + BKE_mask_point_select_set(point, TRUE); + } + else if (deselect) { + BKE_mask_point_select_set(point, FALSE); + } + else { + maskobj->act_spline = spline; + maskobj->act_point = point; + + if (!MASKPOINT_ISSEL(point)) { + BKE_mask_point_select_set(point, TRUE); + } + else if (toggle) { + BKE_mask_point_select_set(point, FALSE); + } + } } maskobj->act_spline = spline; @@ -298,8 +307,10 @@ void MASK_OT_select(wmOperatorType *ot) ot->flag = OPTYPE_UNDO; /* properties */ - RNA_def_boolean(ot->srna, "extend", 0, - "Extend", "Extend selection rather than clearing the existing selection"); + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first"); + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from selection"); + RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Selection", "Toggles selection"); + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, "Location", "Location of vertex in normalized space", -1.0f, 1.0f); } From 8ab667c17491c16573289471fea3647830b589f5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 28 May 2012 09:53:59 +0000 Subject: [PATCH 094/360] many small improvements to adding points - splines are open by default (double ctrl+click closes them) - adding new points can be done even when a point in the middle of the spline is selected. - adding new points re-orients the handles of previous point. - fix for crash with open curve with one point only. Workflow is Ctrl+Click about and double click to finish - works fast and gives nicer result then before. --- source/blender/blenkernel/BKE_mask.h | 4 +- source/blender/blenkernel/intern/mask.c | 52 ++++- source/blender/editors/mask/mask_intern.h | 2 - source/blender/editors/mask/mask_ops.c | 224 +++++++++++++++++----- 4 files changed, 222 insertions(+), 60 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 9c944a98564..963b5a8e0ba 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -91,8 +91,10 @@ void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime, const int do_n void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene, const int do_newframe); void BKE_mask_parent_init(struct MaskParent *parent); void BKE_mask_calc_handle_adjacent_length(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point); +void BKE_mask_calc_tangent_polyline(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, float t[2]); void BKE_mask_calc_handle_point(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point); -void BKE_mask_calc_handle_point_auto(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point); +void BKE_mask_calc_handle_point_auto(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, + const short do_recalc_length); void BKE_mask_get_handle_point_adjacent(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, struct MaskSplinePoint **r_point_prev, struct MaskSplinePoint **r_point_next); void BKE_mask_calc_handles(struct Mask *mask); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index ec01f303bae..24804ff3e5a 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -123,7 +123,7 @@ MaskSpline *BKE_mask_spline_add(MaskObject *maskobj) spline->tot_point = 1; /* cyclic shapes are more usually used */ - spline->flag |= MASK_SPLINE_CYCLIC; + // spline->flag |= MASK_SPLINE_CYCLIC; // disable because its not so nice for drawing. could be done differently spline->weight_interp = MASK_SPLINE_INTERP_LINEAR; @@ -855,7 +855,9 @@ static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *prev next_bezt = &next_point->bezt; #if 1 - BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0); + if (prev_bezt || next_bezt) { + BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0); + } #else if (handle_type == HD_VECT) { BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0); @@ -922,6 +924,37 @@ void BKE_mask_get_handle_point_adjacent(Mask *UNUSED(mask), MaskSpline *spline, *r_point_next = next_point; } +/* calculates the tanget of a point by its previous and next + * (ignoring handles - as if its a poly line) */ +void BKE_mask_calc_tangent_polyline(Mask *mask, MaskSpline *spline, MaskSplinePoint *point, float t[2]) +{ + float tvec_a[2], tvec_b[2]; + + MaskSplinePoint *prev_point, *next_point; + + BKE_mask_get_handle_point_adjacent(mask, spline, point, + &prev_point, &next_point); + + if (prev_point) { + sub_v2_v2v2(tvec_a, point->bezt.vec[1], prev_point->bezt.vec[1]); + normalize_v2(tvec_a); + } + else { + zero_v2(tvec_a); + } + + if (next_point) { + sub_v2_v2v2(tvec_b, next_point->bezt.vec[1], point->bezt.vec[1]); + normalize_v2(tvec_b); + } + else { + zero_v2(tvec_b); + } + + add_v2_v2v2(t, tvec_a, tvec_b); + normalize_v2(t); +} + void BKE_mask_calc_handle_point(Mask *mask, MaskSpline *spline, MaskSplinePoint *point) { MaskSplinePoint *prev_point, *next_point; @@ -945,7 +978,7 @@ static void enforce_dist_v2_v2fl(float v1[2], const float v2[2], const float dis void BKE_mask_calc_handle_adjacent_length(Mask *mask, MaskSpline *spline, MaskSplinePoint *point) { - /* TODO! - make this aspect aware! */ + /* TODO! - make this interpolate between siblings - not always midpoint! */ int length_tot = 0; float length_average = 0.0f; @@ -977,11 +1010,14 @@ void BKE_mask_calc_handle_adjacent_length(Mask *mask, MaskSpline *spline, MaskSp * * Useful for giving sane defaults. */ -void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplinePoint *point) +void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplinePoint *point, + const short do_recalc_length) { - /* TODO! - make this aspect aware! */ MaskSplinePoint *prev_point, *next_point; const char h_back[2] = {point->bezt.h1, point->bezt.h2}; + const float length_average = (do_recalc_length) ? 0.0f /* dummy value */ : + (len_v3v3(point->bezt.vec[0], point->bezt.vec[1]) + + len_v3v3(point->bezt.vec[1], point->bezt.vec[2])) / 2.0f; BKE_mask_get_handle_point_adjacent(mask, spline, point, &prev_point, &next_point); @@ -992,6 +1028,12 @@ void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplineP point->bezt.h1 = h_back[0]; point->bezt.h2 = h_back[1]; + + /* preserve length by applying it back */ + if (do_recalc_length == FALSE) { + enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average); + enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average); + } } void BKE_mask_calc_handles(Mask *mask) diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index d6392b07a80..4eab64b2bcd 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -73,8 +73,6 @@ void MASK_OT_select_all(struct wmOperatorType *ot); int ED_mask_spline_select_check(struct MaskSplinePoint *points, int tot_point); int ED_mask_select_check(struct Mask *mask); -void ED_mask_point_select_set(struct MaskSplinePoint *point, int action); -void ED_mask_point_select_set_handle(struct MaskSplinePoint *point, int select); void ED_mask_select_toggle_all(struct Mask *mask, int action); void ED_mask_select_flush_all(struct Mask *mask); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 365b3fc31c7..1e46b893dcd 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -301,7 +301,7 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in return FALSE; } -static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], int threshold, int feather, +static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_co[2], int threshold, int feather, MaskObject **maskobj_r, MaskSpline **spline_r, MaskSplinePoint **point_r, float *u_r, float tangent[2]) { @@ -937,7 +937,7 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask add_v2_v2(bezt->vec[0], vec); sub_v2_v2(bezt->vec[2], vec); #else - BKE_mask_calc_handle_point_auto(mask, spline, new_point); + BKE_mask_calc_handle_point_auto(mask, spline, new_point, TRUE); BKE_mask_calc_handle_adjacent_length(mask, spline, new_point); #endif @@ -952,7 +952,22 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask /* **** add subdivide vertex **** */ -static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) +static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index) +{ + MaskSplinePoint *new_point_array; + + new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); + + memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1)); + memcpy(new_point_array + point_index + 2, spline->points + point_index + 1, + sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1)); + + MEM_freeN(spline->points); + spline->points = new_point_array; + spline->tot_point++; +} + +static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2]) { MaskObject *maskobj; MaskSpline *spline; @@ -961,22 +976,14 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2]) float tangent[2]; if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &maskobj, &spline, &point, NULL, tangent)) { - MaskSplinePoint *new_point_array, *new_point; + MaskSplinePoint *new_point; int point_index = point - spline->points; ED_mask_select_toggle_all(mask, SEL_DESELECT); - new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); + mask_spline_add_point_at_index(spline, point_index); - memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1)); - memcpy(new_point_array + point_index + 2, spline->points + point_index + 1, - sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1)); - - MEM_freeN(spline->points); - spline->points = new_point_array; - spline->tot_point++; - - new_point = &new_point_array[point_index + 1]; + new_point = &spline->points[point_index + 1]; setup_vertex_point(C, mask, spline, new_point, co, tangent, NULL, TRUE); @@ -1036,7 +1043,110 @@ static void finSelectedSplinePoint(MaskObject *maskobj, MaskSpline **spline, Mas } } -static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) +static int add_vertex_extrude(bContext *C, Mask *mask, const float co[2]) +{ + MaskObject *maskobj; + MaskSpline *spline; + MaskSplinePoint *point; + MaskSplinePoint *new_point = NULL, *ref_point = NULL; + + /* check on which side we want to add the point */ + int point_index; + float tangent_point[2]; + float tangent_co[2]; + int do_cyclic_correct = FALSE; + int do_recalc_src = FALSE; /* when extruding from endpoints only */ + int do_prev; /* use prev point rather then next?? */ + + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + maskobj = BKE_mask_object_active(mask); + + if (!maskobj) { + return FALSE; + } + else { + finSelectedSplinePoint(maskobj, &spline, &point, TRUE); + } + + point_index = (point - spline->points); + + MASKPOINT_DESEL(point); + + if ((spline->flag & MASK_SPLINE_CYCLIC) || + (point_index > 0 && point_index != spline->tot_point - 1)) + { + BKE_mask_calc_tangent_polyline(mask, spline, point, tangent_point); + sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]); + + if (dot_v2v2(tangent_point, tangent_co) < 0.0f) { + do_prev = TRUE; + } + else { + do_prev = FALSE; + } + } + else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == 0)) { + do_prev = TRUE; + do_recalc_src = TRUE; + } + else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == spline->tot_point - 1)) { + do_prev = FALSE; + do_recalc_src = TRUE; + } + else { + /* should never get here */ + BLI_assert(0); + } + + /* use the point before the active one */ + if (do_prev) { + point_index--; + if (point_index < 0) { + point_index += spline->tot_point; /* wrap index */ + if ((spline->flag & MASK_SPLINE_CYCLIC) == 0) { + do_cyclic_correct = TRUE; + point_index = 0; + } + } + } + +// print_v2("", tangent_point); +// printf("%d\n", point_index); + + mask_spline_add_point_at_index(spline, point_index); + + if (do_cyclic_correct) { + ref_point = &spline->points[point_index + 1]; + new_point = &spline->points[point_index]; + *ref_point = *new_point; + memset(new_point, 0, sizeof(*new_point)); + } + else { + ref_point = &spline->points[point_index]; + new_point = &spline->points[point_index + 1]; + } + + maskobj->act_point = new_point; + + setup_vertex_point(C, mask, spline, new_point, co, NULL, ref_point, FALSE); + + if (maskobj->splines_shapes.first) { + point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); + BKE_mask_object_shape_changed_add(maskobj, BKE_mask_object_shape_spline_to_index(maskobj, spline) + point_index, TRUE, TRUE); + } + + if (do_recalc_src) { + /* TODO, update keyframes in time */ + BKE_mask_calc_handle_point_auto(mask, spline, ref_point, FALSE); + } + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return TRUE; +} + +static int add_vertex_new(bContext *C, Mask *mask, const float co[2]) { MaskObject *maskobj; MaskSpline *spline; @@ -1061,48 +1171,16 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) if (!spline) { /* no selected splines in active maskobj, create new spline */ spline = BKE_mask_spline_add(maskobj); - maskobj->act_spline = spline; - new_point = spline->points; } - if (!new_point) { - MaskSplinePoint *new_point_array; - - if (point == &spline->points[spline->tot_point - 1]) { - MASKPOINT_DESEL(point); - new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); - memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * spline->tot_point); - MEM_freeN(spline->points); - spline->points = new_point_array; - spline->tot_point++; - - new_point = &spline->points[spline->tot_point - 1]; - ref_point = &spline->points[spline->tot_point - 2]; - } - else if (point == &spline->points[0]) { - MASKPOINT_DESEL(point); - new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); - memcpy(new_point_array + 1, spline->points, sizeof(MaskSplinePoint) * spline->tot_point); - MEM_freeN(spline->points); - spline->points = new_point_array; - spline->tot_point++; - - new_point = &spline->points[0]; - ref_point = &spline->points[1]; - } - else { - spline = BKE_mask_spline_add(maskobj); - maskobj->act_spline = spline; - new_point = spline->points; - } - } + maskobj->act_spline = spline; + new_point = spline->points; maskobj->act_point = new_point; setup_vertex_point(C, mask, spline, new_point, co, NULL, ref_point, FALSE); { - //int point_index = (((int)(new_point - spline->points) + 1) % spline->tot_point); int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); BKE_mask_object_shape_changed_add(maskobj, BKE_mask_object_shape_spline_to_index(maskobj, spline) + point_index, TRUE, TRUE); } @@ -1115,13 +1193,55 @@ static int add_vertex_extrude(bContext *C, Mask *mask, float co[2]) static int add_vertex_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); + MaskObject *maskobj; + float co[2]; + maskobj = BKE_mask_object_active(mask); + RNA_float_get_array(op->ptr, "location", co); - if (!add_vertex_subdivide(C, mask, co)) { - if (!add_vertex_extrude(C, mask, co)) - return OPERATOR_CANCELLED; + if (maskobj && maskobj->act_point && MASKPOINT_ISSEL(maskobj->act_point)) { + + /* cheap trick - double click for cyclic */ + MaskSpline *spline = maskobj->act_spline; + MaskSplinePoint *point = maskobj->act_point; + + int is_sta = (point == spline->points); + int is_end = (point == &spline->points[spline->tot_point - 1]); + + /* then check are we overlapping the mouse */ + if ((is_sta || is_end) && equals_v2v2(co, point->bezt.vec[1])) { + if (spline->flag & MASK_SPLINE_CYCLIC) { + /* nothing to do */ + return OPERATOR_CANCELLED; + } + else { + /* recalc the connecting point as well to make a nice even curve */ + MaskSplinePoint *point_other = is_end ? spline->points : &spline->points[spline->tot_point - 1]; + spline->flag |= MASK_SPLINE_CYCLIC; + + /* TODO, update keyframes in time */ + BKE_mask_calc_handle_point_auto(mask, spline, point, FALSE); + BKE_mask_calc_handle_point_auto(mask, spline, point_other, FALSE); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + return OPERATOR_FINISHED; + } + } + + if (!add_vertex_subdivide(C, mask, co)) { + if (!add_vertex_extrude(C, mask, co)) { + return OPERATOR_CANCELLED; + } + } + } + else { + if (!add_vertex_subdivide(C, mask, co)) { + if (!add_vertex_new(C, mask, co)) { + return OPERATOR_CANCELLED; + } + } } return OPERATOR_FINISHED; From b9d1830d77fbbef2f616f648f688389ef05e7d06 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 29 May 2012 06:31:42 +0000 Subject: [PATCH 095/360] check for parent before applying offset --- source/blender/blenkernel/intern/mask.c | 33 +++++++++++++++---------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 24804ff3e5a..e9937cbc617 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -812,13 +812,13 @@ void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_c } } -static void evaluate_mask_parent(MaskParent *parent, float ctime, float r_co[2]) +static int evaluate_mask_parent(MaskParent *parent, float ctime, float r_co[2]) { if (!parent) - return; + return FALSE; if ((parent->flag & MASK_PARENT_ACTIVE) == 0) - return; + return FALSE; if (parent->id_type == ID_MC) { if (parent->id) { @@ -836,10 +836,14 @@ static void evaluate_mask_parent(MaskParent *parent, float ctime, float r_co[2]) MovieTrackingMarker *marker = BKE_tracking_get_marker(track, ctime); BKE_mask_coord_from_movieclip(clip, &user, r_co, marker->pos); add_v2_v2(r_co, parent->offset); + + return TRUE; } } } } + + return FALSE; } static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *prev_point, MaskSplinePoint *next_point) @@ -979,7 +983,7 @@ static void enforce_dist_v2_v2fl(float v1[2], const float v2[2], const float dis void BKE_mask_calc_handle_adjacent_length(Mask *mask, MaskSpline *spline, MaskSplinePoint *point) { /* TODO! - make this interpolate between siblings - not always midpoint! */ - int length_tot = 0; + int length_tot = 0; float length_average = 0.0f; MaskSplinePoint *prev_point, *next_point; @@ -1098,16 +1102,19 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) for (spline = maskobj->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; - BezTriple *bezt = &point->bezt; - float co[2], delta[2]; + float co[2]; - copy_v2_v2(co, bezt->vec[1]); - evaluate_mask_parent(&point->parent, ctime, co); - sub_v2_v2v2(delta, co, bezt->vec[1]); + if (evaluate_mask_parent(&point->parent, ctime, co)) { + BezTriple *bezt = &point->bezt; + float delta[2]; - add_v2_v2(bezt->vec[0], delta); - add_v2_v2(bezt->vec[1], delta); - add_v2_v2(bezt->vec[2], delta); + copy_v2_v2(co, bezt->vec[1]); + sub_v2_v2v2(delta, co, bezt->vec[1]); + + add_v2_v2(bezt->vec[0], delta); + add_v2_v2(bezt->vec[1], delta); + add_v2_v2(bezt->vec[2], delta); + } } } } @@ -1220,7 +1227,7 @@ void BKE_mask_object_shape_to_mask(MaskObject *maskobj, MaskObjectShape *maskobj } BLI_INLINE void interp_v2_v2v2_flfl(float target[2], const float a[2], const float b[2], - const float t, const float s) + const float t, const float s) { target[0] = s * a[0] + t * b[0]; target[1] = s * a[1] + t * b[1]; From edad58c5b17835b598b824cc0726a6e269e54ee8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 29 May 2012 08:55:16 +0000 Subject: [PATCH 096/360] initial support for animating parented mask points. --- source/blender/blenkernel/BKE_mask.h | 3 + source/blender/blenkernel/intern/mask.c | 172 +++++++++++++++--- source/blender/blenloader/intern/writefile.c | 5 + source/blender/editors/mask/mask_draw.c | 28 ++- source/blender/editors/mask/mask_ops.c | 11 +- .../blender/editors/mask/mask_relationships.c | 1 + source/blender/makesdna/DNA_mask_types.h | 3 + 7 files changed, 187 insertions(+), 36 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 963b5a8e0ba..5020fd97895 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -39,6 +39,9 @@ struct MovieClip; struct MovieClipUser; struct Scene; +struct MaskSplinePoint *BKE_mask_spline_point_array(struct MaskSpline *spline); +struct MaskSplinePoint *BKE_mask_spline_point_array_from_point(struct MaskSpline *spline, struct MaskSplinePoint *point_ref); + /* mask objects */ struct MaskObject *BKE_mask_object_new(struct Mask *mask, const char *name); struct MaskObject *BKE_mask_object_active(struct Mask *mask); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index e9937cbc617..566c0920bbf 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -58,6 +58,25 @@ #include "raskter.h" +MaskSplinePoint *BKE_mask_spline_point_array(MaskSpline *spline) +{ + return spline->points_deform ? spline->points_deform : spline->points; +} + +MaskSplinePoint *BKE_mask_spline_point_array_from_point(MaskSpline *spline, MaskSplinePoint *point_ref) +{ + if ((point_ref >= spline->points) && (point_ref < &spline->points[spline->tot_point])) { + return spline->points; + } + + if ((point_ref >= spline->points_deform) && (point_ref < &spline->points_deform[spline->tot_point])) { + return spline->points_deform; + } + + BLI_assert(!"wrong array"); + return NULL; +} + /* mask objects */ MaskObject *BKE_mask_object_new(Mask *mask, const char *name) @@ -201,6 +220,8 @@ int BKE_mask_spline_feather_resolution(MaskSpline *spline) float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + MaskSplinePoint *point, *prev; float *diff_points, *fp; int a, len, resol = BKE_mask_spline_resolution(spline); @@ -227,7 +248,7 @@ float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) if (spline->flag & MASK_SPLINE_CYCLIC) a++; - prev = spline->points; + prev = points_array; point = prev + 1; while (a--) { @@ -236,7 +257,7 @@ float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) int j; if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC)) - point = spline->points; + point = points_array; prevbezt = &prev->bezt; bezt = &point->bezt; @@ -262,6 +283,8 @@ float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) float *BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + float *feather, *fp; int i, j, tot, resol = BKE_mask_spline_feather_resolution(spline); @@ -269,7 +292,7 @@ float *BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *to feather = fp = MEM_callocN(2 * tot * sizeof(float), "mask spline feather diff points"); for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point = &points_array[i]; for (j = 0; j < resol; j++, fp += 2) { float u = (float) j / resol, weight; @@ -291,12 +314,14 @@ float *BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *to float *BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + int i, tot = 0; float *feather, *fp; /* count */ for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point = &points_array[i]; tot += point->tot_uw + 1; } @@ -305,7 +330,7 @@ float *BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point feather = fp = MEM_callocN(2 * tot * sizeof(float), "mask spline feather points"); for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point = &points_array[i]; BezTriple *bezt = &point->bezt; float weight, n[2]; int j; @@ -431,15 +456,17 @@ float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint * float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_diff_point) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); + BezTriple *bezt, *next; float *diff_points, *fp; int j, resol = BKE_mask_spline_resolution(spline); bezt = &point->bezt; - if (point == &spline->points[spline->tot_point - 1]) { + if (point == &points_array[spline->tot_point - 1]) { if (spline->flag & MASK_SPLINE_CYCLIC) - next = &(spline->points[0].bezt); + next = &(points_array[0].bezt); else next = NULL; } @@ -465,12 +492,14 @@ float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, i void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float u, float co[2]) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); + BezTriple *bezt = &point->bezt, *next; float q0[2], q1[2], q2[2], r0[2], r1[2]; - if (point == &spline->points[spline->tot_point - 1]) { + if (point == &points_array[spline->tot_point - 1]) { if (spline->flag & MASK_SPLINE_CYCLIC) - next = &(spline->points[0].bezt); + next = &(points_array[0].bezt); else next = NULL; } @@ -493,12 +522,14 @@ void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float u, float n[2]) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); + BezTriple *bezt = &point->bezt, *next; float q0[2], q1[2], q2[2], r0[2], r1[2], vec[2]; - if (point == &spline->points[spline->tot_point - 1]) { + if (point == &points_array[spline->tot_point - 1]) { if (spline->flag & MASK_SPLINE_CYCLIC) - next = &(spline->points[0].bezt); + next = &(points_array[0].bezt); else next = NULL; } @@ -531,13 +562,15 @@ void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float u, float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, float u) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); + BezTriple *bezt = &point->bezt, *next; float cur_u, cur_w, next_u, next_w, fac; int i; - if (point == &spline->points[spline->tot_point - 1]) { + if (point == &points_array[spline->tot_point - 1]) { if (spline->flag & MASK_SPLINE_CYCLIC) - next = &(spline->points[0].bezt); + next = &(points_array[0].bezt); else next = NULL; } @@ -686,13 +719,22 @@ void BKE_mask_spline_free(MaskSpline *spline) int i = 0; for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; - + MaskSplinePoint *point; + point = &spline->points[i]; BKE_mask_point_free(point); + + if (spline->points_deform) { + point = &spline->points_deform[i]; + BKE_mask_point_free(point); + } } MEM_freeN(spline->points); + if (spline->points_deform) { + MEM_freeN(spline->points_deform); + } + MEM_freeN(spline); } @@ -812,7 +854,7 @@ void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_c } } -static int evaluate_mask_parent(MaskParent *parent, float ctime, float r_co[2]) +static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[2]) { if (!parent) return FALSE; @@ -846,6 +888,19 @@ static int evaluate_mask_parent(MaskParent *parent, float ctime, float r_co[2]) return FALSE; } +int BKE_mask_evaluate_parent_delta(MaskParent *parent, float ctime, float r_delta[2]) +{ + float parent_co[2]; + + if (BKE_mask_evaluate_parent(parent, ctime, parent_co)) { + sub_v2_v2v2(r_delta, parent->parent_orig, parent_co); + return TRUE; + } + else { + return FALSE; + } +} + static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *prev_point, MaskSplinePoint *next_point) { BezTriple *bezt = &point->bezt; @@ -1057,6 +1112,63 @@ void BKE_mask_calc_handles(Mask *mask) } } +void BKE_mask_update_deform(Mask *mask) +{ + MaskObject *maskobj; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + const int i_prev = (i - 1) % spline->tot_point; + const int i_next = (i + 1) % spline->tot_point; + + BezTriple *bezt_prev = &spline->points[i_prev].bezt; + BezTriple *bezt = &spline->points[i ].bezt; + BezTriple *bezt_next = &spline->points[i_next].bezt; + + BezTriple *bezt_def_prev = &spline->points_deform[i_prev].bezt; + BezTriple *bezt_def = &spline->points_deform[i ].bezt; + BezTriple *bezt_def_next = &spline->points_deform[i_next].bezt; + + float w_src[4]; + int j; + + for (j = 0; j <= 2; j += 2) { /* (0, 2) */ + printf("--- %d %d, %d, %d\n", i, j, i_prev, i_next); + barycentric_weights_v2(bezt_prev->vec[1], bezt->vec[1], bezt_next->vec[1], + bezt->vec[j], w_src); + interp_v3_v3v3v3(bezt_def->vec[j], + bezt_def_prev->vec[1], bezt_def->vec[1], bezt_def_next->vec[1], w_src); + } + } + } + } +} + +void BKE_mask_spline_ensure_deform(MaskSpline *spline) +{ +// printf("SPLINE ALLOC %p %d\n", spline->points_deform, (int)(MEM_allocN_len(spline->points_deform) / sizeof(*spline->points_deform))); + + if ((spline->points_deform == NULL) || + (MEM_allocN_len(spline->points_deform) / sizeof(*spline->points_deform)) != spline->tot_point) + { + printf("alloc new spline\n"); + + if (spline->points_deform) { + MEM_freeN(spline->points_deform); + } + + spline->points_deform = MEM_mallocN(sizeof(*spline->points_deform) * spline->tot_point, __func__); + } + else { + printf("alloc spline done\n"); + } +} + void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) { MaskObject *maskobj; @@ -1100,20 +1212,30 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) /* animation done... */ for (spline = maskobj->splines.first; spline; spline = spline->next) { + + BKE_mask_spline_ensure_deform(spline); + for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; - float co[2]; + MaskSplinePoint *point_deform = &spline->points_deform[i]; + float delta[2]; - if (evaluate_mask_parent(&point->parent, ctime, co)) { - BezTriple *bezt = &point->bezt; - float delta[2]; + if (BKE_mask_evaluate_parent_delta(&point->parent, ctime, delta)) { - copy_v2_v2(co, bezt->vec[1]); - sub_v2_v2v2(delta, co, bezt->vec[1]); + *point_deform = *point; + point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL; - add_v2_v2(bezt->vec[0], delta); - add_v2_v2(bezt->vec[1], delta); - add_v2_v2(bezt->vec[2], delta); + print_v2("", delta); + + sub_v2_v2(point_deform->bezt.vec[0], delta); + sub_v2_v2(point_deform->bezt.vec[1], delta); + add_v2_v2(point_deform->bezt.vec[2], delta); + + //point_deform->bezt.vec[1][1] += 1; + } + else { + *point_deform = *point; + point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL; } } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 7c9945ef517..320278544ae 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2778,9 +2778,14 @@ static void write_masks(WriteData *wd, ListBase *idbase) for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; + void *points_deform = spline->points_deform; + spline->points_deform = NULL; + writestruct(wd, DATA, "MaskSpline", 1, spline); writestruct(wd, DATA, "MaskSplinePoint", spline->tot_point, spline->points); + spline->points_deform = points_deform; + for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 7077450c807..f09c1fa232f 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -65,6 +65,7 @@ static void set_spline_color(MaskObject *maskobj, MaskSpline *spline) static void draw_spline_parents(MaskObject *UNUSED(maskobj), MaskSpline *spline) { int i; + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); if (!spline->tot_point) return; @@ -76,14 +77,15 @@ static void draw_spline_parents(MaskObject *UNUSED(maskobj), MaskSpline *spline) glBegin(GL_LINES); for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point = &points_array[i]; + BezTriple *bezt = &point->bezt; if (point->parent.flag & MASK_PARENT_ACTIVE) { - glVertex2f(point->bezt.vec[1][0], - point->bezt.vec[1][1]); + glVertex2f(bezt->vec[1][0], + bezt->vec[1][1]); - glVertex2f(point->bezt.vec[1][0] - point->parent.offset[0], - point->bezt.vec[1][1] - point->parent.offset[1]); + glVertex2f(bezt->vec[1][0] - point->parent.offset[0], + bezt->vec[1][1] - point->parent.offset[1]); } } @@ -95,6 +97,8 @@ static void draw_spline_parents(MaskObject *UNUSED(maskobj), MaskSpline *spline) /* return non-zero if spline is selected */ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + int i, hsize, tot_feather_point; float *feather_points, *fp; @@ -108,9 +112,12 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) /* feather points */ feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); for (i = 0; i < spline->tot_point; i++) { - int j; + + /* watch it! this is intentionally not the deform array, only check for sel */ MaskSplinePoint *point = &spline->points[i]; + int j; + for (j = 0; j < point->tot_uw + 1; j++) { int sel = FALSE; @@ -142,12 +149,17 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) /* control points */ for (i = 0; i < spline->tot_point; i++) { + + /* watch it! this is intentionally not the deform array, only check for sel */ MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; + BezTriple *bezt = &point_deform->bezt; + float handle[2]; - float *vert = point->bezt.vec[1]; + float *vert = bezt->vec[1]; int has_handle = BKE_mask_point_has_handle(point); - BKE_mask_point_handle(point, handle); + BKE_mask_point_handle(point_deform, handle); /* draw handle segment */ if (has_handle) { diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 1e46b893dcd..ded45e73323 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -144,17 +144,20 @@ MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float norma MaskSpline *spline; for (spline = maskobj->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + int i; for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *cur_point = &spline->points[i]; + MaskSplinePoint *cur_point_deform = &points_array[i]; float cur_len, vec[2], handle[2]; - vec[0] = cur_point->bezt.vec[1][0] * scalex; - vec[1] = cur_point->bezt.vec[1][1] * scaley; + vec[0] = cur_point_deform->bezt.vec[1][0] * scalex; + vec[1] = cur_point_deform->bezt.vec[1][1] * scaley; if (BKE_mask_point_has_handle(cur_point)) { - BKE_mask_point_handle(cur_point, handle); + BKE_mask_point_handle(cur_point_deform, handle); handle[0] *= scalex; handle[1] *= scaley; @@ -233,6 +236,8 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in MaskSpline *spline; for (spline = maskobj->splines.first; spline; spline = spline->next) { + //MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + int i, tot_feather_point; float *feather_points, *fp; diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index 136376336d8..9d3195a26de 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -151,6 +151,7 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) add_v2_v2(bezt->vec[2], tvec); negate_v2_v2(point->parent.offset, tvec); + copy_v2_v2(point->parent.parent_orig, parmask_pos); } } } diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index 441b15a8aa9..eef7a024d72 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -59,6 +59,7 @@ typedef struct MaskParent { * in case of parenting to movie tracking data contains name of track */ float offset[2]; /* offset from parent position, so object/control point can be parented to a * motion track and also be animated (see ZanQdo's request below) */ + float parent_orig[2]; /* track location at the moment of parenting */ } MaskParent; typedef struct MaskSplinePointUW { @@ -83,6 +84,8 @@ typedef struct MaskSpline { MaskParent parent; /* parenting information of the whole spline */ int weight_interp, pad; /* weight interpolation */ + + MaskSplinePoint *points_deform; /* deformed copy of 'points' BezTriple data - not saved */ } MaskSpline; /* one per frame */ From 74438b63365a99a60260fdf3d55f3a61fd444f2b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 29 May 2012 11:00:02 +0000 Subject: [PATCH 097/360] fix for parent + animation handles. --- source/blender/blenkernel/BKE_mask.h | 1 + source/blender/blenkernel/intern/mask.c | 25 ++++++++++++++++--------- source/blender/editors/mask/mask_draw.c | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 5020fd97895..d463843e561 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -101,6 +101,7 @@ void BKE_mask_calc_handle_point_auto(struct Mask *mask, struct MaskSpline *splin void BKE_mask_get_handle_point_adjacent(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, struct MaskSplinePoint **r_point_prev, struct MaskSplinePoint **r_point_next); void BKE_mask_calc_handles(struct Mask *mask); +void BKE_mask_spline_ensure_deform(struct MaskSpline *spline); /* animation */ int BKE_mask_object_shape_totvert(struct MaskObject *maskobj); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 566c0920bbf..236fc4825ca 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -893,7 +893,7 @@ int BKE_mask_evaluate_parent_delta(MaskParent *parent, float ctime, float r_delt float parent_co[2]; if (BKE_mask_evaluate_parent(parent, ctime, parent_co)) { - sub_v2_v2v2(r_delta, parent->parent_orig, parent_co); + sub_v2_v2v2(r_delta, parent_co, parent->parent_orig); return TRUE; } else { @@ -1107,6 +1107,11 @@ void BKE_mask_calc_handles(Mask *mask) for (i = 0; i < spline->tot_point; i++) { BKE_mask_calc_handle_point(mask, spline, &spline->points[i]); + + /* could be done in a different function... */ + if (spline->points_deform) { + BKE_mask_calc_handle_point(mask, spline, &spline->points[i]); + } } } } @@ -1174,8 +1179,6 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) MaskObject *maskobj; for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskSpline *spline; - int i; /* animation if available */ if (do_newframe) { @@ -1210,6 +1213,14 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) } } /* animation done... */ + } + + BKE_mask_calc_handles(mask); + + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + int i; for (spline = maskobj->splines.first; spline; spline = spline->next) { @@ -1227,11 +1238,9 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) print_v2("", delta); - sub_v2_v2(point_deform->bezt.vec[0], delta); - sub_v2_v2(point_deform->bezt.vec[1], delta); + add_v2_v2(point_deform->bezt.vec[0], delta); + add_v2_v2(point_deform->bezt.vec[1], delta); add_v2_v2(point_deform->bezt.vec[2], delta); - - //point_deform->bezt.vec[1][1] += 1; } else { *point_deform = *point; @@ -1240,8 +1249,6 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) } } } - - BKE_mask_calc_handles(mask); } void BKE_mask_evaluate_all_masks(Main *bmain, float ctime, const int do_newframe) diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index f09c1fa232f..6555e7f804b 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -266,6 +266,9 @@ static void draw_maskobjs(Mask *mask) MaskSpline *spline; for (spline = maskobj->splines.first; spline; spline = spline->next) { + + BKE_mask_spline_ensure_deform(spline); + /* draw curve itself first... */ draw_spline_curve(maskobj, spline); @@ -273,6 +276,17 @@ static void draw_maskobjs(Mask *mask) /* ...and then handles over the curve so they're nicely visible */ draw_spline_points(maskobj, spline); + + /* show undeform for testing */ + if (0) { + void *back = spline->points_deform; + + spline->points_deform = NULL; + draw_spline_curve(maskobj, spline); + draw_spline_parents(maskobj, spline); + draw_spline_points(maskobj, spline); + spline->points_deform = back; + } } } } From 08fa15b64ac9eb55725071a816f178e4491e80b5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 29 May 2012 11:48:34 +0000 Subject: [PATCH 098/360] fix crash with using uninitialized curves --- source/blender/editors/mask/mask_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 6555e7f804b..34c478dceaa 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -267,7 +267,7 @@ static void draw_maskobjs(Mask *mask) for (spline = maskobj->splines.first; spline; spline = spline->next) { - BKE_mask_spline_ensure_deform(spline); +// BKE_mask_spline_ensure_deform(spline); /* draw curve itself first... */ draw_spline_curve(maskobj, spline); From 777d0255ff50e6d57840db3c364aa56039836bbd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 29 May 2012 13:18:11 +0000 Subject: [PATCH 099/360] fix for parenting, offset isnt needed anymore --- source/blender/blenkernel/intern/mask.c | 1 - source/blender/editors/mask/mask_draw.c | 6 ++++-- source/blender/editors/mask/mask_relationships.c | 8 -------- source/blender/makesdna/DNA_mask_types.h | 2 -- 4 files changed, 4 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 236fc4825ca..ffd2630742d 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -877,7 +877,6 @@ static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[ if (track) { MovieTrackingMarker *marker = BKE_tracking_get_marker(track, ctime); BKE_mask_coord_from_movieclip(clip, &user, r_co, marker->pos); - add_v2_v2(r_co, parent->offset); return TRUE; } diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 34c478dceaa..fe11ded64f4 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -62,6 +62,7 @@ static void set_spline_color(MaskObject *maskobj, MaskSpline *spline) } } +#if 0 static void draw_spline_parents(MaskObject *UNUSED(maskobj), MaskSpline *spline) { int i; @@ -93,6 +94,7 @@ static void draw_spline_parents(MaskObject *UNUSED(maskobj), MaskSpline *spline) glDisable(GL_LINE_STIPPLE); } +#endif /* return non-zero if spline is selected */ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) @@ -272,7 +274,7 @@ static void draw_maskobjs(Mask *mask) /* draw curve itself first... */ draw_spline_curve(maskobj, spline); - draw_spline_parents(maskobj, spline); +// draw_spline_parents(maskobj, spline); /* ...and then handles over the curve so they're nicely visible */ draw_spline_points(maskobj, spline); @@ -283,7 +285,7 @@ static void draw_maskobjs(Mask *mask) spline->points_deform = NULL; draw_spline_curve(maskobj, spline); - draw_spline_parents(maskobj, spline); +// draw_spline_parents(maskobj, spline); draw_spline_points(maskobj, spline); spline->points_deform = back; } diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index 9d3195a26de..96782c5b294 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -135,7 +135,6 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) if (MASKPOINT_ISSEL(point)) { BezTriple *bezt = &point->bezt; - float tvec[2]; point->parent.id_type = ID_MC; point->parent.id = &clip->id; @@ -144,13 +143,6 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) point->parent.flag |= MASK_PARENT_ACTIVE; - sub_v2_v2v2(tvec, parmask_pos, bezt->vec[1]); - - add_v2_v2(bezt->vec[0], tvec); - add_v2_v2(bezt->vec[1], tvec); - add_v2_v2(bezt->vec[2], tvec); - - negate_v2_v2(point->parent.offset, tvec); copy_v2_v2(point->parent.parent_orig, parmask_pos); } } diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index eef7a024d72..cf3f5e77544 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -57,8 +57,6 @@ typedef struct MaskParent { * in case of parenting to movie tracking data contains name of object */ char sub_parent[64]; /* sub-entity of parent to which parenting happened * in case of parenting to movie tracking data contains name of track */ - float offset[2]; /* offset from parent position, so object/control point can be parented to a - * motion track and also be animated (see ZanQdo's request below) */ float parent_orig[2]; /* track location at the moment of parenting */ } MaskParent; From f5917b15b5f603f0b9b567915b4aa93320d6dc54 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 29 May 2012 13:23:34 +0000 Subject: [PATCH 100/360] support for marker parent offset --- source/blender/blenkernel/intern/mask.c | 6 +++--- source/blender/editors/mask/mask_relationships.c | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index ffd2630742d..439495e8af1 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -876,7 +876,9 @@ static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[ if (track) { MovieTrackingMarker *marker = BKE_tracking_get_marker(track, ctime); - BKE_mask_coord_from_movieclip(clip, &user, r_co, marker->pos); + float marker_pos_ofs[2]; + add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset); + BKE_mask_coord_from_movieclip(clip, &user, r_co, marker_pos_ofs); return TRUE; } @@ -1235,8 +1237,6 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) *point_deform = *point; point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL; - print_v2("", delta); - add_v2_v2(point_deform->bezt.vec[0], delta); add_v2_v2(point_deform->bezt.vec[1], delta); add_v2_v2(point_deform->bezt.vec[2], delta); diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index 96782c5b294..4d08e2fa439 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -112,6 +112,7 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) MovieTrackingObject *tracking; /* done */ + float marker_pos_ofs[2]; float parmask_pos[2]; if ((NULL == (sc = CTX_wm_space_clip(C))) || @@ -123,7 +124,9 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; } - BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker->pos); + add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset); + + BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker_pos_ofs); for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; @@ -134,8 +137,6 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) MaskSplinePoint *point = &spline->points[i]; if (MASKPOINT_ISSEL(point)) { - BezTriple *bezt = &point->bezt; - point->parent.id_type = ID_MC; point->parent.id = &clip->id; strcpy(point->parent.parent, tracking->name); From 876665ac25a731bcf5937d4e06de7337d6e8af6a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 29 May 2012 14:00:47 +0000 Subject: [PATCH 101/360] Initial commit of new keying nodes First node is called Keying Screen (Add -> Matte -> Keying Screen) and it's aimed to resolve issues with gradients on green screens by producing image with gradient which is later used as an input for screen color in keying nodes. This node gets motion tracks from given movie clip and trackign object and uses them to define color and position of points of gradient: for position marker's position on current frame is sued, for color average color of pattern area is used. Gradient is calculating in the following way: - On first step voronoi diagram is creating for given tracks. - On second step triangulation of this diagram happens by connecting sites to edges which defines area this site belongs to. - On third step gradient filling of this triangles happens. One of triangle vertices is colored with average track color, two rest vertoces are colored with average color between two neighbor sites. Current pixel's color in triangle is calculating as linear combination of vertices colors and barycentric coordinates of this pixel. This node is implemented for both tile and legacy compositor systems. Second node is basically a combination of several existing nodes to make keying more straighforward and reduce spagetti mess in the compositor, but it also ships some fresh approaches calculating matte which seems to be working better for not actually green screens. This node supports: - Chroma preblur - Dispilling - Clip white/black - Dilate/Erode - Matte post blur This node doesn't support chroma pre-blur for legacy compositor (yet). There're still lots of stuff to be improved here, but this nodes night already be used i think. Some details might be found on this wiki page: http://wiki.blender.org/index.php/User:Nazg-gul/Keying This patch also contains some currently unused code from color math module, but it was used for tests and might be used for tests in the future. Think it's ok to have it in branch at least. --- source/blender/blenkernel/BKE_node.h | 2 + source/blender/blenkernel/intern/node.c | 2 + source/blender/blenlib/BLI_math_base.h | 3 + source/blender/blenlib/BLI_math_color.h | 4 + source/blender/blenlib/BLI_math_geom.h | 3 + source/blender/blenlib/BLI_voronoi.h | 70 ++ source/blender/blenlib/CMakeLists.txt | 1 + source/blender/blenlib/intern/math_color.c | 84 ++ source/blender/blenlib/intern/math_geom.c | 39 + source/blender/blenlib/intern/voronoi.c | 833 ++++++++++++++++++ source/blender/compositor/CMakeLists.txt | 12 + .../compositor/intern/COM_Converter.cpp | 7 + .../compositor/nodes/COM_KeyingNode.cpp | 211 +++++ .../blender/compositor/nodes/COM_KeyingNode.h | 44 + .../compositor/nodes/COM_KeyingScreenNode.cpp | 57 ++ .../compositor/nodes/COM_KeyingScreenNode.h | 36 + .../operations/COM_KeyingDispillOperation.cpp | 89 ++ .../operations/COM_KeyingDispillOperation.h | 49 ++ .../operations/COM_KeyingOperation.cpp | 114 +++ .../operations/COM_KeyingOperation.h | 57 ++ .../operations/COM_KeyingScreenOperation.cpp | 217 +++++ .../operations/COM_KeyingScreenOperation.h | 79 ++ source/blender/editors/space_node/drawnode.c | 37 +- source/blender/makesdna/DNA_node_types.h | 11 + source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/intern/rna_nodetree.c | 61 ++ .../makesrna/intern/rna_nodetree_types.h | 2 + source/blender/nodes/CMakeLists.txt | 2 + source/blender/nodes/NOD_composite.h | 3 + .../nodes/composite/node_composite_util.c | 16 + .../nodes/composite/node_composite_util.h | 4 + .../composite/nodes/node_composite_blur.c | 22 +- .../composite/nodes/node_composite_dilate.c | 8 +- .../composite/nodes/node_composite_keying.c | 218 +++++ .../nodes/node_composite_keyingscreen.c | 202 +++++ 35 files changed, 2587 insertions(+), 13 deletions(-) create mode 100644 source/blender/blenlib/BLI_voronoi.h create mode 100644 source/blender/blenlib/intern/voronoi.c create mode 100644 source/blender/compositor/nodes/COM_KeyingNode.cpp create mode 100644 source/blender/compositor/nodes/COM_KeyingNode.h create mode 100644 source/blender/compositor/nodes/COM_KeyingScreenNode.cpp create mode 100644 source/blender/compositor/nodes/COM_KeyingScreenNode.h create mode 100644 source/blender/compositor/operations/COM_KeyingDispillOperation.cpp create mode 100644 source/blender/compositor/operations/COM_KeyingDispillOperation.h create mode 100644 source/blender/compositor/operations/COM_KeyingOperation.cpp create mode 100644 source/blender/compositor/operations/COM_KeyingOperation.h create mode 100644 source/blender/compositor/operations/COM_KeyingScreenOperation.cpp create mode 100644 source/blender/compositor/operations/COM_KeyingScreenOperation.h create mode 100644 source/blender/nodes/composite/nodes/node_composite_keying.c create mode 100644 source/blender/nodes/composite/nodes/node_composite_keyingscreen.c diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 7e925e545dc..fde6d93849d 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -655,6 +655,8 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); #define CMP_NODE_DOUBLEEDGEMASK 266 #define CMP_NODE_OUTPUT_MULTI_FILE__DEPRECATED 267 /* DEPRECATED multi file node has been merged into regular CMP_NODE_OUTPUT_FILE */ #define CMP_NODE_MASK 268 +#define CMP_NODE_KEYINGSCREEN 269 +#define CMP_NODE_KEYING 270 #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 54edd7064a1..35e838d94fa 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1926,6 +1926,8 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_cmp_color_spill(ttype); register_node_type_cmp_luma_matte(ttype); register_node_type_cmp_doubleedgemask(ttype); + register_node_type_cmp_keyingscreen(ttype); + register_node_type_cmp_keying(ttype); register_node_type_cmp_translate(ttype); register_node_type_cmp_rotate(ttype); diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index 22672db9edb..b0e0d3cbf19 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -53,6 +53,9 @@ #ifndef M_SQRT1_2 #define M_SQRT1_2 0.70710678118654752440 #endif +#ifndef M_SQRT3 +#define M_SQRT3 1.7320508075688772 +#endif #ifndef M_1_PI #define M_1_PI 0.318309886183790671538 #endif diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h index 746a2b958ea..44f54c41129 100644 --- a/source/blender/blenlib/BLI_math_color.h +++ b/source/blender/blenlib/BLI_math_color.h @@ -69,6 +69,8 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv); void rgb_to_hsv_v(const float rgb[3], float r_hsv[3]); void rgb_to_hsv_compat(float r, float g, float b, float *lh, float *ls, float *lv); void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3]); +void rgb_to_lab(float r, float g, float b, float *ll, float *la, float *lb); +void rgb_to_xyz(float r, float g, float b, float *x, float *y, float *z); unsigned int rgb_to_cpack(float r, float g, float b); unsigned int hsv_to_cpack(float h, float s, float v); @@ -112,6 +114,8 @@ void rgba_uchar_to_float(float col_r[4], const unsigned char col_ub[4]); void rgb_float_to_uchar(unsigned char col_r[3], const float col_f[3]); void rgba_float_to_uchar(unsigned char col_r[4], const float col_f[4]); +void xyz_to_lab(float x, float y, float z, float *l, float *a, float *b); + /***************** lift/gamma/gain / ASC-CDL conversion *****************/ void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power); diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 0560a3f6e64..93599dee63d 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -191,6 +191,9 @@ void barycentric_transform(float pt_tar[3], float const pt_src[3], void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]); +int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]); +int barycentric_inside_triangle_v2(const float w[3]); + void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]); void resolve_quad_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]); diff --git a/source/blender/blenlib/BLI_voronoi.h b/source/blender/blenlib/BLI_voronoi.h new file mode 100644 index 00000000000..a67b01c5175 --- /dev/null +++ b/source/blender/blenlib/BLI_voronoi.h @@ -0,0 +1,70 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_VORONOI_H__ +#define __BLI_VORONOI_H__ + +struct ListBase; + +/** \file BLI_voronoi.h + * \ingroup bli + */ + +typedef struct VoronoiSite { + float co[2]; + float color[3]; +} VoronoiSite; + +typedef struct VoronoiEdge { + struct VoronoiEdge *next, *prev; + + float start[2], end[2]; /* start and end points */ + + /* this fields are used during diagram computation only */ + + float direction[2]; /* directional vector, from "start", points to "end", normal of |left, right| */ + + float left[2]; /* point on Voronoi place on the left side of edge */ + float right[2]; /* point on Voronoi place on the right side of edge */ + + float f, g; /* directional coeffitients satisfying equation y = f*x + g (edge lies on this line) */ + + /* some edges consist of two parts, so we add the pointer to another part to connect them at the end of an algorithm */ + struct VoronoiEdge *neighbour; +} VoronoiEdge; + +typedef struct VoronoiTriangulationPoint { + float co[2]; + float color[3]; + int power; +} VoronoiTriangulationPoint; + +void BLI_voronoi_compute(const VoronoiSite *sites, int sites_total, int width, int height, struct ListBase *edges); + +void BLI_voronoi_triangulate(const VoronoiSite *sites, int sites_total, struct ListBase *edges, int width, int height, + VoronoiTriangulationPoint **triangulated_points_r, int *triangulated_points_total_r, + int (**triangles_r)[3], int *triangles_total_r); + +#endif /* __BLI_VORONOI_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index d535e190314..ac7681e3be7 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -89,6 +89,7 @@ set(SRC intern/time.c intern/uvproject.c intern/voxel.c + intern/voronoi.c intern/winstuff.c BLI_args.h diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 152fc98945f..9433cfd31df 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -264,6 +264,35 @@ void rgb_to_hsv_v(const float rgb[3], float r_hsv[3]) rgb_to_hsv(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]); } +void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll) +{ + float cmax = MAX3(r, g, b); + float cmin = MIN3(r, g, b); + float h, s, l = (cmax + cmin) / 2.0f; + + if (cmax == cmin) { + h = s = 0.0f; // achromatic + } + else { + float d = cmax - cmin; + s = l > 0.5f ? d / (2.0f - cmax - cmin) : d / (cmax + cmin); + if (cmax == r) { + h = (g - b) / d + (g < b ? 6.0f : 0.0f); + } + else if (cmax == g) { + h = (b - r) / d + 2.0f; + } + else { + h = (r - g) / d + 4.0f; + } + } + h /= 6.0f; + + *lh = h; + *ls = s; + *ll = l; +} + void rgb_to_hsv_compat(float r, float g, float b, float *lh, float *ls, float *lv) { float orig_h = *lh; @@ -603,3 +632,58 @@ void BLI_init_srgb_conversion(void) BLI_color_to_srgb_table[i] = b * 0x100; } } +static float inverse_srgb_companding(float v) +{ + if (v > 0.04045f) { + return powf((v + 0.055f) / 1.055f, 2.4); + } + else { + return v / 12.92f; + } +} + +void rgb_to_xyz(float r, float g, float b, float *x, float *y, float *z) +{ + r = inverse_srgb_companding(r) * 100.0f; + g = inverse_srgb_companding(g) * 100.0f; + b = inverse_srgb_companding(b) * 100.0f; + + *x = r * 0.4124 + g * 0.3576 + b * 0.1805; + *y = r * 0.2126 + g * 0.7152 + b * 0.0722; + *z = r * 0.0193 + g * 0.1192 + b * 0.9505; +} + +static float xyz_to_lab_component(float v) +{ + const float eps = 0.008856f; + const float k = 903.3f; + + if (v > eps) { + return pow(v, 1.0f / 3.0f); + } + else { + return (k * v + 16.0f) / 116.0f; + } +} + +void xyz_to_lab(float x, float y, float z, float *l, float *a, float *b) +{ + float xr = x / 95.047f; + float yr = y / 100.0f; + float zr = z / 108.883f; + + float fx = xyz_to_lab_component(xr); + float fy = xyz_to_lab_component(yr); + float fz = xyz_to_lab_component(zr); + + *l = 116.0f * fy - 16.0f; + *a = 500.0f * (fx - fy); + *b = 200.0f * (fy - fz); +} + +void rgb_to_lab(float r, float g, float b, float *ll, float *la, float *lb) +{ + float x, y, z; + rgb_to_xyz(r, g, b, &x, &y, &z); + xyz_to_lab(x, y, z, ll, la, lb); +} diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 3962f53862d..d35624e84d2 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1825,6 +1825,45 @@ void interp_weights_face_v3(float w[4], const float v1[3], const float v2[3], co } } +/* return 1 of point is inside triangle, 2 if it's on the edge, 0 if point is outside of triangle */ +int barycentric_inside_triangle_v2(const float w[3]) +{ + if (IN_RANGE(w[0], 0.0f, 1.0f) && + IN_RANGE(w[1], 0.0f, 1.0f) && + IN_RANGE(w[2], 0.0f, 1.0f)) + { + return 1; + } + else if (IN_RANGE_INCL(w[0], 0.0f, 1.0f) && + IN_RANGE_INCL(w[1], 0.0f, 1.0f) && + IN_RANGE_INCL(w[2], 0.0f, 1.0f)) + { + return 2; + } + + return 0; +} + +/* returns 0 for degenerated triangles */ +int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]) +{ + float x = co[0], y = co[1]; + float x1 = v1[0], y1 = v1[1]; + float x2 = v2[0], y2 = v2[1]; + float x3 = v3[0], y3 = v3[1]; + float det = (y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3); + + if (fabsf(det) > FLT_EPSILON) { + w[0] = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) / det; + w[1] = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / det; + w[2] = 1.0f - w[0] - w[1]; + + return 1; + } + + return 0; +} + /* used by projection painting * note: using area_tri_signed_v2 means locations outside the triangle are correctly weighted */ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]) diff --git a/source/blender/blenlib/intern/voronoi.c b/source/blender/blenlib/intern/voronoi.c new file mode 100644 index 00000000000..0088d24d741 --- /dev/null +++ b/source/blender/blenlib/intern/voronoi.c @@ -0,0 +1,833 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/* + * Fortune's algorithm implemented using explanation and some code snippets from + * http://blog.ivank.net/fortunes-algorithm-and-implementation.html + */ + +/** \file blender/blenkernel/intern/tracking.c + * \ingroup bli + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_voronoi.h" +#include "BLI_utildefines.h" + +#define VORONOI_EPS 1e-3 + +enum { + voronoiEventType_Site = 0, + voronoiEventType_Circle = 1 +} voronoiEventType; + +typedef struct VoronoiEvent { + struct VoronoiEvent *next, *prev; + + int type; /* type of event (site or circle) */ + float site[2]; /* site for which event was generated */ + + struct VoronoiParabola *parabola; /* parabola for which event was generated */ +} VoronoiEvent; + +typedef struct VoronoiParabola { + struct VoronoiParabola *left, *right, *parent; + VoronoiEvent *event; + int is_leaf; + float site[2]; + VoronoiEdge *edge; +} VoronoiParabola; + +typedef struct VoronoiProcess { + ListBase queue, edges; + VoronoiParabola *root; + int width, height; + float current_y; +} VoronoiProcess; + +/* event */ + +static void voronoi_insertEvent(VoronoiProcess *process, VoronoiEvent *event) +{ + VoronoiEvent *current_event = process->queue.first; + + while (current_event) { + if (current_event->site[1] < event->site[1]) { + break; + } + if (current_event->site[1] == event->site[1]) { + event->site[1] -= VORONOI_EPS; + } + + current_event = current_event->next; + } + + BLI_insertlinkbefore(&process->queue, current_event, event); +} + +/* edge */ +static VoronoiEdge *voronoiEdge_new(float start[2], float left[2], float right[2]) +{ + VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "voronoi edge"); + + copy_v2_v2(edge->start, start); + copy_v2_v2(edge->left, left); + copy_v2_v2(edge->right, right); + + edge->neighbour = NULL; + edge->end[0] = 0; + edge->end[1] = 0; + + edge->f = (right[0] - left[0]) / (left[1] - right[1]); + edge->g = start[1] - edge->f * start[0]; + + edge->direction[0] = right[1] - left[1]; + edge->direction[1] = -(right[0] - left[0]); + + return edge; +} + +/* parabola */ + +static VoronoiParabola *voronoiParabola_new(void) +{ + VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola"); + + parabola->is_leaf = FALSE; + parabola->event = NULL; + parabola->edge = NULL; + parabola->parent = 0; + + return parabola; +} + +static VoronoiParabola *voronoiParabola_newSite(float site[2]) +{ + VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola site"); + + copy_v2_v2(parabola->site, site); + parabola->is_leaf = TRUE; + parabola->event = NULL; + parabola->edge = NULL; + parabola->parent = 0; + + return parabola; +} + +/* returns the closest leave which is on the left of current node */ +static VoronoiParabola *voronoiParabola_getLeftChild(VoronoiParabola *parabola) +{ + VoronoiParabola *current_parabola; + + if (!parabola) + return NULL; + + current_parabola = parabola->left; + while (!current_parabola->is_leaf) { + current_parabola = current_parabola->right; + } + + return current_parabola; +} + +/* returns the closest leave which is on the right of current node */ +static VoronoiParabola *voronoiParabola_getRightChild(VoronoiParabola *parabola) +{ + VoronoiParabola *current_parabola; + + if (!parabola) + return NULL; + + current_parabola = parabola->right; + while (!current_parabola->is_leaf) { + current_parabola = current_parabola->left; + } + + return current_parabola; +} + +/* returns the closest parent which is on the left */ +static VoronoiParabola *voronoiParabola_getLeftParent(VoronoiParabola *parabola) +{ + VoronoiParabola *current_par = parabola->parent; + VoronoiParabola *last_parabola = parabola; + + while (current_par->left == last_parabola) { + if (!current_par->parent) + return NULL; + + last_parabola = current_par; + current_par = current_par->parent; + } + + return current_par; +} + +/* returns the closest parent which is on the right */ +static VoronoiParabola *voronoiParabola_getRightParent(VoronoiParabola *parabola) +{ + VoronoiParabola *current_parabola = parabola->parent; + VoronoiParabola *last_parabola = parabola; + + while (current_parabola->right == last_parabola) { + if (!current_parabola->parent) + return NULL; + + last_parabola = current_parabola; + current_parabola = current_parabola->parent; + } + + return current_parabola; +} + +static void voronoiParabola_setLeft(VoronoiParabola *parabola, VoronoiParabola *left) +{ + parabola->left = left; + left->parent = parabola; +} + +static void voronoiParabola_setRight(VoronoiParabola *parabola, VoronoiParabola *right) +{ + parabola->right = right; + right->parent = parabola; +} + +static float voronoi_getY(VoronoiProcess *process, float p[2], float x) +{ + float ly = process->current_y; + + float dp = 2 * (p[1] - ly); + float a1 = 1 / dp; + float b1 = -2 * p[0] / dp; + float c1 = ly + dp / 4 + p[0] * p[0] / dp; + + return a1 * x * x + b1 * x + c1; +} + +static float voronoi_getXOfEdge(VoronoiProcess *process, VoronoiParabola *par, float y) +{ + VoronoiParabola *left = voronoiParabola_getLeftChild(par); + VoronoiParabola *right = voronoiParabola_getRightChild(par); + float p[2], r[2]; + float dp, a1, b1, c1, a2, b2, c2, a, b, c, disc, ry, x1, x2; + float ly = process->current_y; + + copy_v2_v2(p, left->site); + copy_v2_v2(r, right->site); + + dp = 2.0f * (p[1] - y); + a1 = 1.0f / dp; + b1 = -2.0f * p[0] / dp; + c1 = y + dp / 4 + p[0] * p[0] / dp; + + dp = 2.0f * (r[1] - y); + a2 = 1.0f / dp; + b2 = -2.0f * r[0] / dp; + c2 = ly + dp / 4 + r[0] * r[0] / dp; + + a = a1 - a2; + b = b1 - b2; + c = c1 - c2; + + disc = b*b - 4 * a * c; + x1 = (-b + sqrtf(disc)) / (2*a); + x2 = (-b - sqrtf(disc)) / (2*a); + + if (p[1] < r[1]) + ry = MAX2(x1, x2); + else + ry = MIN2(x1, x2); + + return ry; +} + +static VoronoiParabola *voronoi_getParabolaByX(VoronoiProcess *process, float xx) +{ + VoronoiParabola * par = process->root; + float x = 0.0f; + float ly = process->current_y; + + while (!par->is_leaf) { + x = voronoi_getXOfEdge(process, par, ly); + + if (x > xx) + par = par->left; + else + par = par->right; + } + + return par; +} + +static int voronoi_getEdgeIntersection(VoronoiEdge *a, VoronoiEdge *b, float p[2]) +{ + float x = (b->g - a->g) / (a->f - b->f); + float y = a->f * x + a->g; + + if ((x - a->start[0]) / a->direction[0] < 0) + return 0; + + if ((y - a->start[1]) / a->direction[1] < 0) + return 0; + + if ((x - b->start[0]) / b->direction[0] < 0) + return 0; + + if ((y - b->start[1]) / b->direction[1] < 0) + return 0; + + p[0] = x; + p[1] = y; + + return 1; +} + +static void voronoi_checkCircle(VoronoiProcess *process, VoronoiParabola *b) +{ + VoronoiParabola *lp = voronoiParabola_getLeftParent(b); + VoronoiParabola *rp = voronoiParabola_getRightParent(b); + + VoronoiParabola *a = voronoiParabola_getLeftChild(lp); + VoronoiParabola *c = voronoiParabola_getRightChild(rp); + + VoronoiEvent *event; + + float ly = process->current_y; + float s[2], dx, dy, d; + + if (!a || !c || len_squared_v2v2(a->site, c->site) < VORONOI_EPS) + return; + + if (!voronoi_getEdgeIntersection(lp->edge, rp->edge, s)) + return; + + dx = a->site[0] - s[0]; + dy = a->site[1] - s[1]; + + d = sqrtf((dx * dx) + (dy * dy)); + + if (s[1] - d >= ly) + return; + + event = MEM_callocN(sizeof(VoronoiEvent), "voronoi circle event"); + + event->type = voronoiEventType_Circle; + + event->site[0] = s[0]; + event->site[1] = s[1] - d; + + b->event = event; + event->parabola = b; + + voronoi_insertEvent(process, event); +} + +static void voronoi_addParabola(VoronoiProcess *process, float site[2]) +{ + VoronoiParabola *root = process->root; + VoronoiParabola *par, *p0, *p1, *p2; + VoronoiEdge *el, *er; + float start[2]; + + if (!process->root) { + process->root = voronoiParabola_newSite(site); + + return; + } + + if (root->is_leaf && root->site[1] - site[1] < 0) { + float *fp = root->site; + float s[2]; + + root->is_leaf = FALSE; + voronoiParabola_setLeft(root, voronoiParabola_newSite(fp)); + voronoiParabola_setRight(root, voronoiParabola_newSite(site)); + + s[0] = (site[0] + fp[0]) / 2.0f; + s[1] = process->height; + + if(site[0] > fp[0]) + root->edge = voronoiEdge_new(s, fp, site); + else + root->edge = voronoiEdge_new(s, site, fp); + + BLI_addtail(&process->edges, root->edge); + + return; + } + + par = voronoi_getParabolaByX(process, site[0]); + + if (par->event) { + BLI_freelinkN(&process->queue, par->event); + + par->event = NULL; + } + + start[0] = site[0]; + start[1] = voronoi_getY(process, par->site, site[0]); + + el = voronoiEdge_new(start, par->site, site); + er = voronoiEdge_new(start, site, par->site); + + el->neighbour = er; + BLI_addtail(&process->edges, el); + + par->edge = er; + par->is_leaf = FALSE; + + p0 = voronoiParabola_newSite(par->site); + p1 = voronoiParabola_newSite(site); + p2 = voronoiParabola_newSite(par->site); + + voronoiParabola_setRight(par, p2); + voronoiParabola_setLeft(par, voronoiParabola_new()); + par->left->edge = el; + + voronoiParabola_setLeft(par->left, p0); + voronoiParabola_setRight(par->left, p1); + + voronoi_checkCircle(process, p0); + voronoi_checkCircle(process, p2); +} + +static void voronoi_removeParabola(VoronoiProcess *process, VoronoiEvent *event) +{ + VoronoiParabola *p1 = event->parabola; + + VoronoiParabola *xl = voronoiParabola_getLeftParent(p1); + VoronoiParabola *xr = voronoiParabola_getRightParent(p1); + + VoronoiParabola *p0 = voronoiParabola_getLeftChild(xl); + VoronoiParabola *p2 = voronoiParabola_getRightChild(xr); + + VoronoiParabola *higher = NULL, *par, *gparent; + + float p[2]; + + if (p0->event) { + BLI_freelinkN(&process->queue, p0->event); + p0->event = NULL; + } + + if (p2->event) { + BLI_freelinkN(&process->queue, p2->event); + p2->event = NULL; + } + + p[0] = event->site[0]; + p[1] = voronoi_getY(process, p1->site, event->site[0]); + + copy_v2_v2(xl->edge->end, p); + copy_v2_v2(xr->edge->end, p); + + par = p1; + while (par != process->root) { + par = par->parent; + + if (par == xl) + higher = xl; + if (par == xr) + higher = xr; + } + + higher->edge = voronoiEdge_new(p, p0->site, p2->site); + BLI_addtail(&process->edges, higher->edge); + + gparent = p1->parent->parent; + if (p1->parent->left == p1) { + if (gparent->left == p1->parent) + voronoiParabola_setLeft(gparent, p1->parent->right); + if (gparent->right == p1->parent) + voronoiParabola_setRight(gparent, p1->parent->right); + } + else { + if (gparent->left == p1->parent) + voronoiParabola_setLeft(gparent, p1->parent->left); + if (gparent->right == p1->parent) + voronoiParabola_setRight(gparent, p1->parent->left); + } + + MEM_freeN(p1->parent); + MEM_freeN(p1); + + voronoi_checkCircle(process, p0); + voronoi_checkCircle(process, p2); +} + +void voronoi_finishEdge(VoronoiProcess *process, VoronoiParabola *parabola) +{ + float mx; + + if (parabola->is_leaf) { + MEM_freeN(parabola); + return; + } + + if (parabola->edge->direction[0] > 0.0f) + mx = MAX2(process->width, parabola->edge->start[0] + 10); + else + mx = MIN2(0.0, parabola->edge->start[0] - 10); + + parabola->edge->end[0] = mx; + parabola->edge->end[1] = mx * parabola->edge->f + parabola->edge->g; + + voronoi_finishEdge(process, parabola->left); + voronoi_finishEdge(process, parabola->right); + + MEM_freeN(parabola); +} + +void voronoi_clampEdgeVertex(int width, int height, float *coord, float *other_coord) +{ + const float corners[4][2] = {{0.0f, 0.0f}, + {width - 1, 0.0f}, + {width - 1, height - 1}, + {0.0f, height - 1}}; + int i; + + if (IN_RANGE_INCL(coord[0], 0, width-1) && IN_RANGE_INCL(coord[1], 0, height-1)) { + return; + } + + for (i = 0; i < 4; i++) { + float v1[2], v2[2]; + float p[2]; + + copy_v2_v2(v1, corners[i]); + + if (i == 3) + copy_v2_v2(v2, corners[0]); + else + copy_v2_v2(v2, corners[i + 1]); + + if (isect_seg_seg_v2_point(v1, v2, coord, other_coord, p) == 1) { + if (i == 0 && coord[1] > p[1]) + continue; + if (i == 1 && coord[0] < p[0]) + continue; + if (i == 2 && coord[1] < p[1]) + continue; + if (i == 3 && coord[0] > p[0]) + continue; + + copy_v2_v2(coord, p); + } + } +} + +void voronoi_clampEdges(ListBase *edges, int width, int height, ListBase *clamped_edges) +{ + VoronoiEdge *edge; + + edge = edges->first; + while (edge) { + VoronoiEdge *new_edge = MEM_callocN(sizeof(VoronoiEdge), "clamped edge"); + + *new_edge = *edge; + BLI_addtail(clamped_edges, new_edge); + + voronoi_clampEdgeVertex(width, height, new_edge->start, new_edge->end); + voronoi_clampEdgeVertex(width, height, new_edge->end, new_edge->start); + + edge = edge->next; + } +} + +static int voronoi_getNextSideCoord(ListBase *edges, float coord[2], int dim, int dir, float next_coord[2]) +{ + VoronoiEdge *edge = edges->first; + float distance = FLT_MAX; + int other_dim = dim ? 0 : 1; + + while (edge) { + int ok = FALSE; + float co[2], cur_distance; + + if (fabsf(edge->start[other_dim] - coord[other_dim]) < VORONOI_EPS && + len_squared_v2v2(coord, edge->start) > VORONOI_EPS) + { + copy_v2_v2(co, edge->start); + ok = TRUE; + } + + if (fabsf(edge->end[other_dim] - coord[other_dim]) < VORONOI_EPS && + len_squared_v2v2(coord, edge->end) > VORONOI_EPS) + { + copy_v2_v2(co, edge->end); + ok = TRUE; + } + + if (ok) { + if (dir > 0 && coord[dim] > co[dim]) { + ok = FALSE; + } + else if (dir < 0 && coord[dim] < co[dim]) { + ok = FALSE; + } + } + + if (ok) { + cur_distance = len_squared_v2v2(coord, co); + if (cur_distance < distance) { + copy_v2_v2(next_coord, co); + distance = cur_distance; + } + } + + edge = edge->next; + } + + return distance < FLT_MAX; +} + +static void voronoi_createBoundaryEdges(ListBase *edges, int width, int height) +{ + const float corners[4][2] = {{width - 1, 0.0f}, + {width - 1, height - 1}, + {0.0f, height - 1}, + {0.0f, 0.0f}}; + int i, dim = 0, dir = 1; + + float coord[2] = {0.0f, 0.0f}; + float next_coord[2] = {0.0f, 0.0f}; + + for (i = 0; i < 4; i++) { + while (voronoi_getNextSideCoord(edges, coord, dim, dir, next_coord)) { + VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "boundary edge"); + + copy_v2_v2(edge->start, coord); + copy_v2_v2(edge->end, next_coord); + BLI_addtail(edges, edge); + + copy_v2_v2(coord, next_coord); + } + + if (len_squared_v2v2(coord, corners[i]) > VORONOI_EPS) { + VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "boundary edge"); + + copy_v2_v2(edge->start, coord); + copy_v2_v2(edge->end, corners[i]); + BLI_addtail(edges, edge); + copy_v2_v2(coord, corners[i]); + } + + dim = dim ? 0 : 1; + if (i == 1) + dir = -1; + } +} + +void BLI_voronoi_compute(const VoronoiSite *sites, int sites_total, int width, int height, ListBase *edges) +{ + VoronoiProcess process; + VoronoiEdge *edge; + int i; + + memset(&process, 0, sizeof(VoronoiProcess)); + + process.width = width; + process.height = height; + + for (i = 0; i < sites_total; i++) { + VoronoiEvent *event = MEM_callocN(sizeof(VoronoiEvent), "voronoi site event"); + + event->type = voronoiEventType_Site; + copy_v2_v2(event->site, sites[i].co); + + voronoi_insertEvent(&process, event); + } + + while (process.queue.first) { + VoronoiEvent *event = process.queue.first; + + process.current_y = event->site[1]; + + if (event->type == voronoiEventType_Site) { + voronoi_addParabola(&process, event->site); + } + else { + voronoi_removeParabola(&process, event); + } + + BLI_freelinkN(&process.queue, event); + } + + voronoi_finishEdge(&process, process.root); + + edge = process.edges.first; + while (edge) { + if (edge->neighbour) { + copy_v2_v2(edge->start, edge->neighbour->end); + MEM_freeN(edge->neighbour); + } + + edge = edge->next; + } + + BLI_movelisttolist(edges, &process.edges); +} + +static int testVoronoiEdge(const float site[2], const float point[2], const VoronoiEdge *edge) +{ + float p[2]; + + if (isect_seg_seg_v2_point(site, point, edge->start, edge->end, p) == 1) { + if (len_squared_v2v2(p, edge->start) > VORONOI_EPS && + len_squared_v2v2(p, edge->end) > VORONOI_EPS) + { + return FALSE; + } + } + + return TRUE; +} + +static int voronoi_addTriangulationPoint(const float coord[2], const float color[3], + VoronoiTriangulationPoint **triangulated_points, + int *triangulated_points_total) +{ + VoronoiTriangulationPoint *triangulation_point; + int i; + + for (i = 0; i < *triangulated_points_total; i++) { + if (equals_v2v2(coord, (*triangulated_points)[i].co)) { + triangulation_point = &(*triangulated_points)[i]; + + add_v3_v3(triangulation_point->color, color); + triangulation_point->power++; + + return i; + } + } + + if (*triangulated_points) { + *triangulated_points = MEM_reallocN(*triangulated_points, + sizeof(VoronoiTriangulationPoint) * (*triangulated_points_total + 1)); + } + else { + *triangulated_points = MEM_callocN(sizeof(VoronoiTriangulationPoint), "triangulation points"); + } + + triangulation_point = &(*triangulated_points)[(*triangulated_points_total)]; + copy_v2_v2(triangulation_point->co, coord); + copy_v3_v3(triangulation_point->color, color); + + triangulation_point->power = 1; + + (*triangulated_points_total)++; + + return (*triangulated_points_total) - 1; +} + +static void voronoi_addTriangle(int v1, int v2, int v3, int (**triangles)[3], int *triangles_total) +{ + int *triangle; + + if (*triangles) { + *triangles = MEM_reallocN(*triangles, sizeof(int[3]) * (*triangles_total + 1)); + } + else { + *triangles = MEM_callocN(sizeof(int[3]), "trianglulation triangles"); + } + + triangle = (int*)&(*triangles)[(*triangles_total)]; + + triangle[0] = v1; + triangle[1] = v2; + triangle[2] = v3; + + (*triangles_total)++; +} + +void BLI_voronoi_triangulate(const VoronoiSite *sites, int sites_total, ListBase *edges, int width, int height, + VoronoiTriangulationPoint **triangulated_points_r, int *triangulated_points_total_r, + int (**triangles_r)[3], int *triangles_total_r) +{ + VoronoiTriangulationPoint *triangulated_points = NULL; + int (*triangles)[3] = NULL; + int triangulated_points_total = 0, triangles_total = 0; + int i; + ListBase boundary_edges = {NULL, NULL}; + + voronoi_clampEdges(edges, width, height, &boundary_edges); + voronoi_createBoundaryEdges(&boundary_edges, width, height); + + for (i = 0; i < sites_total; i++) { + VoronoiEdge *edge; + int v1; + + v1 = voronoi_addTriangulationPoint(sites[i].co, sites[i].color, &triangulated_points, &triangulated_points_total); + + edge = boundary_edges.first; + while (edge) { + VoronoiEdge *test_edge = boundary_edges.first; + int ok_start = TRUE, ok_end = TRUE; + + while (test_edge) { + float v1[2], v2[2]; + + sub_v2_v2v2(v1, edge->start, sites[i].co); + sub_v2_v2v2(v2, edge->end, sites[i].co); + + if (ok_start && !testVoronoiEdge(sites[i].co, edge->start, test_edge)) + ok_start = FALSE; + + if (ok_end && !testVoronoiEdge(sites[i].co, edge->end, test_edge)) + ok_end = FALSE; + + test_edge = test_edge->next; + } + + if (ok_start && ok_end) { + int v2, v3; + + v2 = voronoi_addTriangulationPoint(edge->start, sites[i].color, &triangulated_points, &triangulated_points_total); + v3 = voronoi_addTriangulationPoint(edge->end, sites[i].color, &triangulated_points, &triangulated_points_total); + + voronoi_addTriangle(v1, v2, v3, &triangles, &triangles_total); + } + + edge = edge->next; + } + } + + for (i = 0; i < triangulated_points_total; i++) { + VoronoiTriangulationPoint *triangulation_point = &triangulated_points[i]; + + mul_v3_fl(triangulation_point->color, 1.0f / triangulation_point->power); + } + + *triangulated_points_r = triangulated_points; + *triangulated_points_total_r = triangulated_points_total; + + *triangles_r = triangles; + *triangles_total_r = triangles_total; + + BLI_freelistN(&boundary_edges); +} diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 5e778d4d03b..d4e083f9ec1 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -331,6 +331,18 @@ set(SRC operations/COM_DoubleEdgeMaskOperation.cpp operations/COM_DoubleEdgeMaskOperation.h + + nodes/COM_KeyingNode.cpp + nodes/COM_KeyingNode.h + nodes/COM_KeyingScreenNode.cpp + nodes/COM_KeyingScreenNode.h + operations/COM_KeyingOperation.cpp + operations/COM_KeyingOperation.h + operations/COM_KeyingScreenOperation.cpp + operations/COM_KeyingScreenOperation.h + operations/COM_KeyingDispillOperation.cpp + operations/COM_KeyingDispillOperation.h + operations/COM_ColorSpillOperation.cpp operations/COM_ColorSpillOperation.h operations/COM_RenderLayersBaseProg.cpp diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index dc6409e7b86..747d6495f5d 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -112,6 +112,8 @@ #include "COM_DoubleEdgeMaskNode.h" #include "COM_CropNode.h" #include "COM_MaskNode.h" +#include "COM_KeyingScreenNode.h" +#include "COM_KeyingNode.h" Node *Converter::convert(bNode *bNode) { @@ -350,6 +352,11 @@ case CMP_NODE_OUTPUT_FILE: break; case CMP_NODE_MASK: node = new MaskNode(bNode); + case CMP_NODE_KEYINGSCREEN: + node = new KeyingScreenNode(bNode); + break; + case CMP_NODE_KEYING: + node = new KeyingNode(bNode); break; /* not inplemented yet */ default: diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp new file mode 100644 index 00000000000..725060371a1 --- /dev/null +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -0,0 +1,211 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_KeyingNode.h" + +#include "COM_ExecutionSystem.h" + +#include "COM_KeyingOperation.h" +#include "COM_KeyingDispillOperation.h" + +#include "COM_SeparateChannelOperation.h" +#include "COM_CombineChannelsOperation.h" +#include "COM_ConvertRGBToYCCOperation.h" +#include "COM_ConvertYCCToRGBOperation.h" +#include "COM_FastGaussianBlurOperation.h" +#include "COM_SetValueOperation.h" + +#include "COM_DilateErodeOperation.h" + +#include "COM_SetAlphaOperation.h" + +KeyingNode::KeyingNode(bNode *editorNode): Node(editorNode) +{ +} + +OutputSocket *KeyingNode::setupPreBlur(ExecutionSystem *graph, InputSocket *inputImage, int size, OutputSocket **originalImage) +{ + memset(&preBlurData, 0, sizeof(preBlurData)); + preBlurData.sizex = size; + preBlurData.sizey = size; + + ConvertRGBToYCCOperation *convertRGBToYCCOperation = new ConvertRGBToYCCOperation(); + convertRGBToYCCOperation->setMode(0); /* ITU 601 */ + + inputImage->relinkConnections(convertRGBToYCCOperation->getInputSocket(0), 0, graph); + graph->addOperation(convertRGBToYCCOperation); + + CombineChannelsOperation *combineOperation = new CombineChannelsOperation(); + graph->addOperation(combineOperation); + + for (int channel = 0; channel < 4; channel++) { + SeparateChannelOperation *separateOperation = new SeparateChannelOperation(); + separateOperation->setChannel(channel); + addLink(graph, convertRGBToYCCOperation->getOutputSocket(0), separateOperation->getInputSocket(0)); + graph->addOperation(separateOperation); + + if (channel == 0 || channel == 3) { + addLink(graph, separateOperation->getOutputSocket(0), combineOperation->getInputSocket(channel)); + } + else { + SetValueOperation *setValueOperation = new SetValueOperation(); + setValueOperation->setValue(1.0f); + graph->addOperation(setValueOperation); + + FastGaussianBlurOperation *blurOperation = new FastGaussianBlurOperation(); + blurOperation->setData(&preBlurData); + + addLink(graph, separateOperation->getOutputSocket(0), blurOperation->getInputSocket(0)); + addLink(graph, setValueOperation->getOutputSocket(0), blurOperation->getInputSocket(1)); + addLink(graph, blurOperation->getOutputSocket(0), combineOperation->getInputSocket(channel)); + graph->addOperation(blurOperation); + } + } + + ConvertYCCToRGBOperation *convertYCCToRGBOperation = new ConvertYCCToRGBOperation(); + convertYCCToRGBOperation->setMode(0); /* ITU 601 */ + addLink(graph, combineOperation->getOutputSocket(0), convertYCCToRGBOperation->getInputSocket(0)); + graph->addOperation(convertYCCToRGBOperation); + + *originalImage = convertRGBToYCCOperation->getInputSocket(0)->getConnection()->getFromSocket(); + + return convertYCCToRGBOperation->getOutputSocket(0); +} + +OutputSocket *KeyingNode::setupPostBlur(ExecutionSystem *graph, OutputSocket *postBLurInput, int size) +{ + memset(&postBlurData, 0, sizeof(postBlurData)); + + postBlurData.sizex = size; + postBlurData.sizey = size; + + SetValueOperation *setValueOperation = new SetValueOperation(); + + setValueOperation->setValue(1.0f); + graph->addOperation(setValueOperation); + + FastGaussianBlurOperation *blurOperation = new FastGaussianBlurOperation(); + blurOperation->setData(&postBlurData); + + addLink(graph, postBLurInput, blurOperation->getInputSocket(0)); + addLink(graph, setValueOperation->getOutputSocket(0), blurOperation->getInputSocket(1)); + + graph->addOperation(blurOperation); + + return blurOperation->getOutputSocket(); +} + +OutputSocket *KeyingNode::setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance) +{ + DilateStepOperation *dilateErodeOperation; + + if (distance > 0) { + dilateErodeOperation = new DilateStepOperation(); + dilateErodeOperation->setIterations(distance); + } + else { + dilateErodeOperation = new ErodeStepOperation(); + dilateErodeOperation->setIterations(-distance); + } + + addLink(graph, dilateErodeInput, dilateErodeOperation->getInputSocket(0)); + + graph->addOperation(dilateErodeOperation); + + return dilateErodeOperation->getOutputSocket(0); +} + +OutputSocket *KeyingNode::setupDispill(ExecutionSystem *graph, OutputSocket *dispillInput, InputSocket *inputScreen, float factor) +{ + KeyingDispillOperation *dispillOperation = new KeyingDispillOperation(); + + dispillOperation->setDispillFactor(factor); + + addLink(graph, dispillInput, dispillOperation->getInputSocket(0)); + inputScreen->relinkConnections(dispillOperation->getInputSocket(1), 1, graph); + + graph->addOperation(dispillOperation); + + return dispillOperation->getOutputSocket(0); +} + +void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) +{ + InputSocket *inputImage = this->getInputSocket(0); + InputSocket *inputScreen = this->getInputSocket(1); + OutputSocket *outputImage = this->getOutputSocket(0); + OutputSocket *outputMatte = this->getOutputSocket(1); + OutputSocket *postprocessedMatte, *postprocessedImage, *originalImage; + + bNode *editorNode = this->getbNode(); + NodeKeyingData *keying_data = (NodeKeyingData *) editorNode->storage; + + /* keying operation */ + KeyingOperation *keyingOperation = new KeyingOperation(); + + keyingOperation->setClipBlack(keying_data->clip_black); + keyingOperation->setClipWhite(keying_data->clip_white); + + inputScreen->relinkConnections(keyingOperation->getInputSocket(1), 1, graph); + + if (keying_data->blur_pre) { + /* chroma preblur operation for input of keying operation */ + OutputSocket *preBluredImage = setupPreBlur(graph, inputImage, keying_data->blur_pre, &originalImage); + addLink(graph, preBluredImage, keyingOperation->getInputSocket(0)); + } + else { + inputImage->relinkConnections(keyingOperation->getInputSocket(0), 0, graph); + originalImage = keyingOperation->getInputSocket(0)->getConnection()->getFromSocket(); + } + + graph->addOperation(keyingOperation); + + /* apply blur on matte if needed */ + if (keying_data->blur_post) + postprocessedMatte = setupPostBlur(graph, keyingOperation->getOutputSocket(), keying_data->blur_post); + else + postprocessedMatte = keyingOperation->getOutputSocket(); + + /* matte dilate/erode */ + if (keying_data->dilate_distance != 0) { + postprocessedMatte = setupDilateErode(graph, postprocessedMatte, keying_data->dilate_distance); + } + + /* set alpha channel to output image */ + SetAlphaOperation *alphaOperation = new SetAlphaOperation(); + addLink(graph, originalImage, alphaOperation->getInputSocket(0)); + addLink(graph, postprocessedMatte, alphaOperation->getInputSocket(1)); + + postprocessedImage = alphaOperation->getOutputSocket(); + + /* dispill output image */ + if (keying_data->dispill_factor > 0.0f) { + postprocessedImage = setupDispill(graph, postprocessedImage, inputScreen, keying_data->dispill_factor); + } + + /* connect result to output sockets */ + outputImage->relinkConnections(postprocessedImage); + outputMatte->relinkConnections(postprocessedMatte); + + graph->addOperation(alphaOperation); +} diff --git a/source/blender/compositor/nodes/COM_KeyingNode.h b/source/blender/compositor/nodes/COM_KeyingNode.h new file mode 100644 index 00000000000..8c1ee8fdf72 --- /dev/null +++ b/source/blender/compositor/nodes/COM_KeyingNode.h @@ -0,0 +1,44 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_Node.h" +#include "DNA_node_types.h" + +/** + * @brief KeyingNode + * @ingroup Node + */ +class KeyingNode : public Node { +protected: + NodeBlurData preBlurData; + NodeBlurData postBlurData; + + OutputSocket *setupPreBlur(ExecutionSystem *graph, InputSocket *inputImage, int size, OutputSocket **originalImage); + OutputSocket *setupPostBlur(ExecutionSystem *graph, OutputSocket *postBLurInput, int size); + OutputSocket *setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance); + OutputSocket *setupDispill(ExecutionSystem *graph, OutputSocket *dispillInput, InputSocket *inputSrceen, float factor); +public: + KeyingNode(bNode *editorNode); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); + +}; diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp new file mode 100644 index 00000000000..ad58adae48b --- /dev/null +++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_KeyingScreenNode.h" +#include "COM_ExecutionSystem.h" +#include "COM_KeyingScreenOperation.h" + +extern "C" { + #include "DNA_movieclip_types.h" +} + +KeyingScreenNode::KeyingScreenNode(bNode *editorNode): Node(editorNode) +{ +} + +void KeyingScreenNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +{ + OutputSocket *outputScreen = this->getOutputSocket(0); + + bNode *editorNode = this->getbNode(); + MovieClip *clip = (MovieClip *) editorNode->id; + + NodeKeyingScreenData *keyingscreen_data = (NodeKeyingScreenData *) editorNode->storage; + + // always connect the output image + KeyingScreenOperation *operation = new KeyingScreenOperation(); + + if (outputScreen->isConnected()) { + outputScreen->relinkConnections(operation->getOutputSocket()); + } + + operation->setMovieClip(clip); + operation->setTrackingObject(keyingscreen_data->tracking_object); + operation->setFramenumber(context->getFramenumber()); + + graph->addOperation(operation); +} diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.h b/source/blender/compositor/nodes/COM_KeyingScreenNode.h new file mode 100644 index 00000000000..7c87219ef6e --- /dev/null +++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.h @@ -0,0 +1,36 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_Node.h" +#include "DNA_node_types.h" + +/** + * @brief KeyingScreenNode + * @ingroup Node + */ +class KeyingScreenNode : public Node { +public: + KeyingScreenNode(bNode *editorNode); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); + +}; diff --git a/source/blender/compositor/operations/COM_KeyingDispillOperation.cpp b/source/blender/compositor/operations/COM_KeyingDispillOperation.cpp new file mode 100644 index 00000000000..5f4eaf3148d --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingDispillOperation.cpp @@ -0,0 +1,89 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_KeyingDispillOperation.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" + +static int get_pixel_primary_channel(float *pixel) +{ + float max_value = MAX3(pixel[0], pixel[1], pixel[2]); + + if (max_value == pixel[0]) + return 0; + else if (max_value == pixel[1]) + return 1; + + return 2; +} + +KeyingDispillOperation::KeyingDispillOperation(): NodeOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + + this->dispillFactor = 0.5f; + + this->pixelReader = NULL; + this->screenReader = NULL; +} + +void KeyingDispillOperation::initExecution() +{ + this->pixelReader = this->getInputSocketReader(0); + this->screenReader = this->getInputSocketReader(1); +} + +void KeyingDispillOperation::deinitExecution() +{ + this->pixelReader = NULL; + this->screenReader = NULL; +} + +void KeyingDispillOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +{ + float pixelColor[4]; + float screenColor[4]; + + this->pixelReader->read(pixelColor, x, y, sampler, inputBuffers); + this->screenReader->read(screenColor, x, y, sampler, inputBuffers); + + int screen_primary_channel = get_pixel_primary_channel(screenColor); + float average_value, amount; + + average_value = (pixelColor[0] + pixelColor[1] + pixelColor[2] - pixelColor[screen_primary_channel]) / 2.0f; + amount = pixelColor[screen_primary_channel] - average_value; + + color[0] = pixelColor[0]; + color[1] = pixelColor[1]; + color[2] = pixelColor[2]; + color[3] = pixelColor[3]; + + if (this->dispillFactor * amount > 0) { + color[screen_primary_channel] = pixelColor[screen_primary_channel] - this->dispillFactor * amount; + } +} diff --git a/source/blender/compositor/operations/COM_KeyingDispillOperation.h b/source/blender/compositor/operations/COM_KeyingDispillOperation.h new file mode 100644 index 00000000000..a918a918381 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingDispillOperation.h @@ -0,0 +1,49 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#ifndef _COM_KeyingDispillOperation_h +#define _COM_KeyingDispillOperation_h + +#include "COM_NodeOperation.h" + +/** + * Class with implementation of keying dispill node + */ +class KeyingDispillOperation : public NodeOperation { +protected: + SocketReader *pixelReader; + SocketReader *screenReader; + float dispillFactor; + +public: + KeyingDispillOperation(); + + void initExecution(); + void deinitExecution(); + + void setDispillFactor(float value) {this->dispillFactor = value;} + + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp new file mode 100644 index 00000000000..43348568a5d --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp @@ -0,0 +1,114 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_KeyingOperation.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" + +static int get_pixel_primary_channel(float *pixel) +{ + float max_value = MAX3(pixel[0], pixel[1], pixel[2]); + + if (max_value == pixel[0]) + return 0; + else if (max_value == pixel[1]) + return 1; + + return 2; +} + +static float get_pixel_saturation(float *pixel, float screen_balance) +{ + float min = MIN3(pixel[0], pixel[1], pixel[2]); + float max = MAX3(pixel[0], pixel[1], pixel[2]); + float mid = pixel[0] + pixel[1] + pixel[2] - min - max; + float val = (1.0f - screen_balance) * min + screen_balance * mid; + + return max - val; +} + +KeyingOperation::KeyingOperation(): NodeOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VALUE); + + this->screenBalance = 0.5f; + this->clipBlack = 0.0f; + this->clipWhite = 1.0f; + + this->pixelReader = NULL; + this->screenReader = NULL; +} + +void KeyingOperation::initExecution() +{ + this->pixelReader = this->getInputSocketReader(0); + this->screenReader = this->getInputSocketReader(1); +} + +void KeyingOperation::deinitExecution() +{ + this->pixelReader = NULL; + this->screenReader = NULL; +} + +void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +{ + float pixelColor[4]; + float screenColor[4]; + + this->pixelReader->read(pixelColor, x, y, sampler, inputBuffers); + this->screenReader->read(screenColor, x, y, sampler, inputBuffers); + + float saturation = get_pixel_saturation(pixelColor, this->screenBalance); + float screen_saturation = get_pixel_saturation(screenColor, this->screenBalance); + int primary_channel = get_pixel_primary_channel(pixelColor); + int screen_primary_channel = get_pixel_primary_channel(screenColor); + + if (primary_channel != screen_primary_channel) { + /* different main channel means pixel is on foreground */ + color[0] = 1.0f; + } + else if (saturation >= screen_saturation) { + /* saturation of main channel is more than screen, definitely a background */ + color[0] = 0.0f; + } + else { + float distance; + + distance = 1.0f - saturation / screen_saturation; + + color[0] = distance; + + if (color[0] < this->clipBlack) + color[0] = 0.0f; + else if (color[0] >= this->clipWhite) + color[0] = 1.0f; + else + color[0] = (color[0] - this->clipBlack) / (this->clipWhite - this->clipBlack); + } +} diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h new file mode 100644 index 00000000000..546ff355573 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingOperation.h @@ -0,0 +1,57 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + + +#ifndef _COM_KeyingOperation_h +#define _COM_KeyingOperation_h + +#include + +#include "COM_NodeOperation.h" + +#include "BLI_listbase.h" + +/** + * Class with implementation of keying node + */ +class KeyingOperation : public NodeOperation { +protected: + SocketReader *pixelReader; + SocketReader *screenReader; + float screenBalance; + float clipBlack; + float clipWhite; + +public: + KeyingOperation(); + + void initExecution(); + void deinitExecution(); + + void setClipBlack(float value) {this->clipBlack = value;} + void setClipWhite(float value) {this->clipWhite = value;} + + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp new file mode 100644 index 00000000000..456ab31db24 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -0,0 +1,217 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_KeyingScreenOperation.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_math_color.h" + +#include "DNA_scene_types.h" + +extern "C" { + #include "BKE_movieclip.h" + #include "BKE_tracking.h" + + #include "IMB_imbuf.h" + #include "IMB_imbuf_types.h" +} + +KeyingScreenOperation::KeyingScreenOperation(): NodeOperation() +{ + this->addOutputSocket(COM_DT_COLOR); + this->movieClip = NULL; + this->framenumber = 0; + this->trackingObject[0] = 0; + setComplex(true); +} + +void KeyingScreenOperation::initExecution() +{ + initMutex(); + this->cachedTriangulation = NULL; +} + +void KeyingScreenOperation::deinitExecution() +{ + if (this->cachedTriangulation) { + TriangulationData *triangulation = cachedTriangulation; + + if (triangulation->triangulated_points) + MEM_freeN(triangulation->triangulated_points); + + if (triangulation->triangles) + MEM_freeN(triangulation->triangles); + + MEM_freeN(this->cachedTriangulation); + + this->cachedTriangulation = NULL; + } +} + +KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTriangulation() +{ + MovieClipUser user = {0}; + TriangulationData *triangulation; + MovieTracking *tracking = &movieClip->tracking; + MovieTrackingTrack *track; + VoronoiSite *sites; + ImBuf *ibuf; + ListBase *tracksbase; + ListBase edges = {NULL, NULL}; + int sites_total; + int i; + int width = this->getWidth(); + int height = this->getHeight(); + + if (this->trackingObject[0]) { + MovieTrackingObject *object = BKE_tracking_named_object(tracking, this->trackingObject); + + if (!object) + return NULL; + + tracksbase = BKE_tracking_object_tracks(tracking, object); + } + else + tracksbase = BKE_tracking_get_tracks(tracking); + + sites_total = BLI_countlist(tracksbase); + + if (!sites_total) + return NULL; + + triangulation = (TriangulationData *) MEM_callocN(sizeof(TriangulationData), "keying screen triangulation data"); + + BKE_movieclip_user_set_frame(&user, framenumber); + ibuf = BKE_movieclip_get_ibuf(movieClip, &user); + + sites = (VoronoiSite *) MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites"); + track = (MovieTrackingTrack *) tracksbase->first; + i = 0; + while (track) { + VoronoiSite *site = &sites[i]; + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenumber); + ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, 0, TRUE, NULL, NULL); + int j; + + zero_v3(site->color); + for (j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) { + if (pattern_ibuf->rect_float) { + add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]); + } + else { + unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect; + + site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f); + site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f); + site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f); + } + } + + mul_v3_fl(site->color, 1.0f / (pattern_ibuf->x * pattern_ibuf->y)); + IMB_freeImBuf(pattern_ibuf); + + site->co[0] = marker->pos[0] * width; + site->co[1] = marker->pos[1] * height; + + track = track->next; + i++; + } + + IMB_freeImBuf(ibuf); + + BLI_voronoi_compute(sites, sites_total, width, height, &edges); + + BLI_voronoi_triangulate(sites, sites_total, &edges, width, height, + &triangulation->triangulated_points, &triangulation->triangulated_points_total, + &triangulation->triangles, &triangulation->triangles_total); + + MEM_freeN(sites); + BLI_freelistN(&edges); + + return triangulation; +} + +void *KeyingScreenOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + if (this->movieClip == NULL) + return NULL; + + if (this->cachedTriangulation) + return this->cachedTriangulation; + + BLI_mutex_lock(getMutex()); + if (this->cachedTriangulation == NULL) { + this->cachedTriangulation = buildVoronoiTriangulation(); + } + BLI_mutex_unlock(getMutex()); + + return this->cachedTriangulation; +} + +void KeyingScreenOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) +{ + resolution[0] = 0; + resolution[1] = 0; + + if (this->movieClip) { + MovieClipUser user = {0}; + int width, height; + + BKE_movieclip_user_set_frame(&user, framenumber); + BKE_movieclip_get_size(this->movieClip, &user, &width, &height); + + resolution[0] = width; + resolution[1] = height; + } +} + +void KeyingScreenOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + color[0] = 0.0f; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 1.0f; + + if (this->movieClip && data) { + TriangulationData *triangulation = (TriangulationData *) data; + int i; + for (i = 0; i < triangulation->triangles_total; i++) { + int *triangle = triangulation->triangles[i]; + VoronoiTriangulationPoint *a = &triangulation->triangulated_points[triangle[0]], + *b = &triangulation->triangulated_points[triangle[1]], + *c = &triangulation->triangulated_points[triangle[2]]; + float co[2] = {(float) x, (float) y}, w[3]; + + if (barycentric_coords_v2(a->co, b->co, c->co, co, w)) { + if (barycentric_inside_triangle_v2(w)) { + color[0] += a->color[0] * w[0] + b->color[0] * w[1] + c->color[0] * w[2]; + color[1] += a->color[1] * w[0] + b->color[1] * w[1] + c->color[1] * w[2]; + color[2] += a->color[2] * w[0] + b->color[2] * w[1] + c->color[2] * w[2]; + } + } + } + } +} diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h new file mode 100644 index 00000000000..9d3f44f6be2 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h @@ -0,0 +1,79 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + + +#ifndef _COM_KeyingScreenOperation_h +#define _COM_KeyingScreenOperation_h + +#include + +#include "COM_NodeOperation.h" + +#include "DNA_scene_types.h" +#include "DNA_movieclip_types.h" + +#include "BLI_listbase.h" + +extern "C" { + #include "BLI_voronoi.h" +} + +/** + * Class with implementation of green screen gradient rasterization + */ +class KeyingScreenOperation : public NodeOperation { +protected: + typedef struct TriangulationData { + VoronoiTriangulationPoint *triangulated_points; + int (*triangles)[3]; + int triangulated_points_total, triangles_total; + } TriangulationData; + + MovieClip *movieClip; + int framenumber; + TriangulationData *cachedTriangulation; + char trackingObject[64]; + + /** + * Determine the output resolution. The resolution is retrieved from the Renderer + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + TriangulationData *buildVoronoiTriangulation(); + + public: + KeyingScreenOperation(); + + void initExecution(); + void deinitExecution(); + + void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + void setMovieClip(MovieClip *clip) {this->movieClip = clip;} + void setTrackingObject(char *object) {strncpy(this->trackingObject, object, sizeof(this->trackingObject));} + void setFramenumber(int framenumber) {this->framenumber = framenumber;} + + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); +}; + +#endif diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 3c070b4e637..341926f50a3 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2394,6 +2394,36 @@ static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *p uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL); } +static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + bNode *node= ptr->data; + + uiTemplateID(layout, C, ptr, "clip", NULL, NULL, NULL); + + if (node->id) { + MovieClip *clip = (MovieClip *) node->id; + uiLayout *col; + PointerRNA tracking_ptr; + + RNA_pointer_create(&clip->id, &RNA_MovieTracking, &clip->tracking, &tracking_ptr); + + col = uiLayoutColumn(layout, 1); + uiItemPointerR(col, ptr, "tracking_object", &tracking_ptr, "objects", "", ICON_OBJECT_DATA); + } +} + +static void node_composit_buts_keying(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + bNode *node= ptr->data; + + uiItemR(layout, ptr, "blur_pre", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "dispill_factor", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "clip_black", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "clip_white", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "dilate_distance", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "blur_post", 0, NULL, ICON_NONE); +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -2586,7 +2616,12 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_MASK: ntype->uifunc= node_composit_buts_mask; break; - + case CMP_NODE_KEYINGSCREEN: + ntype->uifunc = node_composit_buts_keyingscreen; + break; + case CMP_NODE_KEYING: + ntype->uifunc = node_composit_buts_keying; + break; default: ntype->uifunc = NULL; } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index b2781675cbe..bad40e80265 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -617,6 +617,17 @@ typedef struct TexNodeOutput { char name[64]; } TexNodeOutput; +typedef struct NodeKeyingScreenData { + char tracking_object[64]; +} NodeKeyingScreenData; + +typedef struct NodeKeyingData { + float dispill_factor; + float clip_black, clip_white; + int dilate_distance; + int blur_pre, blur_post; +} NodeKeyingData; + /* frame node flags */ #define NODE_FRAME_SHRINK 1 /* keep the bounding box minimal */ #define NODE_FRAME_RESIZEABLE 2 /* test flag, if frame can be resized by user */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 0a0efb66f7f..842ad4156d8 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -341,6 +341,7 @@ extern StructRNA RNA_MotionPathVert; extern StructRNA RNA_MouseSensor; extern StructRNA RNA_MovieSequence; extern StructRNA RNA_MovieClipSequence; +extern StructRNA RNA_MovieTracking; extern StructRNA RNA_MovieTrackingTrack; extern StructRNA RNA_MovieTrackingObject; extern StructRNA RNA_MovieTrackingTrack; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 59c4af4c376..7d2935ece6e 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3046,6 +3046,67 @@ static void def_cmp_mask(StructRNA *srna) RNA_def_property_struct_type(prop, "Mask"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Mask", ""); +} + +static void def_cmp_keyingscreen(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "MovieClip"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Movie Clip", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + RNA_def_struct_sdna_from(srna, "NodeKeyingScreenData", "storage"); + + prop = RNA_def_property(srna, "tracking_object", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "tracking_object"); + RNA_def_property_ui_text(prop, "Tracking Object", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); +} + +static void def_cmp_keying(StructRNA *srna) +{ + PropertyRNA *prop; + + RNA_def_struct_sdna_from(srna, "NodeKeyingData", "storage"); + + prop = RNA_def_property(srna, "dispill_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "dispill_factor"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Dispill", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "clip_black", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "clip_black"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Clip Black", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "clip_white", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "clip_white"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Clip White", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "blur_pre", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "blur_pre"); + RNA_def_property_range(prop, 0, 2048); + RNA_def_property_ui_text(prop, "Pre Blur", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "blur_post", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "blur_post"); + RNA_def_property_range(prop, 0, 2048); + RNA_def_property_ui_text(prop, "Post Blur", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "dilate_distance", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "dilate_distance"); + RNA_def_property_range(prop, -100, 100); + RNA_def_property_ui_text(prop, "Dilate/Erode", ""); RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); } diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index d5b33f0d01b..d8c27a3677f 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -166,6 +166,8 @@ DefNode( CompositorNode, CMP_NODE_BOKEHIMAGE, def_cmp_bokehimage, "BOKEH DefNode( CompositorNode, CMP_NODE_SWITCH, def_cmp_switch, "SWITCH" ,Switch, "Switch", "" ) DefNode( CompositorNode, CMP_NODE_COLORCORRECTION,def_cmp_colorcorrection,"COLORCORRECTION",ColorCorrection, "ColorCorrection", "" ) DefNode( CompositorNode, CMP_NODE_MASK, def_cmp_mask, "MASK", Mask, "Mask", "" ) +DefNode( CompositorNode, CMP_NODE_KEYINGSCREEN, def_cmp_keyingscreen, "KEYINGSCREEN", KeyingScreen, "KeyingScreen", "" ) +DefNode( CompositorNode, CMP_NODE_KEYING, def_cmp_keying, "KEYING", Keying, "Keying", "" ) DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" ) DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" ) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 5e36f90f217..d07d00a436d 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -76,6 +76,8 @@ set(SRC composite/nodes/node_composite_idMask.c composite/nodes/node_composite_image.c composite/nodes/node_composite_invert.c + composite/nodes/node_composite_keying.c + composite/nodes/node_composite_keyingscreen.c composite/nodes/node_composite_lensdist.c composite/nodes/node_composite_levels.c composite/nodes/node_composite_lummaMatte.c diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index f850ea91f12..efa107a2223 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -81,6 +81,7 @@ void register_node_type_cmp_bilateralblur(struct bNodeTreeType *ttype); void register_node_type_cmp_vecblur(struct bNodeTreeType *ttype); void register_node_type_cmp_dilateerode(struct bNodeTreeType *ttype); void register_node_type_cmp_defocus(struct bNodeTreeType *ttype); +void register_node_type_cmp_denoise(struct bNodeTreeType *ttype); void register_node_type_cmp_valtorgb(struct bNodeTreeType *ttype); void register_node_type_cmp_rgbtobw(struct bNodeTreeType *ttype); @@ -105,6 +106,8 @@ void register_node_type_cmp_channel_matte(struct bNodeTreeType *ttype); void register_node_type_cmp_color_spill(struct bNodeTreeType *ttype); void register_node_type_cmp_luma_matte(struct bNodeTreeType *ttype); void register_node_type_cmp_doubleedgemask(struct bNodeTreeType *ttype); +void register_node_type_cmp_keyingscreen(struct bNodeTreeType *ttype); +void register_node_type_cmp_keying(struct bNodeTreeType *ttype); void register_node_type_cmp_translate(struct bNodeTreeType *ttype); void register_node_type_cmp_rotate(struct bNodeTreeType *ttype); diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c index 3806cf4543a..ff223ac83cf 100644 --- a/source/blender/nodes/composite/node_composite_util.c +++ b/source/blender/nodes/composite/node_composite_util.c @@ -568,6 +568,22 @@ CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel) return valbuf; } +void valbuf_to_rgbabuf(CompBuf *valbuf, CompBuf *cbuf, int channel) +{ + float *valf, *rectf; + int tot; + + valf= valbuf->rect; + + /* defaults to returning alpha channel */ + if ((channel < CHAN_R) || (channel > CHAN_A)) channel = CHAN_A; + + rectf = cbuf->rect + channel; + + for (tot= cbuf->x*cbuf->y; tot>0; tot--, valf++, rectf+=4) + *rectf = *valf; +} + static CompBuf *generate_procedural_preview(CompBuf *cbuf, int newx, int newy) { CompBuf *outbuf; diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h index 51f047b94ff..18dac5dc5c1 100644 --- a/source/blender/nodes/composite/node_composite_util.h +++ b/source/blender/nodes/composite/node_composite_util.h @@ -155,6 +155,7 @@ void composit4_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, flo int src1_type, int fac1_type, int src2_type, int fac2_type); CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel); +void valbuf_to_rgbabuf(CompBuf *valbuf, CompBuf *cbuf, int channel); void generate_preview(void *data, bNode *node, CompBuf *stackbuf); void do_copy_rgba(bNode *node, float *out, float *in); @@ -220,6 +221,9 @@ void IIR_gauss(CompBuf* src, float sigma, int chan, int xy); #define CMP_SCALE_MAX 12000 CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type); +void node_composit_blur_single_image(bNode *node, int filtertype, int sizex, int sizey, CompBuf *new, CompBuf *img, float scale); +void node_composite_morpho_dilate(CompBuf *cbuf); +void node_composite_morpho_erode(CompBuf *cbuf); float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc); #endif diff --git a/source/blender/nodes/composite/nodes/node_composite_blur.c b/source/blender/nodes/composite/nodes/node_composite_blur.c index d19ea3f202f..9afdd6eadb7 100644 --- a/source/blender/nodes/composite/nodes/node_composite_blur.c +++ b/source/blender/nodes/composite/nodes/node_composite_blur.c @@ -85,9 +85,8 @@ static float *make_bloomtab(int rad) } /* both input images of same type, either 4 or 1 channel */ -static void blur_single_image(bNode *node, CompBuf *new, CompBuf *img, float scale) +void node_composit_blur_single_image(bNode *node, int filtertype, int sizex, int sizey, CompBuf *new, CompBuf *img, float scale) { - NodeBlurData *nbd= node->storage; CompBuf *work; register float sum, val; float rval, gval, bval, aval; @@ -101,17 +100,17 @@ static void blur_single_image(bNode *node, CompBuf *new, CompBuf *img, float sca work= alloc_compbuf(imgx, imgy, img->type, 1); /* allocs */ /* horizontal */ - if (nbd->sizex == 0) { + if (sizex == 0) { memcpy(work->rect, img->rect, sizeof(float) * img->type * imgx * imgy); } else { - rad = scale*(float)nbd->sizex; + rad = scale*(float)sizex; if (rad>imgx/2) rad= imgx/2; else if (rad<1) rad= 1; - gausstab= make_gausstab(nbd->filtertype, rad); + gausstab= make_gausstab(filtertype, rad); gausstabcent= gausstab+rad; for (y = 0; y < imgy; y++) { @@ -152,17 +151,17 @@ static void blur_single_image(bNode *node, CompBuf *new, CompBuf *img, float sca MEM_freeN(gausstab); } - if (nbd->sizey == 0) { + if (sizey == 0) { memcpy(new->rect, work->rect, sizeof(float) * img->type * imgx * imgy); } else { - rad = scale*(float)nbd->sizey; + rad = scale*(float)sizey; if (rad>imgy/2) rad= imgy/2; else if (rad<1) rad= 1; - gausstab= make_gausstab(nbd->filtertype, rad); + gausstab= make_gausstab(filtertype, rad); gausstabcent= gausstab+rad; bigstep = pix*imgx; @@ -207,6 +206,13 @@ static void blur_single_image(bNode *node, CompBuf *new, CompBuf *img, float sca free_compbuf(work); } +static void blur_single_image(bNode *node, CompBuf *new, CompBuf *img, float scale) +{ + NodeBlurData *nbd = node->storage; + + node_composit_blur_single_image(node, nbd->filtertype, nbd->sizex, nbd->sizey, new, img, scale); +} + /* reference has to be mapped 0-1, and equal in size */ static void bloom_with_reference(CompBuf *new, CompBuf *img, CompBuf *UNUSED(ref), float UNUSED(fac), NodeBlurData *nbd) { diff --git a/source/blender/nodes/composite/nodes/node_composite_dilate.c b/source/blender/nodes/composite/nodes/node_composite_dilate.c index ee857dd0007..1dc56fd4279 100644 --- a/source/blender/nodes/composite/nodes/node_composite_dilate.c +++ b/source/blender/nodes/composite/nodes/node_composite_dilate.c @@ -44,7 +44,7 @@ static bNodeSocketTemplate cmp_node_dilateerode_out[]= { { -1, 0, "" } }; -static void morpho_dilate(CompBuf *cbuf) +void node_composite_morpho_dilate(CompBuf *cbuf) { int x, y; float *p, *rectf = cbuf->rect; @@ -78,7 +78,7 @@ static void morpho_dilate(CompBuf *cbuf) } } -static void morpho_erode(CompBuf *cbuf) +void node_composite_morpho_erode(CompBuf *cbuf) { int x, y; float *p, *rectf = cbuf->rect; @@ -133,11 +133,11 @@ static void node_composit_exec_dilateerode(void *UNUSED(data), bNode *node, bNod if (node->custom2 > 0) { // positive, dilate for (i = 0; i < node->custom2; i++) - morpho_dilate(stackbuf); + node_composite_morpho_dilate(stackbuf); } else if (node->custom2 < 0) { // negative, erode for (i = 0; i > node->custom2; i--) - morpho_erode(stackbuf); + node_composite_morpho_erode(stackbuf); } if (cbuf!=in[0]->data) diff --git a/source/blender/nodes/composite/nodes/node_composite_keying.c b/source/blender/nodes/composite/nodes/node_composite_keying.c new file mode 100644 index 00000000000..8e6fd86eae5 --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_keying.c @@ -0,0 +1,218 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_keying.c + * \ingroup cmpnodes + */ + +#include "BLF_translation.h" + +#include "DNA_movieclip_types.h" + +#include "BKE_movieclip.h" + +#include "BLI_listbase.h" +#include "BLI_math_base.h" +#include "BLI_math_color.h" +#include "BLI_voronoi.h" + +#include "node_composite_util.h" + +/* **************** Translate ******************** */ + +static bNodeSocketTemplate cmp_node_keying_in[] = { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Key Color", 1.0f, 1.0f, 1.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate cmp_node_keying_out[] = { + { SOCK_RGBA, 0, "Image"}, + { SOCK_FLOAT, 0, "Matte"}, + { -1, 0, "" } +}; + +static int get_pixel_primary_channel(float *pixel) +{ + float max_value = MAX3(pixel[0], pixel[1], pixel[2]); + + if (max_value == pixel[0]) + return 0; + else if (max_value == pixel[1]) + return 1; + + return 2; +} + +static float get_pixel_saturation(float *pixel, float screen_balance) +{ + float min = MIN3(pixel[0], pixel[1], pixel[2]); + float max = MAX3(pixel[0], pixel[1], pixel[2]); + float mid = pixel[0] + pixel[1] + pixel[2] - min - max; + float val = (1.0f - screen_balance) * min + screen_balance * mid; + + return max - val; +} + +static void despil_pixel(float *out, float *pixel, float *screen, float screen_gain) +{ + int screen_primary_channel = get_pixel_primary_channel(screen); + float average_value, amount; + + average_value = (pixel[0] + pixel[1] + pixel[2] - pixel[screen_primary_channel]) / 2.0f; + amount = pixel[screen_primary_channel] - average_value; + + if (screen_gain * amount > 0) { + out[screen_primary_channel] = pixel[screen_primary_channel] - screen_gain * amount; + } +} + +static void do_key(bNode *node, float *out, float *pixel, float *screen) +{ + NodeKeyingData *data = node->storage; + + float screen_balance = 0.5f; + float dispill_factor = data->dispill_factor; + float clip_black = data->clip_black; + float clip_white = data->clip_white; + + float saturation = get_pixel_saturation(pixel, screen_balance); + float screen_saturation = get_pixel_saturation(screen, screen_balance); + int primary_channel = get_pixel_primary_channel(pixel); + int screen_primary_channel = get_pixel_primary_channel(screen); + + if (primary_channel != screen_primary_channel) { + /* different main channel means pixel is on foreground, + * but screen color still need to be despilled from it */ + despil_pixel(out, pixel, screen, dispill_factor); + out[3] = 1.0f; + } + else if (saturation >= screen_saturation) { + /* saturation of main channel is more than screen, definitely a background */ + out[0] = 0.0f; + out[1] = 0.0f; + out[2] = 0.0f; + out[3] = 0.0f; + } + else { + float distance; + + despil_pixel(out, pixel, screen, dispill_factor); + + distance = 1.0f - saturation / screen_saturation; + + out[3] = distance; + + if (out[3] < clip_black) + out[3] = 0.0f; + else if (out[3] >= clip_white) + out[3] = 1.0f; + else + out[3] = (out[3] - clip_black) / (clip_white - clip_black); + } +} + +static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + if (in[0]->data) { + NodeKeyingData *keying_data = node->storage; + CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA); + CompBuf *keybuf, *mattebuf; + + keybuf = dupalloc_compbuf(cbuf); + + /* single color is used for screen detection */ + composit2_pixel_processor(node, keybuf, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_key, CB_RGBA, CB_VAL); + + /* create a matte from alpha channel */ + mattebuf = valbuf_from_rgbabuf(keybuf, CHAN_A); + + /* apply dilate/erode if needed */ + if (keying_data->dilate_distance != 0) { + int i; + + if (keying_data->dilate_distance > 0) { + for (i = 0; i < keying_data->dilate_distance; i++) + node_composite_morpho_dilate(mattebuf); + } + else { + for (i = 0; i < -keying_data->dilate_distance; i++) + node_composite_morpho_erode(mattebuf); + } + } + + if (keying_data->blur_post > 0.0f) { + /* post-blur of matte */ + CompBuf *newmatte = alloc_compbuf(mattebuf->x, mattebuf->y, mattebuf->type, TRUE); + int size = keying_data->blur_post; + + node_composit_blur_single_image(node, R_FILTER_BOX, size, size, newmatte, mattebuf, 1.0f); + + free_compbuf(mattebuf); + mattebuf = newmatte; + + /* apply blurred matte on output buffer alpha */ + valbuf_to_rgbabuf(mattebuf, keybuf, CHAN_A); + } + + out[0]->data = keybuf; + out[1]->data = mattebuf; + + generate_preview(data, node, keybuf); + + if (cbuf!=in[0]->data) + free_compbuf(cbuf); + } +} + +static void node_composit_init_keying(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +{ + NodeKeyingData *data; + + data = MEM_callocN(sizeof(NodeKeyingData), "node keying data"); + + data->dispill_factor = 1.0f; + data->clip_black = 0.0f; + data->clip_white = 1.0f; + + node->storage = data; +} + +void register_node_type_cmp_keying(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, CMP_NODE_KEYING, "Keying", NODE_CLASS_MATTE, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_keying_in, cmp_node_keying_out); + node_type_size(&ntype, 140, 100, 320); + node_type_init(&ntype, node_composit_init_keying); + node_type_storage(&ntype, "NodeKeyingData", node_free_standard_storage, node_copy_standard_storage); + node_type_exec(&ntype, exec); + + nodeRegisterType(ttype, &ntype); +} diff --git a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c new file mode 100644 index 00000000000..5cbaf4ae2ba --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c @@ -0,0 +1,202 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_keyingscreen.c + * \ingroup cmpnodes + */ + +#include "BLF_translation.h" + +#include "DNA_movieclip_types.h" + +#include "BKE_movieclip.h" + +#include "BLI_listbase.h" +#include "BLI_math_base.h" +#include "BLI_math_color.h" +#include "BLI_voronoi.h" + +#include "node_composite_util.h" + +/* **************** Translate ******************** */ + +static bNodeSocketTemplate cmp_node_keyingscreen_out[] = { + { SOCK_RGBA, 0, "Screen"}, + { -1, 0, "" } +}; + + +static void compute_gradient_screen(RenderData *rd, NodeKeyingScreenData *keyingscreen_data, MovieClip *clip, CompBuf *screenbuf) +{ + MovieClipUser user = {0}; + MovieTracking *tracking = &clip->tracking; + MovieTrackingTrack *track; + VoronoiTriangulationPoint *triangulated_points; + VoronoiSite *sites; + ImBuf *ibuf; + ListBase *tracksbase; + ListBase edges = {NULL, NULL}; + int sites_total, triangulated_points_total, triangles_total; + int (*triangles)[3]; + int i, x, y; + float *rect = screenbuf->rect; + + if (keyingscreen_data->tracking_object[0]) { + MovieTrackingObject *object = BKE_tracking_named_object(tracking, keyingscreen_data->tracking_object); + + if (!object) + return; + + tracksbase = BKE_tracking_object_tracks(tracking, object); + } + else + tracksbase = BKE_tracking_get_tracks(tracking); + + sites_total = BLI_countlist(tracksbase); + + if (!sites_total) + return; + + BKE_movieclip_user_set_frame(&user, rd->cfra); + ibuf = BKE_movieclip_get_ibuf(clip, &user); + + sites = MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites"); + track = tracksbase->first; + i = 0; + while (track) { + VoronoiSite *site = &sites[i]; + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, rd->cfra); + ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, 0, FALSE, NULL, NULL); + int j; + + zero_v3(site->color); + for (j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) { + if (pattern_ibuf->rect_float) { + add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]); + } + else { + unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect; + + site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f); + site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f); + site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f); + } + } + + mul_v3_fl(site->color, 1.0f / (pattern_ibuf->x * pattern_ibuf->y)); + IMB_freeImBuf(pattern_ibuf); + + site->co[0] = marker->pos[0] * screenbuf->x; + site->co[1] = marker->pos[1] * screenbuf->y; + + track = track->next; + i++; + } + + IMB_freeImBuf(ibuf); + + BLI_voronoi_compute(sites, sites_total, screenbuf->x, screenbuf->y, &edges); + + BLI_voronoi_triangulate(sites, sites_total, &edges, screenbuf->x, screenbuf->y, + &triangulated_points, &triangulated_points_total, + &triangles, &triangles_total); + + for (y = 0; y < screenbuf->y; y++) { + for (x = 0; x < screenbuf->x; x++) { + int index = 4 * (y * screenbuf->x + x); + + rect[index + 0] = rect[index + 1] = rect[index + 2] = 0.0f; + rect[index + 3] = 1.0f; + + for (i = 0; i < triangles_total; i++) { + int *triangle = triangles[i]; + VoronoiTriangulationPoint *a = &triangulated_points[triangle[0]], + *b = &triangulated_points[triangle[1]], + *c = &triangulated_points[triangle[2]]; + float co[2] = {x, y}, w[3]; + + if (barycentric_coords_v2(a->co, b->co, c->co, co, w)) { + if (barycentric_inside_triangle_v2(w)) { + rect[index + 0] += a->color[0] * w[0] + b->color[0] * w[1] + c->color[0] * w[2]; + rect[index + 1] += a->color[1] * w[0] + b->color[1] * w[1] + c->color[1] * w[2]; + rect[index + 2] += a->color[2] * w[0] + b->color[2] * w[1] + c->color[2] * w[2]; + } + } + } + } + } + + MEM_freeN(triangulated_points); + MEM_freeN(triangles); + MEM_freeN(sites); + BLI_freelistN(&edges); +} + +static void exec(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) +{ + NodeKeyingScreenData *keyingscreen_data = node->storage; + RenderData *rd = data; + CompBuf *screenbuf = NULL; + + if (node->id) { + MovieClip *clip = (MovieClip *) node->id; + MovieClipUser user = {0}; + int width, height; + + BKE_movieclip_user_set_frame(&user, rd->cfra); + BKE_movieclip_get_size(clip, &user, &width, &height); + + screenbuf = alloc_compbuf(width, height, CB_RGBA, TRUE); + compute_gradient_screen(rd, keyingscreen_data, clip, screenbuf); + } + + out[0]->data = screenbuf; +} + +static void node_composit_init_keyingscreen(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +{ + NodeKeyingScreenData *data; + + data = MEM_callocN(sizeof(NodeKeyingScreenData), "node keyingscreen data"); + + node->storage = data; +} + +void register_node_type_cmp_keyingscreen(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, CMP_NODE_KEYINGSCREEN, "Keying Screen", NODE_CLASS_MATTE, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, cmp_node_keyingscreen_out); + node_type_size(&ntype, 140, 100, 320); + node_type_init(&ntype, node_composit_init_keyingscreen); + node_type_storage(&ntype, "NodeKeyingScreenData", node_free_standard_storage, node_copy_standard_storage); + node_type_exec(&ntype, exec); + + nodeRegisterType(ttype, &ntype); +} From b63a2be5c16d9c0c728cf4e07dc565267b9d2a47 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 29 May 2012 14:54:40 +0000 Subject: [PATCH 102/360] fix for using uninitialized memory when adding spline points, also fix for deleting points not working right. --- source/blender/blenkernel/BKE_mask.h | 2 ++ source/blender/blenkernel/intern/mask.c | 46 ++++++++++++++++++++----- source/blender/editors/mask/mask_ops.c | 9 +++++ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index d463843e561..d02e6f1966b 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -90,6 +90,8 @@ void BKE_mask_coord_to_movieclip(struct MovieClip *clip, struct MovieClipUser *u /* parenting */ +void BKE_mask_update_display(struct Mask *mask, float ctime); + void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime, const int do_newframe); void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene, const int do_newframe); void BKE_mask_parent_init(struct MaskParent *parent); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 439495e8af1..be7fa2fbd74 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1232,24 +1232,54 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) MaskSplinePoint *point_deform = &spline->points_deform[i]; float delta[2]; + *point_deform = *point; + point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL; + if (BKE_mask_evaluate_parent_delta(&point->parent, ctime, delta)) { - - *point_deform = *point; - point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL; - add_v2_v2(point_deform->bezt.vec[0], delta); add_v2_v2(point_deform->bezt.vec[1], delta); add_v2_v2(point_deform->bezt.vec[2], delta); } - else { - *point_deform = *point; - point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL; - } } } } } +/* the purpose of this function is to ensure spline->points_deform is never out of date. + * for now re-evaluate all. eventually this might work differently */ +void BKE_mask_update_display(Mask *mask, float ctime) +{ +#if 0 + MaskObject *maskobj; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + if (spline->points_deform) { + int i = 0; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point; + + if (spline->points_deform) { + point = &spline->points_deform[i]; + BKE_mask_point_free(point); + } + } + if (spline->points_deform) { + MEM_freeN(spline->points_deform); + } + + spline->points_deform = NULL; + } + } + } +#endif + + BKE_mask_evaluate(mask, ctime, FALSE); +} + void BKE_mask_evaluate_all_masks(Main *bmain, float ctime, const int do_newframe) { Mask *mask; diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index ded45e73323..44932cab4df 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1230,6 +1230,9 @@ static int add_vertex_exec(bContext *C, wmOperator *op) BKE_mask_calc_handle_point_auto(mask, spline, point, FALSE); BKE_mask_calc_handle_point_auto(mask, spline, point_other, FALSE); + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; } @@ -1249,6 +1252,9 @@ static int add_vertex_exec(bContext *C, wmOperator *op) } } + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + return OPERATOR_FINISHED; } @@ -1495,6 +1501,9 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) } } + /* TODO: only update edited splines */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; From ec4f6750557218be262cacea53ef4cb0ccaa0671 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 29 May 2012 14:55:01 +0000 Subject: [PATCH 103/360] Fixed stupid typo: dispill vs. despill --- source/blender/compositor/CMakeLists.txt | 4 ++-- .../compositor/nodes/COM_KeyingNode.cpp | 22 +++++++++---------- .../blender/compositor/nodes/COM_KeyingNode.h | 2 +- ...ion.cpp => COM_KeyingDespillOperation.cpp} | 16 +++++++------- ...eration.h => COM_KeyingDespillOperation.h} | 14 ++++++------ source/blender/editors/space_node/drawnode.c | 2 +- source/blender/makesdna/DNA_node_types.h | 2 +- source/blender/makesrna/intern/rna_nodetree.c | 6 ++--- .../composite/nodes/node_composite_keying.c | 8 +++---- 9 files changed, 38 insertions(+), 38 deletions(-) rename source/blender/compositor/operations/{COM_KeyingDispillOperation.cpp => COM_KeyingDespillOperation.cpp} (85%) rename source/blender/compositor/operations/{COM_KeyingDispillOperation.h => COM_KeyingDespillOperation.h} (79%) diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index d4e083f9ec1..3e29583756f 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -340,8 +340,8 @@ set(SRC operations/COM_KeyingOperation.h operations/COM_KeyingScreenOperation.cpp operations/COM_KeyingScreenOperation.h - operations/COM_KeyingDispillOperation.cpp - operations/COM_KeyingDispillOperation.h + operations/COM_KeyingDespillOperation.cpp + operations/COM_KeyingDespillOperation.h operations/COM_ColorSpillOperation.cpp operations/COM_ColorSpillOperation.h diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index 725060371a1..9e29a99293e 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -26,7 +26,7 @@ #include "COM_ExecutionSystem.h" #include "COM_KeyingOperation.h" -#include "COM_KeyingDispillOperation.h" +#include "COM_KeyingDespillOperation.h" #include "COM_SeparateChannelOperation.h" #include "COM_CombineChannelsOperation.h" @@ -135,18 +135,18 @@ OutputSocket *KeyingNode::setupDilateErode(ExecutionSystem *graph, OutputSocket return dilateErodeOperation->getOutputSocket(0); } -OutputSocket *KeyingNode::setupDispill(ExecutionSystem *graph, OutputSocket *dispillInput, InputSocket *inputScreen, float factor) +OutputSocket *KeyingNode::setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, InputSocket *inputScreen, float factor) { - KeyingDispillOperation *dispillOperation = new KeyingDispillOperation(); + KeyingDespillOperation *despillOperation = new KeyingDespillOperation(); - dispillOperation->setDispillFactor(factor); + despillOperation->setDespillFactor(factor); - addLink(graph, dispillInput, dispillOperation->getInputSocket(0)); - inputScreen->relinkConnections(dispillOperation->getInputSocket(1), 1, graph); + addLink(graph, despillInput, despillOperation->getInputSocket(0)); + inputScreen->relinkConnections(despillOperation->getInputSocket(1), 1, graph); - graph->addOperation(dispillOperation); + graph->addOperation(despillOperation); - return dispillOperation->getOutputSocket(0); + return despillOperation->getOutputSocket(0); } void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) @@ -198,9 +198,9 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext * postprocessedImage = alphaOperation->getOutputSocket(); - /* dispill output image */ - if (keying_data->dispill_factor > 0.0f) { - postprocessedImage = setupDispill(graph, postprocessedImage, inputScreen, keying_data->dispill_factor); + /* despill output image */ + if (keying_data->despill_factor > 0.0f) { + postprocessedImage = setupDespill(graph, postprocessedImage, inputScreen, keying_data->despill_factor); } /* connect result to output sockets */ diff --git a/source/blender/compositor/nodes/COM_KeyingNode.h b/source/blender/compositor/nodes/COM_KeyingNode.h index 8c1ee8fdf72..894d0ddc095 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.h +++ b/source/blender/compositor/nodes/COM_KeyingNode.h @@ -36,7 +36,7 @@ protected: OutputSocket *setupPreBlur(ExecutionSystem *graph, InputSocket *inputImage, int size, OutputSocket **originalImage); OutputSocket *setupPostBlur(ExecutionSystem *graph, OutputSocket *postBLurInput, int size); OutputSocket *setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance); - OutputSocket *setupDispill(ExecutionSystem *graph, OutputSocket *dispillInput, InputSocket *inputSrceen, float factor); + OutputSocket *setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, InputSocket *inputSrceen, float factor); public: KeyingNode(bNode *editorNode); void convertToOperations(ExecutionSystem *graph, CompositorContext *context); diff --git a/source/blender/compositor/operations/COM_KeyingDispillOperation.cpp b/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp similarity index 85% rename from source/blender/compositor/operations/COM_KeyingDispillOperation.cpp rename to source/blender/compositor/operations/COM_KeyingDespillOperation.cpp index 5f4eaf3148d..b7fd2772729 100644 --- a/source/blender/compositor/operations/COM_KeyingDispillOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp @@ -21,7 +21,7 @@ * Sergey Sharybin */ -#include "COM_KeyingDispillOperation.h" +#include "COM_KeyingDespillOperation.h" #include "MEM_guardedalloc.h" @@ -40,31 +40,31 @@ static int get_pixel_primary_channel(float *pixel) return 2; } -KeyingDispillOperation::KeyingDispillOperation(): NodeOperation() +KeyingDespillOperation::KeyingDespillOperation(): NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); - this->dispillFactor = 0.5f; + this->despillFactor = 0.5f; this->pixelReader = NULL; this->screenReader = NULL; } -void KeyingDispillOperation::initExecution() +void KeyingDespillOperation::initExecution() { this->pixelReader = this->getInputSocketReader(0); this->screenReader = this->getInputSocketReader(1); } -void KeyingDispillOperation::deinitExecution() +void KeyingDespillOperation::deinitExecution() { this->pixelReader = NULL; this->screenReader = NULL; } -void KeyingDispillOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void KeyingDespillOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { float pixelColor[4]; float screenColor[4]; @@ -83,7 +83,7 @@ void KeyingDispillOperation::executePixel(float *color, float x, float y, PixelS color[2] = pixelColor[2]; color[3] = pixelColor[3]; - if (this->dispillFactor * amount > 0) { - color[screen_primary_channel] = pixelColor[screen_primary_channel] - this->dispillFactor * amount; + if (this->despillFactor * amount > 0) { + color[screen_primary_channel] = pixelColor[screen_primary_channel] - this->despillFactor * amount; } } diff --git a/source/blender/compositor/operations/COM_KeyingDispillOperation.h b/source/blender/compositor/operations/COM_KeyingDespillOperation.h similarity index 79% rename from source/blender/compositor/operations/COM_KeyingDispillOperation.h rename to source/blender/compositor/operations/COM_KeyingDespillOperation.h index a918a918381..92a1415a1f0 100644 --- a/source/blender/compositor/operations/COM_KeyingDispillOperation.h +++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.h @@ -21,27 +21,27 @@ * Sergey Sharybin */ -#ifndef _COM_KeyingDispillOperation_h -#define _COM_KeyingDispillOperation_h +#ifndef _COM_KeyingDespillOperation_h +#define _COM_KeyingDespillOperation_h #include "COM_NodeOperation.h" /** - * Class with implementation of keying dispill node + * Class with implementation of keying despill node */ -class KeyingDispillOperation : public NodeOperation { +class KeyingDespillOperation : public NodeOperation { protected: SocketReader *pixelReader; SocketReader *screenReader; - float dispillFactor; + float despillFactor; public: - KeyingDispillOperation(); + KeyingDespillOperation(); void initExecution(); void deinitExecution(); - void setDispillFactor(float value) {this->dispillFactor = value;} + void setDespillFactor(float value) {this->despillFactor = value;} void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); }; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 341926f50a3..4c5befda8df 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2417,7 +2417,7 @@ static void node_composit_buts_keying(uiLayout *layout, bContext *UNUSED(C), Poi bNode *node= ptr->data; uiItemR(layout, ptr, "blur_pre", 0, NULL, ICON_NONE); - uiItemR(layout, ptr, "dispill_factor", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "despill_factor", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "clip_black", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "clip_white", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "dilate_distance", 0, NULL, ICON_NONE); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index bad40e80265..d605e9ac38f 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -622,7 +622,7 @@ typedef struct NodeKeyingScreenData { } NodeKeyingScreenData; typedef struct NodeKeyingData { - float dispill_factor; + float despill_factor; float clip_black, clip_white; int dilate_distance; int blur_pre, blur_post; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 7d2935ece6e..8cd56983d6c 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3073,10 +3073,10 @@ static void def_cmp_keying(StructRNA *srna) RNA_def_struct_sdna_from(srna, "NodeKeyingData", "storage"); - prop = RNA_def_property(srna, "dispill_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "dispill_factor"); + prop = RNA_def_property(srna, "despill_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "despill_factor"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Dispill", ""); + RNA_def_property_ui_text(prop, "Despill", ""); RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "clip_black", PROP_FLOAT, PROP_FACTOR); diff --git a/source/blender/nodes/composite/nodes/node_composite_keying.c b/source/blender/nodes/composite/nodes/node_composite_keying.c index 8e6fd86eae5..b5f9b823ac2 100644 --- a/source/blender/nodes/composite/nodes/node_composite_keying.c +++ b/source/blender/nodes/composite/nodes/node_composite_keying.c @@ -97,7 +97,7 @@ static void do_key(bNode *node, float *out, float *pixel, float *screen) NodeKeyingData *data = node->storage; float screen_balance = 0.5f; - float dispill_factor = data->dispill_factor; + float despill_factor = data->despill_factor; float clip_black = data->clip_black; float clip_white = data->clip_white; @@ -109,7 +109,7 @@ static void do_key(bNode *node, float *out, float *pixel, float *screen) if (primary_channel != screen_primary_channel) { /* different main channel means pixel is on foreground, * but screen color still need to be despilled from it */ - despil_pixel(out, pixel, screen, dispill_factor); + despil_pixel(out, pixel, screen, despill_factor); out[3] = 1.0f; } else if (saturation >= screen_saturation) { @@ -122,7 +122,7 @@ static void do_key(bNode *node, float *out, float *pixel, float *screen) else { float distance; - despil_pixel(out, pixel, screen, dispill_factor); + despil_pixel(out, pixel, screen, despill_factor); distance = 1.0f - saturation / screen_saturation; @@ -196,7 +196,7 @@ static void node_composit_init_keying(bNodeTree *UNUSED(ntree), bNode* node, bNo data = MEM_callocN(sizeof(NodeKeyingData), "node keying data"); - data->dispill_factor = 1.0f; + data->despill_factor = 1.0f; data->clip_black = 0.0f; data->clip_white = 1.0f; From e95885322d6e98cd23c538745b1d771101342f61 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 29 May 2012 15:30:56 +0000 Subject: [PATCH 104/360] Fix terrible mistake on merging keying patch which originally was against trunk. This resulted in compositor crashes when using mask node. --- source/blender/compositor/intern/COM_Converter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 747d6495f5d..92eb0f0f92c 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -352,6 +352,7 @@ case CMP_NODE_OUTPUT_FILE: break; case CMP_NODE_MASK: node = new MaskNode(bNode); + break; case CMP_NODE_KEYINGSCREEN: node = new KeyingScreenNode(bNode); break; From 8284b8a56def7d170443370cb3c65fa107c00c65 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 29 May 2012 20:48:15 +0000 Subject: [PATCH 105/360] mask - border & lasso select (lasso uses Ctrl+Alt - as with clip view) --- source/blender/editors/mask/mask_editor.c | 51 ++++ source/blender/editors/mask/mask_intern.h | 7 + source/blender/editors/mask/mask_select.c | 271 ++++++++++++++++++ .../windowmanager/intern/wm_operators.c | 1 + 4 files changed, 330 insertions(+) diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index 0290934cf9a..990f668af8d 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -89,6 +89,48 @@ void ED_mask_mouse_pos(bContext *C, wmEvent *event, float co[2]) } } +/* input: x/y - mval space + * output: xr/yr - mask point space */ +void ED_mask_point_pos(bContext *C, float x, float y, float *xr, float *yr) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + float co[2]; + + if (sc) { + ED_clip_point_stable_pos(C, x, y, &co[0], &co[1]); + BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co); + } + else { + /* possible other spaces from which mask editing is available */ + zero_v2(co); + } + + *xr = co[0]; + *yr = co[1]; +} + +void ED_mask_point_pos__reverse(bContext *C, float x, float y, float *xr, float *yr) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + + float co[2]; + + if (sc && ar) { + co[0] = x; + co[1] = y; + BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co); + ED_clip_point_stable_pos__reverse(sc, ar, co, co); + } + else { + /* possible other spaces from which mask editing is available */ + zero_v2(co); + } + + *xr = co[0]; + *yr = co[1]; +} + void ED_mask_size(bContext *C, int *width, int *height) { SpaceClip *sc = CTX_wm_space_clip(C); @@ -158,6 +200,8 @@ void ED_operatortypes_mask(void) /* select */ WM_operatortype_append(MASK_OT_select); WM_operatortype_append(MASK_OT_select_all); + WM_operatortype_append(MASK_OT_select_border); + WM_operatortype_append(MASK_OT_select_lasso); /* shape */ WM_operatortype_append(MASK_OT_slide_point); @@ -204,6 +248,13 @@ void ED_keymap_mask(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0); + + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "deselect", TRUE); + /* select clip while in maker view, * this matches View3D functionality where you can select an * object while in editmode to allow vertex parenting */ diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index 4eab64b2bcd..28560e4e292 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -71,6 +71,10 @@ void MASK_OT_parent_clear(struct wmOperatorType *ot); void MASK_OT_select(struct wmOperatorType *ot); void MASK_OT_select_all(struct wmOperatorType *ot); +void MASK_OT_select_border(struct wmOperatorType *ot); +void MASK_OT_select_lasso(struct wmOperatorType *ot); +void MASK_OT_select_circle(struct wmOperatorType *ot); + int ED_mask_spline_select_check(struct MaskSplinePoint *points, int tot_point); int ED_mask_select_check(struct Mask *mask); @@ -87,6 +91,9 @@ void ED_mask_aspect(struct bContext *C, float *aspx, float *aspy); void ED_mask_pixelspace_factor(struct bContext *C, float *scalex, float *scaley); void ED_mask_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]); +void ED_mask_point_pos(struct bContext *C, float x, float y, float *xr, float *yr); +void ED_mask_point_pos__reverse(struct bContext *C, float x, float y, float *xr, float *yr); + /* mask_shapekey.c */ void MASK_OT_shape_key_insert(struct wmOperatorType *ot); void MASK_OT_shape_key_clear(struct wmOperatorType *ot); diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index ae830bb92b5..1286565df73 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -33,6 +33,8 @@ #include "BLI_utildefines.h" #include "BLI_listbase.h" +#include "BLI_rect.h" +#include "BLI_lasso.h" #include "BLI_math.h" #include "BKE_context.h" @@ -312,3 +314,272 @@ void MASK_OT_select(wmOperatorType *ot) RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, "Location", "Location of vertex in normalized space", -1.0f, 1.0f); } + + + +/********************** border select operator *********************/ + +static int border_select_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskObject *maskobj; + int i; + + rcti rect; + rctf rectf; + int change = FALSE, mode, extend; + + /* get rectangle from operator */ + rect.xmin = RNA_int_get(op->ptr, "xmin"); + rect.ymin = RNA_int_get(op->ptr, "ymin"); + rect.xmax = RNA_int_get(op->ptr, "xmax"); + rect.ymax = RNA_int_get(op->ptr, "ymax"); + + ED_mask_point_pos(C, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); + ED_mask_point_pos(C, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); + + mode = RNA_int_get(op->ptr, "gesture_mode"); + extend = RNA_boolean_get(op->ptr, "extend"); + + /* do actual selection */ + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + /* TODO: handles? */ + /* TODO: uw? */ + + if (1) { /* can the point be selected? */ + if (BLI_in_rctf(&rectf, point->bezt.vec[1][0], point->bezt.vec[1][1])) { + BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT); + BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT); + } + else if (!extend) { + BKE_mask_point_select_set(point, FALSE); + BKE_mask_point_select_set_handle(point, FALSE); + } + + change = TRUE; + } + } + } + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Border Select"; + ot->description = "Select markers using border selection"; + ot->idname = "MASK_OT_select_border"; + + /* api callbacks */ + ot->invoke = WM_border_select_invoke; + ot->exec = border_select_exec; + ot->modal = WM_border_select_modal; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_gesture_border(ot, TRUE); +} + +static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short select) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskObject *maskobj; + int i; + + rcti rect; + int change = FALSE; + + /* get rectangle from operator */ + BLI_lasso_boundbox(&rect, mcords, moves); + + /* do actual selection */ + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + /* TODO: handles? */ + /* TODO: uw? */ + + float screen_co[2]; + + /* marker in screen coords */ + ED_mask_point_pos__reverse(C, + point->bezt.vec[1][0], point->bezt.vec[1][1], + &screen_co[0], &screen_co[1]); + + if (BLI_in_rcti(&rect, screen_co[0], screen_co[1]) && + BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], INT_MAX)) + { + BKE_mask_point_select_set(point, select); + BKE_mask_point_select_set_handle(point, select); + } + + change = TRUE; + } + } + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + } + + return change; +} + +static int clip_lasso_select_exec(bContext *C, wmOperator *op) +{ + int mcords_tot; + int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + + if (mcords) { + short select; + + select = !RNA_boolean_get(op->ptr, "deselect"); + do_lasso_select_mask(C, mcords, mcords_tot, select); + + MEM_freeN(mcords); + + return OPERATOR_FINISHED; + } + return OPERATOR_PASS_THROUGH; +} + +void MASK_OT_select_lasso(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Lasso Select"; + ot->description = "Select markers using lasso selection"; + ot->idname = "MASK_OT_select_lasso"; + + /* api callbacks */ + ot->invoke = WM_gesture_lasso_invoke; + ot->modal = WM_gesture_lasso_modal; + ot->exec = clip_lasso_select_exec; + ot->poll = ED_maskediting_mask_poll; + ot->cancel = WM_gesture_lasso_cancel; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", ""); + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items"); + RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first"); +} + +#if 0 +/********************** circle select operator *********************/ + +static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2]) +{ + /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */ + float x, y; + + x = (marker->pos[0] - offset[0])*ellipse[0]; + y = (marker->pos[1] - offset[1])*ellipse[1]; + + return x*x + y*y < 1.0f; +} + +static int circle_select_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + ARegion *ar = CTX_wm_region(C); + MovieTracking *tracking = &clip->tracking; + MovieTrackingTrack *track; + ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + int x, y, radius, width, height, mode, change = FALSE; + float zoomx, zoomy, offset[2], ellipse[2]; + + /* get operator properties */ + x = RNA_int_get(op->ptr, "x"); + y = RNA_int_get(op->ptr, "y"); + radius = RNA_int_get(op->ptr, "radius"); + + mode = RNA_int_get(op->ptr, "gesture_mode"); + + /* compute ellipse and position in unified coordinates */ + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + + ellipse[0] = width * zoomx / radius; + ellipse[1] = height * zoomy / radius; + + ED_clip_point_stable_pos(C, x, y, &offset[0], &offset[1]); + + /* do selection */ + track = tracksbase->first; + while (track) { + if ((track->flag & TRACK_HIDDEN) == 0) { + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + + if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) { + BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode != GESTURE_MODAL_SELECT); + + change = TRUE; + } + } + + track = track->next; + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_circle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Circle Select"; + ot->description = "Select markers using circle selection"; + ot->idname = "MASK_OT_select_circle"; + + /* api callbacks */ + ot->invoke = WM_gesture_circle_invoke; + ot->modal = WM_gesture_circle_modal; + ot->exec = circle_select_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); +} + +#endif diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 42787be8e02..5ae2bcf9c4b 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3936,6 +3936,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "UV_OT_select_border"); WM_modalkeymap_assign(keymap, "CLIP_OT_select_border"); WM_modalkeymap_assign(keymap, "CLIP_OT_graph_select_border"); + WM_modalkeymap_assign(keymap, "MASK_OT_select_border"); WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border"); From 03136f06807bff9c08ac7dc6584fb5cdb7bffa51 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 06:07:26 +0000 Subject: [PATCH 106/360] mask object hide/reveal - access from H/Alt+H/Shift+H and eye icon in listview. added alpha setting though its not used for rendering yet. --- source/blender/blenkernel/intern/mask.c | 12 +- .../editors/interface/interface_templates.c | 12 ++ source/blender/editors/mask/mask_draw.c | 6 +- source/blender/editors/mask/mask_editor.c | 12 ++ source/blender/editors/mask/mask_intern.h | 5 + source/blender/editors/mask/mask_ops.c | 135 +++++++++++++++++- .../blender/editors/mask/mask_relationships.c | 8 ++ source/blender/editors/mask/mask_select.c | 58 ++++++-- source/blender/editors/mask/mask_shapekey.c | 8 ++ .../blender/editors/space_clip/space_clip.c | 1 + source/blender/makesdna/DNA_mask_types.h | 13 +- source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/intern/rna_mask.c | 26 ++++ 13 files changed, 271 insertions(+), 26 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index be7fa2fbd74..1e2d65c4dd7 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -94,9 +94,12 @@ MaskObject *BKE_mask_object_new(Mask *mask, const char *name) mask->tot_maskobj++; + maskobj->alpha = 1.0f; + return maskobj; } +/* note: may still be hidden, caller needs to check */ MaskObject *BKE_mask_object_active(Mask *mask) { return BLI_findlink(&mask->maskobjs, mask->act_maskobj); @@ -104,12 +107,7 @@ MaskObject *BKE_mask_object_active(Mask *mask) void BKE_mask_object_active_set(Mask *mask, MaskObject *maskobj) { - int index = BLI_findindex(&mask->maskobjs, maskobj); - - if (index >= 0) - mask->act_maskobj = index; - else - mask->act_maskobj = 0; + mask->act_maskobj = BLI_findindex(&mask->maskobjs, maskobj); } void BKE_mask_object_remove(Mask *mask, MaskObject *maskobj) @@ -1171,7 +1169,7 @@ void BKE_mask_spline_ensure_deform(MaskSpline *spline) spline->points_deform = MEM_mallocN(sizeof(*spline->points_deform) * spline->tot_point, __func__); } else { - printf("alloc spline done\n"); + // printf("alloc spline done\n"); } } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 78835192574..54b87fd4509 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2241,6 +2241,18 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe uiItemL(split, name, ICON_OBJECT_DATA); } } + else if (itemptr->type == &RNA_MaskObject) { + split = uiLayoutSplit(sub, 0.5f, 0); + + uiItemL(split, name, icon); + + uiBlockSetEmboss(block, UI_EMBOSSN); + row = uiLayoutRow(split, 1); + uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); + uiItemR(row, itemptr, "hide", 0, "", 0); + + uiBlockSetEmboss(block, UI_EMBOSS); + } /* There is a last chance to display custom controls (in addition to the name/label): * If the given item property group features a string property named as prop_list, diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index fe11ded64f4..ae64294fd3e 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -267,9 +267,11 @@ static void draw_maskobjs(Mask *mask) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } -// BKE_mask_spline_ensure_deform(spline); + for (spline = maskobj->splines.first; spline; spline = spline->next) { /* draw curve itself first... */ draw_spline_curve(maskobj, spline); diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index 990f668af8d..5968c80b270 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -203,6 +203,10 @@ void ED_operatortypes_mask(void) WM_operatortype_append(MASK_OT_select_border); WM_operatortype_append(MASK_OT_select_lasso); + /* hide/reveal */ + WM_operatortype_append(MASK_OT_hide_view_clear); + WM_operatortype_append(MASK_OT_hide_view_set); + /* shape */ WM_operatortype_append(MASK_OT_slide_point); WM_operatortype_append(MASK_OT_cyclic_toggle); @@ -255,6 +259,14 @@ void ED_keymap_mask(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0); RNA_boolean_set(kmi->ptr, "deselect", TRUE); + /* hide/reveal */ + WM_keymap_add_item(keymap, "MASK_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0); + kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + + kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); + /* select clip while in maker view, * this matches View3D functionality where you can select an * object while in editmode to allow vertex parenting */ diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index 28560e4e292..b17d7e7173a 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -51,6 +51,9 @@ void MASK_OT_slide_point(struct wmOperatorType *ot); void MASK_OT_delete(struct wmOperatorType *ot); +void MASK_OT_hide_view_clear(struct wmOperatorType *ot); +void MASK_OT_hide_view_set(struct wmOperatorType *ot); + void MASK_OT_handle_type_set(struct wmOperatorType *ot); int ED_mask_feather_find_nearest( @@ -76,8 +79,10 @@ void MASK_OT_select_lasso(struct wmOperatorType *ot); void MASK_OT_select_circle(struct wmOperatorType *ot); int ED_mask_spline_select_check(struct MaskSplinePoint *points, int tot_point); +int ED_mask_object_select_check(struct MaskObject *maskobj); int ED_mask_select_check(struct Mask *mask); +void ED_mask_object_select_set(struct MaskObject *maskobj, int select); void ED_mask_select_toggle_all(struct Mask *mask, int action); void ED_mask_select_flush_all(struct Mask *mask); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 44932cab4df..5e547d9dec4 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -143,6 +143,10 @@ MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float norma for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + for (spline = maskobj->splines.first; spline; spline = spline->next) { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); @@ -241,6 +245,10 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in int i, tot_feather_point; float *feather_points, *fp; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); for (i = 0; i < spline->tot_point; i++) { @@ -328,6 +336,10 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_c for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; @@ -1204,6 +1216,10 @@ static int add_vertex_exec(bContext *C, wmOperator *op) maskobj = BKE_mask_object_active(mask); + if (maskobj && maskobj->restrictflag & MASK_RESTRICT_VIEW) { + maskobj = NULL; + } + RNA_float_get_array(op->ptr, "location", co); if (maskobj && maskobj->act_point && MASKPOINT_ISSEL(maskobj->act_point)) { @@ -1360,6 +1376,10 @@ static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + for (spline = maskobj->splines.first; spline; spline = spline->next) { if (ED_mask_spline_select_check(spline->points, spline->tot_point)) { spline->flag ^= MASK_SPLINE_CYCLIC; @@ -1432,7 +1452,13 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) int mask_object_shape_ofs = 0; for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskSpline *spline = maskobj->splines.first; + MaskSpline *spline; + + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + + spline = maskobj->splines.first; while (spline) { const int tot_point_orig = spline->tot_point; @@ -1537,6 +1563,10 @@ static int set_handle_type_exec(bContext *C, wmOperator *op) MaskSpline *spline; int i; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + for (spline = maskobj->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; @@ -1581,3 +1611,106 @@ void MASK_OT_handle_type_set(wmOperatorType *ot) /* properties */ ot->prop = RNA_def_enum(ot->srna, "type", editcurve_handle_type_items, 1, "Type", "Spline type"); } + + +/* ********* clear/set restrict view *********/ +static int mask_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskObject *maskobj; + int changed = FALSE; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + + if (maskobj->restrictflag & OB_RESTRICT_VIEW) { + ED_mask_object_select_set(maskobj, TRUE); + maskobj->restrictflag &= ~OB_RESTRICT_VIEW; + changed = 1; + } + } + + if (changed) { + WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_hide_view_clear(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name = "Clear Restrict View"; + ot->description = "Reveal the object by setting the hide flag"; + ot->idname = "MASK_OT_hide_view_clear"; + + /* api callbacks */ + ot->exec = mask_hide_view_clear_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_hide_view_set_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskObject *maskobj; + const int unselected = RNA_boolean_get(op->ptr, "unselected"); + int changed = FALSE; + + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + if (!unselected) { + if (ED_mask_object_select_check(maskobj)) { + ED_mask_object_select_set(maskobj, FALSE); + + maskobj->restrictflag |= OB_RESTRICT_VIEW; + changed = 1; + if (maskobj == BKE_mask_object_active(mask)) { + BKE_mask_object_active_set(mask, NULL); + } + } + } + else { + if (!ED_mask_object_select_check(maskobj)) { + maskobj->restrictflag |= OB_RESTRICT_VIEW; + changed = 1; + if (maskobj == BKE_mask_object_active(mask)) { + BKE_mask_object_active_set(mask, NULL); + } + } + } + } + + if (changed) { + WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_hide_view_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Restrict View"; + ot->description = "Hide the object by setting the hide flag"; + ot->idname = "MASK_OT_hide_view_set"; + + /* api callbacks */ + ot->exec = mask_hide_view_set_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects"); + +} diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index 4d08e2fa439..2d2c527d961 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -66,6 +66,10 @@ static int mask_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) MaskSpline *spline; int i; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + for (spline = maskobj->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; @@ -132,6 +136,10 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) MaskSpline *spline; int i; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + for (spline = maskobj->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 1286565df73..482abbe5818 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -71,23 +71,52 @@ int ED_mask_spline_select_check(MaskSplinePoint *points, int tot_point) return FALSE; } +int ED_mask_object_select_check(MaskObject *maskobj) +{ + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline->points, spline->tot_point)) { + return TRUE; + } + } + + return FALSE; +} + int ED_mask_select_check(Mask *mask) { MaskObject *maskobj; for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskSpline *spline; - - for (spline = maskobj->splines.first; spline; spline = spline->next) { - if (ED_mask_spline_select_check(spline->points, spline->tot_point)) { - return TRUE; - } + if (ED_mask_object_select_check(maskobj)) { + return TRUE; } } return FALSE; } +void ED_mask_object_select_set(MaskObject *maskobj, int select) +{ + MaskSpline *spline; + + for (spline = maskobj->splines.first; spline; spline = spline->next) { + int i; + + if (select) + spline->flag |= SELECT; + else + spline->flag &= ~SELECT; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + BKE_mask_point_select_set(point, select); + } + } +} + void ED_mask_select_toggle_all(Mask *mask, int action) { MaskObject *maskobj; @@ -100,17 +129,12 @@ void ED_mask_select_toggle_all(Mask *mask, int action) } for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { - int i; - - for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; - - BKE_mask_point_select_set(point, (action == SEL_SELECT) ? TRUE : FALSE); - } + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; } + + ED_mask_object_select_set(maskobj, (action == SEL_SELECT) ? TRUE : FALSE); } } @@ -121,6 +145,10 @@ void ED_mask_select_flush_all(Mask *mask) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c index 7a91fbeed13..71b10ae0da3 100755 --- a/source/blender/editors/mask/mask_shapekey.c +++ b/source/blender/editors/mask/mask_shapekey.c @@ -67,6 +67,10 @@ static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op)) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskObjectShape *maskobj_shape; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + maskobj_shape = BKE_mask_object_shape_varify_frame(maskobj, frame); BKE_mask_object_shape_from_mask(maskobj, maskobj_shape); change = TRUE; @@ -109,6 +113,10 @@ static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskObjectShape *maskobj_shape; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + maskobj_shape = BKE_mask_object_shape_find_frame(maskobj, frame); if (maskobj_shape) { diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index c6d35b03468..f952d6bbe47 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -369,6 +369,7 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) switch(wmn->data) { case ND_SELECT: case ND_DATA: + case ND_DRAW: ED_area_tag_redraw(sa); break; } diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index cf3f5e77544..65707725a53 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -44,7 +44,7 @@ typedef struct Mask { ID id; struct AnimData *adt; ListBase maskobjs; /* mask objects */ - int act_maskobj; /* index of active mask object */ + int act_maskobj; /* index of active mask object (-1 == None) */ int tot_maskobj; /* total number of mask objects */ } Mask; @@ -107,12 +107,18 @@ typedef struct MaskObject { struct MaskSpline *act_spline; /* active spline */ struct MaskSplinePoint *act_point; /* active point */ + + float alpha; + //char flag; /* not used yet */ + char restrictflag; /* matching 'Object' flag of the same name - eventually use in the outliner */ + char pad[3]; } MaskObject; /* MaskParent->flag */ #define MASK_PARENT_ACTIVE (1 << 0) /* MaskSpline->flag */ +/* reserve (1 << 0) for SELECT */ #define MASK_SPLINE_CYCLIC (1 << 1) /* MaskSpline->weight_interp */ @@ -121,4 +127,9 @@ typedef struct MaskObject { #define MASK_OBJECT_SHAPE_ELEM_SIZE 8 /* 3x 2D points + weight + radius == 8 */ +/* ob->restrictflag */ +#define MASK_RESTRICT_VIEW 1 +#define MASK_RESTRICT_SELECT 2 +#define MASK_RESTRICT_RENDER 4 + #endif // __DNA_MASK_TYPES_H__ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 532f971ad0a..9c465619b95 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -306,6 +306,7 @@ extern StructRNA RNA_MaterialSubsurfaceScattering; extern StructRNA RNA_MaterialTextureSlot; extern StructRNA RNA_MaterialVolume; extern StructRNA RNA_Mask; +extern StructRNA RNA_MaskObject; extern StructRNA RNA_Menu; extern StructRNA RNA_Mesh; extern StructRNA RNA_MeshColor; diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 1345011cd7e..393ca5f3244 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -533,6 +533,32 @@ static void rna_def_mask_object(BlenderRNA *brna) RNA_def_property_struct_type(prop, "MaskSpline"); RNA_def_property_ui_text(prop, "Splines", "Collection of splines which defines this object"); RNA_def_property_srna(prop, "MaskSplines"); + + /* restrict */ + prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", MASK_RESTRICT_VIEW); + RNA_def_property_ui_text(prop, "Restrict View", "Restrict visibility in the viewport"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1); + RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", MASK_RESTRICT_SELECT); + RNA_def_property_ui_text(prop, "Restrict Select", "Restrict selection in the viewport"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 1); + RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "hide_render", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", MASK_RESTRICT_RENDER); + RNA_def_property_ui_text(prop, "Restrict Render", "Restrict renderability"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); + RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL); + + /* render settings */ + prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "alpha"); + RNA_def_property_range(prop, 0.0, 1.0f); + RNA_def_property_ui_text(prop, "Opacity", "Render Opacity"); + RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL); } static void rna_def_maskobjects(BlenderRNA *brna, PropertyRNA *cprop) From eb6a6edc3d7ceb6dfb9e610e3fb0756fdf7e7e82 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 06:33:44 +0000 Subject: [PATCH 107/360] circle select for mask view (Ckey) --- source/blender/editors/mask/mask_editor.c | 2 + source/blender/editors/mask/mask_select.c | 87 +++++++++++-------- .../windowmanager/intern/wm_operators.c | 1 + 3 files changed, 53 insertions(+), 37 deletions(-) diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index 5968c80b270..aa8a9cbddcc 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -202,6 +202,7 @@ void ED_operatortypes_mask(void) WM_operatortype_append(MASK_OT_select_all); WM_operatortype_append(MASK_OT_select_border); WM_operatortype_append(MASK_OT_select_lasso); + WM_operatortype_append(MASK_OT_select_circle); /* hide/reveal */ WM_operatortype_append(MASK_OT_hide_view_clear); @@ -253,6 +254,7 @@ void ED_keymap_mask(wmKeyConfig *keyconf) RNA_enum_set(kmi->ptr, "action", SEL_INVERT); WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_select_circle", CKEY, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0); RNA_boolean_set(kmi->ptr, "deselect", FALSE); diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 482abbe5818..679f25aafea 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -145,15 +145,17 @@ void ED_mask_select_flush_all(Mask *mask) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { - continue; - } - for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; spline->flag &= ~SELECT; + /* intentionally _dont_ do this in the maskobj loop + * so we clear flags on all splines */ + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *cur_point = &spline->points[i]; @@ -373,6 +375,10 @@ static int border_select_exec(bContext *C, wmOperator *op) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + for (spline = maskobj->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; @@ -380,18 +386,16 @@ static int border_select_exec(bContext *C, wmOperator *op) /* TODO: handles? */ /* TODO: uw? */ - if (1) { /* can the point be selected? */ - if (BLI_in_rctf(&rectf, point->bezt.vec[1][0], point->bezt.vec[1][1])) { - BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT); - BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT); - } - else if (!extend) { - BKE_mask_point_select_set(point, FALSE); - BKE_mask_point_select_set_handle(point, FALSE); - } - - change = TRUE; + if (BLI_in_rctf(&rectf, point->bezt.vec[1][0], point->bezt.vec[1][1])) { + BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT); + BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT); } + else if (!extend) { + BKE_mask_point_select_set(point, FALSE); + BKE_mask_point_select_set_handle(point, FALSE); + } + + change = TRUE; } } } @@ -443,6 +447,10 @@ static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + for (spline = maskobj->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; @@ -519,28 +527,27 @@ void MASK_OT_select_lasso(wmOperatorType *ot) RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first"); } -#if 0 /********************** circle select operator *********************/ -static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2]) +static int mask_spline_point_inside_ellipse(MaskSplinePoint *point, float offset[2], float ellipse[2]) { /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */ float x, y; - x = (marker->pos[0] - offset[0])*ellipse[0]; - y = (marker->pos[1] - offset[1])*ellipse[1]; + x = (point->bezt.vec[1][0] - offset[0]) * ellipse[0]; + y = (point->bezt.vec[1][1] - offset[1]) * ellipse[1]; return x*x + y*y < 1.0f; } static int circle_select_exec(bContext *C, wmOperator *op) { + Mask *mask = CTX_data_edit_mask(C); + MaskObject *maskobj; + int i; + SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip(sc); ARegion *ar = CTX_wm_region(C); - MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *track; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); int x, y, radius, width, height, mode, change = FALSE; float zoomx, zoomy, offset[2], ellipse[2]; @@ -551,29 +558,37 @@ static int circle_select_exec(bContext *C, wmOperator *op) mode = RNA_int_get(op->ptr, "gesture_mode"); + /* TODO - make generic! - this is SpaceClip only! */ /* compute ellipse and position in unified coordinates */ ED_space_clip_size(sc, &width, &height); ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + width = height = MAX2(width, height); ellipse[0] = width * zoomx / radius; ellipse[1] = height * zoomy / radius; - ED_clip_point_stable_pos(C, x, y, &offset[0], &offset[1]); + ED_mask_point_pos(C, x, y, &offset[0], &offset[1]); - /* do selection */ - track = tracksbase->first; - while (track) { - if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + /* do actual selection */ + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + MaskSpline *spline; - if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) { - BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode != GESTURE_MODAL_SELECT); - - change = TRUE; - } + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; } - track = track->next; + for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (mask_spline_point_inside_ellipse(point, offset, ellipse)) { + BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT); + BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT); + + change = TRUE; + } + } + } } if (change) { @@ -609,5 +624,3 @@ void MASK_OT_select_circle(wmOperatorType *ot) RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); } - -#endif diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5ae2bcf9c4b..d7d55885f37 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3853,6 +3853,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_circle"); WM_modalkeymap_assign(keymap, "UV_OT_circle_select"); WM_modalkeymap_assign(keymap, "CLIP_OT_select_circle"); + WM_modalkeymap_assign(keymap, "MASK_OT_select_circle"); } From 6bee4c7a8f739f9d7f1745c57ce1cb5aa5a69220 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 06:42:03 +0000 Subject: [PATCH 108/360] transform wasnt ignoring hidden maskobjects --- .../editors/transform/transform_conversions.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index dd6a5c555be..9dd064e5e07 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5975,7 +5975,11 @@ static void createTransMaskingData(bContext *C, TransInfo *t) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline = maskobj->splines.first; - while (spline) { + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { @@ -5988,8 +5992,6 @@ static void createTransMaskingData(bContext *C, TransInfo *t) t->total += 1; } } - - spline = spline->next; } } @@ -6008,7 +6010,11 @@ static void createTransMaskingData(bContext *C, TransInfo *t) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline = maskobj->splines.first; - while (spline) { + if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { @@ -6029,8 +6035,6 @@ static void createTransMaskingData(bContext *C, TransInfo *t) } } } - - spline = spline->next; } } } From c93bfdd78bb4d7f8dab01a3c1708120df26fd647 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 07:15:09 +0000 Subject: [PATCH 109/360] proportional editing for mask transform --- .../blender/editors/space_clip/space_clip.c | 3 ++ .../editors/transform/transform_conversions.c | 44 ++++++++++++++----- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index f952d6bbe47..7f77dcb5659 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -52,6 +52,7 @@ #include "IMB_imbuf_types.h" #include "ED_mask.h" +#include "ED_space_api.h" #include "ED_screen.h" #include "ED_clip.h" #include "ED_transform.h" @@ -1137,6 +1138,8 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) ED_mask_draw((bContext *)C); + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); + glPopMatrix(); } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 9dd064e5e07..f563a7a089d 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5885,17 +5885,19 @@ typedef struct TransDataMasking{ MaskSplinePoint *point; } TransDataMasking; -static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, TransData *td, TransData2D *td2d, TransDataMasking *tdm) +static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, + TransData *td, TransData2D *td2d, TransDataMasking *tdm, int propmode) { BezTriple *bezt = &point->bezt; float aspx, aspy; + short is_sel_point = MASKPOINT_ISSEL(point); tdm->point = point; copy_m3_m3(tdm->vec, bezt->vec); ED_space_clip_mask_aspect(sc, &aspx, &aspy); - if (MASKPOINT_CV_ISSEL(point)) { + if (propmode || is_sel_point) { int i; for (i = 0; i < 3; i++) { /* CV coords are scaled by aspects. this is needed for rotations and @@ -5918,7 +5920,9 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, TransDat td->ext= NULL; td->val= NULL; - td->flag |= TD_SELECTED; + if (is_sel_point) { + td->flag |= TD_SELECTED; + } td->dist= 0.0; unit_m3(td->mtx); @@ -5951,7 +5955,10 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, TransDat td->ext= NULL; td->val= NULL; - td->flag |= TD_SELECTED; + if (is_sel_point) { + td->flag |= TD_SELECTED; + } + td->dist= 0.0; unit_m3(td->mtx); @@ -5970,6 +5977,8 @@ static void createTransMaskingData(bContext *C, TransInfo *t) TransData *td = NULL; TransData2D *td2d = NULL; TransDataMasking *tdm = NULL; + int count = 0, countsel = 0; + int propmode = t->flag & T_PROP_EDIT; /* count */ for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { @@ -5987,17 +5996,21 @@ static void createTransMaskingData(bContext *C, TransInfo *t) if (MASKPOINT_ISSEL(point)) { if (MASKPOINT_CV_ISSEL(point)) - t->total += 3; + countsel += 3; else - t->total += 1; + countsel += 1; } + + if (propmode) + count += 3; } } } - if (t->total == 0) - return; + /* note: in prop mode we need at least 1 selected */ + if (countsel == 0) return; + t->total = (propmode) ? count: countsel; td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransObData(Mask Editing)"); /* for each 2d uv coord a 3d vector is allocated, so that they can be * treated just as if they were 3d verts */ @@ -6020,10 +6033,10 @@ static void createTransMaskingData(bContext *C, TransInfo *t) for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; - if (MASKPOINT_ISSEL(point)) { - MaskPointToTransData(sc, point, td, td2d, tdm); + if (propmode || MASKPOINT_ISSEL(point)) { + MaskPointToTransData(sc, point, td, td2d, tdm, propmode); - if (MASKPOINT_CV_ISSEL(point)) { + if (propmode || MASKPOINT_CV_ISSEL(point)) { td += 3; td2d += 3; tdm += 3; @@ -6130,8 +6143,15 @@ void createTransData(bContext *C, TransInfo *t) t->flag |= T_POINTS|T_2D_EDIT; if (t->options & CTX_MOVIECLIP) createTransTrackingData(C, t); - else if (t->options & CTX_MASK) + else if (t->options & CTX_MASK) { createTransMaskingData(C, t); + + if (t->data && (t->flag & T_PROP_EDIT)) { + sort_trans_data(t); // makes selected become first in array + set_prop_dist(t, TRUE); + sort_trans_data_dist(t); + } + } } else if (t->obedit) { t->ext = NULL; From a111662e1aac5964ccbcc432bed701866e374359 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 07:34:25 +0000 Subject: [PATCH 110/360] proportional editing for masks --- release/scripts/startup/bl_ui/space_clip.py | 7 +++++++ source/blender/editors/transform/transform.c | 7 ++----- .../blender/editors/transform/transform_generics.c | 14 ++++++++++++++ source/blender/makesdna/DNA_scene_types.h | 3 ++- source/blender/makesrna/intern/rna_scene.c | 6 ++++++ 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index c6ea5633f23..0211ffd0c9f 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -75,8 +75,15 @@ class CLIP_HT_header(Header): row.template_ID(sc, "clip", open='clip.open') if sc.mode == 'MASKEDITING': + toolsettings = context.tool_settings + row = layout.row() row.template_ID(sc, "mask", new="mask.new") + + row = layout.row(align=True) + row.prop(toolsettings, "use_proportional_edit_mask", text="", icon_only=True) + if toolsettings.use_proportional_edit_objects: + row.prop(toolsettings, "proportional_edit_falloff", text="", icon_only=True) if clip: tracking = clip.tracking diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index b80b6d6a1bc..cb2eaf7aef9 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1517,6 +1517,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) { if (t->obedit) ts->proportional = proportional; + else if (t->options & CTX_MASK) + ts->proportional_mask = (proportional != PROP_EDIT_OFF); else ts->proportional_objects = (proportional != PROP_EDIT_OFF); } @@ -1650,13 +1652,8 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), helpline_poll, drawHelpline, t); } else if (t->spacetype == SPACE_CLIP) { - SpaceClip *sc = CTX_wm_space_clip(C); unit_m3(t->spacemtx); t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); - if (ED_space_clip_show_trackedit(sc)) - t->options |= CTX_MOVIECLIP; - else if (ED_space_clip_show_maskedit(sc)) - t->options |= CTX_MASK; } else unit_m3(t->spacemtx); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 985a393f238..46ee80aff5b 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1127,6 +1127,11 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) SpaceClip *sclip = sa->spacedata.first; t->view = &ar->v2d; t->around = sclip->around; + + if (ED_space_clip_show_trackedit(sclip)) + t->options |= CTX_MOVIECLIP; + else if (ED_space_clip_show_maskedit(sclip)) + t->options |= CTX_MASK; } else { if (ar) { @@ -1189,6 +1194,15 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->flag |= T_PROP_CONNECTED; } } + else if (t->options & CTX_MASK) { + if (ts->proportional_mask) { + t->flag |= T_PROP_EDIT; + + if (ts->proportional == PROP_EDIT_CONNECTED) { + t->flag |= T_PROP_CONNECTED; + } + } + } else if (t->obedit == NULL && ts->proportional_objects) { t->flag |= T_PROP_EDIT; } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 198b6a9bf80..75b0b18879d 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -999,7 +999,8 @@ typedef struct ToolSettings { short snap_flag, snap_target; short proportional, prop_mode; char proportional_objects; /* proportional edit, object mode */ - char pad[5]; + char proportional_mask; /* proportional edit, object mode */ + char pad[4]; char auto_normalize; /*auto normalizing mode in wpaint*/ char multipaint; /* paint multiple bones in wpaint */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 17efc25c132..646118debb5 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1565,6 +1565,12 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_ui_icon(prop, ICON_PROP_OFF, 1); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ + prop = RNA_def_property(srna, "use_proportional_edit_mask", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "proportional_mask", 0); + RNA_def_property_ui_text(prop, "Proportional Editing Objects", "Proportional editing mask mode"); + RNA_def_property_ui_icon(prop, ICON_PROP_OFF, 1); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ + prop = RNA_def_property(srna, "proportional_edit_falloff", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "prop_mode"); RNA_def_property_enum_items(prop, proportional_falloff_items); From c53c19ce32a4a8f118091bf6452ff77ecec05d12 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 08:20:20 +0000 Subject: [PATCH 111/360] proportional editing keys now work when editing masks. --- source/blender/editors/include/ED_object.h | 1 + source/blender/editors/mask/mask_editor.c | 5 +++++ source/blender/editors/object/object_ops.c | 8 +++++++ .../blender/editors/space_clip/space_clip.c | 21 +++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 8dc83df2977..9c10a270ef8 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -90,6 +90,7 @@ struct Base *ED_object_scene_link(struct Scene *scene, struct Object *ob); void ED_keymap_proportional_cycle(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); +void ED_keymap_proportional_maskmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, const short do_connected); diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index aa8a9cbddcc..a0b47be8ea3 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -42,6 +42,7 @@ #include "ED_screen.h" #include "ED_mask.h" +#include "ED_object.h" /* ED_keymap_proportional_maskmode only */ #include "ED_clip.h" #include "ED_transform.h" @@ -232,6 +233,10 @@ void ED_keymap_mask(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MASK_OT_new", NKEY, KM_PRESS, KM_ALT, 0); + /* mask mode supports PET now */ + ED_keymap_proportional_cycle(keyconf, keymap); + ED_keymap_proportional_maskmode(keyconf, keymap); + /* geometry */ WM_keymap_add_item(keymap, "MASK_OT_add_vertex_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "MASK_OT_add_feather_vertex_slide", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 6e653eff57c..d0a93302b7f 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -441,6 +441,14 @@ void ED_keymap_proportional_obmode(struct wmKeyConfig *UNUSED(keyconf), struct w RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_edit_objects"); } +void ED_keymap_proportional_maskmode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap) +{ + wmKeyMapItem *kmi; + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", OKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_edit_mask"); +} + void ED_keymap_proportional_editmode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap, const short do_connected) { diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 7f77dcb5659..8c5ae38011d 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -1317,6 +1317,26 @@ static void clip_header_area_draw(const bContext *C, ARegion *ar) ED_region_header(C, ar); } +static void clip_header_area_listener(ARegion *ar, wmNotifier *wmn) +{ + /* context changes */ + switch (wmn->category) { + case NC_SCENE: + switch (wmn->data) { + /* for proportional editmode only */ + case ND_TOOLSETTINGS: + /* TODO - should do this when in mask mode only but no datas available */ + // if(sc->mode == SC_MODE_MASKEDITING) + { + ED_region_tag_redraw(ar); + } + break; + } + break; + } +} + + /****************** tools region ******************/ /* add handlers, stuff you only do once or on area/region changes */ @@ -1478,6 +1498,7 @@ void ED_spacetype_clip(void) art->init = clip_header_area_init; art->draw = clip_header_area_draw; + art->listener = clip_header_area_listener; BLI_addhead(&st->regiontypes, art); From 1116731d97638dc284732b1bbcbc02523f38ad30 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 10:24:34 +0000 Subject: [PATCH 112/360] make rasterizer thread safe. --- intern/raskter/raskter.c | 60 +++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index cf8d76372e7..2cd1b38d525 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -55,8 +55,11 @@ struct r_buffer_stats { int sizey; }; -static struct e_status *all_edges, *possible_edges; -static struct r_buffer_stats rb; +struct r_fill_context { + struct e_status *all_edges, *possible_edges; + struct r_buffer_stats rb; +}; + /* * Sort all the edges of the input polygon by Y, then by X, of the "first" vertex encountered. * This will ensure we can scan convert the entire poly in one pass. @@ -65,7 +68,7 @@ static struct r_buffer_stats rb; * just the poly. Since the DEM code could end up being coupled with this, we'll keep it separate * for now. */ -static void preprocess_all_edges(struct poly_vert *verts, int num_verts, struct e_status *open_edge) +static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, struct e_status *open_edge) { int i; int xbeg; @@ -82,7 +85,7 @@ static void preprocess_all_edges(struct poly_vert *verts, int num_verts, struct struct poly_vert *v; /* set up pointers */ v = verts; - all_edges = NULL; + ctx->all_edges = NULL; /* loop all verts */ for (i = 0; i < num_verts; i++) { /* determine beginnings and endings of edges, linking last vertex to first vertex */ @@ -148,7 +151,7 @@ static void preprocess_all_edges(struct poly_vert *verts, int num_verts, struct e_new->drift_inc = xdist % dy; e_new->xshift = (xdist / dy) * e_new->xdir; } - next_edge_ref = &all_edges; + next_edge_ref = &ctx->all_edges; /* link in all the edges, in sorted order */ for (;; ) { next_edge = *next_edge_ref; @@ -168,7 +171,7 @@ static void preprocess_all_edges(struct poly_vert *verts, int num_verts, struct * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need * if it ends up being coupled with this function. */ -int rast_scan_fill(struct poly_vert *verts, int num_verts) +int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts) { int x_curr; /* current pixel position in X */ int y_curr; /* current scan line being drawn */ @@ -208,13 +211,13 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) * Do some preprocessing on all edges. This constructs a table structure in memory of all * the edge properties and can "flip" some edges so sorting works correctly. */ - preprocess_all_edges(verts, num_verts, edgbuf); + preprocess_all_edges(ctx, verts, num_verts, edgbuf); /* * Set the pointer for tracking the edges currently in processing to NULL to make sure * we don't get some crazy value after initialization. */ - possible_edges = NULL; + ctx->possible_edges = NULL; /* * Loop through all scan lines to be drawn. Since we sorted by Y values during @@ -229,7 +232,7 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) * TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here. * Will get changed once DEM code gets in. */ - for (y_curr = MAX2(all_edges->ybeg, 0); (all_edges || possible_edges) && (y_curr < rb.sizey); y_curr++) { + for (y_curr = MAX2(ctx->all_edges->ybeg, 0); (ctx->all_edges || ctx->possible_edges) && (y_curr < ctx->rb.sizey); y_curr++) { /* * Link any edges that start on the current scan line into the list of @@ -246,16 +249,16 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) * * At each iteration, make sure we still have a non-NULL edge. */ - for (edgec = &possible_edges; all_edges && (all_edges->ybeg == y_curr); ) { - x_curr = all_edges->x; /* Set current X position. */ + for (edgec = &ctx->possible_edges; ctx->all_edges && (ctx->all_edges->ybeg == y_curr); ) { + x_curr = ctx->all_edges->x; /* Set current X position. */ for (;; ) { /* Start looping edges. Will break when edges run out. */ e_curr = *edgec; /* Set up a current edge pointer. */ if (!e_curr || (e_curr->x >= x_curr)) { /* If we have an no edge, or we need to skip some X-span, */ - e_temp = all_edges->e_next; /* set a temp "next" edge to test. */ - *edgec = all_edges; /* Add this edge to the list to be scanned. */ - all_edges->e_next = e_curr; /* Set up the next edge. */ - edgec = &all_edges->e_next; /* Set our list to the next edge's location in memory. */ - all_edges = e_temp; /* Skip the NULL or bad X edge, set pointer to next edge. */ + e_temp = ctx->all_edges->e_next; /* set a temp "next" edge to test. */ + *edgec = ctx->all_edges; /* Add this edge to the list to be scanned. */ + ctx->all_edges->e_next = e_curr; /* Set up the next edge. */ + edgec = &ctx->all_edges->e_next; /* Set our list to the next edge's location in memory. */ + ctx->all_edges = e_temp; /* Skip the NULL or bad X edge, set pointer to next edge. */ break; /* Stop looping edges (since we ran out or hit empty X span. */ } else { @@ -268,11 +271,11 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) * Determine the current scan line's offset in the pixel buffer based on its Y position. * Basically we just multiply the current scan line's Y value by the number of pixels in each line. */ - yp = y_curr * rb.sizex; + yp = y_curr * ctx->rb.sizex; /* * Set a "scan line pointer" in memory. The location of the buffer plus the row offset. */ - spxl = rb.buf + (yp); + spxl = ctx->rb.buf + (yp); /* * Set up the current edge to the first (in X) edge. The edges which could possibly be in this * list were determined in the preceeding edge loop above. They were already sorted in X by the @@ -281,7 +284,7 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) * At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge * we will eventually hit a NULL when the list runs out. */ - for (e_curr = possible_edges; e_curr; e_curr = e_curr->e_next) { + for (e_curr = ctx->possible_edges; e_curr; e_curr = e_curr->e_next) { /* * Calculate a span of pixels to fill on the current scan line. * @@ -300,7 +303,7 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) /* set up xmin and xmax bounds on this scan line */ cpxl = spxl + MAX2(e_curr->x, 0); e_curr = e_curr->e_next; - mpxl = spxl + MIN2(e_curr->x, rb.sizex) - 1; + mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1; /* draw the pixels. */ for (; cpxl <= mpxl; cpxl++){ @@ -321,7 +324,7 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) * polygons, we dont have fractional positions, so we only move in x-direction * when needed to get all the way to the next pixel over... */ - for (edgec = &possible_edges; (e_curr = *edgec); ) { + for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) { if (!(--(e_curr->num))) { *edgec = e_curr->e_next; } @@ -342,8 +345,8 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) * pass, then we know we need to sort by x, so then cycle through edges again and perform * the sort.- */ - if (possible_edges) { - for (edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + if (ctx->possible_edges) { + for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { /* if the current edge hits scan line at greater X than the next edge, we need to exchange the edges */ if (e_curr->x > e_curr->e_next->x) { *edgec = e_curr->e_next; @@ -359,7 +362,7 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) for (;; ) { /* reset exchange flag so it's only set if we encounter another one */ swixd = 0; - for (edgec = &possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { /* again, if current edge hits scan line at higher X than next edge, exchange the edges and set flag */ if (e_curr->x > e_curr->e_next->x) { *edgec = e_curr->e_next; @@ -386,6 +389,7 @@ int rast_scan_fill(struct poly_vert *verts, int num_verts) int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y) { int i; /* i: Loop counter. */ struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */ + struct r_fill_context ctx = {0}; /* * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert @@ -411,11 +415,11 @@ int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y) { ply[i].y = (verts[(i << 1) + 1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */ } - rb.buf = buf; /* Set the output buffer pointer. */ - rb.sizex = buf_x; /* Set the output buffer size in X. (width) */ - rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ + ctx.rb.buf = buf; /* Set the output buffer pointer. */ + ctx.rb.sizex = buf_x; /* Set the output buffer size in X. (width) */ + ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ - i = rast_scan_fill(ply, num); /* Call our rasterizer, passing in the integer coords for each vert. */ + i = rast_scan_fill(&ctx, ply, num); /* Call our rasterizer, passing in the integer coords for each vert. */ free(ply); /* Free the memory allocated for the integer coordinate table. */ return(i); /* Return the value returned by the rasterizer. */ } From ad00c1210acdfd49ffb3cf1eb4c22ccea054d855 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 11:52:44 +0000 Subject: [PATCH 113/360] rename macros for mask point selection - were a bit confusing. --- source/blender/blenkernel/BKE_mask.h | 18 +++++++++--------- source/blender/blenkernel/intern/curve.c | 3 +-- source/blender/blenkernel/intern/mask.c | 8 ++++---- source/blender/editors/mask/mask_draw.c | 6 +++--- source/blender/editors/mask/mask_ops.c | 16 ++++++++-------- .../blender/editors/mask/mask_relationships.c | 4 ++-- source/blender/editors/mask/mask_select.c | 8 ++++---- .../editors/transform/transform_conversions.c | 10 +++++----- 8 files changed, 36 insertions(+), 37 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index d02e6f1966b..e21a2aa54e8 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -135,16 +135,16 @@ void BKE_mask_object_shape_changed_remove(struct MaskObject *maskobj, int index, /* rasterization */ void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer); -#define MASKPOINT_ISSEL(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT) -#define MASKPOINT_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 -#define MASKPOINT_DESEL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 -#define MASKPOINT_INVSEL(p) { (p)->bezt.f1 ^= SELECT; (p)->bezt.f2 ^= SELECT; (p)->bezt.f3 ^= SELECT; } (void)0 +#define MASKPOINT_ISSEL_ANY(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT) +#define MASKPOINT_ISSEL_KNOT(p) ( (p)->bezt.f2 & SELECT) +#define MASKPOINT_ISSEL_HANDLE_ONLY(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) && (((p)->bezt.f2 & SELECT) == 0) ) +#define MASKPOINT_ISSEL_HANDLE(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) ) -#define MASKPOINT_CV_ISSEL(p) ( (p)->bezt.f2 & SELECT) +#define MASKPOINT_SEL_ALL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 +#define MASKPOINT_DESEL_ALL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 +#define MASKPOINT_INVSEL_ALL(p) { (p)->bezt.f1 ^= SELECT; (p)->bezt.f2 ^= SELECT; (p)->bezt.f3 ^= SELECT; } (void)0 -#define MASKPOINT_HANDLE_ONLY_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) && (((p)->bezt.f2 & SELECT) == 0) ) -#define MASKPOINT_HANDLE_ISSEL(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) ) -#define MASKPOINT_HANDLE_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 -#define MASKPOINT_HANDLE_DESEL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 +#define MASKPOINT_SEL_HANDLE(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 +#define MASKPOINT_DESEL_HANDLE(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 #endif diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index ce62b9c10dc..84ac51f68ae 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -3200,8 +3200,7 @@ float (*BKE_curve_vertexCos_get(Curve * UNUSED(cu), ListBase * lb, int *numVerts else { BPoint *bp = nu->bp; - for (i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) { - copy_v3_v3(co, bp->vec); co += 3; + for (i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) { copy_v3_v3(co, bp->vec); co += 3; } } } diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 1e2d65c4dd7..3421f5ad9e5 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -655,10 +655,10 @@ void BKE_mask_point_select_set(MaskSplinePoint *point, int select) int i; if (select) { - MASKPOINT_SEL(point); + MASKPOINT_SEL_ALL(point); } else { - MASKPOINT_DESEL(point); + MASKPOINT_DESEL_ALL(point); } for (i = 0; i < point->tot_uw; i++) { @@ -674,10 +674,10 @@ void BKE_mask_point_select_set(MaskSplinePoint *point, int select) void BKE_mask_point_select_set_handle(MaskSplinePoint *point, int select) { if (select) { - MASKPOINT_HANDLE_SEL(point); + MASKPOINT_SEL_HANDLE(point); } else { - MASKPOINT_HANDLE_DESEL(point); + MASKPOINT_DESEL_HANDLE(point); } } diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index ae64294fd3e..0cf2cb77177 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -124,7 +124,7 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) int sel = FALSE; if (j == 0) { - sel = MASKPOINT_ISSEL(point); + sel = MASKPOINT_ISSEL_ANY(point); } else { sel = point->uw[j - 1].flag & SELECT; @@ -174,7 +174,7 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) } /* draw CV point */ - if (MASKPOINT_CV_ISSEL(point)) { + if (MASKPOINT_ISSEL_KNOT(point)) { if (point == maskobj->act_point) glColor3f(1.0f, 1.0f, 1.0f); else @@ -189,7 +189,7 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) /* draw handle points */ if (has_handle) { - if (MASKPOINT_HANDLE_ISSEL(point)) { + if (MASKPOINT_ISSEL_HANDLE(point)) { if (point == maskobj->act_point) glColor3f(1.0f, 1.0f, 1.0f); else diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 5e547d9dec4..c5371e7760a 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -660,7 +660,7 @@ static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) ED_mask_select_flush_all(mask); } } - else if (!MASKPOINT_ISSEL(slidedata->point)) { + else if (!MASKPOINT_ISSEL_ANY(slidedata->point)) { ED_mask_select_toggle_all(mask, SEL_DESELECT); BKE_mask_point_select_set(slidedata->point, TRUE); @@ -963,7 +963,7 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask BKE_mask_parent_init(&new_point->parent); /* select new point */ - MASKPOINT_SEL(new_point); + MASKPOINT_SEL_ALL(new_point); ED_mask_select_flush_all(mask); } @@ -1040,7 +1040,7 @@ static void finSelectedSplinePoint(MaskObject *maskobj, MaskSpline **spline, Mas for (i = 0; i < cur_spline->tot_point; i++) { MaskSplinePoint *cur_point = &cur_spline->points[i]; - if (MASKPOINT_ISSEL(cur_point)) { + if (MASKPOINT_ISSEL_ANY(cur_point)) { if (*spline != NULL && *spline != cur_spline) { *spline = NULL; *point = NULL; @@ -1088,7 +1088,7 @@ static int add_vertex_extrude(bContext *C, Mask *mask, const float co[2]) point_index = (point - spline->points); - MASKPOINT_DESEL(point); + MASKPOINT_DESEL_ALL(point); if ((spline->flag & MASK_SPLINE_CYCLIC) || (point_index > 0 && point_index != spline->tot_point - 1)) @@ -1222,7 +1222,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op) RNA_float_get_array(op->ptr, "location", co); - if (maskobj && maskobj->act_point && MASKPOINT_ISSEL(maskobj->act_point)) { + if (maskobj && maskobj->act_point && MASKPOINT_ISSEL_ANY(maskobj->act_point)) { /* cheap trick - double click for cyclic */ MaskSpline *spline = maskobj->act_spline; @@ -1469,7 +1469,7 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; - if (!MASKPOINT_ISSEL(point)) + if (!MASKPOINT_ISSEL_ANY(point)) count++; } @@ -1495,7 +1495,7 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) for (i = 0, j = 0; i < tot_point_orig; i++) { MaskSplinePoint *point = &spline->points[i]; - if (!MASKPOINT_ISSEL(point)) { + if (!MASKPOINT_ISSEL_ANY(point)) { if (point == maskobj->act_point) maskobj->act_point = &new_points[j]; @@ -1571,7 +1571,7 @@ static int set_handle_type_exec(bContext *C, wmOperator *op) for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; - if (MASKPOINT_ISSEL(point)) { + if (MASKPOINT_ISSEL_ANY(point)) { BezTriple *bezt = &point->bezt; bezt->h1 = bezt->h2 = handle_type; diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index 2d2c527d961..65c3980e3ea 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -74,7 +74,7 @@ static int mask_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; - if (MASKPOINT_ISSEL(point)) { + if (MASKPOINT_ISSEL_ANY(point)) { point->parent.flag &= ~MASK_PARENT_ACTIVE; } } @@ -144,7 +144,7 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; - if (MASKPOINT_ISSEL(point)) { + if (MASKPOINT_ISSEL_ANY(point)) { point->parent.id_type = ID_MC; point->parent.id = &clip->id; strcpy(point->parent.parent, tracking->name); diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 679f25aafea..4f0b33294d3 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -64,7 +64,7 @@ int ED_mask_spline_select_check(MaskSplinePoint *points, int tot_point) for (i = 0; i < tot_point; i++) { MaskSplinePoint *point = &points[i]; - if (MASKPOINT_ISSEL(point)) + if (MASKPOINT_ISSEL_ANY(point)) return TRUE; } @@ -159,7 +159,7 @@ void ED_mask_select_flush_all(Mask *mask) for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *cur_point = &spline->points[i]; - if (MASKPOINT_ISSEL(cur_point)) { + if (MASKPOINT_ISSEL_ANY(cur_point)) { spline->flag |= SELECT; } else { @@ -248,7 +248,7 @@ static int select_exec(bContext *C, wmOperator *op) maskobj->act_spline = spline; maskobj->act_point = point; - if (!MASKPOINT_HANDLE_ISSEL(point)) { + if (!MASKPOINT_ISSEL_HANDLE(point)) { BKE_mask_point_select_set_handle(point, TRUE); } else if (toggle) { @@ -270,7 +270,7 @@ static int select_exec(bContext *C, wmOperator *op) maskobj->act_spline = spline; maskobj->act_point = point; - if (!MASKPOINT_ISSEL(point)) { + if (!MASKPOINT_ISSEL_ANY(point)) { BKE_mask_point_select_set(point, TRUE); } else if (toggle) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index f563a7a089d..89228423bf5 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5890,7 +5890,7 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, { BezTriple *bezt = &point->bezt; float aspx, aspy; - short is_sel_point = MASKPOINT_ISSEL(point); + short is_sel_point = MASKPOINT_ISSEL_ANY(point); tdm->point = point; copy_m3_m3(tdm->vec, bezt->vec); @@ -5994,8 +5994,8 @@ static void createTransMaskingData(bContext *C, TransInfo *t) for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; - if (MASKPOINT_ISSEL(point)) { - if (MASKPOINT_CV_ISSEL(point)) + if (MASKPOINT_ISSEL_ANY(point)) { + if (MASKPOINT_ISSEL_KNOT(point)) countsel += 3; else countsel += 1; @@ -6033,10 +6033,10 @@ static void createTransMaskingData(bContext *C, TransInfo *t) for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; - if (propmode || MASKPOINT_ISSEL(point)) { + if (propmode || MASKPOINT_ISSEL_ANY(point)) { MaskPointToTransData(sc, point, td, td2d, tdm, propmode); - if (propmode || MASKPOINT_CV_ISSEL(point)) { + if (propmode || MASKPOINT_ISSEL_KNOT(point)) { td += 3; td2d += 3; tdm += 3; From 44806d2c2bfceb061f90dc9ab0795e9e7d57869b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 12:08:08 +0000 Subject: [PATCH 114/360] fix for mask transform in non proportional mode. --- source/blender/editors/transform/transform_conversions.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 89228423bf5..d00539ff43c 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5890,7 +5890,8 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, { BezTriple *bezt = &point->bezt; float aspx, aspy; - short is_sel_point = MASKPOINT_ISSEL_ANY(point); + short is_sel_point = MASKPOINT_ISSEL_KNOT(point); + short is_sel_any = MASKPOINT_ISSEL_ANY(point); tdm->point = point; copy_m3_m3(tdm->vec, bezt->vec); @@ -5920,7 +5921,7 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, td->ext= NULL; td->val= NULL; - if (is_sel_point) { + if (is_sel_any) { td->flag |= TD_SELECTED; } td->dist= 0.0; @@ -5955,7 +5956,7 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, td->ext= NULL; td->val= NULL; - if (is_sel_point) { + if (is_sel_any) { td->flag |= TD_SELECTED; } From ba7606db15f5ee87186269e311cdef3022a5e797 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 12:54:50 +0000 Subject: [PATCH 115/360] impliment restrict select option. --- .../editors/interface/interface_templates.c | 5 +-- source/blender/editors/mask/mask_draw.c | 10 +++--- source/blender/editors/mask/mask_ops.c | 33 +++++++++---------- .../blender/editors/mask/mask_relationships.c | 4 +-- source/blender/editors/mask/mask_select.c | 16 +++++++-- source/blender/editors/mask/mask_shapekey.c | 4 +-- .../editors/transform/transform_conversions.c | 4 +-- 7 files changed, 44 insertions(+), 32 deletions(-) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 54b87fd4509..1acfefe8a4c 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2242,14 +2242,15 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe } } else if (itemptr->type == &RNA_MaskObject) { - split = uiLayoutSplit(sub, 0.5f, 0); + split = uiLayoutSplit(sub, 0.66f, 0); uiItemL(split, name, icon); uiBlockSetEmboss(block, UI_EMBOSSN); row = uiLayoutRow(split, 1); - uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); + // uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); // enable when used uiItemR(row, itemptr, "hide", 0, "", 0); + uiItemR(row, itemptr, "hide_select", 0, "", 0); uiBlockSetEmboss(block, UI_EMBOSS); } diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 0cf2cb77177..ef1dee3f2fe 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -51,7 +51,7 @@ static void set_spline_color(MaskObject *maskobj, MaskSpline *spline) { - if (spline->flag & SELECT) { + if ((spline->flag & SELECT) && (maskobj->restrictflag & MASK_RESTRICT_SELECT) == 0) { if (maskobj->act_spline == spline) glColor3f(1.0f, 1.0f, 1.0f); else @@ -246,7 +246,7 @@ static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline) feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_feather_point); /* draw feather */ - if (spline->flag & SELECT) + if ((spline->flag & SELECT) && (maskobj->restrictflag & MASK_RESTRICT_SELECT) == 0) glColor3f(0.0f, 1.0f, 0.0f); else glColor3f(0.0f, 0.5f, 0.0f); @@ -278,8 +278,10 @@ static void draw_maskobjs(Mask *mask) // draw_spline_parents(maskobj, spline); - /* ...and then handles over the curve so they're nicely visible */ - draw_spline_points(maskobj, spline); + if (!(maskobj->restrictflag & MASK_RESTRICT_SELECT)) { + /* ...and then handles over the curve so they're nicely visible */ + draw_spline_points(maskobj, spline); + } /* show undeform for testing */ if (0) { diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index c5371e7760a..a2e634bdeba 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -143,7 +143,7 @@ MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float norma for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -245,7 +245,7 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in int i, tot_feather_point; float *feather_points, *fp; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -336,7 +336,7 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_c for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -1060,9 +1060,8 @@ static void finSelectedSplinePoint(MaskObject *maskobj, MaskSpline **spline, Mas } } -static int add_vertex_extrude(bContext *C, Mask *mask, const float co[2]) +static int add_vertex_extrude(bContext *C, Mask *mask, MaskObject *maskobj, const float co[2]) { - MaskObject *maskobj; MaskSpline *spline; MaskSplinePoint *point; MaskSplinePoint *new_point = NULL, *ref_point = NULL; @@ -1077,8 +1076,6 @@ static int add_vertex_extrude(bContext *C, Mask *mask, const float co[2]) ED_mask_select_toggle_all(mask, SEL_DESELECT); - maskobj = BKE_mask_object_active(mask); - if (!maskobj) { return FALSE; } @@ -1163,17 +1160,14 @@ static int add_vertex_extrude(bContext *C, Mask *mask, const float co[2]) return TRUE; } -static int add_vertex_new(bContext *C, Mask *mask, const float co[2]) +static int add_vertex_new(bContext *C, Mask *mask, MaskObject *maskobj, const float co[2]) { - MaskObject *maskobj; MaskSpline *spline; MaskSplinePoint *point; MaskSplinePoint *new_point = NULL, *ref_point = NULL; ED_mask_select_toggle_all(mask, SEL_DESELECT); - maskobj = BKE_mask_object_active(mask); - if (!maskobj) { /* if there's no maskobj currently operationg on, create new one */ maskobj = BKE_mask_object_new(mask, ""); @@ -1216,7 +1210,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op) maskobj = BKE_mask_object_active(mask); - if (maskobj && maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { maskobj = NULL; } @@ -1255,14 +1249,14 @@ static int add_vertex_exec(bContext *C, wmOperator *op) } if (!add_vertex_subdivide(C, mask, co)) { - if (!add_vertex_extrude(C, mask, co)) { + if (!add_vertex_extrude(C, mask, maskobj, co)) { return OPERATOR_CANCELLED; } } } else { if (!add_vertex_subdivide(C, mask, co)) { - if (!add_vertex_new(C, mask, co)) { + if (!add_vertex_new(C, mask, maskobj, co)) { return OPERATOR_CANCELLED; } } @@ -1376,7 +1370,7 @@ static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -1454,7 +1448,7 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -1563,7 +1557,7 @@ static int set_handle_type_exec(bContext *C, wmOperator *op) MaskSpline *spline; int i; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -1664,6 +1658,11 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op) int changed = FALSE; for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + + if (maskobj->restrictflag & MASK_RESTRICT_SELECT) { + continue; + } + if (!unselected) { if (ED_mask_object_select_check(maskobj)) { ED_mask_object_select_set(maskobj, FALSE); diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index 65c3980e3ea..c799ca1e071 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -66,7 +66,7 @@ static int mask_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) MaskSpline *spline; int i; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -136,7 +136,7 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) MaskSpline *spline; int i; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 4f0b33294d3..05dad9f380f 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -75,6 +75,10 @@ int ED_mask_object_select_check(MaskObject *maskobj) { MaskSpline *spline; + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + return FALSE; + } + for (spline = maskobj->splines.first; spline; spline = spline->next) { if (ED_mask_spline_select_check(spline->points, spline->tot_point)) { return TRUE; @@ -101,6 +105,12 @@ void ED_mask_object_select_set(MaskObject *maskobj, int select) { MaskSpline *spline; + if (maskobj->restrictflag & MASK_RESTRICT_SELECT) { + if (select == TRUE) { + return; + } + } + for (spline = maskobj->splines.first; spline; spline = spline->next) { int i; @@ -375,7 +385,7 @@ static int border_select_exec(bContext *C, wmOperator *op) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -447,7 +457,7 @@ static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -573,7 +583,7 @@ static int circle_select_exec(bContext *C, wmOperator *op) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c index 71b10ae0da3..cf2fb71920b 100755 --- a/source/blender/editors/mask/mask_shapekey.c +++ b/source/blender/editors/mask/mask_shapekey.c @@ -67,7 +67,7 @@ static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op)) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskObjectShape *maskobj_shape; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -113,7 +113,7 @@ static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskObjectShape *maskobj_shape; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index d00539ff43c..8211df67b17 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5985,7 +5985,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline = maskobj->splines.first; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -6024,7 +6024,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline = maskobj->splines.first; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } From 6340a10cc590187bc105c171288e3e07b7bfbccd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 13:21:13 +0000 Subject: [PATCH 116/360] fix for own mistake --- source/blender/editors/mask/mask_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index a2e634bdeba..e06342090c2 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1210,7 +1210,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op) maskobj = BKE_mask_object_active(mask); - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (maskobj && maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { maskobj = NULL; } From b6950f42b6bfdef3cb9e90872d6564000e5a6c41 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 13:46:44 +0000 Subject: [PATCH 117/360] only keyframe selected maskobjects --- source/blender/editors/mask/mask_shapekey.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c index cf2fb71920b..e323a6abe15 100755 --- a/source/blender/editors/mask/mask_shapekey.c +++ b/source/blender/editors/mask/mask_shapekey.c @@ -67,7 +67,7 @@ static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op)) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskObjectShape *maskobj_shape; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (!ED_mask_object_select_check(maskobj)) { continue; } @@ -113,7 +113,7 @@ static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskObjectShape *maskobj_shape; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (!ED_mask_object_select_check(maskobj)) { continue; } From 4a71d2e86cad5f7371328149c2663390b3ac7975 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 30 May 2012 14:30:28 +0000 Subject: [PATCH 118/360] Fixed crash of mask node when mask is not set --- .../operations/COM_MaskOperation.cpp | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index e6456e73be3..a742306f440 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -65,6 +65,9 @@ void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers if (this->rasterizedMask) return this->rasterizedMask; + if (!this->mask) + return NULL; + BLI_mutex_lock(getMutex()); if (this->rasterizedMask == NULL) { int width = this->getWidth(); @@ -101,13 +104,21 @@ void MaskOperation::determineResolution(unsigned int resolution[], unsigned int void MaskOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { - float *buffer = (float*) data; - int index = (y * this->getWidth() + x); + if (!data) { + color[0] = 0; + color[1] = 0; + color[2] = 0; + color[3] = 1.0f; + } + else { + float *buffer = (float*) data; + int index = (y * this->getWidth() + x); - color[0] = buffer[index]; - color[1] = buffer[index]; - color[2] = buffer[index]; - color[3] = 1.0f; + color[0] = buffer[index]; + color[1] = buffer[index]; + color[2] = buffer[index]; + color[3] = 1.0f; + } } From 6fb53f7c4207240805fa9fc6d3d2f406bb3ef474 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 30 May 2012 14:39:20 +0000 Subject: [PATCH 119/360] Several small fixes to nodes: - Code formation fix in keying node - Fixed crash when creating keying screen for frame where there's no movie - Attempt to improve keying node to handle alpha on hair better --- .../blender/compositor/operations/COM_KeyingOperation.cpp | 8 ++++---- .../compositor/operations/COM_KeyingScreenOperation.cpp | 7 +++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp index 43348568a5d..5f1c9d0640d 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp @@ -47,7 +47,7 @@ static float get_pixel_saturation(float *pixel, float screen_balance) float mid = pixel[0] + pixel[1] + pixel[2] - min - max; float val = (1.0f - screen_balance) * min + screen_balance * mid; - return max - val; + return (max - val) * (1.0f - val) * (1.0f - val); } KeyingOperation::KeyingOperation(): NodeOperation() @@ -92,7 +92,7 @@ void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler if (primary_channel != screen_primary_channel) { /* different main channel means pixel is on foreground */ color[0] = 1.0f; - } + } else if (saturation >= screen_saturation) { /* saturation of main channel is more than screen, definitely a background */ color[0] = 0.0f; @@ -102,7 +102,7 @@ void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler distance = 1.0f - saturation / screen_saturation; - color[0] = distance; + color[0] = distance * distance; if (color[0] < this->clipBlack) color[0] = 0.0f; @@ -110,5 +110,5 @@ void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler color[0] = 1.0f; else color[0] = (color[0] - this->clipBlack) / (this->clipWhite - this->clipBlack); - } + } } diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp index 456ab31db24..f9c9216b75a 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -102,11 +102,14 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri if (!sites_total) return NULL; - triangulation = (TriangulationData *) MEM_callocN(sizeof(TriangulationData), "keying screen triangulation data"); - BKE_movieclip_user_set_frame(&user, framenumber); ibuf = BKE_movieclip_get_ibuf(movieClip, &user); + if (!ibuf) + return NULL; + + triangulation = (TriangulationData *) MEM_callocN(sizeof(TriangulationData), "keying screen triangulation data"); + sites = (VoronoiSite *) MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites"); track = (MovieTrackingTrack *) tracksbase->first; i = 0; From 001ea9fc9f5229394847a1cc0bb6479f6baf0b12 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 15:23:17 +0000 Subject: [PATCH 120/360] minor mask draw code refactor --- source/blender/editors/mask/mask_draw.c | 124 ++++++++++++++++-------- 1 file changed, 85 insertions(+), 39 deletions(-) diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index ef1dee3f2fe..1e405a4851d 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -49,17 +49,39 @@ #include "mask_intern.h" /* own include */ -static void set_spline_color(MaskObject *maskobj, MaskSpline *spline) +static void mask_spline_color_get(MaskObject *maskobj, MaskSpline *spline, const int is_sel, + unsigned char r_rgb[4]) { - if ((spline->flag & SELECT) && (maskobj->restrictflag & MASK_RESTRICT_SELECT) == 0) { - if (maskobj->act_spline == spline) - glColor3f(1.0f, 1.0f, 1.0f); - else - glColor3f(1.0f, 0.0f, 0.0f); + if (is_sel) { + if (maskobj->act_spline == spline) { + r_rgb[0] = r_rgb[1] = r_rgb[2] = 255; + } + else { + r_rgb[0] = 255; + r_rgb[1] = r_rgb[2] = 0; + } } else { - glColor3f(0.5f, 0.0f, 0.0f); + r_rgb[0] = 128; + r_rgb[1] = r_rgb[2] = 0; } + + r_rgb[3] = 255; +} + +static void mask_spline_feather_color_get(MaskObject *UNUSED(maskobj), MaskSpline *UNUSED(spline), const int is_sel, + unsigned char r_rgb[4]) +{ + if (is_sel) { + r_rgb[1] = 255; + r_rgb[0] = r_rgb[2] = 0; + } + else { + r_rgb[1] = 128; + r_rgb[0] = r_rgb[2] = 0; + } + + r_rgb[3] = 255; } #if 0 @@ -99,6 +121,8 @@ static void draw_spline_parents(MaskObject *UNUSED(maskobj), MaskSpline *spline) /* return non-zero if spline is selected */ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) { + const int is_spline_sel = (spline->flag & SELECT) && (maskobj->restrictflag & MASK_RESTRICT_SELECT) == 0; + unsigned char rgb_spline[4]; MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); int i, hsize, tot_feather_point; @@ -111,6 +135,8 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) glPointSize(hsize); + mask_spline_color_get(maskobj, spline, is_spline_sel, rgb_spline); + /* feather points */ feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); for (i = 0; i < spline->tot_point; i++) { @@ -165,7 +191,7 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) /* draw handle segment */ if (has_handle) { - set_spline_color(maskobj, spline); + glColor3ubv(rgb_spline); glBegin(GL_LINES); glVertex3fv(vert); @@ -208,33 +234,43 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) glPointSize(1.0f); } -static void draw_spline_curve_lines(const float *points, int tot_point, int closed) +/* #define USE_XOR */ + +static void draw_curve_dashed(MaskSpline *spline, float *points, int tot_point, const unsigned char rgb_sel[4]) { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, points); - glDrawArrays(closed ? GL_LINE_LOOP : GL_LINE_STRIP, 0, tot_point); - glDisableClientState(GL_VERTEX_ARRAY); -} + const int draw_method = (spline->flag & MASK_SPLINE_CYCLIC) ? GL_LINE_LOOP : GL_LINE_STRIP; -static void draw_dashed_curve(MaskSpline *spline, float *points, int tot_point) -{ - glEnable(GL_COLOR_LOGIC_OP); - glLogicOp(GL_OR); - - draw_spline_curve_lines(points, tot_point, spline->flag & MASK_SPLINE_CYCLIC); - - glDisable(GL_COLOR_LOGIC_OP); - glLineStipple(3, 0xaaaa); glEnable(GL_LINE_STIPPLE); - glColor3f(0.0f, 0.0f, 0.0f); - draw_spline_curve_lines(points, tot_point, spline->flag & MASK_SPLINE_CYCLIC); +#ifdef USE_XOR + glEnable(GL_COLOR_LOGIC_OP); + glLogicOp(GL_OR); +#endif + + glColor4ubv(rgb_sel); + glLineStipple(3, 0xaaaa); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, points); + glDrawArrays(draw_method, 0, tot_point); + +#ifdef USE_XOR + glDisable(GL_COLOR_LOGIC_OP); +#endif + + glColor4ub(0, 0, 0, 255); + glLineStipple(3, 0x5555); + glDrawArrays(draw_method, 0, tot_point); + glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_LINE_STIPPLE); } -static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline) +static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline, + const char use_smooth, const char draw_type) { + unsigned char rgb_tmp[4]; + + const int is_spline_sel = (spline->flag & SELECT) && (maskobj->restrictflag & MASK_RESTRICT_SELECT) == 0; float *diff_points, *feather_points; int tot_diff_point, tot_feather_point; @@ -243,24 +279,34 @@ static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline) if (!diff_points) return; + if (use_smooth) { + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_feather_point); /* draw feather */ - if ((spline->flag & SELECT) && (maskobj->restrictflag & MASK_RESTRICT_SELECT) == 0) - glColor3f(0.0f, 1.0f, 0.0f); - else - glColor3f(0.0f, 0.5f, 0.0f); - draw_dashed_curve(spline, feather_points, tot_feather_point); + mask_spline_feather_color_get(maskobj, spline, is_spline_sel, rgb_tmp); + draw_curve_dashed(spline, feather_points, tot_feather_point, rgb_tmp); + MEM_freeN(feather_points); /* draw main curve */ - set_spline_color(maskobj, spline); - draw_dashed_curve(spline, diff_points, tot_diff_point); - + mask_spline_color_get(maskobj, spline, is_spline_sel, rgb_tmp); + draw_curve_dashed(spline, diff_points, tot_diff_point, rgb_tmp); MEM_freeN(diff_points); - MEM_freeN(feather_points); + + if (use_smooth) { + glDisable(GL_LINE_SMOOTH); + glDisable(GL_BLEND); + } + + (void)draw_type; } -static void draw_maskobjs(Mask *mask) +static void draw_maskobjs(Mask *mask, + const char use_smooth, const char draw_type) { MaskObject *maskobj; @@ -274,7 +320,7 @@ static void draw_maskobjs(Mask *mask) for (spline = maskobj->splines.first; spline; spline = spline->next) { /* draw curve itself first... */ - draw_spline_curve(maskobj, spline); + draw_spline_curve(maskobj, spline, use_smooth, draw_type); // draw_spline_parents(maskobj, spline); @@ -288,7 +334,7 @@ static void draw_maskobjs(Mask *mask) void *back = spline->points_deform; spline->points_deform = NULL; - draw_spline_curve(maskobj, spline); + draw_spline_curve(maskobj, spline, use_smooth, draw_type); // draw_spline_parents(maskobj, spline); draw_spline_points(maskobj, spline); spline->points_deform = back; @@ -304,5 +350,5 @@ void ED_mask_draw(const bContext *C) if (!mask) return; - draw_maskobjs(mask); + draw_maskobjs(mask, FALSE, 0); } From 125e7550ffd4139eab9c71fd2b5ac41e5c599680 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 May 2012 16:22:33 +0000 Subject: [PATCH 121/360] draw options for mask spline matching the UV view --- release/scripts/startup/bl_ui/space_clip.py | 6 + source/blender/editors/include/ED_mask.h | 2 +- source/blender/editors/mask/mask_draw.c | 117 ++++++++++++++---- .../blender/editors/space_clip/space_clip.c | 2 +- source/blender/makesdna/DNA_mask_types.h | 12 ++ source/blender/makesdna/DNA_space_types.h | 4 + source/blender/makesrna/intern/rna_space.c | 30 +++-- 7 files changed, 136 insertions(+), 37 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 0211ffd0c9f..6815aef56d6 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -711,6 +711,12 @@ class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel): col.label(text="Display Aspect Ratio:") row = col.row() row.prop(clip, "display_aspect", text="") + + if sc.mode == 'MASKEDITING': + col = layout.column() + col.prop(sc, "mask_draw_type", text="") + col.prop(sc, "show_mask_smooth") + class CLIP_PT_marker_display(CLIP_PT_clip_view_panel, Panel): diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h index ed1d2ba688e..b7dee09cbe9 100644 --- a/source/blender/editors/include/ED_mask.h +++ b/source/blender/editors/include/ED_mask.h @@ -39,7 +39,7 @@ void ED_keymap_mask(struct wmKeyConfig *keyconf); void ED_operatormacros_mask(void); /* mask_draw.c */ -void ED_mask_draw(const bContext *C); +void ED_mask_draw(const bContext *C, const char draw_flag, const char draw_type); /* mask_shapekey.c */ int ED_mask_object_shape_auto_key_all(struct Mask *mask, const int frame); diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 1e405a4851d..69c57018ab2 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -236,41 +236,99 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) /* #define USE_XOR */ -static void draw_curve_dashed(MaskSpline *spline, float *points, int tot_point, const unsigned char rgb_sel[4]) +static void mask_draw_curve_type(MaskSpline *spline, float *points, int tot_point, + const short is_feather, const short is_smooth, + const unsigned char rgb_spline[4], const char draw_type) { const int draw_method = (spline->flag & MASK_SPLINE_CYCLIC) ? GL_LINE_LOOP : GL_LINE_STRIP; + unsigned char rgb_tmp[4]; - glEnable(GL_LINE_STIPPLE); - -#ifdef USE_XOR - glEnable(GL_COLOR_LOGIC_OP); - glLogicOp(GL_OR); -#endif - - glColor4ubv(rgb_sel); - glLineStipple(3, 0xaaaa); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, points); - glDrawArrays(draw_method, 0, tot_point); + + switch (draw_type) { + + case MASK_DT_OUTLINE: + glLineWidth(3); + cpack(0x0); + + glDrawArrays(draw_method, 0, tot_point); + + glLineWidth(1); + glColor4ubv(rgb_spline); + glDrawArrays(draw_method, 0, tot_point); + + break; + + case MASK_DT_DASH: + default: + glEnable(GL_LINE_STIPPLE); #ifdef USE_XOR - glDisable(GL_COLOR_LOGIC_OP); + glEnable(GL_COLOR_LOGIC_OP); + glLogicOp(GL_OR); #endif + glColor4ubv(rgb_spline); + glLineStipple(3, 0xaaaa); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, points); + glDrawArrays(draw_method, 0, tot_point); + +#ifdef USE_XOR + glDisable(GL_COLOR_LOGIC_OP); +#endif + glColor4ub(0, 0, 0, 255); + glLineStipple(3, 0x5555); + glDrawArrays(draw_method, 0, tot_point); + + glDisable(GL_LINE_STIPPLE); + break; + + + case MASK_DT_BLACK: + case MASK_DT_WHITE: + if (draw_type == MASK_DT_BLACK) { rgb_tmp[0] = rgb_tmp[1] = rgb_tmp[2] = 0; } + else { rgb_tmp[0] = rgb_tmp[1] = rgb_tmp[2] = 255; } + /* alpha values seem too low but gl draws many points that compensate for it */ + if (is_feather) { rgb_tmp[3] = 64; } + else { rgb_tmp[3] = 128; } + + if (is_feather) { + rgb_tmp[0] = (unsigned char)(((short)rgb_tmp[0] + (short)rgb_spline[0]) / 2); + rgb_tmp[1] = (unsigned char)(((short)rgb_tmp[1] + (short)rgb_spline[1]) / 2); + rgb_tmp[2] = (unsigned char)(((short)rgb_tmp[2] + (short)rgb_spline[2]) / 2); + } + + if (is_smooth == FALSE && is_feather) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + glColor4ubv(rgb_tmp); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, points); + glDrawArrays(draw_method, 0, tot_point); + + glDrawArrays(draw_method, 0, tot_point); + + if (is_smooth == FALSE && is_feather) { + glDisable(GL_BLEND); + } + + break; + } - glColor4ub(0, 0, 0, 255); - glLineStipple(3, 0x5555); - glDrawArrays(draw_method, 0, tot_point); glDisableClientState(GL_VERTEX_ARRAY); - glDisable(GL_LINE_STIPPLE); } static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline, - const char use_smooth, const char draw_type) + const char draw_flag, const char draw_type) { unsigned char rgb_tmp[4]; - const int is_spline_sel = (spline->flag & SELECT) && (maskobj->restrictflag & MASK_RESTRICT_SELECT) == 0; + const short is_spline_sel = (spline->flag & SELECT) && (maskobj->restrictflag & MASK_RESTRICT_SELECT) == 0; + const short is_smooth = (draw_flag & MASK_DRAWFLAG_SMOOTH); float *diff_points, *feather_points; int tot_diff_point, tot_feather_point; @@ -279,7 +337,7 @@ static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline, if (!diff_points) return; - if (use_smooth) { + if (is_smooth) { glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -289,15 +347,19 @@ static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline, /* draw feather */ mask_spline_feather_color_get(maskobj, spline, is_spline_sel, rgb_tmp); - draw_curve_dashed(spline, feather_points, tot_feather_point, rgb_tmp); + mask_draw_curve_type(spline, feather_points, tot_feather_point, + TRUE, is_smooth, + rgb_tmp, draw_type); MEM_freeN(feather_points); /* draw main curve */ mask_spline_color_get(maskobj, spline, is_spline_sel, rgb_tmp); - draw_curve_dashed(spline, diff_points, tot_diff_point, rgb_tmp); + mask_draw_curve_type(spline, diff_points, tot_diff_point, + FALSE, is_smooth, + rgb_tmp, draw_type); MEM_freeN(diff_points); - if (use_smooth) { + if (draw_flag & MASK_DRAWFLAG_SMOOTH) { glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); } @@ -306,7 +368,7 @@ static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline, } static void draw_maskobjs(Mask *mask, - const char use_smooth, const char draw_type) + const char draw_flag, const char draw_type) { MaskObject *maskobj; @@ -320,7 +382,7 @@ static void draw_maskobjs(Mask *mask, for (spline = maskobj->splines.first; spline; spline = spline->next) { /* draw curve itself first... */ - draw_spline_curve(maskobj, spline, use_smooth, draw_type); + draw_spline_curve(maskobj, spline, draw_flag, draw_type); // draw_spline_parents(maskobj, spline); @@ -334,7 +396,7 @@ static void draw_maskobjs(Mask *mask, void *back = spline->points_deform; spline->points_deform = NULL; - draw_spline_curve(maskobj, spline, use_smooth, draw_type); + draw_spline_curve(maskobj, spline, draw_flag, draw_type); // draw_spline_parents(maskobj, spline); draw_spline_points(maskobj, spline); spline->points_deform = back; @@ -343,12 +405,13 @@ static void draw_maskobjs(Mask *mask, } } -void ED_mask_draw(const bContext *C) +void ED_mask_draw(const bContext *C, + const char draw_flag, const char draw_type) { Mask *mask = CTX_data_edit_mask(C); if (!mask) return; - draw_maskobjs(mask, FALSE, 0); + draw_maskobjs(mask, draw_flag, draw_type); } diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 8c5ae38011d..b24db67cfc2 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -1136,7 +1136,7 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) glScalef(maxdim * zoomx, maxdim * zoomy, 0); glMultMatrixf(sc->stabmat); - ED_mask_draw((bContext *)C); + ED_mask_draw((bContext *)C, sc->mask_draw_flag, sc->mask_draw_type); ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index 65707725a53..d427e1561cb 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -132,4 +132,16 @@ typedef struct MaskObject { #define MASK_RESTRICT_SELECT 2 #define MASK_RESTRICT_RENDER 4 +/* SpaceClip->mask_draw_flag */ +#define MASK_DRAWFLAG_SMOOTH 1 + +/* copy of eSpaceImage_UVDT */ +/* SpaceClip->mask_draw_type */ +enum { + MASK_DT_OUTLINE = 0, + MASK_DT_DASH, + MASK_DT_BLACK, + MASK_DT_WHITE +}; + #endif // __DNA_MASK_TYPES_H__ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index fe8617079aa..b1e64641985 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1014,6 +1014,10 @@ typedef struct SpaceClip { /* **** mask editing **** */ struct Mask *mask; + /* draw options */ + char mask_draw_flag; + char mask_draw_type; + char pad3[6]; } SpaceClip; /* SpaceClip->flag */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index c6d5ded0b9b..5e1a17b8e1d 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -45,6 +45,7 @@ #include "DNA_object_types.h" #include "DNA_space_types.h" #include "DNA_sequence_types.h" +#include "DNA_mask_types.h" #include "DNA_view3d_types.h" #include "WM_api.h" @@ -1068,6 +1069,14 @@ static void rna_SpaceClipEditor_view_type_update(Main *UNUSED(bmain), Scene *UNU #else +static EnumPropertyItem dt_uv_items[] = { + {SI_UVDT_OUTLINE, "OUTLINE", 0, "Outline", "Draw white edges with black outline"}, + {SI_UVDT_DASH, "DASH", 0, "Dash", "Draw dashed black-white edges"}, + {SI_UVDT_BLACK, "BLACK", 0, "Black", "Draw black edges"}, + {SI_UVDT_WHITE, "WHITE", 0, "White", "Draw white edges"}, + {0, NULL, 0, NULL, NULL} +}; + static void rna_def_space(BlenderRNA *brna) { StructRNA *srna; @@ -1099,14 +1108,6 @@ static void rna_def_space_image_uv(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static EnumPropertyItem dt_uv_items[] = { - {SI_UVDT_OUTLINE, "OUTLINE", 0, "Outline", "Draw white edges with black outline"}, - {SI_UVDT_DASH, "DASH", 0, "Dash", "Draw dashed black-white edges"}, - {SI_UVDT_BLACK, "BLACK", 0, "Black", "Draw black edges"}, - {SI_UVDT_WHITE, "WHITE", 0, "White", "Draw white edges"}, - {0, NULL, 0, NULL, NULL} - }; - static EnumPropertyItem dt_uvstretch_items[] = { {SI_UVDT_STRETCH_ANGLE, "ANGLE", 0, "Angle", "Angular distortion between UV and 3D angles"}, {SI_UVDT_STRETCH_AREA, "AREA", 0, "Area", "Area distortion between UV and 3D faces"}, @@ -3043,6 +3044,19 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceClipEditor_mask_set", NULL, NULL); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + /* mask drawing */ + prop = RNA_def_property(srna, "mask_draw_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "mask_draw_type"); + RNA_def_property_enum_items(prop, dt_uv_items); + RNA_def_property_ui_text(prop, "Edge Draw Type", "Draw type for mask splines"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + + prop = RNA_def_property(srna, "show_mask_smooth", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mask_draw_flag", MASK_DRAWFLAG_SMOOTH); + RNA_def_property_ui_text(prop, "Draw Smooth Splines", ""); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + + /* mode */ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "mode"); From 6f64165b952276e7e251c06a8d3043441e3f4a07 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Wed, 30 May 2012 18:39:42 +0000 Subject: [PATCH 122/360] Mask out of bounds fix for mask rasterizer --- intern/raskter/raskter.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index 2cd1b38d525..e68379486e9 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -232,7 +232,7 @@ int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_ * TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here. * Will get changed once DEM code gets in. */ - for (y_curr = MAX2(ctx->all_edges->ybeg, 0); (ctx->all_edges || ctx->possible_edges) && (y_curr < ctx->rb.sizey); y_curr++) { + for (y_curr = ctx->all_edges->ybeg; (ctx->all_edges || ctx->possible_edges); y_curr++) { /* * Link any edges that start on the current scan line into the list of @@ -305,12 +305,14 @@ int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_ e_curr = e_curr->e_next; mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1; - /* draw the pixels. */ - for (; cpxl <= mpxl; cpxl++){ - if(*cpxl < 0.5f){ - *cpxl = 1.0f; - }else{ - *cpxl = 0.0f; + if((y_curr >= 0) && (y_curr < ctx->rb.sizey)){ + /* draw the pixels. */ + for (; cpxl <= mpxl; cpxl++){ + if(*cpxl < 0.5f){ + *cpxl = 1.0f; + }else{ + *cpxl = 0.0f; + } } } } From 3795d73235b9b310687ad80744a1db071cc6f193 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Wed, 30 May 2012 21:15:17 +0000 Subject: [PATCH 123/360] Adds property to mask splines to allow them to be negated (black masks), still needs work in tracking.c --- intern/raskter/raskter.c | 12 ++++-------- intern/raskter/raskter.h | 2 +- release/scripts/startup/bl_ui/space_clip.py | 1 + source/blender/blenkernel/intern/mask.c | 2 +- source/blender/blenkernel/intern/tracking.c | 4 ++-- source/blender/makesdna/DNA_mask_types.h | 1 + source/blender/makesrna/intern/rna_mask.c | 7 +++++++ 7 files changed, 17 insertions(+), 12 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index e68379486e9..d4e8c4f4fce 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -171,7 +171,7 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need * if it ends up being coupled with this function. */ -int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts) +int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, float fill_color) { int x_curr; /* current pixel position in X */ int y_curr; /* current scan line being drawn */ @@ -308,11 +308,7 @@ int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_ if((y_curr >= 0) && (y_curr < ctx->rb.sizey)){ /* draw the pixels. */ for (; cpxl <= mpxl; cpxl++){ - if(*cpxl < 0.5f){ - *cpxl = 1.0f; - }else{ - *cpxl = 0.0f; - } + *cpxl = fill_color; } } } @@ -388,7 +384,7 @@ int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_ return 1; } -int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y) { +int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y, float fill_color) { int i; /* i: Loop counter. */ struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */ struct r_fill_context ctx = {0}; @@ -421,7 +417,7 @@ int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y) { ctx.rb.sizex = buf_x; /* Set the output buffer size in X. (width) */ ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ - i = rast_scan_fill(&ctx, ply, num); /* Call our rasterizer, passing in the integer coords for each vert. */ + i = rast_scan_fill(&ctx, ply, num, fill_color); /* Call our rasterizer, passing in the integer coords for each vert. */ free(ply); /* Free the memory allocated for the integer coordinate table. */ return(i); /* Return the value returned by the rasterizer. */ } diff --git a/intern/raskter/raskter.h b/intern/raskter/raskter.h index 98aaf0f6885..e0c256d892a 100644 --- a/intern/raskter/raskter.h +++ b/intern/raskter/raskter.h @@ -48,7 +48,7 @@ struct scan_line_batch { extern "C" { #endif -int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y); +int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y, float fill_color); #ifdef __cplusplus } diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 6815aef56d6..7ed08d16139 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -618,6 +618,7 @@ class CLIP_PT_active_mask_spline(Panel): col = layout.column() col.prop(spline, "weight_interpolation") col.prop(spline, "use_cyclic") + col.prop(spline, "mask_negate") class CLIP_PT_active_mask_point(Panel): diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 3421f5ad9e5..76ff7158b8f 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1754,7 +1754,7 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) } if (tot_diff_point) { - PLX_raskterize(diff_points, tot_diff_point, buffer, width, height); + PLX_raskterize(diff_points, tot_diff_point, buffer, width, height, (spline->flag & MASK_SPLINE_NEGATE)?0.0f:1.0f); MEM_freeN(diff_points); } diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 8df6e4c3748..acc0a8636ff 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1322,8 +1322,8 @@ static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTra fp[0] = stroke_points[i].x * width / ibuf->x - marker->search_min[0]; fp[1] = stroke_points[i].y * height * aspy / ibuf->x - marker->search_min[1]; } - - PLX_raskterize(mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y); + /* TODO: not sure best method to get spline->flag here... to tell if mask is negative color */ + PLX_raskterize(mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y, /* TODO: this is color */ 1.0f); MEM_freeN(mask_points); } diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index d427e1561cb..680da5fc82e 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -120,6 +120,7 @@ typedef struct MaskObject { /* MaskSpline->flag */ /* reserve (1 << 0) for SELECT */ #define MASK_SPLINE_CYCLIC (1 << 1) +#define MASK_SPLINE_NEGATE (1 << 2) /* MaskSpline->weight_interp */ #define MASK_SPLINE_INTERP_LINEAR 1 diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 393ca5f3244..dc6d41b5626 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -506,6 +506,13 @@ static void rna_def_maskSpline(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_SPLINE_CYCLIC); RNA_def_property_ui_text(prop, "Cyclic", "Make this spline a closed loop"); RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* negative mask? */ + prop = RNA_def_property(srna, "mask_negate", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_SPLINE_NEGATE); + RNA_def_property_ui_text(prop, "Negate", "Make this spline subtract from mask"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); } static void rna_def_mask_object(BlenderRNA *brna) From 1541c5f6d0de35bfc7083059d6d965fc41de757d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 07:55:04 +0000 Subject: [PATCH 124/360] fix for own mistake --- source/blender/blenkernel/intern/curve.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 84ac51f68ae..ce62b9c10dc 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -3200,7 +3200,8 @@ float (*BKE_curve_vertexCos_get(Curve * UNUSED(cu), ListBase * lb, int *numVerts else { BPoint *bp = nu->bp; - for (i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) { copy_v3_v3(co, bp->vec); co += 3; + for (i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) { + copy_v3_v3(co, bp->vec); co += 3; } } } From d74200a3af286e82b6a262c6cf14157be38e1b58 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 08:24:53 +0000 Subject: [PATCH 125/360] svn merge -r47246:47245 . --- revert 47246, this needs more considersation and planning to do this well --- intern/raskter/raskter.c | 12 ++++++++---- intern/raskter/raskter.h | 2 +- release/scripts/startup/bl_ui/space_clip.py | 1 - source/blender/blenkernel/intern/mask.c | 2 +- source/blender/blenkernel/intern/tracking.c | 4 ++-- source/blender/makesdna/DNA_mask_types.h | 1 - source/blender/makesrna/intern/rna_mask.c | 7 ------- 7 files changed, 12 insertions(+), 17 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index d4e8c4f4fce..e68379486e9 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -171,7 +171,7 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need * if it ends up being coupled with this function. */ -int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, float fill_color) +int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts) { int x_curr; /* current pixel position in X */ int y_curr; /* current scan line being drawn */ @@ -308,7 +308,11 @@ int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_ if((y_curr >= 0) && (y_curr < ctx->rb.sizey)){ /* draw the pixels. */ for (; cpxl <= mpxl; cpxl++){ - *cpxl = fill_color; + if(*cpxl < 0.5f){ + *cpxl = 1.0f; + }else{ + *cpxl = 0.0f; + } } } } @@ -384,7 +388,7 @@ int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_ return 1; } -int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y, float fill_color) { +int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y) { int i; /* i: Loop counter. */ struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */ struct r_fill_context ctx = {0}; @@ -417,7 +421,7 @@ int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y, floa ctx.rb.sizex = buf_x; /* Set the output buffer size in X. (width) */ ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ - i = rast_scan_fill(&ctx, ply, num, fill_color); /* Call our rasterizer, passing in the integer coords for each vert. */ + i = rast_scan_fill(&ctx, ply, num); /* Call our rasterizer, passing in the integer coords for each vert. */ free(ply); /* Free the memory allocated for the integer coordinate table. */ return(i); /* Return the value returned by the rasterizer. */ } diff --git a/intern/raskter/raskter.h b/intern/raskter/raskter.h index e0c256d892a..98aaf0f6885 100644 --- a/intern/raskter/raskter.h +++ b/intern/raskter/raskter.h @@ -48,7 +48,7 @@ struct scan_line_batch { extern "C" { #endif -int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y, float fill_color); +int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y); #ifdef __cplusplus } diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 7ed08d16139..6815aef56d6 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -618,7 +618,6 @@ class CLIP_PT_active_mask_spline(Panel): col = layout.column() col.prop(spline, "weight_interpolation") col.prop(spline, "use_cyclic") - col.prop(spline, "mask_negate") class CLIP_PT_active_mask_point(Panel): diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 76ff7158b8f..3421f5ad9e5 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1754,7 +1754,7 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) } if (tot_diff_point) { - PLX_raskterize(diff_points, tot_diff_point, buffer, width, height, (spline->flag & MASK_SPLINE_NEGATE)?0.0f:1.0f); + PLX_raskterize(diff_points, tot_diff_point, buffer, width, height); MEM_freeN(diff_points); } diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index acc0a8636ff..8df6e4c3748 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1322,8 +1322,8 @@ static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTra fp[0] = stroke_points[i].x * width / ibuf->x - marker->search_min[0]; fp[1] = stroke_points[i].y * height * aspy / ibuf->x - marker->search_min[1]; } - /* TODO: not sure best method to get spline->flag here... to tell if mask is negative color */ - PLX_raskterize(mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y, /* TODO: this is color */ 1.0f); + + PLX_raskterize(mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y); MEM_freeN(mask_points); } diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index 680da5fc82e..d427e1561cb 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -120,7 +120,6 @@ typedef struct MaskObject { /* MaskSpline->flag */ /* reserve (1 << 0) for SELECT */ #define MASK_SPLINE_CYCLIC (1 << 1) -#define MASK_SPLINE_NEGATE (1 << 2) /* MaskSpline->weight_interp */ #define MASK_SPLINE_INTERP_LINEAR 1 diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index dc6d41b5626..393ca5f3244 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -506,13 +506,6 @@ static void rna_def_maskSpline(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_SPLINE_CYCLIC); RNA_def_property_ui_text(prop, "Cyclic", "Make this spline a closed loop"); RNA_def_property_update(prop, 0, "rna_Mask_update_data"); - - /* negative mask? */ - prop = RNA_def_property(srna, "mask_negate", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_SPLINE_NEGATE); - RNA_def_property_ui_text(prop, "Negate", "Make this spline subtract from mask"); - RNA_def_property_update(prop, 0, "rna_Mask_update_data"); } static void rna_def_mask_object(BlenderRNA *brna) From 9aaaa7eeadae7deb8026fb6808fb32a9ae824811 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 31 May 2012 08:38:50 +0000 Subject: [PATCH 126/360] No need in +x flag for mask_shapekey.c --- source/blender/editors/mask/mask_shapekey.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 source/blender/editors/mask/mask_shapekey.c diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c old mode 100755 new mode 100644 From 1308cad23406f24f8c7f1f1bcfe5575a6aa3a4fb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 08:39:22 +0000 Subject: [PATCH 127/360] patch from pete larabell - feather support for masking. --- intern/raskter/raskter.c | 359 +++++++++++++++++++- intern/raskter/raskter.h | 7 +- source/blender/blenkernel/intern/mask.c | 19 +- source/blender/blenkernel/intern/tracking.c | 2 +- 4 files changed, 375 insertions(+), 12 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index e68379486e9..c0da97ddbd5 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -388,19 +388,20 @@ int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_ return 1; } -int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y) { +int PLX_raskterize(float (*base_verts)[2], int num_base_verts, float *buf, int buf_x, int buf_y) +{ int i; /* i: Loop counter. */ struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */ struct r_fill_context ctx = {0}; /* * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert - * data structure multiplied by the number of verts. + * data structure multiplied by the number of base_verts. * * In the event of a failure to allocate the memory, return 0, so this error can * be distinguished as a memory allocation error. */ - if ((ply = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num))) == NULL) { + if ((ply = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num_base_verts))) == NULL) { return(0); } @@ -412,17 +413,357 @@ int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y) { * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel * drawn will be 1.0f in value, there is no anti-aliasing. */ - for (i = 0; i < num; i++) { /* Loop over all verts. */ - ply[i].x = (verts[i << 1] * buf_x) + 0.5f; /* Range expand normalized X to integer buffer-space X. */ - ply[i].y = (verts[(i << 1) + 1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */ + for (i = 0; i < num_base_verts; i++) { /* Loop over all base_verts. */ + ply[i].x = (base_verts[i][0] * buf_x) + 0.5f; /* Range expand normalized X to integer buffer-space X. */ + ply[i].y = (base_verts[i][1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */ } ctx.rb.buf = buf; /* Set the output buffer pointer. */ ctx.rb.sizex = buf_x; /* Set the output buffer size in X. (width) */ ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ - i = rast_scan_fill(&ctx, ply, num); /* Call our rasterizer, passing in the integer coords for each vert. */ - free(ply); /* Free the memory allocated for the integer coordinate table. */ - return(i); /* Return the value returned by the rasterizer. */ + i = rast_scan_fill(&ctx, ply, num_base_verts); /* Call our rasterizer, passing in the integer coords for each vert. */ + free(ply); /* Free the memory allocated for the integer coordinate table. */ + return(i); /* Return the value returned by the rasterizer. */ } +/* + * This function clips drawing to the frame buffer. That clipping will likely be moved into the preprocessor + * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need + * if it ends up being coupled with this function. + */ +int rast_scan_feather(struct r_fill_context *ctx, + struct poly_vert *base_verts, int num_base_verts, + struct poly_vert *feather_verts, int num_feather_verts) +{ + int x_curr; /* current pixel position in X */ + int y_curr; /* current scan line being drawn */ + int yp; /* y-pixel's position in frame buffer */ + int swixd = 0; /* whether or not edges switched position in X */ + float *cpxl; /* pixel pointers... */ + float *mpxl; + float *spxl; + struct e_status *e_curr; /* edge pointers... */ + struct e_status *e_temp; + struct e_status *edgbuf; + struct e_status **edgec; + + /* from dem */ + int a; // a = temporary pixel index buffer loop counter + int fsz; // size of the frame + unsigned int rsl; // long used for finding fast 1.0/sqrt + float rsf; // float used for finding fast 1.0/sqrt + const float rsopf = 1.5f; // constant float used for finding fast 1.0/sqrt + + //unsigned int gradientFillOffset; + unsigned int t; + unsigned int ud; // ud = unscaled edge distance + unsigned int dmin; // dmin = minimun edge distance + float odist; // odist = current outer edge distance + float idist; // idist = current inner edge distance + int dx; // dx = X-delta (used for distance proportion calculation) + int dy; // dy = Y-delta (used for distance proportion calculation) + + + /* + * If the number of verts specified to render as a polygon is less than 3, + * return immediately. Obviously we cant render a poly with sides < 3. The + * return for this we set to 1, simply so it can be distinguished from the + * next place we could return, /home/guest/blender-svn/soc-2011-tomato/intern/raskter/raskter + * which is a failure to allocate memory. + */ + if (num_feather_verts < 3) { + return(1); + } + + /* + * Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data + * multiplied by the number of edges, which is always equal to the number of verts in + * a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for + * the preceeding error, which was a rasterization request on a 2D poly with less than + * 3 sides. + */ + if ((edgbuf = (struct e_status *)(malloc(sizeof(struct e_status) * num_feather_verts))) == NULL) { + return(0); + } + + /* + * Do some preprocessing on all edges. This constructs a table structure in memory of all + * the edge properties and can "flip" some edges so sorting works correctly. + */ + preprocess_all_edges(ctx, feather_verts, num_feather_verts, edgbuf); + + /* + * Set the pointer for tracking the edges currently in processing to NULL to make sure + * we don't get some crazy value after initialization. + */ + ctx->possible_edges = NULL; + + /* + * Loop through all scan lines to be drawn. Since we sorted by Y values during + * preprocess_all_edges(), we can already exact values for the lowest and + * highest Y values we could possibly need by induction. The preprocessing sorted + * out edges by Y position, we can cycle the current edge being processed once + * it runs out of Y pixels. When we have no more edges, meaning the current edge + * is NULL after setting the "current" edge to be the previous current edge's + * "next" edge in the Y sorted edge connection chain, we can stop looping Y values, + * since we can't possibly have more scan lines if we ran out of edges. :) + * + * TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here. + * Will get changed once DEM code gets in. + */ + for (y_curr = ctx->all_edges->ybeg; (ctx->all_edges || ctx->possible_edges); y_curr++) { + + /* + * Link any edges that start on the current scan line into the list of + * edges currently needed to draw at least this, if not several, scan lines. + */ + + /* + * Set the current edge to the beginning of the list of edges to be rasterized + * into this scan line. + * + * We could have lots of edge here, so iterate over all the edges needed. The + * preprocess_all_edges() function sorted edges by X within each chunk of Y sorting + * so we safely cycle edges to thier own "next" edges in order. + * + * At each iteration, make sure we still have a non-NULL edge. + */ + for (edgec = &ctx->possible_edges; ctx->all_edges && (ctx->all_edges->ybeg == y_curr); ) { + x_curr = ctx->all_edges->x; /* Set current X position. */ + for (;; ) { /* Start looping edges. Will break when edges run out. */ + e_curr = *edgec; /* Set up a current edge pointer. */ + if (!e_curr || (e_curr->x >= x_curr)) { /* If we have an no edge, or we need to skip some X-span, */ + e_temp = ctx->all_edges->e_next; /* set a temp "next" edge to test. */ + *edgec = ctx->all_edges; /* Add this edge to the list to be scanned. */ + ctx->all_edges->e_next = e_curr; /* Set up the next edge. */ + edgec = &ctx->all_edges->e_next; /* Set our list to the next edge's location in memory. */ + ctx->all_edges = e_temp; /* Skip the NULL or bad X edge, set pointer to next edge. */ + break; /* Stop looping edges (since we ran out or hit empty X span. */ + } + else { + edgec = &e_curr->e_next; /* Set the pointer to the edge list the "next" edge. */ + } + } + } + + /* + * Determine the current scan line's offset in the pixel buffer based on its Y position. + * Basically we just multiply the current scan line's Y value by the number of pixels in each line. + */ + yp = y_curr * ctx->rb.sizex; + /* + * Set a "scan line pointer" in memory. The location of the buffer plus the row offset. + */ + spxl = ctx->rb.buf + (yp); + /* + * Set up the current edge to the first (in X) edge. The edges which could possibly be in this + * list were determined in the preceeding edge loop above. They were already sorted in X by the + * initial processing function. + * + * At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge + * we will eventually hit a NULL when the list runs out. + */ + for (e_curr = ctx->possible_edges; e_curr; e_curr = e_curr->e_next) { + /* + * Calculate a span of pixels to fill on the current scan line. + * + * Set the current pixel pointer by adding the X offset to the scan line's start offset. + * Cycle the current edge the next edge. + * Set the max X value to draw to be one less than the next edge's first pixel. This way we are + * sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than + * one time because it's on a vertex connecting two edges) + * + * Then blast through all the pixels in the span, advancing the pointer and setting the color to white. + * + * TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor, + * but for now it is done here until the DEM code comes in. + */ + + /* set up xmin and xmax bounds on this scan line */ + cpxl = spxl + MAX2(e_curr->x, 0); + e_curr = e_curr->e_next; + mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1; + + if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) { + /* draw the pixels. */ + for (; cpxl <= mpxl; cpxl++) { + //do feather check + // first check that pixel isn't already full, and only operate if it is not + if (*cpxl < 0.9999f) { +/* + * Begin modified code from double edge mask compo node... + */ + t = (cpxl - spxl) % ctx->rb.sizex; // calculate column of pixel + + fsz = y_curr; // calculate row of pixel + + + dmin = 0xffffffff; // reset min distance to edge pixel + for (a = 0; a < num_feather_verts; a++) { // loop through all outer edge buffer pixels + dy = t - feather_verts[a].x; // set dx to gradient pixel column - outer edge pixel row + dx = fsz - feather_verts[a].y; // set dy to gradient pixel row - outer edge pixel column + ud = dx * dx + dy * dy; // compute sum of squares + if (ud < dmin) { // if our new sum of squares is less than the current minimum + dmin = ud; // set a new minimum equal to the new lower value + } + } + odist = (float)(dmin); // cast outer min to a float + rsf = odist * 0.5f; // + rsl = *(unsigned int *)&odist; // use some peculiar properties of the way bits are stored + rsl = 0x5f3759df - (rsl >> 1); // in floats vs. unsigned ints to compute an approximate + odist = *(float *)&rsl; // reciprocal square root + odist = odist * (rsopf - (rsf * odist * odist)); // -- ** this line can be iterated for more accuracy ** -- + dmin = 0xffffffff; // reset min distance to edge pixel + for (a = 0; a < num_base_verts; a++) { // loop through all inside edge pixels + dy = t - base_verts[a].x; // compute delta in Y from gradient pixel to inside edge pixel + dx = fsz - base_verts[a].y; // compute delta in X from gradient pixel to inside edge pixel + ud = dx * dx + dy * dy; // compute sum of squares + if (ud < dmin) { // if our new sum of squares is less than the current minimum we've found + dmin = ud; // set a new minimum equal to the new lower value + } + } + idist = (float)(dmin); // cast inner min to a float + rsf = idist * 0.5f; // + rsl = *(unsigned int *)&idist; // + rsl = 0x5f3759df - (rsl >> 1); // see notes above + idist = *(float *)&rsl; // + idist = idist * (rsopf - (rsf * idist * idist)); // + /* + * Note once again that since we are using reciprocals of distance values our + * proportion is already the correct intensity, and does not need to be + * subracted from 1.0 like it would have if we used real distances. + */ + + /* set intensity, do the += so overlapping gradients are additive */ + *cpxl = (idist / (idist + odist)); +/* + * End modified code from double edge mask node + */ + } + } + } + } + + /* + * Loop through all edges of polygon that could be hit by this scan line, + * and figure out their x-intersections with the next scan line. + * + * Either A.) we wont have any more edges to test, or B.) we just add on the + * slope delta computed in preprocessing step. Since this draws non-antialiased + * polygons, we dont have fractional positions, so we only move in x-direction + * when needed to get all the way to the next pixel over... + */ + for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) { + if (!(--(e_curr->num))) { + *edgec = e_curr->e_next; + } + else { + e_curr->x += e_curr->xshift; + if ((e_curr->drift += e_curr->drift_inc) > 0) { + e_curr->x += e_curr->xdir; + e_curr->drift -= e_curr->drift_dec; + } + edgec = &e_curr->e_next; + } + } + /* + * It's possible that some edges may have crossed during the last step, so we'll be sure + * that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges + * sorted by x-intersection coordinate. We'll always scan through at least once to see if + * edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial + * pass, then we know we need to sort by x, so then cycle through edges again and perform + * the sort.- + */ + if (ctx->possible_edges) { + for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + /* if the current edge hits scan line at greater X than the next edge, we need to exchange the edges */ + if (e_curr->x > e_curr->e_next->x) { + *edgec = e_curr->e_next; + /* exchange the pointers */ + e_temp = e_curr->e_next->e_next; + e_curr->e_next->e_next = e_curr; + e_curr->e_next = e_temp; + /* set flag that we had at least one switch */ + swixd = 1; + } + } + /* if we did have a switch, look for more (there will more if there was one) */ + for (;; ) { + /* reset exchange flag so it's only set if we encounter another one */ + swixd = 0; + for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) { + /* again, if current edge hits scan line at higher X than next edge, + * exchange the edges and set flag */ + if (e_curr->x > e_curr->e_next->x) { + *edgec = e_curr->e_next; + /* exchange the pointers */ + e_temp = e_curr->e_next->e_next; + e_curr->e_next->e_next = e_curr; + e_curr->e_next = e_temp; + /* flip the exchanged flag */ + swixd = 1; + } + } + /* if we had no exchanges, we're done reshuffling the pointers */ + if (!swixd) { + break; + } + } + } + } + + free(edgbuf); + return 1; +} + +int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*feather_verts)[2], int num_feather_verts, + float *buf, int buf_x, int buf_y) +{ + int i; /* i: Loop counter. */ + struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */ + struct poly_vert *fe; /* fe: Pointer to a list of integer buffer-space feather vertex coords. */ + struct r_fill_context ctx = {0}; + + /* + * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert + * data structure multiplied by the number of verts. + * + * In the event of a failure to allocate the memory, return 0, so this error can + * be distinguished as a memory allocation error. + */ + if ((ply = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num_base_verts))) == NULL) { + return(0); + } + + if ((fe = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num_feather_verts))) == NULL) { + return(0); + } + + /* + * Loop over all verts passed in to be rasterized. Each vertex's X and Y coordinates are + * then converted from normalized screen space (0.0 <= POS <= 1.0) to integer coordinates + * in the buffer-space coordinates passed in inside buf_x and buf_y. + * + * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel + * drawn will be 1.0f in value, there is no anti-aliasing. + */ + for (i = 0; i < num_base_verts; i++) { /* Loop over all verts. */ + ply[i].x = (base_verts[i][0] * buf_x) + 0.5f; /* Range expand normalized X to integer buffer-space X. */ + ply[i].y = (base_verts[i][1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */ + } + for (i = 0; i < num_feather_verts; i++) { /* Loop over all verts. */ + fe[i].x = (feather_verts[i][0] * buf_x) + 0.5f; /* Range expand normalized X to integer buffer-space X. */ + fe[i].y = (feather_verts[i][1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */ + } + + ctx.rb.buf = buf; /* Set the output buffer pointer. */ + ctx.rb.sizex = buf_x; /* Set the output buffer size in X. (width) */ + ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ + + /* Call our rasterizer, passing in the integer coords for each vert. */ + i = rast_scan_feather(&ctx, ply, num_base_verts, fe, num_feather_verts); + free(ply); /* Free the memory allocated for the integer coordinate table. */ + free(fe); + return i; /* Return the value returned by the rasterizer. */ +} diff --git a/intern/raskter/raskter.h b/intern/raskter/raskter.h index 98aaf0f6885..3292d4f8163 100644 --- a/intern/raskter/raskter.h +++ b/intern/raskter/raskter.h @@ -48,7 +48,12 @@ struct scan_line_batch { extern "C" { #endif -int PLX_raskterize(float *verts, int num, float *buf, int buf_x, int buf_y); +int PLX_raskterize(float (*base_verts)[2], int num_base_verts, + float *buf, int buf_x, int buf_y); + +int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, + float (*feather_verts)[2], int num_feather_verts, + float *buf, int buf_x, int buf_y); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 3421f5ad9e5..02d73d1463e 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1731,30 +1731,47 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) float *diff_points; int tot_diff_point; + float *diff_feather_points; + int tot_diff_feather_points; + diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); + diff_feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_diff_feather_points); /* TODO, make this optional! */ if (width != height) { float *fp; + float *ffp; int i; float asp; if (width < height) { fp = &diff_points[0]; + ffp = &diff_feather_points[0]; asp = (float)width / (float)height; } else { fp = &diff_points[1]; + ffp = &diff_feather_points[1]; asp = (float)height / (float)width; } for (i = 0; i < tot_diff_point; i++, fp += 2) { (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; } + for (i = 0; i < tot_diff_feather_points; i++, ffp += 2) { + (*ffp) = (((*ffp) - 0.5f) / asp) + 0.5f; + } } if (tot_diff_point) { - PLX_raskterize(diff_points, tot_diff_point, buffer, width, height); + PLX_raskterize((float (*)[2])diff_points, tot_diff_point, buffer, width, height); + + if (tot_diff_feather_points) { + PLX_raskterize_feather((float (*)[2])diff_points, tot_diff_point, + (float (*)[2])diff_feather_points, tot_diff_feather_points, + buffer, width, height); + MEM_freeN(diff_feather_points); + } MEM_freeN(diff_points); } diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 8df6e4c3748..c51601202ff 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1323,7 +1323,7 @@ static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTra fp[1] = stroke_points[i].y * height * aspy / ibuf->x - marker->search_min[1]; } - PLX_raskterize(mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y); + PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y); MEM_freeN(mask_points); } From 1794b9b00fbc7c505eba45600bc3e75c78be79aa Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 31 May 2012 09:01:15 +0000 Subject: [PATCH 128/360] Fixed memory leak caused by not freeing uw array for points in deformed spline --- source/blender/blenkernel/intern/mask.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 02d73d1463e..4884a1d013f 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1155,18 +1155,24 @@ void BKE_mask_update_deform(Mask *mask) void BKE_mask_spline_ensure_deform(MaskSpline *spline) { + int allocated_points = (MEM_allocN_len(spline->points_deform) / sizeof(*spline->points_deform)); // printf("SPLINE ALLOC %p %d\n", spline->points_deform, (int)(MEM_allocN_len(spline->points_deform) / sizeof(*spline->points_deform))); - if ((spline->points_deform == NULL) || - (MEM_allocN_len(spline->points_deform) / sizeof(*spline->points_deform)) != spline->tot_point) - { + if (spline->points_deform == NULL || allocated_points != spline->tot_point) { printf("alloc new spline\n"); if (spline->points_deform) { + int i; + + for (i = 0; i < allocated_points; i++) { + MaskSplinePoint *point = &spline->points_deform[i]; + BKE_mask_point_free(point); + } + MEM_freeN(spline->points_deform); } - spline->points_deform = MEM_mallocN(sizeof(*spline->points_deform) * spline->tot_point, __func__); + spline->points_deform = MEM_callocN(sizeof(*spline->points_deform) * spline->tot_point, __func__); } else { // printf("alloc spline done\n"); @@ -1230,6 +1236,8 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) MaskSplinePoint *point_deform = &spline->points_deform[i]; float delta[2]; + BKE_mask_point_free(point_deform); + *point_deform = *point; point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL; From 038f41c087223b2ba22e739fd00355c508defb6e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 09:35:50 +0000 Subject: [PATCH 129/360] minor refactor - use float (*)[2] for 2D point arratys. --- source/blender/blenkernel/BKE_mask.h | 6 +- source/blender/blenkernel/intern/mask.c | 74 +++++++++++++------------ source/blender/editors/mask/mask_draw.c | 16 ++++-- source/blender/editors/mask/mask_ops.c | 8 +-- 4 files changed, 55 insertions(+), 49 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index e21a2aa54e8..4032bf3002c 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -57,9 +57,9 @@ void BKE_mask_object_unique_name(struct Mask *mask, struct MaskObject *maskobj); /* splines */ struct MaskSpline *BKE_mask_spline_add(struct MaskObject *maskobj); int BKE_mask_spline_resolution(struct MaskSpline *spline); -float *BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point); -float *BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point); -float *BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point); +float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point))[2]; +float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point))[2]; +float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point))[2]; /* point */ int BKE_mask_point_has_handle(struct MaskSplinePoint *point); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 4884a1d013f..0cbba350c89 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -216,12 +216,12 @@ int BKE_mask_spline_feather_resolution(MaskSpline *spline) return resol; } -float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) +float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); MaskSplinePoint *point, *prev; - float *diff_points, *fp; + float (*diff_points)[2], (*fp)[2]; int a, len, resol = BKE_mask_spline_resolution(spline); if (spline->tot_point <= 1) { @@ -240,7 +240,7 @@ float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) /* len+1 because of 'forward_diff_bezier' function */ *tot_diff_point = len; - diff_points = fp = MEM_callocN((len + 1) * 2 * sizeof(float), "mask spline vets"); + diff_points = fp = MEM_callocN((len + 1) * sizeof(*diff_points), "mask spline vets"); a = spline->tot_point - 1; if (spline->flag & MASK_SPLINE_CYCLIC) @@ -263,13 +263,13 @@ float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) for (j = 0; j < 2; j++) { BKE_curve_forward_diff_bezier(prevbezt->vec[1][j], prevbezt->vec[2][j], bezt->vec[0][j], bezt->vec[1][j], - fp + j, resol, 2 * sizeof(float)); + &(*fp)[j], resol, 2 * sizeof(float)); } - fp += 2 * resol; + fp += resol; if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) { - copy_v2_v2(fp, bezt->vec[1]); + copy_v2_v2(*fp, bezt->vec[1]); } prev = point; @@ -279,29 +279,30 @@ float *BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point) return diff_points; } -float *BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point) +float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); - float *feather, *fp; + float (*feather)[2], (*fp)[2]; int i, j, tot, resol = BKE_mask_spline_feather_resolution(spline); tot = resol * spline->tot_point; - feather = fp = MEM_callocN(2 * tot * sizeof(float), "mask spline feather diff points"); + feather = fp = MEM_callocN(tot * sizeof(*feather), "mask spline feather diff points"); for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &points_array[i]; - for (j = 0; j < resol; j++, fp += 2) { + for (j = 0; j < resol; j++, fp++) { float u = (float) j / resol, weight; float co[2], n[2]; + /* TODO - these calls all calculate similar things + * could be unified for some speed */ BKE_mask_point_segment_co(spline, point, u, co); BKE_mask_point_normal(spline, point, u, n); weight = BKE_mask_point_weight(spline, point, u); - fp[0] = co[0] + n[0] * weight; - fp[1] = co[1] + n[1] * weight; + madd_v2_v2v2fl(*fp, co, n, weight); } } @@ -310,12 +311,12 @@ float *BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *to return feather; } -float *BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point) +float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); int i, tot = 0; - float *feather, *fp; + float (*feather)[2], (*fp)[2]; /* count */ for (i = 0; i < spline->tot_point; i++) { @@ -325,7 +326,7 @@ float *BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point } /* create data */ - feather = fp = MEM_callocN(2 * tot * sizeof(float), "mask spline feather points"); + feather = fp = MEM_callocN(tot * sizeof(*feather), "mask spline feather points"); for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &points_array[i]; @@ -336,9 +337,8 @@ float *BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point BKE_mask_point_normal(spline, point, 0.0f, n); weight = BKE_mask_point_weight(spline, point, 0.0f); - fp[0] = bezt->vec[1][0] + n[0] * weight; - fp[1] = bezt->vec[1][1] + n[1] * weight; - fp += 2; + madd_v2_v2v2fl(*fp, bezt->vec[1], n, weight); + fp++; for (j = 0; j < point->tot_uw; j++) { float u = point->uw[j].u; @@ -348,10 +348,8 @@ float *BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point BKE_mask_point_normal(spline, point, u, n); weight = BKE_mask_point_weight(spline, point, u); - fp[0] = co[0] + n[0] * weight; - fp[1] = co[1] + n[1] * weight; - - fp += 2; + madd_v2_v2v2fl(*fp, co, n, weight); + fp++; } } @@ -562,19 +560,23 @@ float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, float u) { MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); - BezTriple *bezt = &point->bezt, *next; + BezTriple *bezt = &point->bezt, *bezt_next; float cur_u, cur_w, next_u, next_w, fac; int i; if (point == &points_array[spline->tot_point - 1]) { - if (spline->flag & MASK_SPLINE_CYCLIC) - next = &(points_array[0].bezt); - else - next = NULL; + if (spline->flag & MASK_SPLINE_CYCLIC) { + bezt_next = &(points_array[0].bezt); + } + else { + bezt_next = NULL; + } + } + else { + bezt_next = &((point + 1))->bezt; } - else next = &((point + 1))->bezt; - if (!next) + if (!bezt_next) return bezt->weight; for (i = 0; i < point->tot_uw + 1; i++) { @@ -590,7 +592,7 @@ float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, float u) if (i == point->tot_uw) { next_u = 1.0f; - next_w = next->weight; + next_w = bezt_next->weight; } else { next_u = point->uw[i].u; @@ -1736,10 +1738,10 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) MaskSpline *spline; for (spline = maskobj->splines.first; spline; spline = spline->next) { - float *diff_points; + float (*diff_points)[2]; int tot_diff_point; - float *diff_feather_points; + float (*diff_feather_points)[2]; int tot_diff_feather_points; diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); @@ -1753,13 +1755,13 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) float asp; if (width < height) { - fp = &diff_points[0]; - ffp = &diff_feather_points[0]; + fp = &diff_points[0][0]; + ffp = &diff_feather_points[0][0]; asp = (float)width / (float)height; } else { - fp = &diff_points[1]; - ffp = &diff_feather_points[1]; + fp = &diff_points[0][1]; + ffp = &diff_feather_points[0][1]; asp = (float)height / (float)width; } diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 69c57018ab2..83d6c04c46d 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -126,7 +126,7 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); int i, hsize, tot_feather_point; - float *feather_points, *fp; + float (*feather_points)[2], (*fp)[2]; if (!spline->tot_point) return; @@ -167,10 +167,10 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) } glBegin(GL_POINTS); - glVertex2fv(fp); + glVertex2fv(*fp); glEnd(); - fp += 2; + fp++; } } MEM_freeN(feather_points); @@ -236,7 +236,7 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) /* #define USE_XOR */ -static void mask_draw_curve_type(MaskSpline *spline, float *points, int tot_point, +static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot_point, const short is_feather, const short is_smooth, const unsigned char rgb_spline[4], const char draw_type) { @@ -329,8 +329,12 @@ static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline, const short is_spline_sel = (spline->flag & SELECT) && (maskobj->restrictflag & MASK_RESTRICT_SELECT) == 0; const short is_smooth = (draw_flag & MASK_DRAWFLAG_SMOOTH); - float *diff_points, *feather_points; - int tot_diff_point, tot_feather_point; + + int tot_diff_point; + float (*diff_points)[2]; + + int tot_feather_point; + float (*feather_points)[2]; diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index e06342090c2..53f87b92707 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -243,7 +243,7 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in //MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); int i, tot_feather_point; - float *feather_points, *fp; + float (*feather_points)[2], (*fp)[2]; if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; @@ -258,8 +258,8 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in for (j = 0; j < cur_point->tot_uw + 1; j++) { float cur_len, vec[2]; - vec[0] = fp[0] * scalex; - vec[1] = fp[1] * scaley; + vec[0] = (*fp)[0] * scalex; + vec[1] = (*fp)[1] * scaley; cur_len = len_v2v2(vec, co); @@ -275,7 +275,7 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in len = cur_len; } - fp += 2; + fp++; } } From 332366643b58ebc2f2b14e361850669144e91990 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 09:46:17 +0000 Subject: [PATCH 130/360] use malloc for point arrays since they are filled in immediately. --- source/blender/blenkernel/BKE_mask.h | 1 + source/blender/blenkernel/intern/mask.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 4032bf3002c..7324f366e8d 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -57,6 +57,7 @@ void BKE_mask_object_unique_name(struct Mask *mask, struct MaskObject *maskobj); /* splines */ struct MaskSpline *BKE_mask_spline_add(struct MaskObject *maskobj); int BKE_mask_spline_resolution(struct MaskSpline *spline); + float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point))[2]; float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point))[2]; float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point))[2]; diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 0cbba350c89..34396544b77 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -240,7 +240,7 @@ float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[ /* len+1 because of 'forward_diff_bezier' function */ *tot_diff_point = len; - diff_points = fp = MEM_callocN((len + 1) * sizeof(*diff_points), "mask spline vets"); + diff_points = fp = MEM_mallocN((len + 1) * sizeof(*diff_points), "mask spline vets"); a = spline->tot_point - 1; if (spline->flag & MASK_SPLINE_CYCLIC) @@ -287,7 +287,7 @@ float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *t int i, j, tot, resol = BKE_mask_spline_feather_resolution(spline); tot = resol * spline->tot_point; - feather = fp = MEM_callocN(tot * sizeof(*feather), "mask spline feather diff points"); + feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather diff points"); for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &points_array[i]; @@ -326,7 +326,7 @@ float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_poin } /* create data */ - feather = fp = MEM_callocN(tot * sizeof(*feather), "mask spline feather points"); + feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather points"); for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &points_array[i]; From 998c34a7fa1551d65591d0855b3df3cd63769979 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 09:50:50 +0000 Subject: [PATCH 131/360] minor cleanup --- intern/raskter/raskter.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index c0da97ddbd5..fd274c5f5f5 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -388,7 +388,8 @@ int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_ return 1; } -int PLX_raskterize(float (*base_verts)[2], int num_base_verts, float *buf, int buf_x, int buf_y) +int PLX_raskterize(float (*base_verts)[2], int num_base_verts, + float *buf, int buf_x, int buf_y) { int i; /* i: Loop counter. */ struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */ @@ -718,13 +719,17 @@ int rast_scan_feather(struct r_fill_context *ctx, } int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*feather_verts)[2], int num_feather_verts, - float *buf, int buf_x, int buf_y) + float *buf, int buf_x, int buf_y) { int i; /* i: Loop counter. */ struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */ struct poly_vert *fe; /* fe: Pointer to a list of integer buffer-space feather vertex coords. */ struct r_fill_context ctx = {0}; + /* for faster multiply */ + const float buf_x_f = (float)buf_x; + const float buf_y_f = (float)buf_y; + /* * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert * data structure multiplied by the number of verts. @@ -749,12 +754,12 @@ int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*f * drawn will be 1.0f in value, there is no anti-aliasing. */ for (i = 0; i < num_base_verts; i++) { /* Loop over all verts. */ - ply[i].x = (base_verts[i][0] * buf_x) + 0.5f; /* Range expand normalized X to integer buffer-space X. */ - ply[i].y = (base_verts[i][1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */ + ply[i].x = (int)((base_verts[i][0] * buf_x_f) + 0.5f); /* Range expand normalized X to integer buffer-space X. */ + ply[i].y = (int)((base_verts[i][1] * buf_y_f) + 0.5f); /* Range expand normalized Y to integer buffer-space Y. */ } for (i = 0; i < num_feather_verts; i++) { /* Loop over all verts. */ - fe[i].x = (feather_verts[i][0] * buf_x) + 0.5f; /* Range expand normalized X to integer buffer-space X. */ - fe[i].y = (feather_verts[i][1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */ + fe[i].x = (int)((feather_verts[i][0] * buf_x_f) + 0.5f); /* Range expand normalized X to integer buffer-space X. */ + fe[i].y = (int)((feather_verts[i][1] * buf_y_f) + 0.5f); /* Range expand normalized Y to integer buffer-space Y. */ } ctx.rb.buf = buf; /* Set the output buffer pointer. */ From efe289f3121f1eb9a7d85520cf5bfaeed88bcf50 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 31 May 2012 10:01:21 +0000 Subject: [PATCH 132/360] Fix adding feather points when there's deformed spline for mask Deformed spline should be re-evaluated after adding new feather points Used both BKE_mask_update_display and DAG_id_tag_update because of: - If adding feather point is happening from macro which adds point and slides it, deformed spline should be updated immediatelly so sliding operator will use updated feather, - If adding happens outside of such macro, update DAG is necessary to make needed updates in other areas (such as compositor, i.e.) --- source/blender/editors/mask/mask_ops.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 53f87b92707..2eaae673364 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1317,12 +1317,17 @@ static int add_feather_vertex_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; if (find_nearest_diff_point(C, mask, co, threshold, TRUE, &maskobj, &spline, &point, &u, NULL)) { + Scene *scene = CTX_data_scene(C); float w = BKE_mask_point_weight(spline, point, u); BKE_mask_point_add_uw(point, u, w); + BKE_mask_update_display(mask, scene->r.cfra); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + DAG_id_tag_update(&mask->id, 0); + return OPERATOR_FINISHED; } From 744360479060be75df955bef48987324eb8eec58 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 12:12:28 +0000 Subject: [PATCH 133/360] mask object blending and alpha options --- release/scripts/startup/bl_ui/space_clip.py | 7 ++ source/blender/blenkernel/intern/mask.c | 102 +++++++++++++++++- .../editors/interface/interface_templates.c | 1 + source/blender/makesdna/DNA_mask_types.h | 18 +++- source/blender/makesrna/intern/rna_mask.c | 36 ++++++- 5 files changed, 156 insertions(+), 8 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 6815aef56d6..a5b1996ae0d 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -591,6 +591,13 @@ class CLIP_PT_mask_objects(Panel): active = mask.objects.active if active: layout.prop(active, "name") + + # blending + row = layout.row(align=True) + row.prop(active, "alpha") + row.prop(active, "invert", text="", icon='IMAGE_ALPHA') + + layout.prop(active, "blend") class CLIP_PT_active_mask_spline(Panel): diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 34396544b77..42a083e56d7 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1729,13 +1729,57 @@ void BKE_mask_object_shape_changed_remove(MaskObject *maskobj, int index, int co } } +/* local functions */ +static void invert_vn_vn(float *array, const int size) +{ + float *arr = array + (size - 1); + int i = size; + while (i--) { + *(arr) = 1.0f - *(arr); + arr--; + } +} + +static void m_invert_vn_vn(float *array, const float f, const int size) +{ + float *arr = array + (size - 1); + int i = size; + while (i--) { + *(arr) = 1.0f - (*(arr) * f); + arr--; + } +} + +static void clamp_vn_vn(float *array, const int size) +{ + float *arr = array + (size - 1); + + int i = size; + while (i--) { + if (*arr < 0.0f) *arr = 0.0f; + else if (*arr > 1.0f) *arr = 1.0f; + arr--; + } +} + /* rasterization */ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) { MaskObject *maskobj; + /* temp blending buffer */ + const int buffer_size = width * height; + float *buffer_tmp = MEM_mallocN(sizeof(float) * buffer_size, __func__); + for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; + float alpha; + + if (maskobj->restrictflag & MASK_RESTRICT_RENDER) { + continue; + } + + memset(buffer_tmp, 0, sizeof(float) * buffer_size); for (spline = maskobj->splines.first; spline; spline = spline->next) { float (*diff_points)[2]; @@ -1774,17 +1818,67 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) } if (tot_diff_point) { - PLX_raskterize((float (*)[2])diff_points, tot_diff_point, buffer, width, height); + PLX_raskterize((float (*)[2])diff_points, tot_diff_point, + buffer_tmp, width, height); if (tot_diff_feather_points) { PLX_raskterize_feather((float (*)[2])diff_points, tot_diff_point, (float (*)[2])diff_feather_points, tot_diff_feather_points, - buffer, width, height); - MEM_freeN(diff_feather_points); + buffer_tmp, width, height); } - MEM_freeN(diff_points); + if (tot_diff_point) { + MEM_freeN(diff_points); + } + if (tot_diff_feather_points) { + MEM_freeN(diff_feather_points); + } } } + + /* blend with original */ + if (maskobj->blend_flag & MASK_BLENDFLAG_INVERT) { + /* apply alpha multiply before inverting */ + if (maskobj->alpha != 1.0f) { + m_invert_vn_vn(buffer_tmp, maskobj->alpha, buffer_size); + } + else { + invert_vn_vn(buffer_tmp, buffer_size); + } + + alpha = 1.0f; + } + else { + alpha = maskobj->alpha; + } + + switch (maskobj->blend) { + case MASK_BLEND_SUBTRACT: + { + if (alpha == 1.0f) { + sub_vn_vn(buffer, buffer_tmp, buffer_size); + } + else { + msub_vn_vn(buffer, buffer_tmp, alpha, buffer_size); + } + break; + } + case MASK_BLEND_ADD: + default: + { + if (alpha == 1.0f) { + add_vn_vn(buffer, buffer_tmp, buffer_size); + } + else { + madd_vn_vn(buffer, buffer_tmp, alpha, buffer_size); + } + break; + } + } + + /* clamp at the end */ + clamp_vn_vn(buffer, buffer_size); } + + MEM_freeN(buffer_tmp); } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 1acfefe8a4c..d23cd88cf05 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2251,6 +2251,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe // uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); // enable when used uiItemR(row, itemptr, "hide", 0, "", 0); uiItemR(row, itemptr, "hide_select", 0, "", 0); + uiItemR(row, itemptr, "hide_render", 0, "", 0); uiBlockSetEmboss(block, UI_EMBOSS); } diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index d427e1561cb..d677239e300 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -108,10 +108,14 @@ typedef struct MaskObject { struct MaskSpline *act_spline; /* active spline */ struct MaskSplinePoint *act_point; /* active point */ + /* blending options */ float alpha; + char blend; + char blend_flag; + //char flag; /* not used yet */ char restrictflag; /* matching 'Object' flag of the same name - eventually use in the outliner */ - char pad[3]; + char pad[1]; } MaskObject; /* MaskParent->flag */ @@ -144,4 +148,16 @@ enum { MASK_DT_WHITE }; +/* maskobj->blend */ +enum { + MASK_BLEND_ADD = 0, + MASK_BLEND_SUBTRACT = 1 +}; + +/* maskobj->blend_flag */ +enum { + MASK_BLENDFLAG_INVERT = (1 << 0) +}; + + #endif // __DNA_MASK_TYPES_H__ diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 393ca5f3244..c072676b665 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -126,6 +126,11 @@ static void rna_Mask_object_active_index_range(PointerRNA *ptr, int *min, int *m *softmax = *max; } +static char *rna_MaskObject_path(PointerRNA *ptr) +{ + return BLI_sprintfN("objects[\"%s\"]", ((MaskObject *)ptr->data)->name); +} + static PointerRNA rna_Mask_object_active_get(PointerRNA *ptr) { Mask *mask = (Mask *)ptr->id.data; @@ -483,7 +488,8 @@ static void rna_def_maskSpline(BlenderRNA *brna) static EnumPropertyItem spline_interpolation_items[] = { {MASK_SPLINE_INTERP_LINEAR, "LINEAR", 0, "Linear", ""}, {MASK_SPLINE_INTERP_EASE, "EASE", 0, "Ease", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; StructRNA *srna; PropertyRNA *prop; @@ -510,6 +516,12 @@ static void rna_def_maskSpline(BlenderRNA *brna) static void rna_def_mask_object(BlenderRNA *brna) { + static EnumPropertyItem maskobj_blend_mode_items[] = { + {MASK_BLEND_ADD, "ADD", 0, "Add", ""}, + {MASK_BLEND_SUBTRACT, "SUBTRACT", 0, "Subtract", ""}, + {0, NULL, 0, NULL, NULL} + }; + StructRNA *srna; PropertyRNA *prop; @@ -518,6 +530,7 @@ static void rna_def_mask_object(BlenderRNA *brna) srna = RNA_def_struct(brna, "MaskObject", NULL); RNA_def_struct_ui_text(srna, "Mask Object", "Single object used for masking pixels"); + RNA_def_struct_path_func(srna, "rna_MaskObject_path"); /* name */ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); @@ -551,14 +564,28 @@ static void rna_def_mask_object(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", MASK_RESTRICT_RENDER); RNA_def_property_ui_text(prop, "Restrict Render", "Restrict renderability"); RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); - RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL); + RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); /* render settings */ prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "alpha"); RNA_def_property_range(prop, 0.0, 1.0f); RNA_def_property_ui_text(prop, "Opacity", "Render Opacity"); - RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL); + RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); + + /* weight interpolation */ + prop = RNA_def_property(srna, "blend", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "blend"); + RNA_def_property_enum_items(prop, maskobj_blend_mode_items); + RNA_def_property_ui_text(prop, "Blend", "Method of blending mask objects"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); + + prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MASK_BLENDFLAG_INVERT); + RNA_def_property_ui_text(prop, "Restrict View", "Restrict visibility in the viewport"); + RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); + } static void rna_def_maskobjects(BlenderRNA *brna, PropertyRNA *cprop) @@ -616,6 +643,9 @@ static void rna_def_mask(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_funcs(prop, "rna_Mask_object_active_index_get", "rna_Mask_object_active_index_set", "rna_Mask_object_active_index_range"); RNA_def_property_ui_text(prop, "Active Shape Index", "Index of active object in list of all mask's objects"); + + /* pointers */ + rna_def_animdata_common(srna); } void RNA_def_mask(BlenderRNA *brna) From 153259ff7441b496264db217983adffee36f963f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 12:24:06 +0000 Subject: [PATCH 134/360] support for mask keyframing --- source/blender/blenkernel/intern/anim_sys.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 1358c2e34a8..7fc80529753 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -90,6 +90,7 @@ short id_type_can_have_animdata(ID *id) case ID_SPK: case ID_SCE: case ID_MC: + case ID_MSK: { return 1; } @@ -802,10 +803,13 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u /* objects */ ANIMDATA_IDS_CB(mainptr->object.first); + + /* masks */ + ANIMDATA_IDS_CB(mainptr->mask.first); /* worlds */ ANIMDATA_IDS_CB(mainptr->world.first); - + /* scenes */ ANIMDATA_NODETREE_IDS_CB(mainptr->scene.first, Scene); } @@ -886,6 +890,9 @@ void BKE_all_animdata_fix_paths_rename(ID *ref_id, const char *prefix, const cha /* objects */ RENAMEFIX_ANIM_IDS(mainptr->object.first); + + /* masks */ + RENAMEFIX_ANIM_IDS(mainptr->mask.first); /* worlds */ RENAMEFIX_ANIM_IDS(mainptr->world.first); @@ -2350,6 +2357,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime) * linked from other (not-visible) scenes will not need their data calculated. */ EVAL_ANIM_IDS(main->object.first, 0); + + /* masks */ + EVAL_ANIM_IDS(main->mask.first, ADT_RECALC_ANIM); /* worlds */ EVAL_ANIM_NODETREE_IDS(main->world.first, World, ADT_RECALC_ANIM); From 58a7c451c1d9eecb59de46995386272154cbf582 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 13:37:32 +0000 Subject: [PATCH 135/360] convert mask to linear color. --- source/blender/blenkernel/intern/mask.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 42a083e56d7..bfe8ae54e0c 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1750,7 +1750,7 @@ static void m_invert_vn_vn(float *array, const float f, const int size) } } -static void clamp_vn_vn(float *array, const int size) +static void linear_clamp_vn_vn(float *array, const int size) { float *arr = array + (size - 1); @@ -1758,6 +1758,7 @@ static void clamp_vn_vn(float *array, const int size) while (i--) { if (*arr < 0.0f) *arr = 0.0f; else if (*arr > 1.0f) *arr = 1.0f; + else *arr = srgb_to_linearrgb(*arr); arr--; } } @@ -1877,7 +1878,7 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) } /* clamp at the end */ - clamp_vn_vn(buffer, buffer_size); + linear_clamp_vn_vn(buffer, buffer_size); } MEM_freeN(buffer_tmp); From 198a914db12a02e85114513f7a5f2ef3124b4443 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 13:43:21 +0000 Subject: [PATCH 136/360] save calling srgb_to_linearrgb() for 0 or 1 when converting mask color. --- source/blender/blenkernel/intern/mask.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index bfe8ae54e0c..7070edc0054 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1756,9 +1756,9 @@ static void linear_clamp_vn_vn(float *array, const int size) int i = size; while (i--) { - if (*arr < 0.0f) *arr = 0.0f; - else if (*arr > 1.0f) *arr = 1.0f; - else *arr = srgb_to_linearrgb(*arr); + if (*arr <= 0.0f) *arr = 0.0f; + else if (*arr >= 1.0f) *arr = 1.0f; + else *arr = srgb_to_linearrgb(*arr); arr--; } } From 65c8a338429e3d2b07e77e5c65265d4fc17134b8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 14:03:25 +0000 Subject: [PATCH 137/360] fix for using wrong poll function in mask parenting --- source/blender/editors/mask/mask_relationships.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index c799ca1e071..bf57bce9957 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -97,7 +97,7 @@ void MASK_OT_parent_clear(wmOperatorType *ot) /* api callbacks */ ot->exec = mask_parent_clear_exec; - ot->poll = ED_operator_object_active_editable; + ot->poll = ED_maskediting_mask_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -176,7 +176,7 @@ void MASK_OT_parent_set(wmOperatorType *ot) //ot->invoke = mask_parent_set_invoke; ot->exec = mask_parent_set_exec; - ot->poll = ED_operator_object_active; + ot->poll = ED_maskediting_mask_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; From 0451dedf6f1838aebe8dbc8205aa2b110fcefe89 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Thu, 31 May 2012 14:29:09 +0000 Subject: [PATCH 138/360] remove some redundant checks when freeing memory after rasterizing masks. --- source/blender/blenkernel/intern/mask.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 7070edc0054..363efd2dd54 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1826,14 +1826,10 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) PLX_raskterize_feather((float (*)[2])diff_points, tot_diff_point, (float (*)[2])diff_feather_points, tot_diff_feather_points, buffer_tmp, width, height); - } - - if (tot_diff_point) { - MEM_freeN(diff_points); - } - if (tot_diff_feather_points) { MEM_freeN(diff_feather_points); } + + MEM_freeN(diff_points); } } From f7fb32fb8a6270df6416c0894230308f854fa404 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Thu, 31 May 2012 14:36:22 +0000 Subject: [PATCH 139/360] Fix possible memory leak where spline differentiation fails but feather differentiation does not. --- source/blender/blenkernel/intern/mask.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 363efd2dd54..d1ed99bd0c6 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1790,7 +1790,9 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) int tot_diff_feather_points; diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); - diff_feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_diff_feather_points); + if(tot_diff_point){ + diff_feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_diff_feather_points); + } /* TODO, make this optional! */ if (width != height) { From 55621216ceee1bb962f687255d57fb802952a6d0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 15:37:44 +0000 Subject: [PATCH 140/360] fix for border/circle/lasso select not using the deformed locations when selecting. --- source/blender/editors/mask/mask_select.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 05dad9f380f..c204dbf0110 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -390,13 +390,16 @@ static int border_select_exec(bContext *C, wmOperator *op) } for (spline = maskobj->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; /* TODO: handles? */ /* TODO: uw? */ - if (BLI_in_rctf(&rectf, point->bezt.vec[1][0], point->bezt.vec[1][1])) { + if (BLI_in_rctf(&rectf, point_deform->bezt.vec[1][0], point_deform->bezt.vec[1][1])) { BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT); BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT); } @@ -462,8 +465,11 @@ static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short } for (spline = maskobj->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; /* TODO: handles? */ /* TODO: uw? */ @@ -472,7 +478,7 @@ static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short /* marker in screen coords */ ED_mask_point_pos__reverse(C, - point->bezt.vec[1][0], point->bezt.vec[1][1], + point_deform->bezt.vec[1][0], point_deform->bezt.vec[1][1], &screen_co[0], &screen_co[1]); if (BLI_in_rcti(&rect, screen_co[0], screen_co[1]) && @@ -539,15 +545,15 @@ void MASK_OT_select_lasso(wmOperatorType *ot) /********************** circle select operator *********************/ -static int mask_spline_point_inside_ellipse(MaskSplinePoint *point, float offset[2], float ellipse[2]) +static int mask_spline_point_inside_ellipse(BezTriple *bezt, float offset[2], float ellipse[2]) { /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */ float x, y; - x = (point->bezt.vec[1][0] - offset[0]) * ellipse[0]; - y = (point->bezt.vec[1][1] - offset[1]) * ellipse[1]; + x = (bezt->vec[1][0] - offset[0]) * ellipse[0]; + y = (bezt->vec[1][1] - offset[1]) * ellipse[1]; - return x*x + y*y < 1.0f; + return x * x + y * y < 1.0f; } static int circle_select_exec(bContext *C, wmOperator *op) @@ -588,10 +594,13 @@ static int circle_select_exec(bContext *C, wmOperator *op) } for (spline = maskobj->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; - if (mask_spline_point_inside_ellipse(point, offset, ellipse)) { + if (mask_spline_point_inside_ellipse(&point_deform->bezt, offset, ellipse)) { BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT); BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT); From 3834134cf0585adc61ab988d522467e534225d2f Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Thu, 31 May 2012 16:59:25 +0000 Subject: [PATCH 141/360] Add dynamic mask curve differentiation for more accurate feather gradients. --- source/blender/blenkernel/BKE_mask.h | 6 ++-- source/blender/blenkernel/intern/mask.c | 41 +++++++++++++++++-------- source/blender/editors/mask/mask_draw.c | 4 +-- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 7324f366e8d..5663aa69e8b 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -56,10 +56,10 @@ void BKE_mask_object_unique_name(struct Mask *mask, struct MaskObject *maskobj); /* splines */ struct MaskSpline *BKE_mask_spline_add(struct MaskObject *maskobj); -int BKE_mask_spline_resolution(struct MaskSpline *spline); +int BKE_mask_spline_resolution(struct MaskSpline *spline, float max_seg_len); -float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point))[2]; -float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point))[2]; +float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point, int dynamic_res, float max_dseg_len))[2]; +float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point, int dynamic_res, float max_dseg_len))[2]; float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point))[2]; /* point */ diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index d1ed99bd0c6..9e509c10989 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -149,9 +149,9 @@ MaskSpline *BKE_mask_spline_add(MaskObject *maskobj) return spline; } -int BKE_mask_spline_resolution(MaskSpline *spline) +int BKE_mask_spline_resolution(MaskSpline *spline, float max_seg_len) { - const float max_segment = 0.01; + const float max_segment = max_seg_len; int i, resol = 1; for (i = 0; i < spline->tot_point; i++) { @@ -186,10 +186,10 @@ int BKE_mask_spline_resolution(MaskSpline *spline) return resol; } -int BKE_mask_spline_feather_resolution(MaskSpline *spline) +int BKE_mask_spline_feather_resolution(MaskSpline *spline, float max_seg_len) { const float max_segment = 0.005; - int resol = BKE_mask_spline_resolution(spline); + int resol = BKE_mask_spline_resolution(spline, max_seg_len); float max_jump = 0.0f; int i; @@ -216,13 +216,18 @@ int BKE_mask_spline_feather_resolution(MaskSpline *spline) return resol; } -float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[2] +float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point, int dynamic_res, float max_dseg_len))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); MaskSplinePoint *point, *prev; float (*diff_points)[2], (*fp)[2]; - int a, len, resol = BKE_mask_spline_resolution(spline); + int a, len, resol; + if(!dynamic_res){ + max_dseg_len = 0.01f; + } + resol = BKE_mask_spline_resolution(spline, max_dseg_len); + if (spline->tot_point <= 1) { /* nothing to differentiate */ @@ -279,12 +284,16 @@ float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[ return diff_points; } -float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point))[2] +float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point, int dynamic_res, float max_dseg_len))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); float (*feather)[2], (*fp)[2]; - int i, j, tot, resol = BKE_mask_spline_feather_resolution(spline); + int i, j, tot, resol; + if(!dynamic_res){ + max_dseg_len = 0.005f; + } + resol = BKE_mask_spline_feather_resolution(spline, max_dseg_len); tot = resol * spline->tot_point; feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather diff points"); @@ -429,7 +438,7 @@ void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_di float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_feather_point) { float *feather, *fp; - int i, resol = BKE_mask_spline_feather_resolution(spline); + int i, resol = BKE_mask_spline_feather_resolution(spline, 0.005f); feather = fp = MEM_callocN(2 * resol * sizeof(float), "mask point spline feather diff points"); @@ -456,7 +465,7 @@ float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, i BezTriple *bezt, *next; float *diff_points, *fp; - int j, resol = BKE_mask_spline_resolution(spline); + int j, resol = BKE_mask_spline_resolution(spline, 0.01f); bezt = &point->bezt; @@ -1771,6 +1780,14 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) /* temp blending buffer */ const int buffer_size = width * height; float *buffer_tmp = MEM_mallocN(sizeof(float) * buffer_size, __func__); + float max_dseg_len = 0.0f; + + if(width >= height){ + max_dseg_len = (float)(width); + }else{ + max_dseg_len = (float)(height); + } + max_dseg_len = 1.0f / max_dseg_len; for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { MaskSpline *spline; @@ -1789,9 +1806,9 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) float (*diff_feather_points)[2]; int tot_diff_feather_points; - diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); + diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point, 1, max_dseg_len); if(tot_diff_point){ - diff_feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_diff_feather_points); + diff_feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_diff_feather_points, 1, max_dseg_len); } /* TODO, make this optional! */ diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 83d6c04c46d..c282153acbf 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -336,7 +336,7 @@ static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline, int tot_feather_point; float (*feather_points)[2]; - diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point); + diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point, 0, 0.0f); if (!diff_points) return; @@ -347,7 +347,7 @@ static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline, glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_feather_point); + feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_feather_point, 0, 0.0f); /* draw feather */ mask_spline_feather_color_get(maskobj, spline, is_spline_sel, rgb_tmp); From 192a28bb32e8888c4477f724bfab036a466458be Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 May 2012 19:12:22 +0000 Subject: [PATCH 142/360] rename mask-objects to mask-layers. --- release/scripts/startup/bl_ui/space_clip.py | 20 +- source/blender/blenkernel/BKE_mask.h | 60 +-- source/blender/blenkernel/intern/mask.c | 404 +++++++++--------- source/blender/blenloader/intern/readfile.c | 28 +- source/blender/blenloader/intern/writefile.c | 16 +- .../editors/animation/keyframes_draw.c | 44 +- .../editors/include/ED_keyframes_draw.h | 4 +- source/blender/editors/include/ED_mask.h | 2 +- .../editors/interface/interface_templates.c | 2 +- source/blender/editors/mask/mask_draw.c | 54 +-- source/blender/editors/mask/mask_editor.c | 6 +- source/blender/editors/mask/mask_intern.h | 12 +- source/blender/editors/mask/mask_ops.c | 286 ++++++------- .../blender/editors/mask/mask_relationships.c | 16 +- source/blender/editors/mask/mask_select.c | 90 ++-- source/blender/editors/mask/mask_shapekey.c | 38 +- source/blender/editors/screen/screen_ops.c | 4 +- source/blender/editors/space_clip/clip_draw.c | 14 +- .../editors/transform/transform_conversions.c | 20 +- source/blender/makesdna/DNA_mask_types.h | 28 +- source/blender/makesrna/RNA_access.h | 2 +- source/blender/makesrna/intern/rna_mask.c | 186 ++++---- 22 files changed, 668 insertions(+), 668 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index a5b1996ae0d..ab1bd817490 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -565,7 +565,7 @@ class CLIP_PT_tracking_camera(Panel): class CLIP_PT_mask_objects(Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'UI' - bl_label = "Mask Objects" + bl_label = "Mask Layers" @classmethod def poll(cls, context): @@ -580,15 +580,15 @@ class CLIP_PT_mask_objects(Panel): mask = sc.mask row = layout.row() - row.template_list(mask, "objects", - mask, "active_object_index", rows=3) + row.template_list(mask, "layers", + mask, "active_layer_index", rows=3) sub = row.column(align=True) - sub.operator("mask.object_new", icon='ZOOMIN', text="") - sub.operator("mask.object_remove", icon='ZOOMOUT', text="") + sub.operator("mask.layer_new", icon='ZOOMIN', text="") + sub.operator("mask.layer_remove", icon='ZOOMOUT', text="") - active = mask.objects.active + active = mask.layers.active if active: layout.prop(active, "name") @@ -611,7 +611,7 @@ class CLIP_PT_active_mask_spline(Panel): mask = sc.mask if mask and sc.mode == 'MASKEDITING': - return mask.objects.active and mask.objects.active.splines.active + return mask.layers.active and mask.layers.active.splines.active return False @@ -620,7 +620,7 @@ class CLIP_PT_active_mask_spline(Panel): sc = context.space_data mask = sc.mask - spline = mask.objects.active.splines.active + spline = mask.layers.active.splines.active col = layout.column() col.prop(spline, "weight_interpolation") @@ -638,7 +638,7 @@ class CLIP_PT_active_mask_point(Panel): mask = sc.mask if mask and sc.mode == 'MASKEDITING': - return mask.objects.active and mask.objects.active.splines.active_point + return mask.layers.active and mask.layers.active.splines.active_point return False @@ -647,7 +647,7 @@ class CLIP_PT_active_mask_point(Panel): sc = context.space_data mask = sc.mask - point = mask.objects.active.splines.active_point + point = mask.layers.active.splines.active_point parent = point.parent col = layout.column() diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 5663aa69e8b..8fc979e941b 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -30,8 +30,8 @@ struct Main; struct Mask; struct MaskParent; -struct MaskObject; -struct MaskObjectShape; +struct MaskLayer; +struct MaskLayerShape; struct MaskSpline; struct MaskSplinePoint; struct MaskSplinePointUW; @@ -42,20 +42,20 @@ struct Scene; struct MaskSplinePoint *BKE_mask_spline_point_array(struct MaskSpline *spline); struct MaskSplinePoint *BKE_mask_spline_point_array_from_point(struct MaskSpline *spline, struct MaskSplinePoint *point_ref); -/* mask objects */ -struct MaskObject *BKE_mask_object_new(struct Mask *mask, const char *name); -struct MaskObject *BKE_mask_object_active(struct Mask *mask); -void BKE_mask_object_active_set(struct Mask *mask, struct MaskObject *maskobj); -void BKE_mask_object_remove(struct Mask *mask, struct MaskObject *maskobj); +/* mask layers */ +struct MaskLayer *BKE_mask_layer_new(struct Mask *mask, const char *name); +struct MaskLayer *BKE_mask_layer_active(struct Mask *mask); +void BKE_mask_layer_active_set(struct Mask *mask, struct MaskLayer *masklay); +void BKE_mask_layer_remove(struct Mask *mask, struct MaskLayer *masklay); -void BKE_mask_object_free(struct MaskObject *maskobj); +void BKE_mask_layer_free(struct MaskLayer *masklay); void BKE_mask_spline_free(struct MaskSpline *spline); void BKE_mask_point_free(struct MaskSplinePoint *point); -void BKE_mask_object_unique_name(struct Mask *mask, struct MaskObject *maskobj); +void BKE_mask_layer_unique_name(struct Mask *mask, struct MaskLayer *masklay); /* splines */ -struct MaskSpline *BKE_mask_spline_add(struct MaskObject *maskobj); +struct MaskSpline *BKE_mask_spline_add(struct MaskLayer *masklay); int BKE_mask_spline_resolution(struct MaskSpline *spline, float max_seg_len); float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point, int dynamic_res, float max_dseg_len))[2]; @@ -107,31 +107,31 @@ void BKE_mask_calc_handles(struct Mask *mask); void BKE_mask_spline_ensure_deform(struct MaskSpline *spline); /* animation */ -int BKE_mask_object_shape_totvert(struct MaskObject *maskobj); -void BKE_mask_object_shape_from_mask(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape); -void BKE_mask_object_shape_to_mask(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape); -void BKE_mask_object_shape_to_mask_interp(struct MaskObject *maskobj, - struct MaskObjectShape *maskobj_shape_a, - struct MaskObjectShape *maskobj_shape_b, +int BKE_mask_layer_shape_totvert(struct MaskLayer *masklay); +void BKE_mask_layer_shape_from_mask(struct MaskLayer *masklay, struct MaskLayerShape *masklay_shape); +void BKE_mask_layer_shape_to_mask(struct MaskLayer *masklay, struct MaskLayerShape *masklay_shape); +void BKE_mask_layer_shape_to_mask_interp(struct MaskLayer *masklay, + struct MaskLayerShape *masklay_shape_a, + struct MaskLayerShape *masklay_shape_b, const float fac); -struct MaskObjectShape *BKE_mask_object_shape_find_frame(struct MaskObject *maskobj, int frame); -int BKE_mask_object_shape_find_frame_range(struct MaskObject *maskobj, int frame, - struct MaskObjectShape **r_maskobj_shape_a, - struct MaskObjectShape **r_maskobj_shape_b); -struct MaskObjectShape *BKE_mask_object_shape_varify_frame(struct MaskObject *maskobj, int frame); -void BKE_mask_object_shape_unlink(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape); -void BKE_mask_object_shape_sort(struct MaskObject *maskobj); +struct MaskLayerShape *BKE_mask_layer_shape_find_frame(struct MaskLayer *masklay, int frame); +int BKE_mask_layer_shape_find_frame_range(struct MaskLayer *masklay, int frame, + struct MaskLayerShape **r_masklay_shape_a, + struct MaskLayerShape **r_masklay_shape_b); +struct MaskLayerShape *BKE_mask_layer_shape_varify_frame(struct MaskLayer *masklay, int frame); +void BKE_mask_layer_shape_unlink(struct MaskLayer *masklay, struct MaskLayerShape *masklay_shape); +void BKE_mask_layer_shape_sort(struct MaskLayer *masklay); -int BKE_mask_object_shape_spline_from_index(struct MaskObject *maskobj, int index, - struct MaskSpline **r_maskobj_shape, int *r_index); -int BKE_mask_object_shape_spline_to_index(struct MaskObject *maskobj, struct MaskSpline *spline); +int BKE_mask_layer_shape_spline_from_index(struct MaskLayer *masklay, int index, + struct MaskSpline **r_masklay_shape, int *r_index); +int BKE_mask_layer_shape_spline_to_index(struct MaskLayer *masklay, struct MaskSpline *spline); -int BKE_mask_object_shape_spline_index(struct MaskObject *maskobj, int index, - struct MaskSpline **r_maskobj_shape, int *r_index); -void BKE_mask_object_shape_changed_add(struct MaskObject *maskobj, int index, +int BKE_mask_layer_shape_spline_index(struct MaskLayer *masklay, int index, + struct MaskSpline **r_masklay_shape, int *r_index); +void BKE_mask_layer_shape_changed_add(struct MaskLayer *masklay, int index, int do_init, int do_init_interpolate); -void BKE_mask_object_shape_changed_remove(struct MaskObject *maskobj, int index, int count); +void BKE_mask_layer_shape_changed_remove(struct MaskLayer *masklay, int index, int count); /* rasterization */ void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 9e509c10989..e6f328546f5 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -77,63 +77,63 @@ MaskSplinePoint *BKE_mask_spline_point_array_from_point(MaskSpline *spline, Mask return NULL; } -/* mask objects */ +/* mask layers */ -MaskObject *BKE_mask_object_new(Mask *mask, const char *name) +MaskLayer *BKE_mask_layer_new(Mask *mask, const char *name) { - MaskObject *maskobj = MEM_callocN(sizeof(MaskObject), "new mask object"); + MaskLayer *masklay = MEM_callocN(sizeof(MaskLayer), __func__); if (name && name[0]) - BLI_strncpy(maskobj->name, name, sizeof(maskobj->name)); + BLI_strncpy(masklay->name, name, sizeof(masklay->name)); else - strcpy(maskobj->name, "MaskObject"); + strcpy(masklay->name, "MaskLayer"); - BLI_addtail(&mask->maskobjs, maskobj); + BLI_addtail(&mask->masklayers, masklay); - BKE_mask_object_unique_name(mask, maskobj); + BKE_mask_layer_unique_name(mask, masklay); - mask->tot_maskobj++; + mask->masklay_tot++; - maskobj->alpha = 1.0f; + masklay->alpha = 1.0f; - return maskobj; + return masklay; } /* note: may still be hidden, caller needs to check */ -MaskObject *BKE_mask_object_active(Mask *mask) +MaskLayer *BKE_mask_layer_active(Mask *mask) { - return BLI_findlink(&mask->maskobjs, mask->act_maskobj); + return BLI_findlink(&mask->masklayers, mask->masklay_act); } -void BKE_mask_object_active_set(Mask *mask, MaskObject *maskobj) +void BKE_mask_layer_active_set(Mask *mask, MaskLayer *masklay) { - mask->act_maskobj = BLI_findindex(&mask->maskobjs, maskobj); + mask->masklay_act = BLI_findindex(&mask->masklayers, masklay); } -void BKE_mask_object_remove(Mask *mask, MaskObject *maskobj) +void BKE_mask_layer_remove(Mask *mask, MaskLayer *masklay) { - BLI_remlink(&mask->maskobjs, maskobj); - BKE_mask_object_free(maskobj); + BLI_remlink(&mask->masklayers, masklay); + BKE_mask_layer_free(masklay); - mask->tot_maskobj--; + mask->masklay_tot--; - if (mask->act_maskobj >= mask->tot_maskobj) - mask->act_maskobj = mask->tot_maskobj - 1; + if (mask->masklay_act >= mask->masklay_tot) + mask->masklay_act = mask->masklay_tot - 1; } -void BKE_mask_object_unique_name(Mask *mask, MaskObject *maskobj) +void BKE_mask_layer_unique_name(Mask *mask, MaskLayer *masklay) { - BLI_uniquename(&mask->maskobjs, maskobj, "MaskObject", '.', offsetof(MaskObject, name), sizeof(maskobj->name)); + BLI_uniquename(&mask->masklayers, masklay, "MaskLayer", '.', offsetof(MaskLayer, name), sizeof(masklay->name)); } /* splines */ -MaskSpline *BKE_mask_spline_add(MaskObject *maskobj) +MaskSpline *BKE_mask_spline_add(MaskLayer *masklay) { MaskSpline *spline; spline = MEM_callocN(sizeof(MaskSpline), "new mask spline"); - BLI_addtail(&maskobj->splines, spline); + BLI_addtail(&masklay->splines, spline); /* spline shall have one point at least */ spline->points = MEM_callocN(sizeof(MaskSplinePoint), "new mask spline point"); @@ -747,54 +747,54 @@ void BKE_mask_spline_free(MaskSpline *spline) MEM_freeN(spline); } -void BKE_mask_object_shape_free(MaskObjectShape *maskobj_shape) +void BKE_mask_layer_shape_free(MaskLayerShape *masklay_shape) { - MEM_freeN(maskobj_shape->data); + MEM_freeN(masklay_shape->data); - MEM_freeN(maskobj_shape); + MEM_freeN(masklay_shape); } -void BKE_mask_object_free(MaskObject *maskobj) +void BKE_mask_layer_free(MaskLayer *masklay) { MaskSpline *spline; - MaskObjectShape *maskobj_shape; + MaskLayerShape *masklay_shape; /* free splines */ - spline = maskobj->splines.first; + spline = masklay->splines.first; while (spline) { MaskSpline *next_spline = spline->next; - BLI_remlink(&maskobj->splines, spline); + BLI_remlink(&masklay->splines, spline); BKE_mask_spline_free(spline); spline = next_spline; } /* free animation data */ - maskobj_shape = maskobj->splines_shapes.first; - while (maskobj_shape) { - MaskObjectShape *next_maskobj_shape = maskobj_shape->next; + masklay_shape = masklay->splines_shapes.first; + while (masklay_shape) { + MaskLayerShape *next_masklay_shape = masklay_shape->next; - BLI_remlink(&maskobj->splines_shapes, maskobj_shape); - BKE_mask_object_shape_free(maskobj_shape); + BLI_remlink(&masklay->splines_shapes, masklay_shape); + BKE_mask_layer_shape_free(masklay_shape); - maskobj_shape = next_maskobj_shape; + masklay_shape = next_masklay_shape; } - MEM_freeN(maskobj); + MEM_freeN(masklay); } void BKE_mask_free(Mask *mask) { - MaskObject *maskobj = mask->maskobjs.first; + MaskLayer *masklay = mask->masklayers.first; - while (maskobj) { - MaskObject *next_maskobj = maskobj->next; + while (masklay) { + MaskLayer *next_masklay = masklay->next; - BLI_remlink(&mask->maskobjs, maskobj); - BKE_mask_object_free(maskobj); + BLI_remlink(&mask->masklayers, masklay); + BKE_mask_layer_free(masklay); - maskobj = next_maskobj; + masklay = next_masklay; } } @@ -1107,12 +1107,12 @@ void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplineP void BKE_mask_calc_handles(Mask *mask) { - MaskObject *maskobj; + MaskLayer *masklay; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { @@ -1129,12 +1129,12 @@ void BKE_mask_calc_handles(Mask *mask) void BKE_mask_update_deform(Mask *mask) { - MaskObject *maskobj; + MaskLayer *masklay; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { @@ -1192,35 +1192,35 @@ void BKE_mask_spline_ensure_deform(MaskSpline *spline) void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) { - MaskObject *maskobj; + MaskLayer *masklay; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { /* animation if available */ if (do_newframe) { - MaskObjectShape *maskobj_shape_a; - MaskObjectShape *maskobj_shape_b; + MaskLayerShape *masklay_shape_a; + MaskLayerShape *masklay_shape_b; int found; - if ((found = BKE_mask_object_shape_find_frame_range(maskobj, (int)ctime, - &maskobj_shape_a, &maskobj_shape_b))) + if ((found = BKE_mask_layer_shape_find_frame_range(masklay, (int)ctime, + &masklay_shape_a, &masklay_shape_b))) { if (found == 1) { #if 0 - printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_countlist(&maskobj->splines_shapes), - maskobj_shape_a->frame); + printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes), + masklay_shape_a->frame); #endif - BKE_mask_object_shape_to_mask(maskobj, maskobj_shape_a); + BKE_mask_layer_shape_to_mask(masklay, masklay_shape_a); } else if (found == 2) { - float w = maskobj_shape_b->frame - maskobj_shape_a->frame; + float w = masklay_shape_b->frame - masklay_shape_a->frame; #if 0 - printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_countlist(&maskobj->splines_shapes), - maskobj_shape_a->frame, maskobj_shape_b->frame); + printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes), + masklay_shape_a->frame, masklay_shape_b->frame); #endif - BKE_mask_object_shape_to_mask_interp(maskobj, maskobj_shape_a, maskobj_shape_b, - (ctime - maskobj_shape_a->frame) / w); + BKE_mask_layer_shape_to_mask_interp(masklay, masklay_shape_a, masklay_shape_b, + (ctime - masklay_shape_a->frame) / w); } else { /* always fail, should never happen */ @@ -1234,11 +1234,11 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) BKE_mask_calc_handles(mask); - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; int i; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { BKE_mask_spline_ensure_deform(spline); @@ -1267,12 +1267,12 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) void BKE_mask_update_display(Mask *mask, float ctime) { #if 0 - MaskObject *maskobj; + MaskLayer *masklay; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { if (spline->points_deform) { int i = 0; @@ -1324,21 +1324,21 @@ void BKE_mask_parent_init(MaskParent *parent) /* *** own animation/shapekey implimentation *** - * BKE_mask_object_shape_XXX */ + * BKE_mask_layer_shape_XXX */ -int BKE_mask_object_shape_totvert(MaskObject *maskobj) +int BKE_mask_layer_shape_totvert(MaskLayer *masklay) { int tot = 0; MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { tot += spline->tot_point; } return tot; } -static void mask_object_shape_from_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE]) +static void mask_layer_shape_from_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE]) { copy_v2_v2(&fp[0], bezt->vec[0]); copy_v2_v2(&fp[2], bezt->vec[1]); @@ -1347,7 +1347,7 @@ static void mask_object_shape_from_mask_point(BezTriple *bezt, float fp[MASK_OBJ fp[7] = bezt->radius; } -static void mask_object_shape_to_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE]) +static void mask_layer_shape_to_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE]) { copy_v2_v2(bezt->vec[0], &fp[0]); copy_v2_v2(bezt->vec[1], &fp[2]); @@ -1357,47 +1357,47 @@ static void mask_object_shape_to_mask_point(BezTriple *bezt, float fp[MASK_OBJEC } /* these functions match. copy is swapped */ -void BKE_mask_object_shape_from_mask(MaskObject *maskobj, MaskObjectShape *maskobj_shape) +void BKE_mask_layer_shape_from_mask(MaskLayer *masklay, MaskLayerShape *masklay_shape) { - int tot = BKE_mask_object_shape_totvert(maskobj); + int tot = BKE_mask_layer_shape_totvert(masklay); - if (maskobj_shape->tot_vert == tot) { - float *fp = maskobj_shape->data; + if (masklay_shape->tot_vert == tot) { + float *fp = masklay_shape->data; MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { - mask_object_shape_from_mask_point(&spline->points[i].bezt, fp); + mask_layer_shape_from_mask_point(&spline->points[i].bezt, fp); fp += MASK_OBJECT_SHAPE_ELEM_SIZE; } } } else { printf("%s: vert mismatch %d != %d (frame %d)\n", - __func__, maskobj_shape->tot_vert, tot, maskobj_shape->frame); + __func__, masklay_shape->tot_vert, tot, masklay_shape->frame); } } -void BKE_mask_object_shape_to_mask(MaskObject *maskobj, MaskObjectShape *maskobj_shape) +void BKE_mask_layer_shape_to_mask(MaskLayer *masklay, MaskLayerShape *masklay_shape) { - int tot = BKE_mask_object_shape_totvert(maskobj); + int tot = BKE_mask_layer_shape_totvert(masklay); - if (maskobj_shape->tot_vert == tot) { - float *fp = maskobj_shape->data; + if (masklay_shape->tot_vert == tot) { + float *fp = masklay_shape->data; MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { - mask_object_shape_to_mask_point(&spline->points[i].bezt, fp); + mask_layer_shape_to_mask_point(&spline->points[i].bezt, fp); fp += MASK_OBJECT_SHAPE_ELEM_SIZE; } } } else { printf("%s: vert mismatch %d != %d (frame %d)\n", - __func__, maskobj_shape->tot_vert, tot, maskobj_shape->frame); + __func__, masklay_shape->tot_vert, tot, masklay_shape->frame); } } @@ -1409,23 +1409,23 @@ BLI_INLINE void interp_v2_v2v2_flfl(float target[2], const float a[2], const flo } /* linear interpolation only */ -void BKE_mask_object_shape_to_mask_interp(MaskObject *maskobj, - MaskObjectShape *maskobj_shape_a, - MaskObjectShape *maskobj_shape_b, +void BKE_mask_layer_shape_to_mask_interp(MaskLayer *masklay, + MaskLayerShape *masklay_shape_a, + MaskLayerShape *masklay_shape_b, const float fac) { - int tot = BKE_mask_object_shape_totvert(maskobj); - if (maskobj_shape_a->tot_vert == tot && maskobj_shape_b->tot_vert == tot) { - float *fp_a = maskobj_shape_a->data; - float *fp_b = maskobj_shape_b->data; + int tot = BKE_mask_layer_shape_totvert(masklay); + if (masklay_shape_a->tot_vert == tot && masklay_shape_b->tot_vert == tot) { + float *fp_a = masklay_shape_a->data; + float *fp_b = masklay_shape_b->data; const float ifac = 1.0f - fac; MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { BezTriple *bezt = &spline->points[i].bezt; - /* *** BKE_mask_object_shape_from_mask - swapped *** */ + /* *** BKE_mask_layer_shape_from_mask - swapped *** */ interp_v2_v2v2_flfl(bezt->vec[0], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2; interp_v2_v2v2_flfl(bezt->vec[1], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2; interp_v2_v2v2_flfl(bezt->vec[2], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2; @@ -1436,23 +1436,23 @@ void BKE_mask_object_shape_to_mask_interp(MaskObject *maskobj, } else { printf("%s: vert mismatch %d != %d != %d (frame %d - %d)\n", - __func__, maskobj_shape_a->tot_vert, maskobj_shape_b->tot_vert, tot, - maskobj_shape_a->frame, maskobj_shape_b->frame); + __func__, masklay_shape_a->tot_vert, masklay_shape_b->tot_vert, tot, + masklay_shape_a->frame, masklay_shape_b->frame); } } -MaskObjectShape *BKE_mask_object_shape_find_frame(MaskObject *maskobj, int frame) +MaskLayerShape *BKE_mask_layer_shape_find_frame(MaskLayer *masklay, int frame) { - MaskObjectShape *maskobj_shape; + MaskLayerShape *masklay_shape; - for (maskobj_shape = maskobj->splines_shapes.first; - maskobj_shape; - maskobj_shape = maskobj_shape->next) + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) { - if (frame == maskobj_shape->frame) { - return maskobj_shape; + if (frame == masklay_shape->frame) { + return masklay_shape; } - else if (frame < maskobj_shape->frame) { + else if (frame < masklay_shape->frame) { break; } } @@ -1461,106 +1461,106 @@ MaskObjectShape *BKE_mask_object_shape_find_frame(MaskObject *maskobj, int frame } /* when returning 2 - the frame isnt found but before/after frames are */ -int BKE_mask_object_shape_find_frame_range(MaskObject *maskobj, int frame, - MaskObjectShape **r_maskobj_shape_a, - MaskObjectShape **r_maskobj_shape_b) +int BKE_mask_layer_shape_find_frame_range(MaskLayer *masklay, int frame, + MaskLayerShape **r_masklay_shape_a, + MaskLayerShape **r_masklay_shape_b) { - MaskObjectShape *maskobj_shape; + MaskLayerShape *masklay_shape; - for (maskobj_shape = maskobj->splines_shapes.first; - maskobj_shape; - maskobj_shape = maskobj_shape->next) + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) { - if (frame == maskobj_shape->frame) { - *r_maskobj_shape_a = maskobj_shape; - *r_maskobj_shape_b = NULL; + if (frame == masklay_shape->frame) { + *r_masklay_shape_a = masklay_shape; + *r_masklay_shape_b = NULL; return 1; } - else if (frame < maskobj_shape->frame) { - if (maskobj_shape->prev) { - *r_maskobj_shape_a = maskobj_shape->prev; - *r_maskobj_shape_b = maskobj_shape; + else if (frame < masklay_shape->frame) { + if (masklay_shape->prev) { + *r_masklay_shape_a = masklay_shape->prev; + *r_masklay_shape_b = masklay_shape; return 2; } else { - *r_maskobj_shape_a = maskobj_shape; - *r_maskobj_shape_b = NULL; + *r_masklay_shape_a = masklay_shape; + *r_masklay_shape_b = NULL; return 1; } } } - *r_maskobj_shape_a = NULL; - *r_maskobj_shape_b = NULL; + *r_masklay_shape_a = NULL; + *r_masklay_shape_b = NULL; return 0; } -MaskObjectShape *BKE_mask_object_shape_varify_frame(MaskObject *maskobj, int frame) +MaskLayerShape *BKE_mask_layer_shape_varify_frame(MaskLayer *masklay, int frame) { - MaskObjectShape *maskobj_shape; + MaskLayerShape *masklay_shape; - maskobj_shape = BKE_mask_object_shape_find_frame(maskobj, frame); + masklay_shape = BKE_mask_layer_shape_find_frame(masklay, frame); - if (maskobj_shape == NULL) { - int tot_vert = BKE_mask_object_shape_totvert(maskobj); + if (masklay_shape == NULL) { + int tot_vert = BKE_mask_layer_shape_totvert(masklay); - maskobj_shape = MEM_mallocN(sizeof(MaskObjectShape), __func__); - maskobj_shape->frame = frame; - maskobj_shape->tot_vert = tot_vert; - maskobj_shape->data = MEM_mallocN(tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); + masklay_shape = MEM_mallocN(sizeof(MaskLayerShape), __func__); + masklay_shape->frame = frame; + masklay_shape->tot_vert = tot_vert; + masklay_shape->data = MEM_mallocN(tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); - BLI_addtail(&maskobj->splines_shapes, maskobj_shape); + BLI_addtail(&masklay->splines_shapes, masklay_shape); - BKE_mask_object_shape_sort(maskobj); + BKE_mask_layer_shape_sort(masklay); } #if 0 { - MaskObjectShape *maskobj_shape; + MaskLayerShape *masklay_shape; int i = 0; - for (maskobj_shape = maskobj->splines_shapes.first; - maskobj_shape; - maskobj_shape = maskobj_shape->next) + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) { - printf("mask %d, %d\n", i++, maskobj_shape->frame); + printf("mask %d, %d\n", i++, masklay_shape->frame); } } #endif - return maskobj_shape; + return masklay_shape; } -void BKE_mask_object_shape_unlink(MaskObject *maskobj, MaskObjectShape *maskobj_shape) +void BKE_mask_layer_shape_unlink(MaskLayer *masklay, MaskLayerShape *masklay_shape) { - BLI_remlink(&maskobj->splines_shapes, maskobj_shape); + BLI_remlink(&masklay->splines_shapes, masklay_shape); - BKE_mask_object_shape_free(maskobj_shape); + BKE_mask_layer_shape_free(masklay_shape); } -static int mask_object_shape_sort_cb(void *maskobj_shape_a_ptr, void *maskobj_shape_b_ptr) +static int mask_layer_shape_sort_cb(void *masklay_shape_a_ptr, void *masklay_shape_b_ptr) { - MaskObjectShape *maskobj_shape_a = (MaskObjectShape *)maskobj_shape_a_ptr; - MaskObjectShape *maskobj_shape_b = (MaskObjectShape *)maskobj_shape_b_ptr; + MaskLayerShape *masklay_shape_a = (MaskLayerShape *)masklay_shape_a_ptr; + MaskLayerShape *masklay_shape_b = (MaskLayerShape *)masklay_shape_b_ptr; - if (maskobj_shape_a->frame < maskobj_shape_b->frame) return -1; - else if (maskobj_shape_a->frame > maskobj_shape_b->frame) return 1; + if (masklay_shape_a->frame < masklay_shape_b->frame) return -1; + else if (masklay_shape_a->frame > masklay_shape_b->frame) return 1; else return 0; } -void BKE_mask_object_shape_sort(MaskObject *maskobj) +void BKE_mask_layer_shape_sort(MaskLayer *masklay) { - BLI_sortlist(&maskobj->splines_shapes, mask_object_shape_sort_cb); + BLI_sortlist(&masklay->splines_shapes, mask_layer_shape_sort_cb); } -int BKE_mask_object_shape_spline_from_index(MaskObject *maskobj, int index, - MaskSpline **r_maskobj_shape, int *r_index) +int BKE_mask_layer_shape_spline_from_index(MaskLayer *masklay, int index, + MaskSpline **r_masklay_shape, int *r_index) { MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { if (index < spline->tot_point) { - *r_maskobj_shape = spline; + *r_masklay_shape = spline; *r_index = index; return TRUE; } @@ -1570,11 +1570,11 @@ int BKE_mask_object_shape_spline_from_index(MaskObject *maskobj, int index, return FALSE; } -int BKE_mask_object_shape_spline_to_index(MaskObject *maskobj, MaskSpline *spline) +int BKE_mask_layer_shape_spline_to_index(MaskLayer *masklay, MaskSpline *spline) { MaskSpline *spline_iter; int i_abs = 0; - for (spline_iter = maskobj->splines.first; + for (spline_iter = masklay->splines.first; spline_iter && spline_iter != spline; i_abs += spline_iter->tot_point, spline_iter = spline_iter->next) { @@ -1608,21 +1608,21 @@ static void interp_weights_uv_v2_apply(const float uv[2], float r_pt[2], const f } /* when a now points added - resize all shapekey array */ -void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, +void BKE_mask_layer_shape_changed_add(MaskLayer *masklay, int index, int do_init, int do_init_interpolate) { - MaskObjectShape *maskobj_shape; + MaskLayerShape *masklay_shape; - /* spline index from maskobj */ + /* spline index from masklay */ MaskSpline *spline; int spline_point_index; - if (BKE_mask_object_shape_spline_from_index(maskobj, index, + if (BKE_mask_layer_shape_spline_from_index(masklay, index, &spline, &spline_point_index)) { /* sanity check */ /* the point has already been removed in this array so subtract one when comparing with the shapes */ - int tot = BKE_mask_object_shape_totvert(maskobj) - 1; + int tot = BKE_mask_layer_shape_totvert(masklay) - 1; /* for interpolation */ /* TODO - assumes closed curve for now */ @@ -1646,31 +1646,31 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, } } - for (maskobj_shape = maskobj->splines_shapes.first; - maskobj_shape; - maskobj_shape = maskobj_shape->next) + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) { - if (tot == maskobj_shape->tot_vert) { + if (tot == masklay_shape->tot_vert) { float *data_resized; - maskobj_shape->tot_vert++; - data_resized = MEM_mallocN(maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); + masklay_shape->tot_vert++; + data_resized = MEM_mallocN(masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); if (index > 0) { memcpy(data_resized, - maskobj_shape->data, + masklay_shape->data, index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } - if (index != maskobj_shape->tot_vert - 1) { + if (index != masklay_shape->tot_vert - 1) { memcpy(&data_resized[(index + 1) * MASK_OBJECT_SHAPE_ELEM_SIZE], - maskobj_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), - (maskobj_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + masklay_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), + (masklay_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } if (do_init) { float *fp = &data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE]; - mask_object_shape_from_mask_point(&spline->points[spline_point_index].bezt, fp); + mask_layer_shape_from_mask_point(&spline->points[spline_point_index].bezt, fp); if (do_init_interpolate && spline->tot_point > 2) { for (i = 0; i < 3; i++) { @@ -1687,12 +1687,12 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } - MEM_freeN(maskobj_shape->data); - maskobj_shape->data = data_resized; + MEM_freeN(masklay_shape->data); + masklay_shape->data = data_resized; } else { printf("%s: vert mismatch %d != %d (frame %d)\n", - __func__, maskobj_shape->tot_vert, tot, maskobj_shape->frame); + __func__, masklay_shape->tot_vert, tot, masklay_shape->frame); } } } @@ -1700,40 +1700,40 @@ void BKE_mask_object_shape_changed_add(MaskObject *maskobj, int index, /* move array to account for removed point */ -void BKE_mask_object_shape_changed_remove(MaskObject *maskobj, int index, int count) +void BKE_mask_layer_shape_changed_remove(MaskLayer *masklay, int index, int count) { - MaskObjectShape *maskobj_shape; + MaskLayerShape *masklay_shape; /* the point has already been removed in this array so add one when comparing with the shapes */ - int tot = BKE_mask_object_shape_totvert(maskobj); + int tot = BKE_mask_layer_shape_totvert(masklay); - for (maskobj_shape = maskobj->splines_shapes.first; - maskobj_shape; - maskobj_shape = maskobj_shape->next) + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) { - if (tot == maskobj_shape->tot_vert - count) { + if (tot == masklay_shape->tot_vert - count) { float *data_resized; - maskobj_shape->tot_vert -= count; - data_resized = MEM_mallocN(maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); + masklay_shape->tot_vert -= count; + data_resized = MEM_mallocN(masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); if (index > 0) { memcpy(data_resized, - maskobj_shape->data, + masklay_shape->data, index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } - if (index != maskobj_shape->tot_vert) { + if (index != masklay_shape->tot_vert) { memcpy(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE], - maskobj_shape->data + ((index + count) * MASK_OBJECT_SHAPE_ELEM_SIZE), - (maskobj_shape->tot_vert - index) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + masklay_shape->data + ((index + count) * MASK_OBJECT_SHAPE_ELEM_SIZE), + (masklay_shape->tot_vert - index) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); } - MEM_freeN(maskobj_shape->data); - maskobj_shape->data = data_resized; + MEM_freeN(masklay_shape->data); + masklay_shape->data = data_resized; } else { printf("%s: vert mismatch %d != %d (frame %d)\n", - __func__, maskobj_shape->tot_vert - count, tot, maskobj_shape->frame); + __func__, masklay_shape->tot_vert - count, tot, masklay_shape->frame); } } } @@ -1775,7 +1775,7 @@ static void linear_clamp_vn_vn(float *array, const int size) /* rasterization */ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) { - MaskObject *maskobj; + MaskLayer *masklay; /* temp blending buffer */ const int buffer_size = width * height; @@ -1789,17 +1789,17 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) } max_dseg_len = 1.0f / max_dseg_len; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; float alpha; - if (maskobj->restrictflag & MASK_RESTRICT_RENDER) { + if (masklay->restrictflag & MASK_RESTRICT_RENDER) { continue; } memset(buffer_tmp, 0, sizeof(float) * buffer_size); - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { float (*diff_points)[2]; int tot_diff_point; @@ -1853,10 +1853,10 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) } /* blend with original */ - if (maskobj->blend_flag & MASK_BLENDFLAG_INVERT) { + if (masklay->blend_flag & MASK_BLENDFLAG_INVERT) { /* apply alpha multiply before inverting */ - if (maskobj->alpha != 1.0f) { - m_invert_vn_vn(buffer_tmp, maskobj->alpha, buffer_size); + if (masklay->alpha != 1.0f) { + m_invert_vn_vn(buffer_tmp, masklay->alpha, buffer_size); } else { invert_vn_vn(buffer_tmp, buffer_size); @@ -1865,10 +1865,10 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) alpha = 1.0f; } else { - alpha = maskobj->alpha; + alpha = masklay->alpha; } - switch (maskobj->blend) { + switch (masklay->blend) { case MASK_BLEND_SUBTRACT: { if (alpha == 1.0f) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9122e01fb2a..602c410dc21 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6182,19 +6182,19 @@ static void lib_link_movieclip(FileData *fd, Main *main) static void direct_link_mask(FileData *fd, Mask *mask) { - MaskObject *maskobj; + MaskLayer *masklay; mask->adt = newdataadr(fd, mask->adt); - link_list(fd, &mask->maskobjs); + link_list(fd, &mask->masklayers); - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - MaskObjectShape *maskobj_shape; + MaskLayerShape *masklay_shape; - link_list(fd, &maskobj->splines); + link_list(fd, &masklay->splines); - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; spline->points = newdataadr(fd, spline->points); @@ -6207,14 +6207,14 @@ static void direct_link_mask(FileData *fd, Mask *mask) } } - link_list(fd, &maskobj->splines_shapes); + link_list(fd, &masklay->splines_shapes); - for (maskobj_shape = maskobj->splines_shapes.first; maskobj_shape; maskobj_shape = maskobj_shape->next) { - maskobj_shape->data = newdataadr(fd, maskobj_shape->data); + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + masklay_shape->data = newdataadr(fd, masklay_shape->data); } - maskobj->act_spline = newdataadr(fd, maskobj->act_spline); - maskobj->act_point = newdataadr(fd, maskobj->act_point); + masklay->act_spline = newdataadr(fd, masklay->act_spline); + masklay->act_point = newdataadr(fd, masklay->act_point); } } @@ -6230,15 +6230,15 @@ static void lib_link_mask(FileData *fd, Main *main) mask = main->mask.first; while (mask) { if(mask->id.flag & LIB_NEEDLINK) { - MaskObject *maskobj; + MaskLayer *masklay; if (mask->adt) lib_link_animdata(fd, &mask->id, mask->adt); - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - spline = maskobj->splines.first; + spline = masklay->splines.first; while (spline) { int i; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 0b552ce220c..74287f0e693 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2760,20 +2760,20 @@ static void write_masks(WriteData *wd, ListBase *idbase) mask = idbase->first; while (mask) { if (mask->id.us > 0 || wd->current) { - MaskObject *maskobj; + MaskLayer *masklay; writestruct(wd, ID_MSK, "Mask", 1, mask); if (mask->adt) write_animdata(wd, mask->adt); - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - MaskObjectShape *maskobj_shape; + MaskLayerShape *masklay_shape; - writestruct(wd, DATA, "MaskObject", 1, maskobj); + writestruct(wd, DATA, "MaskLayer", 1, masklay); - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; void *points_deform = spline->points_deform; @@ -2792,9 +2792,9 @@ static void write_masks(WriteData *wd, ListBase *idbase) } } - for (maskobj_shape = maskobj->splines_shapes.first; maskobj_shape; maskobj_shape = maskobj_shape->next) { - writestruct(wd, DATA, "MaskObjectShape", 1, maskobj_shape); - writedata(wd, DATA, maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, maskobj_shape->data); + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + writestruct(wd, DATA, "MaskLayerShape", 1, masklay_shape); + writedata(wd, DATA, masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, masklay_shape->data); } } } diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 579527dfc56..cee8d15a807 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -188,28 +188,28 @@ static void nupdate_ak_gpframe(void *node, void *data) /* ......... */ /* Comparator callback used for ActKeyColumns and GPencil frame */ -static short compare_ak_maskobjshape(void *node, void *data) +static short compare_ak_masklayshape(void *node, void *data) { ActKeyColumn *ak = (ActKeyColumn *)node; - MaskObjectShape *maskobj_shape = (MaskObjectShape *)data; + MaskLayerShape *masklay_shape = (MaskLayerShape *)data; - if (maskobj_shape->frame < ak->cfra) + if (masklay_shape->frame < ak->cfra) return -1; - else if (maskobj_shape->frame > ak->cfra) + else if (masklay_shape->frame > ak->cfra) return 1; else return 0; } /* New node callback used for building ActKeyColumns from GPencil frames */ -static DLRBT_Node *nalloc_ak_maskobjshape(void *data) +static DLRBT_Node *nalloc_ak_masklayshape(void *data) { ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF"); - MaskObjectShape *maskobj_shape = (MaskObjectShape *)data; + MaskLayerShape *masklay_shape = (MaskLayerShape *)data; /* store settings based on state of BezTriple */ - ak->cfra = maskobj_shape->frame; - ak->sel = (maskobj_shape->flag & SELECT) ? SELECT : 0; + ak->cfra = masklay_shape->frame; + ak->sel = (masklay_shape->flag & SELECT) ? SELECT : 0; /* set 'modified', since this is used to identify long keyframes */ ak->modified = 1; @@ -218,13 +218,13 @@ static DLRBT_Node *nalloc_ak_maskobjshape(void *data) } /* Node updater callback used for building ActKeyColumns from GPencil frames */ -static void nupdate_ak_maskobjshape(void *node, void *data) +static void nupdate_ak_masklayshape(void *node, void *data) { ActKeyColumn *ak = (ActKeyColumn *)node; - MaskObjectShape *maskobj_shape = (MaskObjectShape *)data; + MaskLayerShape *masklay_shape = (MaskLayerShape *)data; /* set selection status and 'touched' status */ - if (maskobj_shape->flag & SELECT) ak->sel = SELECT; + if (masklay_shape->flag & SELECT) ak->sel = SELECT; ak->modified += 1; } @@ -249,13 +249,13 @@ static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf) BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf); } -/* Add the given MaskObjectShape Frame to the given 'list' of Keyframes */ -static void add_maskobj_to_keycolumns_list(DLRBT_Tree *keys, MaskObjectShape *maskobj_shape) +/* Add the given MaskLayerShape Frame to the given 'list' of Keyframes */ +static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *masklay_shape) { - if (ELEM(NULL, keys, maskobj_shape)) + if (ELEM(NULL, keys, masklay_shape)) return; else - BLI_dlrbTree_add(keys, compare_ak_maskobjshape, nalloc_ak_maskobjshape, nupdate_ak_maskobjshape, maskobj_shape); + BLI_dlrbTree_add(keys, compare_ak_masklayshape, nalloc_ak_masklayshape, nupdate_ak_masklayshape, masklay_shape); } /* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */ @@ -994,16 +994,16 @@ void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys) } } -void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskObject *maskobj, DLRBT_Tree *keys) +void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, DLRBT_Tree *keys) { - MaskObjectShape *maskobj_shape; + MaskLayerShape *masklay_shape; - if (maskobj && keys) { - for (maskobj_shape = maskobj->splines_shapes.first; - maskobj_shape; - maskobj_shape = maskobj_shape->next) + if (masklay && keys) { + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) { - add_maskobj_to_keycolumns_list(keys, maskobj_shape); + add_masklay_to_keycolumns_list(keys, masklay_shape); } } } diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index d90b5648c23..e24c21bc133 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -42,7 +42,7 @@ struct bActionGroup; struct Object; struct ListBase; struct bGPDlayer; -struct MaskObject; +struct MaskLayer; struct Scene; struct View2D; struct DLRBT_Tree; @@ -142,7 +142,7 @@ void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, struct void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys); /* Mask */ // XXX not restored -void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskObject *maskobj, struct DLRBT_Tree *keys); +void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskLayer *masklay, struct DLRBT_Tree *keys); /* ActKeyColumn API ---------------- */ /* Comparator callback used for ActKeyColumns and cframe float-value pointer */ diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h index b7dee09cbe9..0c4c2f4788c 100644 --- a/source/blender/editors/include/ED_mask.h +++ b/source/blender/editors/include/ED_mask.h @@ -42,6 +42,6 @@ void ED_operatormacros_mask(void); void ED_mask_draw(const bContext *C, const char draw_flag, const char draw_type); /* mask_shapekey.c */ -int ED_mask_object_shape_auto_key_all(struct Mask *mask, const int frame); +int ED_mask_layer_shape_auto_key_all(struct Mask *mask, const int frame); #endif /* ED_TEXT_H */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index d23cd88cf05..daba096696c 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2241,7 +2241,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe uiItemL(split, name, ICON_OBJECT_DATA); } } - else if (itemptr->type == &RNA_MaskObject) { + else if (itemptr->type == &RNA_MaskLayer) { split = uiLayoutSplit(sub, 0.66f, 0); uiItemL(split, name, icon); diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index c282153acbf..5b8bf1075b4 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -49,11 +49,11 @@ #include "mask_intern.h" /* own include */ -static void mask_spline_color_get(MaskObject *maskobj, MaskSpline *spline, const int is_sel, +static void mask_spline_color_get(MaskLayer *masklay, MaskSpline *spline, const int is_sel, unsigned char r_rgb[4]) { if (is_sel) { - if (maskobj->act_spline == spline) { + if (masklay->act_spline == spline) { r_rgb[0] = r_rgb[1] = r_rgb[2] = 255; } else { @@ -69,7 +69,7 @@ static void mask_spline_color_get(MaskObject *maskobj, MaskSpline *spline, const r_rgb[3] = 255; } -static void mask_spline_feather_color_get(MaskObject *UNUSED(maskobj), MaskSpline *UNUSED(spline), const int is_sel, +static void mask_spline_feather_color_get(MaskLayer *UNUSED(masklay), MaskSpline *UNUSED(spline), const int is_sel, unsigned char r_rgb[4]) { if (is_sel) { @@ -85,7 +85,7 @@ static void mask_spline_feather_color_get(MaskObject *UNUSED(maskobj), MaskSplin } #if 0 -static void draw_spline_parents(MaskObject *UNUSED(maskobj), MaskSpline *spline) +static void draw_spline_parents(MaskLayer *UNUSED(masklay), MaskSpline *spline) { int i; MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); @@ -119,9 +119,9 @@ static void draw_spline_parents(MaskObject *UNUSED(maskobj), MaskSpline *spline) #endif /* return non-zero if spline is selected */ -static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) +static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline) { - const int is_spline_sel = (spline->flag & SELECT) && (maskobj->restrictflag & MASK_RESTRICT_SELECT) == 0; + const int is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; unsigned char rgb_spline[4]; MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); @@ -135,7 +135,7 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) glPointSize(hsize); - mask_spline_color_get(maskobj, spline, is_spline_sel, rgb_spline); + mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline); /* feather points */ feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); @@ -157,7 +157,7 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) } if (sel) { - if (point == maskobj->act_point) + if (point == masklay->act_point) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); @@ -201,7 +201,7 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) /* draw CV point */ if (MASKPOINT_ISSEL_KNOT(point)) { - if (point == maskobj->act_point) + if (point == masklay->act_point) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); @@ -216,7 +216,7 @@ static void draw_spline_points(MaskObject *maskobj, MaskSpline *spline) /* draw handle points */ if (has_handle) { if (MASKPOINT_ISSEL_HANDLE(point)) { - if (point == maskobj->act_point) + if (point == masklay->act_point) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); @@ -322,12 +322,12 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot } -static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline, +static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, const char draw_flag, const char draw_type) { unsigned char rgb_tmp[4]; - const short is_spline_sel = (spline->flag & SELECT) && (maskobj->restrictflag & MASK_RESTRICT_SELECT) == 0; + const short is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; const short is_smooth = (draw_flag & MASK_DRAWFLAG_SMOOTH); int tot_diff_point; @@ -350,14 +350,14 @@ static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline, feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_feather_point, 0, 0.0f); /* draw feather */ - mask_spline_feather_color_get(maskobj, spline, is_spline_sel, rgb_tmp); + mask_spline_feather_color_get(masklay, spline, is_spline_sel, rgb_tmp); mask_draw_curve_type(spline, feather_points, tot_feather_point, TRUE, is_smooth, rgb_tmp, draw_type); MEM_freeN(feather_points); /* draw main curve */ - mask_spline_color_get(maskobj, spline, is_spline_sel, rgb_tmp); + mask_spline_color_get(masklay, spline, is_spline_sel, rgb_tmp); mask_draw_curve_type(spline, diff_points, tot_diff_point, FALSE, is_smooth, rgb_tmp, draw_type); @@ -371,28 +371,28 @@ static void draw_spline_curve(MaskObject *maskobj, MaskSpline *spline, (void)draw_type; } -static void draw_maskobjs(Mask *mask, +static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type) { - MaskObject *maskobj; + MaskLayer *masklay; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (masklay->restrictflag & MASK_RESTRICT_VIEW) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { /* draw curve itself first... */ - draw_spline_curve(maskobj, spline, draw_flag, draw_type); + draw_spline_curve(masklay, spline, draw_flag, draw_type); -// draw_spline_parents(maskobj, spline); +// draw_spline_parents(masklay, spline); - if (!(maskobj->restrictflag & MASK_RESTRICT_SELECT)) { + if (!(masklay->restrictflag & MASK_RESTRICT_SELECT)) { /* ...and then handles over the curve so they're nicely visible */ - draw_spline_points(maskobj, spline); + draw_spline_points(masklay, spline); } /* show undeform for testing */ @@ -400,9 +400,9 @@ static void draw_maskobjs(Mask *mask, void *back = spline->points_deform; spline->points_deform = NULL; - draw_spline_curve(maskobj, spline, draw_flag, draw_type); -// draw_spline_parents(maskobj, spline); - draw_spline_points(maskobj, spline); + draw_spline_curve(masklay, spline, draw_flag, draw_type); +// draw_spline_parents(masklay, spline); + draw_spline_points(masklay, spline); spline->points_deform = back; } } @@ -417,5 +417,5 @@ void ED_mask_draw(const bContext *C, if (!mask) return; - draw_maskobjs(mask, draw_flag, draw_type); + draw_masklays(mask, draw_flag, draw_type); } diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index a0b47be8ea3..778990726e5 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -189,9 +189,9 @@ void ED_operatortypes_mask(void) { WM_operatortype_append(MASK_OT_new); - /* mask objects */ - WM_operatortype_append(MASK_OT_object_new); - WM_operatortype_append(MASK_OT_object_remove); + /* mask layers */ + WM_operatortype_append(MASK_OT_layer_new); + WM_operatortype_append(MASK_OT_layer_remove); /* geometry */ WM_operatortype_append(MASK_OT_add_vertex); diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index b17d7e7173a..5940b76abf0 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -40,8 +40,8 @@ struct wmOperatorType; /* mask_ops.c */ void MASK_OT_new(struct wmOperatorType *ot); -void MASK_OT_object_new(struct wmOperatorType *ot); -void MASK_OT_object_remove(struct wmOperatorType *ot); +void MASK_OT_layer_new(struct wmOperatorType *ot); +void MASK_OT_layer_remove(struct wmOperatorType *ot); void MASK_OT_add_vertex(struct wmOperatorType *ot); void MASK_OT_add_feather_vertex(struct wmOperatorType *ot); @@ -58,12 +58,12 @@ void MASK_OT_handle_type_set(struct wmOperatorType *ot); int ED_mask_feather_find_nearest( struct bContext *C, struct Mask *mask, float normal_co[2], int threshold, - struct MaskObject **maskobj_r, struct MaskSpline **spline_r, struct MaskSplinePoint **point_r, + struct MaskLayer **masklay_r, struct MaskSpline **spline_r, struct MaskSplinePoint **point_r, struct MaskSplinePointUW **uw_r, float *score); struct MaskSplinePoint *ED_mask_point_find_nearest( struct bContext *C, struct Mask *mask, float normal_co[2], int threshold, - struct MaskObject **maskobj_r, struct MaskSpline **spline_r, int *is_handle_r, + struct MaskLayer **masklay_r, struct MaskSpline **spline_r, int *is_handle_r, float *score); /* mask_relationships.c */ @@ -79,10 +79,10 @@ void MASK_OT_select_lasso(struct wmOperatorType *ot); void MASK_OT_select_circle(struct wmOperatorType *ot); int ED_mask_spline_select_check(struct MaskSplinePoint *points, int tot_point); -int ED_mask_object_select_check(struct MaskObject *maskobj); +int ED_mask_layer_select_check(struct MaskLayer *masklay); int ED_mask_select_check(struct Mask *mask); -void ED_mask_object_select_set(struct MaskObject *maskobj, int select); +void ED_mask_layer_select_set(struct MaskLayer *masklay, int select); void ED_mask_select_toggle_all(struct Mask *mask, int action); void ED_mask_select_flush_all(struct Mask *mask); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 2eaae673364..e56eb181a51 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -122,11 +122,11 @@ static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, fl } MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float normal_co[2], int threshold, - MaskObject **maskobj_r, MaskSpline **spline_r, int *is_handle_r, + MaskLayer **masklay_r, MaskSpline **spline_r, int *is_handle_r, float *score) { - MaskObject *maskobj; - MaskObject *point_maskobj = NULL; + MaskLayer *masklay; + MaskLayer *point_masklay = NULL; MaskSpline *point_spline = NULL; MaskSplinePoint *point = NULL; float co[2], aspx, aspy; @@ -140,14 +140,14 @@ MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float norma co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); int i; @@ -168,7 +168,7 @@ MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float norma cur_len = len_v2v2(co, handle); if (cur_len < len) { - point_maskobj = maskobj; + point_masklay = masklay; point_spline = spline; point = cur_point; len = cur_len; @@ -180,7 +180,7 @@ MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float norma if (cur_len < len) { point_spline = spline; - point_maskobj = maskobj; + point_masklay = masklay; point = cur_point; len = cur_len; is_handle = FALSE; @@ -190,8 +190,8 @@ MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float norma } if (len < threshold) { - if (maskobj_r) - *maskobj_r = point_maskobj; + if (masklay_r) + *masklay_r = point_masklay; if (spline_r) *spline_r = point_spline; @@ -205,8 +205,8 @@ MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float norma return point; } - if (maskobj_r) - *maskobj_r = NULL; + if (masklay_r) + *masklay_r = NULL; if (spline_r) *spline_r = NULL; @@ -218,10 +218,10 @@ MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float norma } int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], int threshold, - MaskObject **maskobj_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r, MaskSplinePointUW **uw_r, float *score) { - MaskObject *maskobj, *point_maskobj = NULL; + MaskLayer *masklay, *point_masklay = NULL; MaskSpline *point_spline = NULL; MaskSplinePoint *point = NULL; MaskSplinePointUW *uw = NULL; @@ -236,16 +236,16 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { //MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); int i, tot_feather_point; float (*feather_points)[2], (*fp)[2]; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } @@ -269,7 +269,7 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in else uw = &cur_point->uw[j - 1]; - point_maskobj = maskobj; + point_masklay = masklay; point_spline = spline; point = cur_point; len = cur_len; @@ -284,8 +284,8 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in } if (len < threshold) { - if (maskobj_r) - *maskobj_r = point_maskobj; + if (masklay_r) + *masklay_r = point_masklay; if (spline_r) *spline_r = point_spline; @@ -302,8 +302,8 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in return TRUE; } - if (maskobj_r) - *maskobj_r = NULL; + if (masklay_r) + *masklay_r = NULL; if (spline_r) *spline_r = NULL; @@ -315,10 +315,10 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in } static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_co[2], int threshold, int feather, - MaskObject **maskobj_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r, float *u_r, float tangent[2]) { - MaskObject *maskobj, *point_maskobj; + MaskLayer *masklay, *point_masklay; MaskSpline *point_spline; MaskSplinePoint *point = NULL; float dist, co[2]; @@ -333,14 +333,14 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_c co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { @@ -381,7 +381,7 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_c if (tangent) sub_v2_v2v2(tangent, &diff_points[2 * i + 2], &diff_points[2 * i]); - point_maskobj = maskobj; + point_masklay = masklay; point_spline = spline; point = cur_point; dist = cur_dist; @@ -400,8 +400,8 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_c } if (point && dist < threshold) { - if (maskobj_r) - *maskobj_r = point_maskobj; + if (masklay_r) + *masklay_r = point_masklay; if (spline_r) *spline_r = point_spline; @@ -418,8 +418,8 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_c return TRUE; } - if (maskobj_r) - *maskobj_r = NULL; + if (masklay_r) + *masklay_r = NULL; if (spline_r) *spline_r = NULL; @@ -466,50 +466,50 @@ void MASK_OT_new(wmOperatorType *ot) RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new mask"); } -/******************** create new maskobj *********************/ +/******************** create new masklay *********************/ -static int maskobj_new_exec(bContext *C, wmOperator *op) +static int masklay_new_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); char name[MAX_ID_NAME - 2]; RNA_string_get(op->ptr, "name", name); - BKE_mask_object_new(mask, name); - mask->act_maskobj = mask->tot_maskobj - 1; + BKE_mask_layer_new(mask, name); + mask->masklay_act = mask->masklay_tot - 1; WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; } -void MASK_OT_object_new(wmOperatorType *ot) +void MASK_OT_layer_new(wmOperatorType *ot) { /* identifiers */ - ot->name = "Add Mask Object"; - ot->description = "Add new mask object for masking"; - ot->idname = "MASK_OT_object_new"; + ot->name = "Add Mask Layer"; + ot->description = "Add new mask layer for masking"; + ot->idname = "MASK_OT_layer_new"; /* api callbacks */ - ot->exec = maskobj_new_exec; + ot->exec = masklay_new_exec; ot->poll = ED_maskediting_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new mask object"); + RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new mask layer"); } -/******************** remove mask object *********************/ +/******************** remove mask layer *********************/ -static int maskobj_remove_exec(bContext *C, wmOperator *UNUSED(op)) +static int masklay_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj = BKE_mask_object_active(mask); + MaskLayer *masklay = BKE_mask_layer_active(mask); - if (maskobj) { - BKE_mask_object_remove(mask, maskobj); + if (masklay) { + BKE_mask_layer_remove(mask, masklay); WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); } @@ -517,15 +517,15 @@ static int maskobj_remove_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -void MASK_OT_object_remove(wmOperatorType *ot) +void MASK_OT_layer_remove(wmOperatorType *ot) { /* identifiers */ - ot->name = "Remove Mask Object"; - ot->description = "Remove mask object"; - ot->idname = "MASK_OT_object_remove"; + ot->name = "Remove Mask Layer"; + ot->description = "Remove mask layer"; + ot->idname = "MASK_OT_layer_remove"; /* api callbacks */ - ot->exec = maskobj_remove_exec; + ot->exec = masklay_remove_exec; ot->poll = ED_maskediting_poll; /* flags */ @@ -546,7 +546,7 @@ typedef struct SlidePointData { float vec[3][3]; Mask *mask; - MaskObject *maskobj; + MaskLayer *masklay; MaskSpline *spline; MaskSplinePoint *point; MaskSplinePointUW *uw; @@ -562,7 +562,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) { Mask *mask = CTX_data_edit_mask(C); SlidePointData *customdata = NULL; - MaskObject *maskobj, *cv_maskobj, *feather_maskobj; + MaskLayer *masklay, *cv_masklay, *feather_masklay; MaskSpline *spline, *cv_spline, *feather_spline; MaskSplinePoint *point, *cv_point, *feather_point; MaskSplinePointUW *uw = NULL; @@ -574,13 +574,13 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) ED_mask_mouse_pos(C, event, co); ED_mask_size(C, &width, &height); - cv_point = ED_mask_point_find_nearest(C, mask, co, threshold, &cv_maskobj, &cv_spline, &is_handle, &cv_score); + cv_point = ED_mask_point_find_nearest(C, mask, co, threshold, &cv_masklay, &cv_spline, &is_handle, &cv_score); - if (ED_mask_feather_find_nearest(C, mask, co, threshold, &feather_maskobj, &feather_spline, &feather_point, &uw, &feather_score)) { + if (ED_mask_feather_find_nearest(C, mask, co, threshold, &feather_masklay, &feather_spline, &feather_point, &uw, &feather_score)) { if (slide_feather || !cv_point || feather_score < cv_score) { action = SLIDE_ACTION_FEATHER; - maskobj = feather_maskobj; + masklay = feather_masklay; spline = feather_spline; point = feather_point; } @@ -592,7 +592,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) else action = SLIDE_ACTION_POINT; - maskobj = cv_maskobj; + masklay = cv_masklay; spline = cv_spline; point = cv_point; } @@ -601,7 +601,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) customdata = MEM_callocN(sizeof(SlidePointData), "mask slide point data"); customdata->mask = mask; - customdata->maskobj = maskobj; + customdata->masklay = masklay; customdata->spline = spline; customdata->point = point; customdata->width = width; @@ -668,8 +668,8 @@ static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) ED_mask_select_flush_all(mask); } - slidedata->maskobj->act_spline = slidedata->spline; - slidedata->maskobj->act_point = slidedata->point; + slidedata->masklay->act_spline = slidedata->spline; + slidedata->masklay->act_point = slidedata->point; WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); @@ -794,7 +794,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) free_slide_point_data(op->customdata); if (IS_AUTOKEY_ON(scene)) { - ED_mask_object_shape_auto_key_all(data->mask, CFRA); + ED_mask_layer_shape_auto_key_all(data->mask, CFRA); } WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); @@ -986,13 +986,13 @@ static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index) static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2]) { - MaskObject *maskobj; + MaskLayer *masklay; MaskSpline *spline; MaskSplinePoint *point = NULL; const float threshold = 9; float tangent[2]; - if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &maskobj, &spline, &point, NULL, tangent)) { + if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &masklay, &spline, &point, NULL, tangent)) { MaskSplinePoint *new_point; int point_index = point - spline->points; @@ -1005,9 +1005,9 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2]) setup_vertex_point(C, mask, spline, new_point, co, tangent, NULL, TRUE); /* TODO - we could pass the spline! */ - BKE_mask_object_shape_changed_add(maskobj, BKE_mask_object_shape_spline_to_index(maskobj, spline) + point_index + 1, TRUE, TRUE); + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index + 1, TRUE, TRUE); - maskobj->act_point = new_point; + masklay->act_point = new_point; WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); @@ -1019,17 +1019,17 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2]) /* **** add extrude vertex **** */ -static void finSelectedSplinePoint(MaskObject *maskobj, MaskSpline **spline, MaskSplinePoint **point, short check_active) +static void finSelectedSplinePoint(MaskLayer *masklay, MaskSpline **spline, MaskSplinePoint **point, short check_active) { - MaskSpline *cur_spline = maskobj->splines.first; + MaskSpline *cur_spline = masklay->splines.first; *spline = NULL; *point = NULL; if (check_active) { - if (maskobj->act_spline && maskobj->act_point) { - *spline = maskobj->act_spline; - *point = maskobj->act_point; + if (masklay->act_spline && masklay->act_point) { + *spline = masklay->act_spline; + *point = masklay->act_point; return; } } @@ -1060,7 +1060,7 @@ static void finSelectedSplinePoint(MaskObject *maskobj, MaskSpline **spline, Mas } } -static int add_vertex_extrude(bContext *C, Mask *mask, MaskObject *maskobj, const float co[2]) +static int add_vertex_extrude(bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) { MaskSpline *spline; MaskSplinePoint *point; @@ -1076,11 +1076,11 @@ static int add_vertex_extrude(bContext *C, Mask *mask, MaskObject *maskobj, cons ED_mask_select_toggle_all(mask, SEL_DESELECT); - if (!maskobj) { + if (!masklay) { return FALSE; } else { - finSelectedSplinePoint(maskobj, &spline, &point, TRUE); + finSelectedSplinePoint(masklay, &spline, &point, TRUE); } point_index = (point - spline->points); @@ -1141,13 +1141,13 @@ static int add_vertex_extrude(bContext *C, Mask *mask, MaskObject *maskobj, cons new_point = &spline->points[point_index + 1]; } - maskobj->act_point = new_point; + masklay->act_point = new_point; setup_vertex_point(C, mask, spline, new_point, co, NULL, ref_point, FALSE); - if (maskobj->splines_shapes.first) { + if (masklay->splines_shapes.first) { point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); - BKE_mask_object_shape_changed_add(maskobj, BKE_mask_object_shape_spline_to_index(maskobj, spline) + point_index, TRUE, TRUE); + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); } if (do_recalc_src) { @@ -1160,7 +1160,7 @@ static int add_vertex_extrude(bContext *C, Mask *mask, MaskObject *maskobj, cons return TRUE; } -static int add_vertex_new(bContext *C, Mask *mask, MaskObject *maskobj, const float co[2]) +static int add_vertex_new(bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) { MaskSpline *spline; MaskSplinePoint *point; @@ -1168,32 +1168,32 @@ static int add_vertex_new(bContext *C, Mask *mask, MaskObject *maskobj, const fl ED_mask_select_toggle_all(mask, SEL_DESELECT); - if (!maskobj) { - /* if there's no maskobj currently operationg on, create new one */ - maskobj = BKE_mask_object_new(mask, ""); - mask->act_maskobj = mask->tot_maskobj - 1; + if (!masklay) { + /* if there's no masklay currently operationg on, create new one */ + masklay = BKE_mask_layer_new(mask, ""); + mask->masklay_act = mask->masklay_tot - 1; spline = NULL; point = NULL; } else { - finSelectedSplinePoint(maskobj, &spline, &point, TRUE); + finSelectedSplinePoint(masklay, &spline, &point, TRUE); } if (!spline) { - /* no selected splines in active maskobj, create new spline */ - spline = BKE_mask_spline_add(maskobj); + /* no selected splines in active masklay, create new spline */ + spline = BKE_mask_spline_add(masklay); } - maskobj->act_spline = spline; + masklay->act_spline = spline; new_point = spline->points; - maskobj->act_point = new_point; + masklay->act_point = new_point; setup_vertex_point(C, mask, spline, new_point, co, NULL, ref_point, FALSE); { int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); - BKE_mask_object_shape_changed_add(maskobj, BKE_mask_object_shape_spline_to_index(maskobj, spline) + point_index, TRUE, TRUE); + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); @@ -1204,23 +1204,23 @@ static int add_vertex_new(bContext *C, Mask *mask, MaskObject *maskobj, const fl static int add_vertex_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; float co[2]; - maskobj = BKE_mask_object_active(mask); + masklay = BKE_mask_layer_active(mask); - if (maskobj && maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { - maskobj = NULL; + if (masklay && masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + masklay = NULL; } RNA_float_get_array(op->ptr, "location", co); - if (maskobj && maskobj->act_point && MASKPOINT_ISSEL_ANY(maskobj->act_point)) { + if (masklay && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { /* cheap trick - double click for cyclic */ - MaskSpline *spline = maskobj->act_spline; - MaskSplinePoint *point = maskobj->act_point; + MaskSpline *spline = masklay->act_spline; + MaskSplinePoint *point = masklay->act_point; int is_sta = (point == spline->points); int is_end = (point == &spline->points[spline->tot_point - 1]); @@ -1249,14 +1249,14 @@ static int add_vertex_exec(bContext *C, wmOperator *op) } if (!add_vertex_subdivide(C, mask, co)) { - if (!add_vertex_extrude(C, mask, maskobj, co)) { + if (!add_vertex_extrude(C, mask, masklay, co)) { return OPERATOR_CANCELLED; } } } else { if (!add_vertex_subdivide(C, mask, co)) { - if (!add_vertex_new(C, mask, maskobj, co)) { + if (!add_vertex_new(C, mask, masklay, co)) { return OPERATOR_CANCELLED; } } @@ -1304,7 +1304,7 @@ void MASK_OT_add_vertex(wmOperatorType *ot) static int add_feather_vertex_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; MaskSpline *spline; MaskSplinePoint *point = NULL; const float threshold = 9; @@ -1316,7 +1316,7 @@ static int add_feather_vertex_exec(bContext *C, wmOperator *op) if (point) return OPERATOR_FINISHED; - if (find_nearest_diff_point(C, mask, co, threshold, TRUE, &maskobj, &spline, &point, &u, NULL)) { + if (find_nearest_diff_point(C, mask, co, threshold, TRUE, &masklay, &spline, &point, &u, NULL)) { Scene *scene = CTX_data_scene(C); float w = BKE_mask_point_weight(spline, point, u); @@ -1370,16 +1370,16 @@ void MASK_OT_add_feather_vertex(wmOperatorType *ot) static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { if (ED_mask_spline_select_check(spline->points, spline->tot_point)) { spline->flag ^= MASK_SPLINE_CYCLIC; } @@ -1447,17 +1447,17 @@ static void delete_feather_points(MaskSplinePoint *point) static int delete_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; - int mask_object_shape_ofs = 0; + MaskLayer *masklay; + int mask_layer_shape_ofs = 0; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - spline = maskobj->splines.first; + spline = masklay->splines.first; while (spline) { const int tot_point_orig = spline->tot_point; @@ -1475,15 +1475,15 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) if (count == 0) { /* delete the whole spline */ - BLI_remlink(&maskobj->splines, spline); + BLI_remlink(&masklay->splines, spline); BKE_mask_spline_free(spline); - if (spline == maskobj->act_spline) { - maskobj->act_spline = NULL; - maskobj->act_point = NULL; + if (spline == masklay->act_spline) { + masklay->act_spline = NULL; + masklay->act_point = NULL; } - BKE_mask_object_shape_changed_remove(maskobj, mask_object_shape_ofs, tot_point_orig); + BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs, tot_point_orig); } else { MaskSplinePoint *new_points; @@ -1495,8 +1495,8 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) MaskSplinePoint *point = &spline->points[i]; if (!MASKPOINT_ISSEL_ANY(point)) { - if (point == maskobj->act_point) - maskobj->act_point = &new_points[j]; + if (point == masklay->act_point) + masklay->act_point = &new_points[j]; delete_feather_points(point); @@ -1504,17 +1504,17 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) j++; } else { - if (point == maskobj->act_point) - maskobj->act_point = NULL; + if (point == masklay->act_point) + masklay->act_point = NULL; BKE_mask_point_free(point); spline->tot_point--; - BKE_mask_object_shape_changed_remove(maskobj, mask_object_shape_ofs + j, 1); + BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs + j, 1); } } - mask_object_shape_ofs += spline->tot_point; + mask_layer_shape_ofs += spline->tot_point; MEM_freeN(spline->points); spline->points = new_points; @@ -1555,18 +1555,18 @@ void MASK_OT_delete(wmOperatorType *ot) static int set_handle_type_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; int handle_type = RNA_enum_get(op->ptr, "type"); - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; int i; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; @@ -1616,14 +1616,14 @@ void MASK_OT_handle_type_set(wmOperatorType *ot) static int mask_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; int changed = FALSE; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { - if (maskobj->restrictflag & OB_RESTRICT_VIEW) { - ED_mask_object_select_set(maskobj, TRUE); - maskobj->restrictflag &= ~OB_RESTRICT_VIEW; + if (masklay->restrictflag & OB_RESTRICT_VIEW) { + ED_mask_layer_select_set(masklay, TRUE); + masklay->restrictflag &= ~OB_RESTRICT_VIEW; changed = 1; } } @@ -1644,7 +1644,7 @@ void MASK_OT_hide_view_clear(wmOperatorType *ot) /* identifiers */ ot->name = "Clear Restrict View"; - ot->description = "Reveal the object by setting the hide flag"; + ot->description = "Reveal the layer by setting the hide flag"; ot->idname = "MASK_OT_hide_view_clear"; /* api callbacks */ @@ -1658,33 +1658,33 @@ void MASK_OT_hide_view_clear(wmOperatorType *ot) static int mask_hide_view_set_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; const int unselected = RNA_boolean_get(op->ptr, "unselected"); int changed = FALSE; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { - if (maskobj->restrictflag & MASK_RESTRICT_SELECT) { + if (masklay->restrictflag & MASK_RESTRICT_SELECT) { continue; } if (!unselected) { - if (ED_mask_object_select_check(maskobj)) { - ED_mask_object_select_set(maskobj, FALSE); + if (ED_mask_layer_select_check(masklay)) { + ED_mask_layer_select_set(masklay, FALSE); - maskobj->restrictflag |= OB_RESTRICT_VIEW; + masklay->restrictflag |= OB_RESTRICT_VIEW; changed = 1; - if (maskobj == BKE_mask_object_active(mask)) { - BKE_mask_object_active_set(mask, NULL); + if (masklay == BKE_mask_layer_active(mask)) { + BKE_mask_layer_active_set(mask, NULL); } } } else { - if (!ED_mask_object_select_check(maskobj)) { - maskobj->restrictflag |= OB_RESTRICT_VIEW; + if (!ED_mask_layer_select_check(masklay)) { + masklay->restrictflag |= OB_RESTRICT_VIEW; changed = 1; - if (maskobj == BKE_mask_object_active(mask)) { - BKE_mask_object_active_set(mask, NULL); + if (masklay == BKE_mask_layer_active(mask)) { + BKE_mask_layer_active_set(mask, NULL); } } } @@ -1705,7 +1705,7 @@ void MASK_OT_hide_view_set(wmOperatorType *ot) { /* identifiers */ ot->name = "Set Restrict View"; - ot->description = "Hide the object by setting the hide flag"; + ot->description = "Hide the layer by setting the hide flag"; ot->idname = "MASK_OT_hide_view_set"; /* api callbacks */ @@ -1715,6 +1715,6 @@ void MASK_OT_hide_view_set(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects"); + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected layers"); } diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index bf57bce9957..8a8427c024b 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -60,17 +60,17 @@ static int mask_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; int i; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; @@ -106,7 +106,7 @@ void MASK_OT_parent_clear(wmOperatorType *ot) static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; /* parent info */ SpaceClip *sc; @@ -132,15 +132,15 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker_pos_ofs); - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; int i; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index c204dbf0110..95c2808bc3e 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -71,15 +71,15 @@ int ED_mask_spline_select_check(MaskSplinePoint *points, int tot_point) return FALSE; } -int ED_mask_object_select_check(MaskObject *maskobj) +int ED_mask_layer_select_check(MaskLayer *masklay) { MaskSpline *spline; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { return FALSE; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { if (ED_mask_spline_select_check(spline->points, spline->tot_point)) { return TRUE; } @@ -90,10 +90,10 @@ int ED_mask_object_select_check(MaskObject *maskobj) int ED_mask_select_check(Mask *mask) { - MaskObject *maskobj; + MaskLayer *masklay; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - if (ED_mask_object_select_check(maskobj)) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + if (ED_mask_layer_select_check(masklay)) { return TRUE; } } @@ -101,17 +101,17 @@ int ED_mask_select_check(Mask *mask) return FALSE; } -void ED_mask_object_select_set(MaskObject *maskobj, int select) +void ED_mask_layer_select_set(MaskLayer *masklay, int select) { MaskSpline *spline; - if (maskobj->restrictflag & MASK_RESTRICT_SELECT) { + if (masklay->restrictflag & MASK_RESTRICT_SELECT) { if (select == TRUE) { return; } } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; if (select) @@ -129,7 +129,7 @@ void ED_mask_object_select_set(MaskObject *maskobj, int select) void ED_mask_select_toggle_all(Mask *mask, int action) { - MaskObject *maskobj; + MaskLayer *masklay; if (action == SEL_TOGGLE) { if (ED_mask_select_check(mask)) @@ -138,31 +138,31 @@ void ED_mask_select_toggle_all(Mask *mask, int action) action = SEL_SELECT; } - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (masklay->restrictflag & MASK_RESTRICT_VIEW) { continue; } - ED_mask_object_select_set(maskobj, (action == SEL_SELECT) ? TRUE : FALSE); + ED_mask_layer_select_set(masklay, (action == SEL_SELECT) ? TRUE : FALSE); } } void ED_mask_select_flush_all(Mask *mask) { - MaskObject *maskobj; + MaskLayer *masklay; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; spline->flag &= ~SELECT; - /* intentionally _dont_ do this in the maskobj loop + /* intentionally _dont_ do this in the masklay loop * so we clear flags on all splines */ - if (maskobj->restrictflag & MASK_RESTRICT_VIEW) { + if (masklay->restrictflag & MASK_RESTRICT_VIEW) { continue; } @@ -225,7 +225,7 @@ void MASK_OT_select_all(wmOperatorType *ot) static int select_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; MaskSpline *spline; MaskSplinePoint *point = NULL; float co[2]; @@ -238,7 +238,7 @@ static int select_exec(bContext *C, wmOperator *op) RNA_float_get_array(op->ptr, "location", co); - point = ED_mask_point_find_nearest(C, mask, co, threshold, &maskobj, &spline, &is_handle, NULL); + point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &is_handle, NULL); if (point) { if (extend == 0 && deselect == 0 && toggle == 0) @@ -246,8 +246,8 @@ static int select_exec(bContext *C, wmOperator *op) if (is_handle) { if (extend) { - maskobj->act_spline = spline; - maskobj->act_point = point; + masklay->act_spline = spline; + masklay->act_point = point; BKE_mask_point_select_set_handle(point, TRUE); } @@ -255,8 +255,8 @@ static int select_exec(bContext *C, wmOperator *op) BKE_mask_point_select_set_handle(point, FALSE); } else { - maskobj->act_spline = spline; - maskobj->act_point = point; + masklay->act_spline = spline; + masklay->act_point = point; if (!MASKPOINT_ISSEL_HANDLE(point)) { BKE_mask_point_select_set_handle(point, TRUE); @@ -268,8 +268,8 @@ static int select_exec(bContext *C, wmOperator *op) } else { if (extend) { - maskobj->act_spline = spline; - maskobj->act_point = point; + masklay->act_spline = spline; + masklay->act_point = point; BKE_mask_point_select_set(point, TRUE); } @@ -277,8 +277,8 @@ static int select_exec(bContext *C, wmOperator *op) BKE_mask_point_select_set(point, FALSE); } else { - maskobj->act_spline = spline; - maskobj->act_point = point; + masklay->act_spline = spline; + masklay->act_point = point; if (!MASKPOINT_ISSEL_ANY(point)) { BKE_mask_point_select_set(point, TRUE); @@ -289,8 +289,8 @@ static int select_exec(bContext *C, wmOperator *op) } } - maskobj->act_spline = spline; - maskobj->act_point = point; + masklay->act_spline = spline; + masklay->act_point = point; ED_mask_select_flush_all(mask); @@ -301,15 +301,15 @@ static int select_exec(bContext *C, wmOperator *op) else { MaskSplinePointUW *uw; - if (ED_mask_feather_find_nearest(C, mask, co, threshold, &maskobj, &spline, &point, &uw, NULL)) { + if (ED_mask_feather_find_nearest(C, mask, co, threshold, &masklay, &spline, &point, &uw, NULL)) { if (!extend) ED_mask_select_toggle_all(mask, SEL_DESELECT); if (uw) uw->flag |= SELECT; - maskobj->act_spline = spline; - maskobj->act_point = point; + masklay->act_spline = spline; + masklay->act_point = point; ED_mask_select_flush_all(mask); @@ -362,7 +362,7 @@ void MASK_OT_select(wmOperatorType *ot) static int border_select_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; int i; rcti rect; @@ -382,14 +382,14 @@ static int border_select_exec(bContext *C, wmOperator *op) extend = RNA_boolean_get(op->ptr, "extend"); /* do actual selection */ - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); for (i = 0; i < spline->tot_point; i++) { @@ -447,7 +447,7 @@ void MASK_OT_select_border(wmOperatorType *ot) static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short select) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; int i; rcti rect; @@ -457,14 +457,14 @@ static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short BLI_lasso_boundbox(&rect, mcords, moves); /* do actual selection */ - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); for (i = 0; i < spline->tot_point; i++) { @@ -559,7 +559,7 @@ static int mask_spline_point_inside_ellipse(BezTriple *bezt, float offset[2], fl static int circle_select_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; int i; SpaceClip *sc = CTX_wm_space_clip(C); @@ -586,14 +586,14 @@ static int circle_select_exec(bContext *C, wmOperator *op) ED_mask_point_pos(C, x, y, &offset[0], &offset[1]); /* do actual selection */ - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); for (i = 0; i < spline->tot_point; i++) { diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c index e323a6abe15..94aebb9f3a1 100644 --- a/source/blender/editors/mask/mask_shapekey.c +++ b/source/blender/editors/mask/mask_shapekey.c @@ -61,18 +61,18 @@ static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); const int frame = CFRA; Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; int change = FALSE; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskObjectShape *maskobj_shape; + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskLayerShape *masklay_shape; - if (!ED_mask_object_select_check(maskobj)) { + if (!ED_mask_layer_select_check(masklay)) { continue; } - maskobj_shape = BKE_mask_object_shape_varify_frame(maskobj, frame); - BKE_mask_object_shape_from_mask(maskobj, maskobj_shape); + masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, frame); + BKE_mask_layer_shape_from_mask(masklay, masklay_shape); change = TRUE; } @@ -107,20 +107,20 @@ static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); const int frame = CFRA; Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; int change = FALSE; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskObjectShape *maskobj_shape; + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskLayerShape *masklay_shape; - if (!ED_mask_object_select_check(maskobj)) { + if (!ED_mask_layer_select_check(masklay)) { continue; } - maskobj_shape = BKE_mask_object_shape_find_frame(maskobj, frame); + masklay_shape = BKE_mask_layer_shape_find_frame(masklay, frame); - if (maskobj_shape) { - BKE_mask_object_shape_unlink(maskobj, maskobj_shape); + if (masklay_shape) { + BKE_mask_layer_shape_unlink(masklay, masklay_shape); change = TRUE; } } @@ -151,16 +151,16 @@ void MASK_OT_shape_key_clear(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -int ED_mask_object_shape_auto_key_all(Mask *mask, const int frame) +int ED_mask_layer_shape_auto_key_all(Mask *mask, const int frame) { - MaskObject *maskobj; + MaskLayer *masklay; int change = FALSE; - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskObjectShape *maskobj_shape; + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskLayerShape *masklay_shape; - maskobj_shape = BKE_mask_object_shape_varify_frame(maskobj, frame); - BKE_mask_object_shape_from_mask(maskobj, maskobj_shape); + masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, frame); + BKE_mask_layer_shape_from_mask(masklay, masklay_shape); change = TRUE; } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 7caff30807d..89c7896d53c 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1952,8 +1952,8 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); if (sc) { if ((sc->mode == SC_MODE_MASKEDITING) && sc->mask) { - MaskObject *maskobj = BKE_mask_object_active(sc->mask); - mask_to_keylist(&ads, maskobj, &keys); + MaskLayer *masklay = BKE_mask_layer_active(sc->mask); + mask_to_keylist(&ads, masklay, &keys); } } } diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index fd47bc376c7..003fa5c5cef 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -199,18 +199,18 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc /* movie clip animation */ if ((sc->mode == SC_MODE_MASKEDITING) && sc->mask) { - MaskObject *maskobj = BKE_mask_object_active(sc->mask); - if (maskobj) { - MaskObjectShape *maskobj_shape; + MaskLayer *masklay = BKE_mask_layer_active(sc->mask); + if (masklay) { + MaskLayerShape *masklay_shape; glColor4ub(255, 175, 0, 255); glBegin(GL_LINES); - for (maskobj_shape = maskobj->splines_shapes.first; - maskobj_shape; - maskobj_shape = maskobj_shape->next) + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) { - i = maskobj_shape->frame; + i = masklay_shape->frame; /* glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 4); */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 8211df67b17..23a88e6e547 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4915,7 +4915,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) if (IS_AUTOKEY_ON(t->scene)) { Scene *scene = t->scene; - ED_mask_object_shape_auto_key_all(mask, CFRA); + ED_mask_layer_shape_auto_key_all(mask, CFRA); } } } @@ -5974,7 +5974,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t) { SpaceClip *sc = CTX_wm_space_clip(C); Mask *mask = CTX_data_edit_mask(C); - MaskObject *maskobj; + MaskLayer *masklay; TransData *td = NULL; TransData2D *td2d = NULL; TransDataMasking *tdm = NULL; @@ -5982,14 +5982,14 @@ static void createTransMaskingData(bContext *C, TransInfo *t) int propmode = t->flag & T_PROP_EDIT; /* count */ - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskSpline *spline = maskobj->splines.first; + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline = masklay->splines.first; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { @@ -6021,14 +6021,14 @@ static void createTransMaskingData(bContext *C, TransInfo *t) t->flag |= T_FREE_CUSTOMDATA; /* create data */ - for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) { - MaskSpline *spline = maskobj->splines.first; + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline = masklay->splines.first; - if (maskobj->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { int i; for (i = 0; i < spline->tot_point; i++) { diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index d677239e300..28fc9466613 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -43,9 +43,9 @@ typedef struct Mask { ID id; struct AnimData *adt; - ListBase maskobjs; /* mask objects */ - int act_maskobj; /* index of active mask object (-1 == None) */ - int tot_maskobj; /* total number of mask objects */ + ListBase masklayers; /* mask layers */ + int masklay_act; /* index of active mask layer (-1 == None) */ + int masklay_tot; /* total number of mask layers */ } Mask; typedef struct MaskParent { @@ -54,7 +54,7 @@ typedef struct MaskParent { ID *id; /* ID block of entity to which mask/spline is parented to * in case of parenting to movie tracking data set to MovieClip datablock */ char parent[64]; /* entity of parent to which parenting happened - * in case of parenting to movie tracking data contains name of object */ + * in case of parenting to movie tracking data contains name of layer */ char sub_parent[64]; /* sub-entity of parent to which parenting happened * in case of parenting to movie tracking data contains name of track */ float parent_orig[2]; /* track location at the moment of parenting */ @@ -87,22 +87,22 @@ typedef struct MaskSpline { } MaskSpline; /* one per frame */ -typedef struct MaskObjectShape { - struct MaskObjectShape *next, *prev; +typedef struct MaskLayerShape { + struct MaskLayerShape *next, *prev; float *data; /* u coordinate along spline segment and weight of this point */ int tot_vert; /* to ensure no buffer overruns's: alloc size is (tot_vert * MASK_OBJECT_SHAPE_ELEM_SIZE) */ int frame; /* different flags of this point */ char flag; char pad[7]; -} MaskObjectShape; +} MaskLayerShape; -typedef struct MaskObject { - struct MaskObject *next, *prev; +typedef struct MaskLayer { + struct MaskLayer *next, *prev; - char name[64]; /* name of the mask object (64 = MAD_ID_NAME - 2) */ + char name[64]; /* name of the mask layer (64 = MAD_ID_NAME - 2) */ - ListBase splines; /* list of splines which defines this mask object */ + ListBase splines; /* list of splines which defines this mask layer */ ListBase splines_shapes; struct MaskSpline *act_spline; /* active spline */ @@ -116,7 +116,7 @@ typedef struct MaskObject { //char flag; /* not used yet */ char restrictflag; /* matching 'Object' flag of the same name - eventually use in the outliner */ char pad[1]; -} MaskObject; +} MaskLayer; /* MaskParent->flag */ #define MASK_PARENT_ACTIVE (1 << 0) @@ -148,13 +148,13 @@ enum { MASK_DT_WHITE }; -/* maskobj->blend */ +/* masklay->blend */ enum { MASK_BLEND_ADD = 0, MASK_BLEND_SUBTRACT = 1 }; -/* maskobj->blend_flag */ +/* masklay->blend_flag */ enum { MASK_BLENDFLAG_INVERT = (1 << 0) }; diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 9c465619b95..319e93b3084 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -306,7 +306,7 @@ extern StructRNA RNA_MaterialSubsurfaceScattering; extern StructRNA RNA_MaterialTextureSlot; extern StructRNA RNA_MaterialVolume; extern StructRNA RNA_Mask; -extern StructRNA RNA_MaskObject; +extern StructRNA RNA_MaskLayer; extern StructRNA RNA_Menu; extern StructRNA RNA_Mesh; extern StructRNA RNA_MeshColor; diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index c072676b665..c356cae81af 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -93,114 +93,114 @@ static void rna_MaskParent_id_type_set(PointerRNA *ptr, int value) mpar->id = NULL; } -static void rna_Mask_objects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +static void rna_Mask_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Mask *mask = (Mask *)ptr->id.data; - rna_iterator_listbase_begin(iter, &mask->maskobjs, NULL); + rna_iterator_listbase_begin(iter, &mask->masklayers, NULL); } -static int rna_Mask_object_active_index_get(PointerRNA *ptr) +static int rna_Mask_layer_active_index_get(PointerRNA *ptr) { Mask *mask = (Mask *)ptr->id.data; - return mask->act_maskobj; + return mask->masklay_act; } -static void rna_Mask_object_active_index_set(PointerRNA *ptr, int value) +static void rna_Mask_layer_active_index_set(PointerRNA *ptr, int value) { Mask *mask = (Mask *)ptr->id.data; - mask->act_maskobj = value; + mask->masklay_act = value; } -static void rna_Mask_object_active_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) +static void rna_Mask_layer_active_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) { Mask *mask = (Mask *)ptr->id.data; *min = 0; - *max = mask->tot_maskobj - 1; + *max = mask->masklay_tot - 1; *max = MAX2(0, *max); *softmin = *min; *softmax = *max; } -static char *rna_MaskObject_path(PointerRNA *ptr) +static char *rna_MaskLayer_path(PointerRNA *ptr) { - return BLI_sprintfN("objects[\"%s\"]", ((MaskObject *)ptr->data)->name); + return BLI_sprintfN("layers[\"%s\"]", ((MaskLayer *)ptr->data)->name); } -static PointerRNA rna_Mask_object_active_get(PointerRNA *ptr) +static PointerRNA rna_Mask_layer_active_get(PointerRNA *ptr) { Mask *mask = (Mask *)ptr->id.data; - MaskObject *maskobj = BKE_mask_object_active(mask); + MaskLayer *masklay = BKE_mask_layer_active(mask); - return rna_pointer_inherit_refine(ptr, &RNA_MaskObject, maskobj); + return rna_pointer_inherit_refine(ptr, &RNA_MaskLayer, masklay); } -static void rna_Mask_object_active_set(PointerRNA *ptr, PointerRNA value) +static void rna_Mask_layer_active_set(PointerRNA *ptr, PointerRNA value) { Mask *mask = (Mask *)ptr->id.data; - MaskObject *maskobj = (MaskObject *)value.data; + MaskLayer *masklay = (MaskLayer *)value.data; - BKE_mask_object_active_set(mask, maskobj); + BKE_mask_layer_active_set(mask, masklay); } -static void rna_MaskObject_splines_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +static void rna_MaskLayer_splines_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { - MaskObject *maskobj = (MaskObject *)ptr->data; + MaskLayer *masklay = (MaskLayer *)ptr->data; - rna_iterator_listbase_begin(iter, &maskobj->splines, NULL); + rna_iterator_listbase_begin(iter, &masklay->splines, NULL); } -void rna_MaskObject_name_set(PointerRNA *ptr, const char *value) +void rna_MaskLayer_name_set(PointerRNA *ptr, const char *value) { Mask *mask = (Mask *)ptr->id.data; - MaskObject *maskobj = (MaskObject *)ptr->data; + MaskLayer *masklay = (MaskLayer *)ptr->data; - BLI_strncpy(maskobj->name, value, sizeof(maskobj->name)); + BLI_strncpy(masklay->name, value, sizeof(masklay->name)); - BKE_mask_object_unique_name(mask, maskobj); + BKE_mask_layer_unique_name(mask, masklay); } -static PointerRNA rna_MaskObject_active_spline_get(PointerRNA *ptr) +static PointerRNA rna_MaskLayer_active_spline_get(PointerRNA *ptr) { - MaskObject *maskobj = (MaskObject *)ptr->data; + MaskLayer *masklay = (MaskLayer *)ptr->data; - return rna_pointer_inherit_refine(ptr, &RNA_MaskSpline, maskobj->act_spline); + return rna_pointer_inherit_refine(ptr, &RNA_MaskSpline, masklay->act_spline); } -static void rna_MaskObject_active_spline_set(PointerRNA *ptr, PointerRNA value) +static void rna_MaskLayer_active_spline_set(PointerRNA *ptr, PointerRNA value) { - MaskObject *maskobj = (MaskObject *)ptr->data; + MaskLayer *masklay = (MaskLayer *)ptr->data; MaskSpline *spline = (MaskSpline *)value.data; - int index = BLI_findindex(&maskobj->splines, spline); + int index = BLI_findindex(&masklay->splines, spline); if (index >= 0) - maskobj->act_spline = spline; + masklay->act_spline = spline; else - maskobj->act_spline = NULL; + masklay->act_spline = NULL; } -static PointerRNA rna_MaskObject_active_spline_point_get(PointerRNA *ptr) +static PointerRNA rna_MaskLayer_active_spline_point_get(PointerRNA *ptr) { - MaskObject *maskobj = (MaskObject *)ptr->data; + MaskLayer *masklay = (MaskLayer *)ptr->data; - return rna_pointer_inherit_refine(ptr, &RNA_MaskSplinePoint, maskobj->act_point); + return rna_pointer_inherit_refine(ptr, &RNA_MaskSplinePoint, masklay->act_point); } -static void rna_MaskObject_active_spline_point_set(PointerRNA *ptr, PointerRNA value) +static void rna_MaskLayer_active_spline_point_set(PointerRNA *ptr, PointerRNA value) { - MaskObject *maskobj = (MaskObject *)ptr->data; + MaskLayer *masklay = (MaskLayer *)ptr->data; MaskSpline *spline; MaskSplinePoint *point = (MaskSplinePoint *)value.data; - maskobj->act_point = NULL; + masklay->act_point = NULL; - for (spline = maskobj->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { if (point >= spline->points && point < spline->points + spline->tot_point) { - maskobj->act_point = point; + masklay->act_point = point; break; } @@ -285,29 +285,29 @@ static void rna_MaskSplinePoint_handle_type_set(PointerRNA *ptr, int value) /* ** API ** */ -static MaskObject *rna_Mask_object_new(Mask *mask, const char *name) +static MaskLayer *rna_Mask_layer_new(Mask *mask, const char *name) { - MaskObject *maskobj = BKE_mask_object_new(mask, name); + MaskLayer *masklay = BKE_mask_layer_new(mask, name); WM_main_add_notifier(NC_MASK|NA_EDITED, mask); - return maskobj; + return masklay; } -void rna_Mask_object_remove(Mask *mask, MaskObject *maskobj) +void rna_Mask_layer_remove(Mask *mask, MaskLayer *masklay) { - BKE_mask_object_remove(mask, maskobj); + BKE_mask_layer_remove(mask, masklay); WM_main_add_notifier(NC_MASK|NA_EDITED, mask); } -static void rna_MaskObject_spline_add(ID *id, MaskObject *maskobj, int number) +static void rna_MaskLayer_spline_add(ID *id, MaskLayer *masklay, int number) { Mask *mask = (Mask*) id; int i; for (i = 0; i < number; i++) - BKE_mask_spline_add(maskobj); + BKE_mask_spline_add(masklay); WM_main_add_notifier(NC_MASK|NA_EDITED, mask); } @@ -330,7 +330,7 @@ static void rna_def_maskParent(BlenderRNA *brna) prop = RNA_def_property(srna, "use_parent", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_PARENT_ACTIVE); - RNA_def_property_ui_text(prop, "Use Parent", "Use parenting for this object"); + RNA_def_property_ui_text(prop, "Use Parent", "Use parenting for this layer"); RNA_def_property_update(prop, 0, "rna_Mask_update_data"); /* Target Properties - ID-block to Drive */ @@ -460,27 +460,27 @@ static void rna_def_mask_splines(BlenderRNA *brna) PropertyRNA *prop; srna = RNA_def_struct(brna, "MaskSplines", NULL); - RNA_def_struct_sdna(srna, "MaskObject"); + RNA_def_struct_sdna(srna, "MaskLayer"); RNA_def_struct_ui_text(srna, "Mask Splines", "Collection of masking splines"); - func = RNA_def_function(srna, "add", "rna_MaskObject_spline_add"); + func = RNA_def_function(srna, "add", "rna_MaskLayer_spline_add"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Add a number of splines to mask object"); - RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of splines to add to the object", 0, INT_MAX); + RNA_def_function_ui_description(func, "Add a number of splines to mask layer"); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of splines to add to the layer", 0, INT_MAX); /* active spline */ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MaskSpline"); - RNA_def_property_pointer_funcs(prop, "rna_MaskObject_active_spline_get", "rna_MaskObject_active_spline_set", NULL, NULL); + RNA_def_property_pointer_funcs(prop, "rna_MaskLayer_active_spline_get", "rna_MaskLayer_active_spline_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); - RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking object"); + RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking layer"); /* active point */ prop = RNA_def_property(srna, "active_point", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MaskSplinePoint"); - RNA_def_property_pointer_funcs(prop, "rna_MaskObject_active_spline_point_get", "rna_MaskObject_active_spline_point_set", NULL, NULL); + RNA_def_property_pointer_funcs(prop, "rna_MaskLayer_active_spline_point_get", "rna_MaskLayer_active_spline_point_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); - RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking object"); + RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking layer"); } static void rna_def_maskSpline(BlenderRNA *brna) @@ -514,9 +514,9 @@ static void rna_def_maskSpline(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Mask_update_data"); } -static void rna_def_mask_object(BlenderRNA *brna) +static void rna_def_mask_layer(BlenderRNA *brna) { - static EnumPropertyItem maskobj_blend_mode_items[] = { + static EnumPropertyItem masklay_blend_mode_items[] = { {MASK_BLEND_ADD, "ADD", 0, "Add", ""}, {MASK_BLEND_SUBTRACT, "SUBTRACT", 0, "Subtract", ""}, {0, NULL, 0, NULL, NULL} @@ -528,23 +528,23 @@ static void rna_def_mask_object(BlenderRNA *brna) rna_def_maskSpline(brna); rna_def_mask_splines(brna); - srna = RNA_def_struct(brna, "MaskObject", NULL); - RNA_def_struct_ui_text(srna, "Mask Object", "Single object used for masking pixels"); - RNA_def_struct_path_func(srna, "rna_MaskObject_path"); + srna = RNA_def_struct(brna, "MaskLayer", NULL); + RNA_def_struct_ui_text(srna, "Mask Layer", "Single layer used for masking pixels"); + RNA_def_struct_path_func(srna, "rna_MaskLayer_path"); /* name */ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_ui_text(prop, "Name", "Unique name of object"); - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MaskObject_name_set"); + RNA_def_property_ui_text(prop, "Name", "Unique name of layer"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MaskLayer_name_set"); RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); RNA_def_property_update(prop, 0, "rna_Mask_update_data"); RNA_def_struct_name_property(srna, prop); /* splines */ prop = RNA_def_property(srna, "splines", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_funcs(prop, "rna_MaskObject_splines_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_MaskLayer_splines_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); RNA_def_property_struct_type(prop, "MaskSpline"); - RNA_def_property_ui_text(prop, "Splines", "Collection of splines which defines this object"); + RNA_def_property_ui_text(prop, "Splines", "Collection of splines which defines this layer"); RNA_def_property_srna(prop, "MaskSplines"); /* restrict */ @@ -576,8 +576,8 @@ static void rna_def_mask_object(BlenderRNA *brna) /* weight interpolation */ prop = RNA_def_property(srna, "blend", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "blend"); - RNA_def_property_enum_items(prop, maskobj_blend_mode_items); - RNA_def_property_ui_text(prop, "Blend", "Method of blending mask objects"); + RNA_def_property_enum_items(prop, masklay_blend_mode_items); + RNA_def_property_ui_text(prop, "Blend", "Method of blending mask layers"); RNA_def_property_update(prop, 0, "rna_Mask_update_data"); RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); @@ -588,7 +588,7 @@ static void rna_def_mask_object(BlenderRNA *brna) } -static void rna_def_maskobjects(BlenderRNA *brna, PropertyRNA *cprop) +static void rna_def_masklayers(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; PropertyRNA *prop; @@ -596,27 +596,27 @@ static void rna_def_maskobjects(BlenderRNA *brna, PropertyRNA *cprop) FunctionRNA *func; PropertyRNA *parm; - RNA_def_property_srna(cprop, "MaskObjects"); - srna = RNA_def_struct(brna, "MaskObjects", NULL); + RNA_def_property_srna(cprop, "MaskLayers"); + srna = RNA_def_struct(brna, "MaskLayers", NULL); RNA_def_struct_sdna(srna, "Mask"); - RNA_def_struct_ui_text(srna, "Mask Objects", "Collection of objects used by mask"); + RNA_def_struct_ui_text(srna, "Mask Layers", "Collection of layers used by mask"); - func = RNA_def_function(srna, "new", "rna_Mask_object_new"); - RNA_def_function_ui_description(func, "Add object to this mask"); - RNA_def_string(func, "name", "", 0, "Name", "Name of new object"); - parm = RNA_def_pointer(func, "object", "MaskObject", "", "New mask object"); + func = RNA_def_function(srna, "new", "rna_Mask_layer_new"); + RNA_def_function_ui_description(func, "Add layer to this mask"); + RNA_def_string(func, "name", "", 0, "Name", "Name of new layer"); + parm = RNA_def_pointer(func, "layer", "MaskLayer", "", "New mask layer"); RNA_def_function_return(func, parm); - func = RNA_def_function(srna, "remove", "rna_Mask_object_remove"); - RNA_def_function_ui_description(func, "Remove object from this mask"); - RNA_def_pointer(func, "object", "MaskObject", "", "Shape to be removed"); + func = RNA_def_function(srna, "remove", "rna_Mask_layer_remove"); + RNA_def_function_ui_description(func, "Remove layer from this mask"); + RNA_def_pointer(func, "layer", "MaskLayer", "", "Shape to be removed"); - /* active object */ + /* active layer */ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "MaskObject"); - RNA_def_property_pointer_funcs(prop, "rna_Mask_object_active_get", "rna_Mask_object_active_set", NULL, NULL); + RNA_def_property_struct_type(prop, "MaskLayer"); + RNA_def_property_pointer_funcs(prop, "rna_Mask_layer_active_get", "rna_Mask_layer_active_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); - RNA_def_property_ui_text(prop, "Active Shape", "Active object in this mask"); + RNA_def_property_ui_text(prop, "Active Shape", "Active layer in this mask"); } static void rna_def_mask(BlenderRNA *brna) @@ -624,25 +624,25 @@ static void rna_def_mask(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - rna_def_mask_object(brna); + rna_def_mask_layer(brna); srna = RNA_def_struct(brna, "Mask", "ID"); RNA_def_struct_ui_text(srna, "Mask", "Mask datablock defining mask for compositing"); RNA_def_struct_ui_icon(srna, ICON_MOD_MASK); - /* mask objects */ - prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_funcs(prop, "rna_Mask_objects_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); - RNA_def_property_struct_type(prop, "MaskObject"); - RNA_def_property_ui_text(prop, "Objects", "Collection of objects which defines this mask"); - rna_def_maskobjects(brna, prop); + /* mask layers */ + prop = RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_Mask_layers_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_struct_type(prop, "MaskLayer"); + RNA_def_property_ui_text(prop, "Layers", "Collection of layers which defines this mask"); + rna_def_masklayers(brna, prop); - /* active maskobj index */ - prop = RNA_def_property(srna, "active_object_index", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "act_maskobj"); + /* active masklay index */ + prop = RNA_def_property(srna, "active_layer_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "masklay_act"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_funcs(prop, "rna_Mask_object_active_index_get", "rna_Mask_object_active_index_set", "rna_Mask_object_active_index_range"); - RNA_def_property_ui_text(prop, "Active Shape Index", "Index of active object in list of all mask's objects"); + RNA_def_property_int_funcs(prop, "rna_Mask_layer_active_index_get", "rna_Mask_layer_active_index_set", "rna_Mask_layer_active_index_range"); + RNA_def_property_ui_text(prop, "Active Shape Index", "Index of active layer in list of all mask's layers"); /* pointers */ rna_def_animdata_common(srna); From 1abbb21fee7dea1ed5dfa9e6c60d531510c20538 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Thu, 31 May 2012 19:17:17 +0000 Subject: [PATCH 143/360] fixed gradient visual stepping in mask feather regions. converted all distance calculations from int to float. --- intern/raskter/raskter.c | 50 +++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index fd274c5f5f5..33da097f063 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -434,8 +434,8 @@ int PLX_raskterize(float (*base_verts)[2], int num_base_verts, * if it ends up being coupled with this function. */ int rast_scan_feather(struct r_fill_context *ctx, - struct poly_vert *base_verts, int num_base_verts, - struct poly_vert *feather_verts, int num_feather_verts) + float (*base_verts_f)[2], int num_base_verts, + struct poly_vert *feather_verts, float (*feather_verts_f)[2], int num_feather_verts) { int x_curr; /* current pixel position in X */ int y_curr; /* current scan line being drawn */ @@ -451,19 +451,19 @@ int rast_scan_feather(struct r_fill_context *ctx, /* from dem */ int a; // a = temporary pixel index buffer loop counter - int fsz; // size of the frame + float fsz; // size of the frame unsigned int rsl; // long used for finding fast 1.0/sqrt float rsf; // float used for finding fast 1.0/sqrt const float rsopf = 1.5f; // constant float used for finding fast 1.0/sqrt //unsigned int gradientFillOffset; - unsigned int t; - unsigned int ud; // ud = unscaled edge distance - unsigned int dmin; // dmin = minimun edge distance + float t; + float ud; // ud = unscaled edge distance + float dmin; // dmin = minimun edge distance float odist; // odist = current outer edge distance float idist; // idist = current inner edge distance - int dx; // dx = X-delta (used for distance proportion calculation) - int dy; // dy = Y-delta (used for distance proportion calculation) + float dx; // dx = X-delta (used for distance proportion calculation) + float dy; // dy = Y-delta (used for distance proportion calculation) /* @@ -595,41 +595,43 @@ int rast_scan_feather(struct r_fill_context *ctx, /* * Begin modified code from double edge mask compo node... */ - t = (cpxl - spxl) % ctx->rb.sizex; // calculate column of pixel + t = ((float)((cpxl - spxl) % ctx->rb.sizex) + 0.5f) * (1.0f / (float)(ctx->rb.sizex)); // calculate column of pixel - fsz = y_curr; // calculate row of pixel + fsz = ((float)(y_curr) + 0.5) * (1.0f / (float)(ctx->rb.sizey)); // calculate row of pixel - dmin = 0xffffffff; // reset min distance to edge pixel + dmin = 2.0f; // reset min distance to edge pixel for (a = 0; a < num_feather_verts; a++) { // loop through all outer edge buffer pixels - dy = t - feather_verts[a].x; // set dx to gradient pixel column - outer edge pixel row - dx = fsz - feather_verts[a].y; // set dy to gradient pixel row - outer edge pixel column + dy = t - feather_verts_f[a][0]; // set dx to gradient pixel column - outer edge pixel row + dx = fsz - feather_verts_f[a][1]; // set dy to gradient pixel row - outer edge pixel column ud = dx * dx + dy * dy; // compute sum of squares if (ud < dmin) { // if our new sum of squares is less than the current minimum dmin = ud; // set a new minimum equal to the new lower value } } - odist = (float)(dmin); // cast outer min to a float + odist = dmin; // cast outer min to a float rsf = odist * 0.5f; // rsl = *(unsigned int *)&odist; // use some peculiar properties of the way bits are stored rsl = 0x5f3759df - (rsl >> 1); // in floats vs. unsigned ints to compute an approximate odist = *(float *)&rsl; // reciprocal square root odist = odist * (rsopf - (rsf * odist * odist)); // -- ** this line can be iterated for more accuracy ** -- - dmin = 0xffffffff; // reset min distance to edge pixel + odist = odist * (rsopf - (rsf * odist * odist)); + dmin = 2.0f; // reset min distance to edge pixel for (a = 0; a < num_base_verts; a++) { // loop through all inside edge pixels - dy = t - base_verts[a].x; // compute delta in Y from gradient pixel to inside edge pixel - dx = fsz - base_verts[a].y; // compute delta in X from gradient pixel to inside edge pixel + dy = t - base_verts_f[a][0]; // compute delta in Y from gradient pixel to inside edge pixel + dx = fsz - base_verts_f[a][1]; // compute delta in X from gradient pixel to inside edge pixel ud = dx * dx + dy * dy; // compute sum of squares if (ud < dmin) { // if our new sum of squares is less than the current minimum we've found dmin = ud; // set a new minimum equal to the new lower value } } - idist = (float)(dmin); // cast inner min to a float + idist = dmin; // cast inner min to a float rsf = idist * 0.5f; // rsl = *(unsigned int *)&idist; // rsl = 0x5f3759df - (rsl >> 1); // see notes above idist = *(float *)&rsl; // idist = idist * (rsopf - (rsf * idist * idist)); // + idist = idist * (rsopf - (rsf * idist * idist)); /* * Note once again that since we are using reciprocals of distance values our * proportion is already the correct intensity, and does not need to be @@ -722,7 +724,6 @@ int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*f float *buf, int buf_x, int buf_y) { int i; /* i: Loop counter. */ - struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */ struct poly_vert *fe; /* fe: Pointer to a list of integer buffer-space feather vertex coords. */ struct r_fill_context ctx = {0}; @@ -737,10 +738,6 @@ int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*f * In the event of a failure to allocate the memory, return 0, so this error can * be distinguished as a memory allocation error. */ - if ((ply = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num_base_verts))) == NULL) { - return(0); - } - if ((fe = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num_feather_verts))) == NULL) { return(0); } @@ -753,10 +750,6 @@ int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*f * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel * drawn will be 1.0f in value, there is no anti-aliasing. */ - for (i = 0; i < num_base_verts; i++) { /* Loop over all verts. */ - ply[i].x = (int)((base_verts[i][0] * buf_x_f) + 0.5f); /* Range expand normalized X to integer buffer-space X. */ - ply[i].y = (int)((base_verts[i][1] * buf_y_f) + 0.5f); /* Range expand normalized Y to integer buffer-space Y. */ - } for (i = 0; i < num_feather_verts; i++) { /* Loop over all verts. */ fe[i].x = (int)((feather_verts[i][0] * buf_x_f) + 0.5f); /* Range expand normalized X to integer buffer-space X. */ fe[i].y = (int)((feather_verts[i][1] * buf_y_f) + 0.5f); /* Range expand normalized Y to integer buffer-space Y. */ @@ -767,8 +760,7 @@ int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*f ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ /* Call our rasterizer, passing in the integer coords for each vert. */ - i = rast_scan_feather(&ctx, ply, num_base_verts, fe, num_feather_verts); - free(ply); /* Free the memory allocated for the integer coordinate table. */ + i = rast_scan_feather(&ctx, base_verts, num_base_verts, fe, feather_verts, num_feather_verts); free(fe); return i; /* Return the value returned by the rasterizer. */ } From 34c52b010e914578982142a70b80e14357e4c831 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Thu, 31 May 2012 19:53:35 +0000 Subject: [PATCH 144/360] speedup normalized buffer space pixel position calculations... now incremental adds rather than full per pixel evaluation. --- intern/raskter/raskter.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index 33da097f063..3d1785e2263 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -464,7 +464,8 @@ int rast_scan_feather(struct r_fill_context *ctx, float idist; // idist = current inner edge distance float dx; // dx = X-delta (used for distance proportion calculation) float dy; // dy = Y-delta (used for distance proportion calculation) - + float xpxw; + float ypxh; /* * If the number of verts specified to render as a polygon is less than 3, @@ -587,17 +588,21 @@ int rast_scan_feather(struct r_fill_context *ctx, mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1; if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) { + xpxw = (1.0f / (float)(ctx->rb.sizex)); + ypxh = (1.0f / (float)(ctx->rb.sizey)); + t = ((float)((cpxl - spxl) % ctx->rb.sizex) + 0.5f) * xpxw; + fsz = ((float)(y_curr) + 0.5f) * ypxh; /* draw the pixels. */ - for (; cpxl <= mpxl; cpxl++) { + for (; cpxl <= mpxl; cpxl++, t += xpxw) { //do feather check // first check that pixel isn't already full, and only operate if it is not if (*cpxl < 0.9999f) { /* * Begin modified code from double edge mask compo node... */ - t = ((float)((cpxl - spxl) % ctx->rb.sizex) + 0.5f) * (1.0f / (float)(ctx->rb.sizex)); // calculate column of pixel + //t = ((float)((cpxl - spxl) % ctx->rb.sizex) + 0.5f) * (1.0f / (float)(ctx->rb.sizex)); // calculate column of pixel - fsz = ((float)(y_curr) + 0.5) * (1.0f / (float)(ctx->rb.sizey)); // calculate row of pixel + //fsz = ((float)(y_curr) + 0.5) * (1.0f / (float)(ctx->rb.sizey)); // calculate row of pixel dmin = 2.0f; // reset min distance to edge pixel From 05ff63b09d9804a7699dd38d3b79bb6064904fde Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Thu, 31 May 2012 20:58:46 +0000 Subject: [PATCH 145/360] code and comment cleanup in feather region drawing code --- intern/raskter/raskter.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index 3d1785e2263..e30df66648b 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -597,13 +597,6 @@ int rast_scan_feather(struct r_fill_context *ctx, //do feather check // first check that pixel isn't already full, and only operate if it is not if (*cpxl < 0.9999f) { -/* - * Begin modified code from double edge mask compo node... - */ - //t = ((float)((cpxl - spxl) % ctx->rb.sizex) + 0.5f) * (1.0f / (float)(ctx->rb.sizex)); // calculate column of pixel - - //fsz = ((float)(y_curr) + 0.5) * (1.0f / (float)(ctx->rb.sizey)); // calculate row of pixel - dmin = 2.0f; // reset min distance to edge pixel for (a = 0; a < num_feather_verts; a++) { // loop through all outer edge buffer pixels @@ -645,9 +638,6 @@ int rast_scan_feather(struct r_fill_context *ctx, /* set intensity, do the += so overlapping gradients are additive */ *cpxl = (idist / (idist + odist)); -/* - * End modified code from double edge mask node - */ } } } From 6aeb3ddb20e607387d6f52db48c8327930d3b6d9 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Thu, 31 May 2012 21:56:41 +0000 Subject: [PATCH 146/360] small code refactor to remove redundant calculations --- intern/raskter/raskter.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index e30df66648b..e565348cc79 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -464,8 +464,8 @@ int rast_scan_feather(struct r_fill_context *ctx, float idist; // idist = current inner edge distance float dx; // dx = X-delta (used for distance proportion calculation) float dy; // dy = Y-delta (used for distance proportion calculation) - float xpxw; - float ypxh; + float xpxw = (1.0f / (float)(ctx->rb.sizex)); // xpxw = normalized pixel width + float ypxh = (1.0f / (float)(ctx->rb.sizey)); // ypxh = normalized pixel height /* * If the number of verts specified to render as a polygon is less than 3, @@ -588,8 +588,6 @@ int rast_scan_feather(struct r_fill_context *ctx, mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1; if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) { - xpxw = (1.0f / (float)(ctx->rb.sizex)); - ypxh = (1.0f / (float)(ctx->rb.sizey)); t = ((float)((cpxl - spxl) % ctx->rb.sizex) + 0.5f) * xpxw; fsz = ((float)(y_curr) + 0.5f) * ypxh; /* draw the pixels. */ From 7f6dd1861d5f97375ae23d72dbd13d493ff97a2a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 1 Jun 2012 05:46:09 +0000 Subject: [PATCH 147/360] style cleanup --- intern/raskter/raskter.c | 9 ++-- source/blender/blenkernel/intern/mask.c | 63 +++++++++++++------------ source/blender/editors/mask/mask_ops.c | 2 +- 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index e565348cc79..2e57ef746c3 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -305,12 +305,13 @@ int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_ e_curr = e_curr->e_next; mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1; - if((y_curr >= 0) && (y_curr < ctx->rb.sizey)){ + if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) { /* draw the pixels. */ - for (; cpxl <= mpxl; cpxl++){ - if(*cpxl < 0.5f){ + for (; cpxl <= mpxl; cpxl++) { + if (*cpxl < 0.5f) { *cpxl = 1.0f; - }else{ + } + else { *cpxl = 0.0f; } } diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index e6f328546f5..c510dce12ec 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -223,7 +223,7 @@ float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point, i MaskSplinePoint *point, *prev; float (*diff_points)[2], (*fp)[2]; int a, len, resol; - if(!dynamic_res){ + if (!dynamic_res) { max_dseg_len = 0.01f; } resol = BKE_mask_spline_resolution(spline, max_dseg_len); @@ -284,13 +284,13 @@ float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point, i return diff_points; } -float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point, int dynamic_res, float max_dseg_len))[2] +float (*BKE_mask_spline_feather_differentiated_points(MaskSpline * spline, int *tot_feather_point, int dynamic_res, float max_dseg_len))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); float (*feather)[2], (*fp)[2]; int i, j, tot, resol; - if(!dynamic_res){ + if (!dynamic_res) { max_dseg_len = 0.005f; } resol = BKE_mask_spline_feather_resolution(spline, max_dseg_len); @@ -320,7 +320,7 @@ float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *t return feather; } -float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2] +float (*BKE_mask_spline_feather_points(MaskSpline * spline, int *tot_feather_point))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); @@ -1085,8 +1085,8 @@ void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplineP MaskSplinePoint *prev_point, *next_point; const char h_back[2] = {point->bezt.h1, point->bezt.h2}; const float length_average = (do_recalc_length) ? 0.0f /* dummy value */ : - (len_v3v3(point->bezt.vec[0], point->bezt.vec[1]) + - len_v3v3(point->bezt.vec[1], point->bezt.vec[2])) / 2.0f; + (len_v3v3(point->bezt.vec[0], point->bezt.vec[1]) + + len_v3v3(point->bezt.vec[1], point->bezt.vec[2])) / 2.0f; BKE_mask_get_handle_point_adjacent(mask, spline, point, &prev_point, &next_point); @@ -1142,11 +1142,11 @@ void BKE_mask_update_deform(Mask *mask) const int i_next = (i + 1) % spline->tot_point; BezTriple *bezt_prev = &spline->points[i_prev].bezt; - BezTriple *bezt = &spline->points[i ].bezt; + BezTriple *bezt = &spline->points[i].bezt; BezTriple *bezt_next = &spline->points[i_next].bezt; BezTriple *bezt_def_prev = &spline->points_deform[i_prev].bezt; - BezTriple *bezt_def = &spline->points_deform[i ].bezt; + BezTriple *bezt_def = &spline->points_deform[i].bezt; BezTriple *bezt_def_next = &spline->points_deform[i_next].bezt; float w_src[4]; @@ -1203,7 +1203,7 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) int found; if ((found = BKE_mask_layer_shape_find_frame_range(masklay, (int)ctime, - &masklay_shape_a, &masklay_shape_b))) + &masklay_shape_a, &masklay_shape_b))) { if (found == 1) { #if 0 @@ -1220,7 +1220,7 @@ void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe) masklay_shape_a->frame, masklay_shape_b->frame); #endif BKE_mask_layer_shape_to_mask_interp(masklay, masklay_shape_a, masklay_shape_b, - (ctime - masklay_shape_a->frame) / w); + (ctime - masklay_shape_a->frame) / w); } else { /* always fail, should never happen */ @@ -1410,9 +1410,9 @@ BLI_INLINE void interp_v2_v2v2_flfl(float target[2], const float a[2], const flo /* linear interpolation only */ void BKE_mask_layer_shape_to_mask_interp(MaskLayer *masklay, - MaskLayerShape *masklay_shape_a, - MaskLayerShape *masklay_shape_b, - const float fac) + MaskLayerShape *masklay_shape_a, + MaskLayerShape *masklay_shape_b, + const float fac) { int tot = BKE_mask_layer_shape_totvert(masklay); if (masklay_shape_a->tot_vert == tot && masklay_shape_b->tot_vert == tot) { @@ -1462,8 +1462,8 @@ MaskLayerShape *BKE_mask_layer_shape_find_frame(MaskLayer *masklay, int frame) /* when returning 2 - the frame isnt found but before/after frames are */ int BKE_mask_layer_shape_find_frame_range(MaskLayer *masklay, int frame, - MaskLayerShape **r_masklay_shape_a, - MaskLayerShape **r_masklay_shape_b) + MaskLayerShape **r_masklay_shape_a, + MaskLayerShape **r_masklay_shape_b) { MaskLayerShape *masklay_shape; @@ -1516,16 +1516,16 @@ MaskLayerShape *BKE_mask_layer_shape_varify_frame(MaskLayer *masklay, int frame) } #if 0 + { + MaskLayerShape *masklay_shape; + int i = 0; + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) { - MaskLayerShape *masklay_shape; - int i = 0; - for (masklay_shape = masklay->splines_shapes.first; - masklay_shape; - masklay_shape = masklay_shape->next) - { - printf("mask %d, %d\n", i++, masklay_shape->frame); - } + printf("mask %d, %d\n", i++, masklay_shape->frame); } + } #endif return masklay_shape; @@ -1554,7 +1554,7 @@ void BKE_mask_layer_shape_sort(MaskLayer *masklay) } int BKE_mask_layer_shape_spline_from_index(MaskLayer *masklay, int index, - MaskSpline **r_masklay_shape, int *r_index) + MaskSpline **r_masklay_shape, int *r_index) { MaskSpline *spline; @@ -1609,16 +1609,16 @@ static void interp_weights_uv_v2_apply(const float uv[2], float r_pt[2], const f /* when a now points added - resize all shapekey array */ void BKE_mask_layer_shape_changed_add(MaskLayer *masklay, int index, - int do_init, int do_init_interpolate) + int do_init, int do_init_interpolate) { MaskLayerShape *masklay_shape; /* spline index from masklay */ MaskSpline *spline; - int spline_point_index; + int spline_point_index; if (BKE_mask_layer_shape_spline_from_index(masklay, index, - &spline, &spline_point_index)) + &spline, &spline_point_index)) { /* sanity check */ /* the point has already been removed in this array so subtract one when comparing with the shapes */ @@ -1767,7 +1767,7 @@ static void linear_clamp_vn_vn(float *array, const int size) while (i--) { if (*arr <= 0.0f) *arr = 0.0f; else if (*arr >= 1.0f) *arr = 1.0f; - else *arr = srgb_to_linearrgb(*arr); + else *arr = srgb_to_linearrgb(*arr); arr--; } } @@ -1782,9 +1782,10 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) float *buffer_tmp = MEM_mallocN(sizeof(float) * buffer_size, __func__); float max_dseg_len = 0.0f; - if(width >= height){ + if (width >= height) { max_dseg_len = (float)(width); - }else{ + } + else { max_dseg_len = (float)(height); } max_dseg_len = 1.0f / max_dseg_len; @@ -1807,7 +1808,7 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) int tot_diff_feather_points; diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point, 1, max_dseg_len); - if(tot_diff_point){ + if (tot_diff_point) { diff_feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_diff_feather_points, 1, max_dseg_len); } diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index e56eb181a51..4c96e70e710 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1088,7 +1088,7 @@ static int add_vertex_extrude(bContext *C, Mask *mask, MaskLayer *masklay, const MASKPOINT_DESEL_ALL(point); if ((spline->flag & MASK_SPLINE_CYCLIC) || - (point_index > 0 && point_index != spline->tot_point - 1)) + (point_index > 0 && point_index != spline->tot_point - 1)) { BKE_mask_calc_tangent_polyline(mask, spline, point, tangent_point); sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]); From 70df1956a9fc3a661264b9b9fecfa30631fd6b67 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 1 Jun 2012 11:44:46 +0000 Subject: [PATCH 148/360] Small refactor of mask sliding operator Also aspect ratio correction is not needed for BKE_mask_point_set_handle --- source/blender/blenkernel/BKE_mask.h | 2 +- source/blender/blenkernel/intern/mask.c | 17 ++-------- source/blender/editors/mask/mask_ops.c | 33 +++++++++---------- .../editors/transform/transform_conversions.c | 2 +- 4 files changed, 20 insertions(+), 34 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 8fc979e941b..347469ad92d 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -66,7 +66,7 @@ float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feath int BKE_mask_point_has_handle(struct MaskSplinePoint *point); void BKE_mask_point_handle(struct MaskSplinePoint *point, float handle[2]); void BKE_mask_point_set_handle(struct MaskSplinePoint *point, float loc[2], int keep_direction, - float aspx, float aspy, float orig_handle[2], float orig_vec[3][3]); + float orig_handle[2], float orig_vec[3][3]); float *BKE_mask_point_segment_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, int *tot_diff_point); float *BKE_mask_point_segment_feather_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, int *tot_feather_point); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index c510dce12ec..3b7e69c9f29 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -386,7 +386,7 @@ void BKE_mask_point_handle(MaskSplinePoint *point, float handle[2]) handle[1] = (point->bezt.vec[1][1] - vec[0]); } -void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_direction, float aspx, float aspy, +void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_direction, float orig_handle[2], float orig_vec[3][3]) { BezTriple *bezt = &point->bezt; @@ -396,11 +396,6 @@ void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_di sub_v2_v2v2(v1, loc, orig_vec[1]); sub_v2_v2v2(v2, orig_handle, orig_vec[1]); - v1[0] *= aspx; - v1[1] *= aspy; - v2[0] *= aspx; - v2[1] *= aspx; - project_v2_v2v2(vec, v1, v2); if (dot_v2v2(v2, vec) > 0) { @@ -408,14 +403,8 @@ void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_di sub_v2_v2v2(v1, orig_vec[0], orig_vec[1]); - v1[0] *= aspx; - v1[1] *= aspy; - mul_v2_fl(v1, len / len_v2(v1)); - v1[0] /= aspx; - v1[1] /= aspy; - add_v2_v2v2(bezt->vec[0], bezt->vec[1], v1); sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v1); } @@ -427,8 +416,8 @@ void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_di else { sub_v2_v2v2(v1, loc, bezt->vec[1]); - v2[0] = -v1[1] * aspy / aspx; - v2[1] = v1[0] * aspx / aspy; + v2[0] = -v1[1]; + v2[1] = v1[0]; add_v2_v2v2(bezt->vec[0], bezt->vec[1], v2); sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v2); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 4c96e70e710..0da761940eb 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -551,7 +551,6 @@ typedef struct SlidePointData { MaskSplinePoint *point; MaskSplinePointUW *uw; float handle[2], no[2], feather[2]; - float aspx, aspy; int width, height; float weight; @@ -609,8 +608,6 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) customdata->action = action; customdata->uw = uw; - ED_mask_aspect(C, &customdata->aspx, &customdata->aspy); - if (uw) { float co[2]; @@ -732,7 +729,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) add_v2_v2(offco, data->co); add_v2_v2(offco, delta); - BKE_mask_point_set_handle(data->point, offco, data->curvature_only, data->aspx, data->aspy, data->handle, data->vec); + BKE_mask_point_set_handle(data->point, offco, data->curvature_only, data->handle, data->vec); } else if (data->action == SLIDE_ACTION_POINT) { float delta[2]; @@ -747,20 +744,21 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) } else if (data->action == SLIDE_ACTION_FEATHER) { float vec[2], no[2], p[2], c[2], w, offco[2]; - float *weight; + float *weight = NULL; add_v2_v2v2(offco, data->feather, dco); if (data->uw) { float u = projection_on_spline(data->spline, data->point, data->uw->u, offco); - if (u > 0.0f && u < 1.0f) + if (u > 0.0f && u < 1.0f) { data->uw->u = u; - data->uw = BKE_mask_point_sort_uw(data->point, data->uw); - weight = &data->uw->w; - BKE_mask_point_normal(data->spline, data->point, data->uw->u, no); - BKE_mask_point_segment_co(data->spline, data->point, data->uw->u, p); + data->uw = BKE_mask_point_sort_uw(data->point, data->uw); + weight = &data->uw->w; + BKE_mask_point_normal(data->spline, data->point, data->uw->u, no); + BKE_mask_point_segment_co(data->spline, data->point, data->uw->u, p); + } } else { weight = &bezt->weight; @@ -768,18 +766,17 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) copy_v2_v2(p, bezt->vec[1]); } - sub_v2_v2v2(c, offco, p); - project_v2_v2v2(vec, c, no); + if (weight) { + sub_v2_v2v2(c, offco, p); + project_v2_v2v2(vec, c, no); - vec[0] *= data->aspx; - vec[1] *= data->aspy; + w = len_v2(vec); - w = len_v2(vec); + if (dot_v2v2(no, vec) <= 0.0f) + w = 0.0f; - if (dot_v2v2(no, vec) > 0.0f) *weight = w; - else - *weight = 0; + } } WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 23a88e6e547..8a7caeb3060 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -6071,7 +6071,7 @@ void flushTransMasking(TransInfo *t) td->loc2d[1]= td->loc[1]*invy; if (tdm->is_handle) - BKE_mask_point_set_handle(tdm->point, td->loc2d, t->flag & T_ALT_TRANSFORM, aspx, aspy, tdm->orig_handle, tdm->vec); + BKE_mask_point_set_handle(tdm->point, td->loc2d, t->flag & T_ALT_TRANSFORM, tdm->orig_handle, tdm->vec); } } From ecac5aef754e42877e560aa36a7f0a9139c7bf36 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 1 Jun 2012 11:44:52 +0000 Subject: [PATCH 149/360] Changes to mask point slide operator: - Original slide would create overall feather for spline - Sliding of feather points for already defined feather would control individual feather points weight - Sliding of feather points with Ctrl hold down would switch to overall feather control --- source/blender/blenkernel/BKE_mask.h | 1 + source/blender/blenkernel/intern/mask.c | 20 ++++ source/blender/editors/mask/mask_ops.c | 122 ++++++++++++++++++++++-- 3 files changed, 133 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 347469ad92d..03c0b45f84c 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -50,6 +50,7 @@ void BKE_mask_layer_remove(struct Mask *mask, struct MaskLayer *masklay); void BKE_mask_layer_free(struct MaskLayer *masklay); void BKE_mask_spline_free(struct MaskSpline *spline); +struct MaskSpline *BKE_mask_spline_copy(struct MaskSpline *spline); void BKE_mask_point_free(struct MaskSplinePoint *point); void BKE_mask_layer_unique_name(struct Mask *mask, struct MaskLayer *masklay); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 3b7e69c9f29..31da0dae1b3 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -736,6 +736,26 @@ void BKE_mask_spline_free(MaskSpline *spline) MEM_freeN(spline); } +MaskSpline *BKE_mask_spline_copy(MaskSpline *spline) +{ + MaskSpline *nspline = MEM_callocN(sizeof(MaskSpline), "new spline"); + int i; + + *nspline = *spline; + + nspline->points_deform = NULL; + nspline->points = MEM_dupallocN(nspline->points); + + for (i = 0; i < nspline->tot_point; i++) { + MaskSplinePoint *point = &nspline->points[i]; + + if (point->uw) + point->uw = MEM_dupallocN(point->uw); + } + + return nspline; +} + void BKE_mask_layer_shape_free(MaskLayerShape *masklay_shape) { MEM_freeN(masklay_shape->data); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 0da761940eb..f35d58219e2 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -547,7 +547,7 @@ typedef struct SlidePointData { Mask *mask; MaskLayer *masklay; - MaskSpline *spline; + MaskSpline *spline, *orig_spline; MaskSplinePoint *point; MaskSplinePointUW *uw; float handle[2], no[2], feather[2]; @@ -555,8 +555,29 @@ typedef struct SlidePointData { float weight; short curvature_only, accurate; + short initial_feather, overall_feather; } SlidePointData; +static int slide_point_check_initial_feather(MaskSpline *spline) +{ + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + int j; + + if (point->bezt.weight != 0.0f) + return FALSE; + + for (j = 0; j < point->tot_uw; j++) { + if (point->uw[j].w != 0.0f) + return FALSE; + } + } + + return TRUE; +} + static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) { Mask *mask = CTX_data_edit_mask(C); @@ -622,12 +643,18 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) } else { BezTriple *bezt = &point->bezt; + BKE_mask_point_normal(spline, point, 0.0f, customdata->no); customdata->feather[0] = bezt->vec[1][0] + customdata->no[0] * bezt->weight; customdata->feather[1] = bezt->vec[1][1] + customdata->no[1] * bezt->weight; + + customdata->weight = bezt->weight; } + if (customdata->action == SLIDE_ACTION_FEATHER) + customdata->initial_feather = slide_point_check_initial_feather(spline); + copy_m3_m3(customdata->vec, point->bezt.vec); if (BKE_mask_point_has_handle(point)) BKE_mask_point_handle(point, customdata->handle); @@ -676,22 +703,68 @@ static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_PASS_THROUGH; } +static void slide_point_delta_all_feather(SlidePointData *data, float delta) +{ + int i; + + for (i = 0; i < data->spline->tot_point; i++) { + MaskSplinePoint *point = &data->spline->points[i]; + MaskSplinePoint *orig_point = &data->orig_spline->points[i]; + int j; + + point->bezt.weight = orig_point->bezt.weight + delta; + if (point->bezt.weight < 0.0f) + point->bezt.weight = 0.0f; + + for (j = 0; j < point->tot_uw; j++) { + point->uw[j].w = orig_point->uw[j].w + delta; + if (point->uw[j].w < 0.0f) + point->uw[j].w = 0.0f; + } + } +} + +static void slide_point_restore_spline(SlidePointData *data) +{ + int i; + + for (i = 0; i < data->spline->tot_point; i++) { + MaskSplinePoint *point = &data->spline->points[i]; + MaskSplinePoint *orig_point = &data->orig_spline->points[i]; + int j; + + point->bezt = orig_point->bezt; + + for (j = 0; j < point->tot_uw; j++) + point->uw[j] = orig_point->uw[j]; + } +} + static void cancel_slide_point(SlidePointData *data) { /* cancel sliding */ - if (data->action == SLIDE_ACTION_FEATHER) { - if (data->uw) - data->uw->w = data->weight; - else - data->point->bezt.weight = data->weight; + + if (data->orig_spline) { + slide_point_restore_spline(data); } else { - copy_m3_m3(data->point->bezt.vec, data->vec); + if (data->action == SLIDE_ACTION_FEATHER) { + if (data->uw) + data->uw->w = data->weight; + else + data->point->bezt.weight = data->weight; + } + else { + copy_m3_m3(data->point->bezt.vec, data->vec); + } } } static void free_slide_point_data(SlidePointData *data) { + if (data->orig_spline) + BKE_mask_spline_free(data->orig_spline); + MEM_freeN(data); } @@ -706,8 +779,12 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) case RIGHTCTRLKEY: case LEFTSHIFTKEY: case RIGHTSHIFTKEY: - if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) - data->curvature_only = event->val == KM_PRESS; + if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) { + if (data->action == SLIDE_ACTION_FEATHER) + data->overall_feather = event->val == KM_PRESS; + else + data->curvature_only = event->val == KM_PRESS; + } if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) data->accurate = event->val == KM_PRESS; @@ -745,6 +822,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) else if (data->action == SLIDE_ACTION_FEATHER) { float vec[2], no[2], p[2], c[2], w, offco[2]; float *weight = NULL; + int overall_feather = data->overall_feather || data->initial_feather; add_v2_v2v2(offco, data->feather, dco); @@ -775,7 +853,31 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) if (dot_v2v2(no, vec) <= 0.0f) w = 0.0f; - *weight = w; + if (overall_feather) { + float delta = w - data->weight; + + if (data->orig_spline == NULL) { + /* restore weight for currently sliding point, so orig_spline would be created + * with original weights used + */ + *weight = data->weight; + + data->orig_spline = BKE_mask_spline_copy(data->spline); + } + + slide_point_delta_all_feather(data, delta); + } + else { + if (data->orig_spline) { + /* restore possible overall feather changes */ + slide_point_restore_spline(data); + + BKE_mask_spline_free(data->orig_spline); + data->orig_spline = NULL; + } + + *weight = w; + } } } From 1450bc244fbaeb518d8826b216bd1b4b47bef2af Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 1 Jun 2012 12:25:18 +0000 Subject: [PATCH 150/360] Cleanup in spline diffirintiation code - encapsulate max segment length to resolution calculation functions rather than doing this from callee. Also switch mask drawing code do the same spline resolution calculation as used for compositor (which takes frame dimensions into account). --- source/blender/blenkernel/BKE_mask.h | 19 +++++-- source/blender/blenkernel/intern/mask.c | 69 ++++++++++++++++--------- source/blender/editors/mask/mask_draw.c | 23 ++++++--- source/blender/editors/mask/mask_ops.c | 6 ++- 4 files changed, 81 insertions(+), 36 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 03c0b45f84c..1eb130f1713 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -57,10 +57,14 @@ void BKE_mask_layer_unique_name(struct Mask *mask, struct MaskLayer *masklay); /* splines */ struct MaskSpline *BKE_mask_spline_add(struct MaskLayer *masklay); -int BKE_mask_spline_resolution(struct MaskSpline *spline, float max_seg_len); -float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point, int dynamic_res, float max_dseg_len))[2]; -float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point, int dynamic_res, float max_dseg_len))[2]; +float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point))[2]; +float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point))[2]; + +float (*BKE_mask_spline_differentiate_with_resolution(struct MaskSpline *spline, int width, int height, int *tot_diff_point))[2]; +float (*BKE_mask_spline_feather_differentiated_points_with_resolution(struct MaskSpline *spline, + int width, int height, int *tot_feather_point))[2]; + float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point))[2]; /* point */ @@ -68,9 +72,18 @@ int BKE_mask_point_has_handle(struct MaskSplinePoint *point); void BKE_mask_point_handle(struct MaskSplinePoint *point, float handle[2]); void BKE_mask_point_set_handle(struct MaskSplinePoint *point, float loc[2], int keep_direction, float orig_handle[2], float orig_vec[3][3]); + float *BKE_mask_point_segment_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, int *tot_diff_point); float *BKE_mask_point_segment_feather_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, int *tot_feather_point); + +float *BKE_mask_point_segment_diff_with_resolution(struct MaskSpline *spline, struct MaskSplinePoint *point, + int width, int height, int *tot_diff_point); + +float *BKE_mask_point_segment_feather_diff_with_resolution(struct MaskSpline *spline, struct MaskSplinePoint *point, + int width, int height, + int *tot_feather_point); + void BKE_mask_point_segment_co(struct MaskSpline *spline, struct MaskSplinePoint *point, float u, float co[2]); void BKE_mask_point_normal(struct MaskSpline *spline, struct MaskSplinePoint *point, float u, float n[2]); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 31da0dae1b3..6b57b22311d 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -149,11 +149,18 @@ MaskSpline *BKE_mask_spline_add(MaskLayer *masklay) return spline; } -int BKE_mask_spline_resolution(MaskSpline *spline, float max_seg_len) +static int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height) { - const float max_segment = max_seg_len; + float max_segment = 0.01f; int i, resol = 1; + if (width != 0 && height != 0) { + if (width >= height) + max_segment = 1.0f / (float) width; + else + max_segment = 1.0f / (float) height; + } + for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; MaskSplinePoint *next_point; @@ -186,10 +193,10 @@ int BKE_mask_spline_resolution(MaskSpline *spline, float max_seg_len) return resol; } -int BKE_mask_spline_feather_resolution(MaskSpline *spline, float max_seg_len) +static int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height) { const float max_segment = 0.005; - int resol = BKE_mask_spline_resolution(spline, max_seg_len); + int resol = BKE_mask_spline_resolution(spline, width, height); float max_jump = 0.0f; int i; @@ -216,18 +223,13 @@ int BKE_mask_spline_feather_resolution(MaskSpline *spline, float max_seg_len) return resol; } -float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point, int dynamic_res, float max_dseg_len))[2] +float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, int width, int height, int *tot_diff_point))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); MaskSplinePoint *point, *prev; float (*diff_points)[2], (*fp)[2]; - int a, len, resol; - if (!dynamic_res) { - max_dseg_len = 0.01f; - } - resol = BKE_mask_spline_resolution(spline, max_dseg_len); - + int a, len, resol = BKE_mask_spline_resolution(spline, width, height); if (spline->tot_point <= 1) { /* nothing to differentiate */ @@ -284,16 +286,18 @@ float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point, i return diff_points; } -float (*BKE_mask_spline_feather_differentiated_points(MaskSpline * spline, int *tot_feather_point, int dynamic_res, float max_dseg_len))[2] +float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[2] +{ + return BKE_mask_spline_differentiate_with_resolution(spline, 0, 0, tot_diff_point); +} + +float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline *spline, int width, int height, + int *tot_feather_point))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); float (*feather)[2], (*fp)[2]; - int i, j, tot, resol; - if (!dynamic_res) { - max_dseg_len = 0.005f; - } - resol = BKE_mask_spline_feather_resolution(spline, max_dseg_len); + int i, j, tot, resol = BKE_mask_spline_feather_resolution(spline, width, height); tot = resol * spline->tot_point; feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather diff points"); @@ -320,6 +324,11 @@ float (*BKE_mask_spline_feather_differentiated_points(MaskSpline * spline, int * return feather; } +float (*BKE_mask_spline_feather_differentiated_points(MaskSpline * spline, int *tot_feather_point))[2] +{ + return BKE_mask_spline_feather_differentiated_points_with_resolution(spline, 0, 0, tot_feather_point); +} + float (*BKE_mask_spline_feather_points(MaskSpline * spline, int *tot_feather_point))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); @@ -424,10 +433,12 @@ void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_di } } -float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_feather_point) +float *BKE_mask_point_segment_feather_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point, + int width, int height, + int *tot_feather_point) { float *feather, *fp; - int i, resol = BKE_mask_spline_feather_resolution(spline, 0.005f); + int i, resol = BKE_mask_spline_feather_resolution(spline, width, height); feather = fp = MEM_callocN(2 * resol * sizeof(float), "mask point spline feather diff points"); @@ -448,13 +459,18 @@ float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint * return feather; } -float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_diff_point) +float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_feather_point) +{ + return BKE_mask_point_segment_feather_diff_with_resolution(spline, point, 0, 0, tot_feather_point); +} + +float *BKE_mask_point_segment_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point, int width, int height, int *tot_diff_point) { MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); BezTriple *bezt, *next; float *diff_points, *fp; - int j, resol = BKE_mask_spline_resolution(spline, 0.01f); + int j, resol = BKE_mask_spline_resolution(spline, width, height); bezt = &point->bezt; @@ -484,6 +500,11 @@ float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, i return diff_points; } +float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_diff_point) +{ + return BKE_mask_point_segment_diff_with_resolution(spline, point, 0, 0, tot_diff_point); +} + void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float u, float co[2]) { MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); @@ -1816,9 +1837,11 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) float (*diff_feather_points)[2]; int tot_diff_feather_points; - diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point, 1, max_dseg_len); + diff_points = BKE_mask_spline_differentiate_with_resolution(spline, width, height, &tot_diff_point); if (tot_diff_point) { - diff_feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_diff_feather_points, 1, max_dseg_len); + diff_feather_points = + BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height, + &tot_diff_feather_points); } /* TODO, make this optional! */ diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 5b8bf1075b4..e580088e25b 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -323,7 +323,8 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot } static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, - const char draw_flag, const char draw_type) + const char draw_flag, const char draw_type, + int width, int height) { unsigned char rgb_tmp[4]; @@ -336,7 +337,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, int tot_feather_point; float (*feather_points)[2]; - diff_points = BKE_mask_spline_differentiate(spline, &tot_diff_point, 0, 0.0f); + diff_points = BKE_mask_spline_differentiate_with_resolution(spline, width, height, &tot_diff_point); if (!diff_points) return; @@ -347,7 +348,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - feather_points = BKE_mask_spline_feather_differentiated_points(spline, &tot_feather_point, 0, 0.0f); + feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height, &tot_feather_point); /* draw feather */ mask_spline_feather_color_get(masklay, spline, is_spline_sel, rgb_tmp); @@ -371,8 +372,8 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, (void)draw_type; } -static void draw_masklays(Mask *mask, - const char draw_flag, const char draw_type) +static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type, + int width, int height) { MaskLayer *masklay; @@ -386,7 +387,7 @@ static void draw_masklays(Mask *mask, for (spline = masklay->splines.first; spline; spline = spline->next) { /* draw curve itself first... */ - draw_spline_curve(masklay, spline, draw_flag, draw_type); + draw_spline_curve(masklay, spline, draw_flag, draw_type, width, height); // draw_spline_parents(masklay, spline); @@ -400,7 +401,7 @@ static void draw_masklays(Mask *mask, void *back = spline->points_deform; spline->points_deform = NULL; - draw_spline_curve(masklay, spline, draw_flag, draw_type); + draw_spline_curve(masklay, spline, draw_flag, draw_type, width, height); // draw_spline_parents(masklay, spline); draw_spline_points(masklay, spline); spline->points_deform = back; @@ -413,9 +414,15 @@ void ED_mask_draw(const bContext *C, const char draw_flag, const char draw_type) { Mask *mask = CTX_data_edit_mask(C); + int width, height; if (!mask) return; - draw_masklays(mask, draw_flag, draw_type); + /* TODO: for now, in the future better to make sure all utility functions + * are using const specifier for non-changing pointers + */ + ED_mask_size((bContext *)C, &width, &height); + + draw_masklays(mask, draw_flag, draw_type, width, height); } diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index f35d58219e2..410b8d10c88 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -348,14 +348,16 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_c float *diff_points; int tot_diff_point; - diff_points = BKE_mask_point_segment_diff(spline, cur_point, &tot_diff_point); + diff_points = BKE_mask_point_segment_diff_with_resolution(spline, cur_point, width, height, + &tot_diff_point); if (diff_points) { int i, tot_feather_point, tot_point; float *feather_points = NULL, *points; if (feather) { - feather_points = BKE_mask_point_segment_feather_diff(spline, cur_point, + feather_points = BKE_mask_point_segment_feather_diff_with_resolution(spline, cur_point, + width, height, &tot_feather_point); points = feather_points; From 54b2d1e1ffaee4384259c1f79c27d93d0042e302 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 1 Jun 2012 12:30:27 +0000 Subject: [PATCH 151/360] Small change to mask slide operator: if current weight goes below zero, higher weights are still getting affected by weight delta. --- source/blender/editors/mask/mask_ops.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 410b8d10c88..010066f705f 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -852,11 +852,13 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) w = len_v2(vec); - if (dot_v2v2(no, vec) <= 0.0f) - w = 0.0f; - if (overall_feather) { - float delta = w - data->weight; + float delta; + + if (dot_v2v2(no, vec) <= 0.0f) + w = -w; + + delta = w - data->weight; if (data->orig_spline == NULL) { /* restore weight for currently sliding point, so orig_spline would be created @@ -870,6 +872,9 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) slide_point_delta_all_feather(data, delta); } else { + if (dot_v2v2(no, vec) <= 0.0f) + w = 0.0f; + if (data->orig_spline) { /* restore possible overall feather changes */ slide_point_restore_spline(data); From 44693e709a8afe7dcf294688b8736291646d5a3b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 1 Jun 2012 12:34:44 +0000 Subject: [PATCH 152/360] Change in debug print for BKE_mask_spline_ensure_deform -- "alloc new spline" was a bit misleading, changed with "alloc new deform spline" --- source/blender/blenkernel/intern/mask.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 6b57b22311d..a7f6459f382 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1200,7 +1200,7 @@ void BKE_mask_spline_ensure_deform(MaskSpline *spline) // printf("SPLINE ALLOC %p %d\n", spline->points_deform, (int)(MEM_allocN_len(spline->points_deform) / sizeof(*spline->points_deform))); if (spline->points_deform == NULL || allocated_points != spline->tot_point) { - printf("alloc new spline\n"); + printf("alloc new deform spline\n"); if (spline->points_deform) { int i; From 851954fb49f176572bdcdf2a4b0349f979eac4dd Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 1 Jun 2012 13:05:05 +0000 Subject: [PATCH 153/360] Initial expose of tools into interface for mask editing. Maybe no ideal, but looks better than completely empty panels. --- release/scripts/startup/bl_ui/space_clip.py | 162 ++++++++++++++++---- 1 file changed, 132 insertions(+), 30 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index ab1bd817490..1c94b4db95e 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -44,9 +44,12 @@ class CLIP_HT_header(Header): sub.menu("CLIP_MT_clip") - if clip and sc.mode != 'MASKEDITING': - sub.menu("CLIP_MT_track") - sub.menu("CLIP_MT_reconstruction") + if clip: + if sc.mode == 'MASKEDITING': + sub.menu("CLIP_MT_mask") + else: + sub.menu("CLIP_MT_track") + sub.menu("CLIP_MT_reconstruction") if sc.mode != 'MASKEDITING': layout.prop(sc, "view", text="", expand=True) @@ -55,6 +58,14 @@ class CLIP_HT_header(Header): if sc.view == 'CLIP': layout.prop(sc, "mode", text="") layout.prop(sc, "pivot_point", text="", icon_only=True) + + if sc.mode == 'MASKEDITING': + toolsettings = context.tool_settings + + row = layout.row(align=True) + row.prop(toolsettings, "use_proportional_edit_mask", text="", icon_only=True) + if toolsettings.use_proportional_edit_objects: + row.prop(toolsettings, "proportional_edit_falloff", text="", icon_only=True) elif sc.view == 'GRAPH': row = layout.row(align=True) @@ -75,15 +86,8 @@ class CLIP_HT_header(Header): row.template_ID(sc, "clip", open='clip.open') if sc.mode == 'MASKEDITING': - toolsettings = context.tool_settings - row = layout.row() row.template_ID(sc, "mask", new="mask.new") - - row = layout.row(align=True) - row.prop(toolsettings, "use_proportional_edit_mask", text="", icon_only=True) - if toolsettings.use_proportional_edit_objects: - row.prop(toolsettings, "proportional_edit_falloff", text="", icon_only=True) if clip: tracking = clip.tracking @@ -116,6 +120,16 @@ class CLIP_PT_clip_view_panel: return clip and sc.view == 'CLIP' +class CLIP_PT_mask_view_panel: + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.view == 'CLIP' and sc.mode == 'MASKEDITING' + + class CLIP_PT_tracking_panel: @classmethod @@ -136,16 +150,6 @@ class CLIP_PT_reconstruction_panel: return clip and sc.mode == 'RECONSTRUCTION' and sc.view == 'CLIP' -class CLIP_PT_distortion_panel: - - @classmethod - def poll(cls, context): - sc = context.space_data - clip = sc.clip - - return clip and sc.mode == 'DISTORTION' and sc.view == 'CLIP' - - class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' @@ -372,11 +376,51 @@ class CLIP_PT_tools_object(CLIP_PT_reconstruction_panel, Panel): col.prop(settings, "object_distance") -class CLIP_PT_tools_grease_pencil(CLIP_PT_distortion_panel, Panel): +class CLIP_PT_tools_mask(CLIP_PT_mask_view_panel, Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Mask Tools" + + def draw(self, context): + layout = self.layout + + col = layout.column(align=True) + col.label(text="Transform:") + col.operator("transform.translate") + col.operator("transform.rotate") + col.operator("transform.resize", text="Scale") + + col = layout.column(align=True) + col.label(text="Spline:") + col.operator("mask.delete") + col.operator("mask.cyclic_toggle") + + col = layout.column(align=True) + col.label(text="Parenting:") + col.operator("mask.parent_set") + col.operator("mask.parent_clear") + + +class CLIP_PT_tools_grease_pencil(Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' bl_label = "Grease Pencil" + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + if not clip: + return False + + if sc.mode == 'DISTORTION': + return sc.view == 'CLIP' + elif sc.mode == 'MASKEDITING': + return True + + return False + def draw(self, context): layout = self.layout @@ -591,7 +635,7 @@ class CLIP_PT_mask_objects(Panel): active = mask.layers.active if active: layout.prop(active, "name") - + # blending row = layout.row(align=True) row.prop(active, "alpha") @@ -718,12 +762,11 @@ class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel): col.label(text="Display Aspect Ratio:") row = col.row() row.prop(clip, "display_aspect", text="") - + if sc.mode == 'MASKEDITING': col = layout.column() col.prop(sc, "mask_draw_type", text="") col.prop(sc, "show_mask_smooth") - class CLIP_PT_marker_display(CLIP_PT_clip_view_panel, Panel): @@ -900,6 +943,7 @@ class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel): layout.operator("clip.open", icon='FILESEL') + class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' @@ -1079,16 +1123,26 @@ class CLIP_MT_select(Menu): def draw(self, context): layout = self.layout + sc = context.space_data - layout.operator("clip.select_border") - layout.operator("clip.select_circle") + if sc.mode == 'MASKEDITING': + layout.operator("mask.select_border") + layout.operator("mask.select_circle") - layout.separator() + layout.separator() - layout.operator("clip.select_all").action = 'TOGGLE' - layout.operator("clip.select_all", text="Inverse").action = 'INVERT' + layout.operator("mask.select_all").action = 'TOGGLE' + layout.operator("mask.select_all", text="Inverse").action = 'INVERT' + else: + layout.operator("clip.select_border") + layout.operator("clip.select_circle") - layout.menu("CLIP_MT_select_grouped") + layout.separator() + + layout.operator("clip.select_all").action = 'TOGGLE' + layout.operator("clip.select_all", text="Inverse").action = 'INVERT' + + layout.menu("CLIP_MT_select_grouped") class CLIP_MT_select_grouped(Menu): @@ -1132,6 +1186,54 @@ class CLIP_MT_tracking_specials(Menu): props.action = 'UNLOCK' +class CLIP_MT_mask(Menu): + bl_label = "Mask" + + def draw(self, context): + layout = self.layout + + layout.operator("mask.delete") + + layout.separator() + layout.operator("mask.cyclic_toggle") + + layout.separator() + layout.operator("mask.parent_clear") + layout.operator("mask.parent_set") + + layout.separator() + layout.operator("mask.shape_key_clear") + layout.operator("mask.shape_key_insert") + + layout.separator() + layout.menu("CLIP_MT_mask_visibility") + layout.menu("CLIP_MT_mask_transform") + + +class CLIP_MT_mask_visibility(Menu): + bl_label = "Show/Hide" + + def draw(self, context): + layout = self.layout + + layout.operator("mask.hide_view_clear", text="Show Hidden") + layout.operator("mask.hide_view_set", text="Hide Selected") + + props = layout.operator("mask.hide_view_set", text="Hide Unselected") + props.unselected = True + + +class CLIP_MT_mask_transform(Menu): + bl_label = "Transform" + + def draw(self, context): + layout = self.layout + + layout.operator("transform.translate") + layout.operator("transform.rotate") + layout.operator("transform.resize") + + class CLIP_MT_camera_presets(Menu): """Predefined tracking camera intrinsics""" bl_label = "Camera Presets" From 7f0be018bf7da43cd7c0205513d60481ff8a8905 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 1 Jun 2012 13:46:38 +0000 Subject: [PATCH 154/360] Style cleanup of own recent changes --- source/blender/blenkernel/intern/mask.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index a7f6459f382..407216f5578 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -223,7 +223,8 @@ static int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int return resol; } -float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, int width, int height, int *tot_diff_point))[2] +float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, int width, int height, + int *tot_diff_point))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); @@ -464,7 +465,8 @@ float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint * return BKE_mask_point_segment_feather_diff_with_resolution(spline, point, 0, 0, tot_feather_point); } -float *BKE_mask_point_segment_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point, int width, int height, int *tot_diff_point) +float *BKE_mask_point_segment_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point, + int width, int height, int *tot_diff_point) { MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); @@ -1197,7 +1199,7 @@ void BKE_mask_update_deform(Mask *mask) void BKE_mask_spline_ensure_deform(MaskSpline *spline) { int allocated_points = (MEM_allocN_len(spline->points_deform) / sizeof(*spline->points_deform)); -// printf("SPLINE ALLOC %p %d\n", spline->points_deform, (int)(MEM_allocN_len(spline->points_deform) / sizeof(*spline->points_deform))); + // printf("SPLINE ALLOC %p %d\n", spline->points_deform, allocated_points); if (spline->points_deform == NULL || allocated_points != spline->tot_point) { printf("alloc new deform spline\n"); From 1691414d44402c2730334a215c11e64351873967 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Fri, 1 Jun 2012 13:49:49 +0000 Subject: [PATCH 155/360] re-remove XOR style writes from inner loop of rasterizer. is pointless and less flexible after blending was added at higher level. --- intern/raskter/raskter.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index 2e57ef746c3..279b1226e5f 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -308,12 +308,7 @@ int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_ if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) { /* draw the pixels. */ for (; cpxl <= mpxl; cpxl++) { - if (*cpxl < 0.5f) { - *cpxl = 1.0f; - } - else { - *cpxl = 0.0f; - } + *cpxl = 1.0f; } } } From 341a99189e661e1894e02d3e03698aa66939c3db Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 1 Jun 2012 14:42:55 +0000 Subject: [PATCH 156/360] Ignore track's disabled channels when requesting for pattern used in keying screen node --- source/blender/blenkernel/BKE_tracking.h | 2 ++ source/blender/blenkernel/intern/tracking.c | 30 ++++++++++++++----- .../operations/COM_KeyingScreenOperation.cpp | 2 +- .../nodes/node_composite_keyingscreen.c | 2 +- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 40a023101ba..e2f17a1dd18 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -74,6 +74,8 @@ void BKE_tracking_free(struct MovieTracking *tracking); struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int margin, int anchored, float pos[2], int origin[2]); +struct ImBuf *BKE_tracking_get_pattern_color_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker, int anchored); struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker); struct ImBuf *BKE_tracking_track_mask_get(struct MovieTracking *tracking, struct MovieTrackingTrack *track, diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index c51601202ff..8f181311a6f 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1177,7 +1177,8 @@ static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int g } static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - float min[2], float max[2], int margin, int anchored, float pos[2], int origin[2]) + float min[2], float max[2], int margin, int anchored, + int grayscale, float pos[2], int origin[2]) { ImBuf *tmpibuf; int x, y; @@ -1223,12 +1224,14 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki origin[1] = y1 - margin; } - if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || - (track->flag & TRACK_DISABLE_RED) || - (track->flag & TRACK_DISABLE_GREEN) || - (track->flag & TRACK_DISABLE_BLUE)) - { - disable_imbuf_channels(tmpibuf, track, TRUE /* grayscale */); + if (grayscale) { + if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || + (track->flag & TRACK_DISABLE_RED) || + (track->flag & TRACK_DISABLE_GREEN) || + (track->flag & TRACK_DISABLE_BLUE)) + { + disable_imbuf_channels(tmpibuf, track, TRUE /* grayscale */); + } } return tmpibuf; @@ -1244,7 +1247,18 @@ ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mo */ BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - return get_area_imbuf(ibuf, track, marker, pat_min, pat_max, margin, anchored, pos, origin); + return get_area_imbuf(ibuf, track, marker, pat_min, pat_max, margin, anchored, TRUE, pos, origin); +} + +ImBuf *BKE_tracking_get_pattern_color_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, + MovieTrackingMarker *marker, int anchored) +{ + float pat_min[2], pat_max[2]; + + /* see comment above */ + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + return get_area_imbuf(ibuf, track, marker, pat_min, pat_max, 0, anchored, FALSE, NULL, NULL); } ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker) diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp index f9c9216b75a..4f6abdcbc22 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -116,7 +116,7 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri while (track) { VoronoiSite *site = &sites[i]; MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenumber); - ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, 0, TRUE, NULL, NULL); + ImBuf *pattern_ibuf = BKE_tracking_get_pattern_color_imbuf(ibuf, track, marker, TRUE); int j; zero_v3(site->color); diff --git a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c index 5cbaf4ae2ba..b7ce621a9e1 100644 --- a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c +++ b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c @@ -91,7 +91,7 @@ static void compute_gradient_screen(RenderData *rd, NodeKeyingScreenData *keying while (track) { VoronoiSite *site = &sites[i]; MovieTrackingMarker *marker = BKE_tracking_get_marker(track, rd->cfra); - ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, 0, FALSE, NULL, NULL); + ImBuf *pattern_ibuf = BKE_tracking_get_pattern_color_imbuf(ibuf, track, marker, TRUE); int j; zero_v3(site->color); From db7fd6b94c206ec583c783d405fb07f819ee7e80 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Sat, 2 Jun 2012 00:01:59 +0000 Subject: [PATCH 157/360] small code cleanup in inner loop of rasterizer --- intern/raskter/raskter.c | 4 +--- intern/raskter/raskter.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index 279b1226e5f..152efb05cf0 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -307,9 +307,7 @@ int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_ if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) { /* draw the pixels. */ - for (; cpxl <= mpxl; cpxl++) { - *cpxl = 1.0f; - } + for (; cpxl <= mpxl; *cpxl++ = 1.0f); } } diff --git a/intern/raskter/raskter.h b/intern/raskter/raskter.h index 3292d4f8163..d94eb0b5886 100644 --- a/intern/raskter/raskter.h +++ b/intern/raskter/raskter.h @@ -50,7 +50,7 @@ extern "C" { int PLX_raskterize(float (*base_verts)[2], int num_base_verts, float *buf, int buf_x, int buf_y); - +int PLX_add_feather(float *base_verts, int num_base_verts, float *feather_verts, int num_feather_verts, float *buf, int buf_x, int buf_y, int negaive); int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*feather_verts)[2], int num_feather_verts, float *buf, int buf_x, int buf_y); From fea490c73e361409f4d52c787d9ceed9655adb13 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Sat, 2 Jun 2012 00:16:23 +0000 Subject: [PATCH 158/360] small code cleanup in rasterizer --- intern/raskter/raskter.h | 1 - 1 file changed, 1 deletion(-) diff --git a/intern/raskter/raskter.h b/intern/raskter/raskter.h index d94eb0b5886..e80ca1d41c4 100644 --- a/intern/raskter/raskter.h +++ b/intern/raskter/raskter.h @@ -50,7 +50,6 @@ extern "C" { int PLX_raskterize(float (*base_verts)[2], int num_base_verts, float *buf, int buf_x, int buf_y); -int PLX_add_feather(float *base_verts, int num_base_verts, float *feather_verts, int num_feather_verts, float *buf, int buf_x, int buf_y, int negaive); int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*feather_verts)[2], int num_feather_verts, float *buf, int buf_x, int buf_y); From 49a0f8f73b3056a59b87a04b102132e16857602f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 3 Jun 2012 19:39:19 +0000 Subject: [PATCH 159/360] - adding subdivided points now interpolates weights along the spline. - the handle lengths are now interpolated based on the new points projected location along the spline. --- source/blender/blenkernel/BKE_mask.h | 3 ++- source/blender/blenkernel/intern/mask.c | 35 +++++++++++++++++++------ source/blender/editors/mask/mask_ops.c | 15 ++++++----- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 1eb130f1713..5128141499e 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -110,7 +110,8 @@ void BKE_mask_update_display(struct Mask *mask, float ctime); void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime, const int do_newframe); void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene, const int do_newframe); void BKE_mask_parent_init(struct MaskParent *parent); -void BKE_mask_calc_handle_adjacent_length(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point); +void BKE_mask_calc_handle_adjacent_interp(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, + const float u); void BKE_mask_calc_tangent_polyline(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, float t[2]); void BKE_mask_calc_handle_point(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point); void BKE_mask_calc_handle_point_auto(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 407216f5578..5c7cdc7ef11 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1077,31 +1077,50 @@ static void enforce_dist_v2_v2fl(float v1[2], const float v2[2], const float dis } } -void BKE_mask_calc_handle_adjacent_length(Mask *mask, MaskSpline *spline, MaskSplinePoint *point) +void BKE_mask_calc_handle_adjacent_interp(Mask *mask, MaskSpline *spline, MaskSplinePoint *point, const float u) { /* TODO! - make this interpolate between siblings - not always midpoint! */ int length_tot = 0; float length_average = 0.0f; + float weight_average = 0.0f; + MaskSplinePoint *prev_point, *next_point; + + BLI_assert(u >= 0.0f && u <= 1.0f); + BKE_mask_get_handle_point_adjacent(mask, spline, point, &prev_point, &next_point); - if (prev_point) { - length_average += len_v2v2(prev_point->bezt.vec[0], prev_point->bezt.vec[1]); - length_tot++; - } + if (prev_point && next_point) { + length_average = ((len_v2v2(prev_point->bezt.vec[0], prev_point->bezt.vec[1]) * (1.0f - u)) + + (len_v2v2(next_point->bezt.vec[2], next_point->bezt.vec[1]) * u)); - if (next_point) { - length_average += len_v2v2(next_point->bezt.vec[2], next_point->bezt.vec[1]); - length_tot++; + weight_average = (prev_point->bezt.weight * (1.0f - u) + + next_point->bezt.weight * u); + length_tot = 1; + } + else { + if (prev_point) { + length_average += len_v2v2(prev_point->bezt.vec[0], prev_point->bezt.vec[1]); + weight_average += prev_point->bezt.weight; + length_tot++; + } + + if (next_point) { + length_average += len_v2v2(next_point->bezt.vec[2], next_point->bezt.vec[1]); + weight_average += next_point->bezt.weight; + length_tot++; + } } if (length_tot) { length_average /= (float)length_tot; + weight_average /= (float)length_tot; enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average); enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average); + point->bezt.weight = weight_average; } } diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 010066f705f..f86711d1355 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -946,7 +946,7 @@ void MASK_OT_slide_point(wmOperatorType *ot) /******************** add vertex *********************/ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point, - const float point_co[2], const float tangent[2], + const float point_co[2], const float tangent[2], const float u, MaskSplinePoint *reference_point, const short reference_adjacent) { MaskSplinePoint *prev_point = NULL; @@ -1008,7 +1008,7 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask add_v2_v2(bezt->vec[2], vec); if (reference_adjacent) { - BKE_mask_calc_handle_adjacent_length(mask, spline, new_point); + BKE_mask_calc_handle_adjacent_interp(mask, spline, new_point, u); } } else { @@ -1061,7 +1061,7 @@ static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, Mask sub_v2_v2(bezt->vec[2], vec); #else BKE_mask_calc_handle_point_auto(mask, spline, new_point, TRUE); - BKE_mask_calc_handle_adjacent_length(mask, spline, new_point); + BKE_mask_calc_handle_adjacent_interp(mask, spline, new_point, u); #endif } @@ -1097,8 +1097,9 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2]) MaskSplinePoint *point = NULL; const float threshold = 9; float tangent[2]; + float u; - if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &masklay, &spline, &point, NULL, tangent)) { + if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &masklay, &spline, &point, &u, tangent)) { MaskSplinePoint *new_point; int point_index = point - spline->points; @@ -1108,7 +1109,7 @@ static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2]) new_point = &spline->points[point_index + 1]; - setup_vertex_point(C, mask, spline, new_point, co, tangent, NULL, TRUE); + setup_vertex_point(C, mask, spline, new_point, co, tangent, u, NULL, TRUE); /* TODO - we could pass the spline! */ BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index + 1, TRUE, TRUE); @@ -1249,7 +1250,7 @@ static int add_vertex_extrude(bContext *C, Mask *mask, MaskLayer *masklay, const masklay->act_point = new_point; - setup_vertex_point(C, mask, spline, new_point, co, NULL, ref_point, FALSE); + setup_vertex_point(C, mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE); if (masklay->splines_shapes.first) { point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); @@ -1295,7 +1296,7 @@ static int add_vertex_new(bContext *C, Mask *mask, MaskLayer *masklay, const flo masklay->act_point = new_point; - setup_vertex_point(C, mask, spline, new_point, co, NULL, ref_point, FALSE); + setup_vertex_point(C, mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE); { int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); From 5cf12e9a7866fe4f4797da08ec8811860612e64b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Jun 2012 07:48:10 +0000 Subject: [PATCH 160/360] border select was removed from modal keymap by mistake --- source/blender/windowmanager/intern/wm_operators.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 0c4454c7f7b..d7d55885f37 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3937,6 +3937,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "UV_OT_select_border"); WM_modalkeymap_assign(keymap, "CLIP_OT_select_border"); WM_modalkeymap_assign(keymap, "CLIP_OT_graph_select_border"); + WM_modalkeymap_assign(keymap, "MASK_OT_select_border"); WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border"); From efaeeaf15b4a5e1a404fbe51be922d1f245b5d65 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Jun 2012 08:01:59 +0000 Subject: [PATCH 161/360] fix for selecting UW's --- source/blender/editors/mask/mask_select.c | 32 +++++++++++++++++------ 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 95c2808bc3e..323721e2dfe 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -240,9 +240,10 @@ static int select_exec(bContext *C, wmOperator *op) point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &is_handle, NULL); + if (extend == 0 && deselect == 0 && toggle == 0) + ED_mask_select_toggle_all(mask, SEL_DESELECT); + if (point) { - if (extend == 0 && deselect == 0 && toggle == 0) - ED_mask_select_toggle_all(mask, SEL_DESELECT); if (is_handle) { if (extend) { @@ -302,14 +303,29 @@ static int select_exec(bContext *C, wmOperator *op) MaskSplinePointUW *uw; if (ED_mask_feather_find_nearest(C, mask, co, threshold, &masklay, &spline, &point, &uw, NULL)) { - if (!extend) - ED_mask_select_toggle_all(mask, SEL_DESELECT); - if (uw) - uw->flag |= SELECT; + if (extend) { + masklay->act_spline = spline; + masklay->act_point = point; - masklay->act_spline = spline; - masklay->act_point = point; + if (uw) uw->flag |= SELECT; + } + else if (deselect) { + if (uw) uw->flag &= ~SELECT; + } + else { + masklay->act_spline = spline; + masklay->act_point = point; + + if (uw) { + if (!(uw->flag & SELECT)) { + uw->flag |= SELECT; + } + else if (toggle) { + uw->flag &= ~SELECT; + } + } + } ED_mask_select_flush_all(mask); From 90d7e25b4fe6191b0b433d4e1cf900b90811bd83 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Jun 2012 11:25:02 +0000 Subject: [PATCH 162/360] add select linked operator, works as with meshes. --- source/blender/blenkernel/BKE_mask.h | 4 +- source/blender/blenkernel/intern/mask.c | 10 +- source/blender/editors/mask/mask_editor.c | 8 ++ source/blender/editors/mask/mask_intern.h | 7 +- source/blender/editors/mask/mask_ops.c | 2 +- source/blender/editors/mask/mask_select.c | 145 +++++++++++++++++++--- 6 files changed, 148 insertions(+), 28 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 5128141499e..a26934f103b 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -91,8 +91,8 @@ float BKE_mask_point_weight(struct MaskSpline *spline, struct MaskSplinePoint *p struct MaskSplinePointUW *BKE_mask_point_sort_uw(struct MaskSplinePoint *point, struct MaskSplinePointUW *uw); void BKE_mask_point_add_uw(struct MaskSplinePoint *point, float u, float w); -void BKE_mask_point_select_set(struct MaskSplinePoint *point, int select); -void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, int select); +void BKE_mask_point_select_set(struct MaskSplinePoint *point, const short do_select); +void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const short do_select); /* general */ struct Mask *BKE_mask_new(const char *name); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 5c7cdc7ef11..52225a1fab0 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -673,11 +673,11 @@ void BKE_mask_point_add_uw(MaskSplinePoint *point, float u, float w) BKE_mask_point_sort_uw(point, &point->uw[point->tot_uw - 1]); } -void BKE_mask_point_select_set(MaskSplinePoint *point, int select) +void BKE_mask_point_select_set(MaskSplinePoint *point, const short do_select) { int i; - if (select) { + if (do_select) { MASKPOINT_SEL_ALL(point); } else { @@ -685,7 +685,7 @@ void BKE_mask_point_select_set(MaskSplinePoint *point, int select) } for (i = 0; i < point->tot_uw; i++) { - if (select) { + if (do_select) { point->uw[i].flag |= SELECT; } else { @@ -694,9 +694,9 @@ void BKE_mask_point_select_set(MaskSplinePoint *point, int select) } } -void BKE_mask_point_select_set_handle(MaskSplinePoint *point, int select) +void BKE_mask_point_select_set_handle(MaskSplinePoint *point, const short do_select) { - if (select) { + if (do_select) { MASKPOINT_SEL_HANDLE(point); } else { diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index 778990726e5..8e93086eec8 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -204,6 +204,8 @@ void ED_operatortypes_mask(void) WM_operatortype_append(MASK_OT_select_border); WM_operatortype_append(MASK_OT_select_lasso); WM_operatortype_append(MASK_OT_select_circle); + WM_operatortype_append(MASK_OT_select_linked_pick); + WM_operatortype_append(MASK_OT_select_linked); /* hide/reveal */ WM_operatortype_append(MASK_OT_hide_view_clear); @@ -258,6 +260,12 @@ void ED_keymap_mask(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + WM_keymap_add_item(keymap, "MASK_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "deselect", TRUE); + WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MASK_OT_select_circle", CKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index 5940b76abf0..af1ad96ee17 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -77,12 +77,15 @@ void MASK_OT_select_all(struct wmOperatorType *ot); void MASK_OT_select_border(struct wmOperatorType *ot); void MASK_OT_select_lasso(struct wmOperatorType *ot); void MASK_OT_select_circle(struct wmOperatorType *ot); +void MASK_OT_select_linked_pick(struct wmOperatorType *ot); +void MASK_OT_select_linked(struct wmOperatorType *ot); -int ED_mask_spline_select_check(struct MaskSplinePoint *points, int tot_point); +int ED_mask_spline_select_check(struct MaskSpline *spline); int ED_mask_layer_select_check(struct MaskLayer *masklay); int ED_mask_select_check(struct Mask *mask); -void ED_mask_layer_select_set(struct MaskLayer *masklay, int select); +void ED_mask_spline_select_set(struct MaskSpline *spline, const short do_select); +void ED_mask_layer_select_set(struct MaskLayer *masklay, const short do_select); void ED_mask_select_toggle_all(struct Mask *mask, int action); void ED_mask_select_flush_all(struct Mask *mask); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index f86711d1355..a6954fc8ac6 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1487,7 +1487,7 @@ static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) } for (spline = masklay->splines.first; spline; spline = spline->next) { - if (ED_mask_spline_select_check(spline->points, spline->tot_point)) { + if (ED_mask_spline_select_check(spline)) { spline->flag ^= MASK_SPLINE_CYCLIC; } } diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 323721e2dfe..18d745dcf7b 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -57,12 +57,13 @@ #include "mask_intern.h" /* own include */ -int ED_mask_spline_select_check(MaskSplinePoint *points, int tot_point) +/* 'check' select */ +int ED_mask_spline_select_check(MaskSpline *spline) { int i; - for (i = 0; i < tot_point; i++) { - MaskSplinePoint *point = &points[i]; + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; if (MASKPOINT_ISSEL_ANY(point)) return TRUE; @@ -80,7 +81,7 @@ int ED_mask_layer_select_check(MaskLayer *masklay) } for (spline = masklay->splines.first; spline; spline = spline->next) { - if (ED_mask_spline_select_check(spline->points, spline->tot_point)) { + if (ED_mask_spline_select_check(spline)) { return TRUE; } } @@ -101,29 +102,35 @@ int ED_mask_select_check(Mask *mask) return FALSE; } -void ED_mask_layer_select_set(MaskLayer *masklay, int select) +/* 'sel' select */ +void ED_mask_spline_select_set(MaskSpline *spline, const short do_select) +{ + int i; + + if (do_select) + spline->flag |= SELECT; + else + spline->flag &= ~SELECT; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + BKE_mask_point_select_set(point, do_select); + } +} + +void ED_mask_layer_select_set(MaskLayer *masklay, const short do_select) { MaskSpline *spline; if (masklay->restrictflag & MASK_RESTRICT_SELECT) { - if (select == TRUE) { + if (do_select == TRUE) { return; } } for (spline = masklay->splines.first; spline; spline = spline->next) { - int i; - - if (select) - spline->flag |= SELECT; - else - spline->flag &= ~SELECT; - - for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; - - BKE_mask_point_select_set(point, select); - } + ED_mask_spline_select_set(spline, do_select); } } @@ -659,3 +666,105 @@ void MASK_OT_select_circle(wmOperatorType *ot) RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); } + +static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + float co[2]; + int do_select = !RNA_boolean_get(op->ptr, "deselect"); + + int is_handle = 0; + const float threshold = 19; + int change = FALSE; + + ED_mask_mouse_pos(C, event, co); + + point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &is_handle, NULL); + + if (point) { + ED_mask_spline_select_set(spline, do_select); + masklay->act_spline = spline; + masklay->act_point = point; + + change = TRUE; + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_linked_pick(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked"; + ot->idname = "MASK_OT_select_linked_pick"; + ot->description = "(De)select all points linked to the curve under the mouse cursor"; + + /* api callbacks */ + ot->invoke = mask_select_linked_pick_invoke; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", ""); +} + +static int mask_select_linked_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + int change = FALSE; + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline)) { + ED_mask_spline_select_set(spline, TRUE); + change = TRUE; + } + } + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_linked(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked All"; + ot->idname = "MASK_OT_select_linked"; + ot->description = "Select all vertices linked to the active mesh"; + + /* api callbacks */ + ot->exec = mask_select_linked_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} From c357041e0a3a6291f9f07180b37ea80064cf23c5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Jun 2012 13:24:10 +0000 Subject: [PATCH 163/360] operator to switch direction --- release/scripts/startup/bl_ui/space_clip.py | 2 + source/blender/blenkernel/BKE_mask.h | 5 +- source/blender/blenkernel/intern/mask.c | 78 +++++++++++++++++++++ source/blender/editors/mask/mask_editor.c | 1 + source/blender/editors/mask/mask_intern.h | 1 + source/blender/editors/mask/mask_ops.c | 52 ++++++++++++++ 6 files changed, 138 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 1c94b4db95e..0450e0c615c 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -394,6 +394,7 @@ class CLIP_PT_tools_mask(CLIP_PT_mask_view_panel, Panel): col.label(text="Spline:") col.operator("mask.delete") col.operator("mask.cyclic_toggle") + col.operator("mask.switch_direction") col = layout.column(align=True) col.label(text="Parenting:") @@ -1196,6 +1197,7 @@ class CLIP_MT_mask(Menu): layout.separator() layout.operator("mask.cyclic_toggle") + layout.operator("mask.switch_direction") layout.separator() layout.operator("mask.parent_clear") diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index a26934f103b..32493e4e445 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -63,10 +63,13 @@ float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, float (*BKE_mask_spline_differentiate_with_resolution(struct MaskSpline *spline, int width, int height, int *tot_diff_point))[2]; float (*BKE_mask_spline_feather_differentiated_points_with_resolution(struct MaskSpline *spline, - int width, int height, int *tot_feather_point))[2]; + int width, int height, int *tot_feather_point))[2]; float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point))[2]; +void BKE_mask_point_direction_switch(struct MaskSplinePoint *point); +void BKE_mask_spline_direction_switch(struct MaskLayer *masklay, struct MaskSpline *spline); + /* point */ int BKE_mask_point_has_handle(struct MaskSplinePoint *point); void BKE_mask_point_handle(struct MaskSplinePoint *point, float handle[2]); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 52225a1fab0..f2c1d9f8b65 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -377,6 +377,84 @@ float (*BKE_mask_spline_feather_points(MaskSpline * spline, int *tot_feather_poi return feather; } +void BKE_mask_point_direction_switch(MaskSplinePoint *point) +{ + const int tot_uw = point->tot_uw; + const int tot_uw_half = tot_uw / 2; + int i; + + if (tot_uw < 2) { + return; + } + + /* count */ + for (i = 0; i < tot_uw_half; i++) { + MaskSplinePointUW *uw_a = &point->uw[i]; + MaskSplinePointUW *uw_b = &point->uw[tot_uw - (i + 1)]; + SWAP(MaskSplinePointUW, *uw_a, *uw_b); + } + for (i = 0; i < tot_uw; i++) { + MaskSplinePointUW *uw = &point->uw[i]; + uw->u = 1.0f - uw->u; + } +} + +//typedef (float)[MASK_OBJECT_SHAPE_ELEM_SIZE] MaskLayerShapeElem; + +typedef struct MaskLayerShapeElem { + float value[MASK_OBJECT_SHAPE_ELEM_SIZE]; +} MaskLayerShapeElem; + +void BKE_mask_spline_direction_switch(MaskLayer *masklay, MaskSpline *spline) +{ + const int tot_point = spline->tot_point; + const int tot_point_half = tot_point / 2; + int i, i_prev; + + if (tot_point < 2) { + return; + } + + /* count */ + for (i = 0; i < tot_point_half; i++) { + MaskSplinePoint *point_a = &spline->points[i]; + MaskSplinePoint *point_b = &spline->points[tot_point - (i + 1)]; + SWAP(MaskSplinePoint, *point_a, *point_b); + } + + /* correct UW's */ + i_prev = tot_point - 1; + for (i = 0; i < tot_point; i++) { + + BKE_mask_point_direction_switch(&spline->points[i]); + + SWAP(MaskSplinePointUW *, spline->points[i].uw, spline->points[i_prev].uw); + SWAP(int, spline->points[i].tot_uw, spline->points[i_prev].tot_uw); + + i_prev = i; + } + + /* correct animation */ + if (masklay->splines_shapes.first) { + MaskLayerShape *masklay_shape; + + const int spline_index = BKE_mask_layer_shape_spline_to_index(masklay, spline); + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + MaskLayerShapeElem *fp_arr = (MaskLayerShapeElem *)masklay_shape->data; + + for (i = 0; i < tot_point_half; i++) { + MaskLayerShapeElem *fp_a = &fp_arr[spline_index + (i) ]; + MaskLayerShapeElem *fp_b = &fp_arr[spline_index + (tot_point - (i + 1))]; + SWAP(MaskLayerShapeElem, *fp_a, *fp_b); + } + } + } +} + /* point */ int BKE_mask_point_has_handle(MaskSplinePoint *point) diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_editor.c index 8e93086eec8..96d645569c5 100644 --- a/source/blender/editors/mask/mask_editor.c +++ b/source/blender/editors/mask/mask_editor.c @@ -196,6 +196,7 @@ void ED_operatortypes_mask(void) /* geometry */ WM_operatortype_append(MASK_OT_add_vertex); WM_operatortype_append(MASK_OT_add_feather_vertex); + WM_operatortype_append(MASK_OT_switch_direction); WM_operatortype_append(MASK_OT_delete); /* select */ diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index af1ad96ee17..f2e862a7d8b 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -53,6 +53,7 @@ void MASK_OT_delete(struct wmOperatorType *ot); void MASK_OT_hide_view_clear(struct wmOperatorType *ot); void MASK_OT_hide_view_set(struct wmOperatorType *ot); +void MASK_OT_switch_direction(struct wmOperatorType *ot); void MASK_OT_handle_type_set(struct wmOperatorType *ot); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index a6954fc8ac6..3f2e82b1ca8 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1657,6 +1657,58 @@ void MASK_OT_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/* *** switch direction *** */ +static int mask_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + int change = FALSE; + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline)) { + BKE_mask_spline_direction_switch(masklay, spline); + change = TRUE; + } + } + } + + if (change) { + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_switch_direction(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Switch Direction"; + ot->description = "Switch direction of selected splines"; + ot->idname = "MASK_OT_switch_direction"; + + /* api callbacks */ + ot->exec = mask_switch_direction_exec; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + /******************** set handle type *********************/ static int set_handle_type_exec(bContext *C, wmOperator *op) From 7cd7a887407d254ca3ac5bff77c3e4b6a42a4307 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Jun 2012 13:46:38 +0000 Subject: [PATCH 164/360] code cleanup --- source/blender/blenkernel/BKE_mask.h | 10 +++++----- source/blender/blenkernel/intern/mask.c | 8 ++++---- source/blender/editors/mask/mask_ops.c | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 32493e4e445..89c8a76f841 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -129,13 +129,13 @@ int BKE_mask_layer_shape_totvert(struct MaskLayer *masklay); void BKE_mask_layer_shape_from_mask(struct MaskLayer *masklay, struct MaskLayerShape *masklay_shape); void BKE_mask_layer_shape_to_mask(struct MaskLayer *masklay, struct MaskLayerShape *masklay_shape); void BKE_mask_layer_shape_to_mask_interp(struct MaskLayer *masklay, - struct MaskLayerShape *masklay_shape_a, - struct MaskLayerShape *masklay_shape_b, - const float fac); + struct MaskLayerShape *masklay_shape_a, + struct MaskLayerShape *masklay_shape_b, + const float fac); struct MaskLayerShape *BKE_mask_layer_shape_find_frame(struct MaskLayer *masklay, int frame); int BKE_mask_layer_shape_find_frame_range(struct MaskLayer *masklay, int frame, - struct MaskLayerShape **r_masklay_shape_a, - struct MaskLayerShape **r_masklay_shape_b); + struct MaskLayerShape **r_masklay_shape_a, + struct MaskLayerShape **r_masklay_shape_b); struct MaskLayerShape *BKE_mask_layer_shape_varify_frame(struct MaskLayer *masklay, int frame); void BKE_mask_layer_shape_unlink(struct MaskLayer *masklay, struct MaskLayerShape *masklay_shape); void BKE_mask_layer_shape_sort(struct MaskLayer *masklay); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index f2c1d9f8b65..41f8cb1ddd2 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -325,12 +325,12 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline return feather; } -float (*BKE_mask_spline_feather_differentiated_points(MaskSpline * spline, int *tot_feather_point))[2] +float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point))[2] { return BKE_mask_spline_feather_differentiated_points_with_resolution(spline, 0, 0, tot_feather_point); } -float (*BKE_mask_spline_feather_points(MaskSpline * spline, int *tot_feather_point))[2] +float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); @@ -1939,8 +1939,8 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) diff_points = BKE_mask_spline_differentiate_with_resolution(spline, width, height, &tot_diff_point); if (tot_diff_point) { diff_feather_points = - BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height, - &tot_diff_feather_points); + BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height, + &tot_diff_feather_points); } /* TODO, make this optional! */ diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 3f2e82b1ca8..7dc486fe40c 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -357,8 +357,8 @@ static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_c if (feather) { feather_points = BKE_mask_point_segment_feather_diff_with_resolution(spline, cur_point, - width, height, - &tot_feather_point); + width, height, + &tot_feather_point); points = feather_points; tot_point = tot_feather_point; From 009798814574028f93b68ffdd8db2e8238c3dece Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Jun 2012 13:51:36 +0000 Subject: [PATCH 165/360] rename mask file --- source/blender/editors/mask/CMakeLists.txt | 2 +- source/blender/editors/mask/{mask_editor.c => mask_edit.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename source/blender/editors/mask/{mask_editor.c => mask_edit.c} (100%) diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt index e6f26e32c06..2a772653506 100644 --- a/source/blender/editors/mask/CMakeLists.txt +++ b/source/blender/editors/mask/CMakeLists.txt @@ -38,7 +38,7 @@ set(INC_SYS set(SRC mask_draw.c - mask_editor.c + mask_edit.c mask_ops.c mask_relationships.c mask_select.c diff --git a/source/blender/editors/mask/mask_editor.c b/source/blender/editors/mask/mask_edit.c similarity index 100% rename from source/blender/editors/mask/mask_editor.c rename to source/blender/editors/mask/mask_edit.c From 7b8ee679337994c6da0f5785282f6cb5ea837df9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Jun 2012 14:27:13 +0000 Subject: [PATCH 166/360] split mask add functions into their own file. --- source/blender/blenkernel/BKE_mask.h | 1 + source/blender/blenkernel/intern/mask.c | 63 ++ source/blender/editors/mask/CMakeLists.txt | 1 + source/blender/editors/mask/mask_add.c | 707 ++++++++++++++++++++ source/blender/editors/mask/mask_edit.c | 4 +- source/blender/editors/mask/mask_intern.h | 7 +- source/blender/editors/mask/mask_ops.c | 710 +-------------------- 7 files changed, 780 insertions(+), 713 deletions(-) create mode 100644 source/blender/editors/mask/mask_add.c diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 89c8a76f841..3f837f995ce 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -69,6 +69,7 @@ float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feath void BKE_mask_point_direction_switch(struct MaskSplinePoint *point); void BKE_mask_spline_direction_switch(struct MaskLayer *masklay, struct MaskSpline *spline); +float BKE_mask_spline_project_co(struct MaskSpline *spline, struct MaskSplinePoint *point, float start_u, const float co[2]); /* point */ int BKE_mask_point_has_handle(struct MaskSplinePoint *point); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 41f8cb1ddd2..870a84df66a 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -455,6 +455,69 @@ void BKE_mask_spline_direction_switch(MaskLayer *masklay, MaskSpline *spline) } } + +float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point, float start_u, const float co[2]) +{ + const float proj_eps = 1e-3; + const float proj_eps_squared = proj_eps * proj_eps; + const int N = 1000; + float u = -1.0f, du = 1.0f / N, u1 = start_u, u2 = start_u; + float ang = -1.0f; + + while (u1 > 0.0f || u2 < 1.0f) { + float n1[2], n2[2], co1[2], co2[2]; + float v1[2], v2[2]; + float ang1, ang2; + + if (u1 >= 0.0f) { + BKE_mask_point_segment_co(spline, point, u1, co1); + BKE_mask_point_normal(spline, point, u1, n1); + sub_v2_v2v2(v1, co, co1); + + if (len_squared_v2(v1) > proj_eps_squared) { + ang1 = angle_v2v2(v1, n1); + if (ang1 > M_PI / 2.0f) + ang1 = M_PI - ang1; + + if (ang < 0.0f || ang1 < ang) { + ang = ang1; + u = u1; + } + } + else { + u = u1; + break; + } + } + + if (u2 <= 1.0f) { + BKE_mask_point_segment_co(spline, point, u2, co2); + BKE_mask_point_normal(spline, point, u2, n2); + sub_v2_v2v2(v2, co, co2); + + if (len_squared_v2(v2) > proj_eps_squared) { + ang2 = angle_v2v2(v2, n2); + if (ang2 > M_PI / 2.0f) + ang2 = M_PI - ang2; + + if (ang2 < ang) { + ang = ang2; + u = u2; + } + } + else { + u = u2; + break; + } + } + + u1 -= du; + u2 += du; + } + + return u; +} + /* point */ int BKE_mask_point_has_handle(MaskSplinePoint *point) diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt index 2a772653506..f15e9c27732 100644 --- a/source/blender/editors/mask/CMakeLists.txt +++ b/source/blender/editors/mask/CMakeLists.txt @@ -37,6 +37,7 @@ set(INC_SYS ) set(SRC + mask_add.c mask_draw.c mask_edit.c mask_ops.c diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c new file mode 100644 index 00000000000..62675635b7b --- /dev/null +++ b/source/blender/editors/mask/mask_add.c @@ -0,0 +1,707 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_add.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "DNA_scene_types.h" +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" +#include "ED_clip.h" +#include "ED_keyframing.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "mask_intern.h" /* own include */ + + +static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_co[2], int threshold, int feather, + MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + float *u_r, float tangent[2]) +{ + MaskLayer *masklay, *point_masklay; + MaskSpline *point_spline; + MaskSplinePoint *point = NULL; + float dist, co[2]; + int width, height; + float u; + float scalex, scaley, aspx, aspy; + + ED_mask_size(C, &width, &height); + ED_mask_aspect(C, &aspx, &aspy); + ED_mask_pixelspace_factor(C, &scalex, &scaley); + + co[0] = normal_co[0] * scalex; + co[1] = normal_co[1] * scaley; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *cur_point = &spline->points[i]; + float *diff_points; + int tot_diff_point; + + diff_points = BKE_mask_point_segment_diff_with_resolution(spline, cur_point, width, height, + &tot_diff_point); + + if (diff_points) { + int i, tot_feather_point, tot_point; + float *feather_points = NULL, *points; + + if (feather) { + feather_points = BKE_mask_point_segment_feather_diff_with_resolution(spline, cur_point, + width, height, + &tot_feather_point); + + points = feather_points; + tot_point = tot_feather_point; + } + else { + points = diff_points; + tot_point = tot_diff_point; + } + + for (i = 0; i < tot_point - 1; i++) { + float cur_dist, a[2], b[2]; + + a[0] = points[2 * i] * scalex; + a[1] = points[2 * i + 1] * scaley; + + b[0] = points[2 * i + 2] * scalex; + b[1] = points[2 * i + 3] * scaley; + + cur_dist = dist_to_line_segment_v2(co, a, b); + + if (point == NULL || cur_dist < dist) { + if (tangent) + sub_v2_v2v2(tangent, &diff_points[2 * i + 2], &diff_points[2 * i]); + + point_masklay = masklay; + point_spline = spline; + point = cur_point; + dist = cur_dist; + u = (float)i / tot_point; + + } + } + + if (feather_points) + MEM_freeN(feather_points); + + MEM_freeN(diff_points); + } + } + } + } + + if (point && dist < threshold) { + if (masklay_r) + *masklay_r = point_masklay; + + if (spline_r) + *spline_r = point_spline; + + if (point_r) + *point_r = point; + + if (u_r) { + u = BKE_mask_spline_project_co(point_spline, point, u, normal_co); + + *u_r = u; + } + + return TRUE; + } + + if (masklay_r) + *masklay_r = NULL; + + if (spline_r) + *spline_r = NULL; + + if (point_r) + *point_r = NULL; + + return FALSE; +} + +/******************** add vertex *********************/ + +static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point, + const float point_co[2], const float tangent[2], const float u, + MaskSplinePoint *reference_point, const short reference_adjacent) +{ + MaskSplinePoint *prev_point = NULL; + MaskSplinePoint *next_point = NULL; + BezTriple *bezt; + int width, height; + float co[3]; + const float len = 20.0; /* default length of handle in pixel space */ + + copy_v2_v2(co, point_co); + co[2] = 0.0f; + + ED_mask_size(C, &width, &height); + + /* point coordinate */ + bezt = &new_point->bezt; + + bezt->h1 = bezt->h2 = HD_ALIGN; + + if (reference_point) { + bezt->h1 = bezt->h2 = MAX2(reference_point->bezt.h2, reference_point->bezt.h1); + } + else if (reference_adjacent) { + if (spline->tot_point != 1) { + int index = (int)(new_point - spline->points); + prev_point = &spline->points[(index - 1) % spline->tot_point]; + next_point = &spline->points[(index + 1) % spline->tot_point]; + + bezt->h1 = bezt->h2 = MAX2(prev_point->bezt.h2, next_point->bezt.h1); + + /* note, we may want to copy other attributes later, radius? pressure? color? */ + } + } + + copy_v3_v3(bezt->vec[0], co); + copy_v3_v3(bezt->vec[1], co); + copy_v3_v3(bezt->vec[2], co); + + /* initial offset for handles */ + if (spline->tot_point == 1) { + /* first point of splien is aligned horizontally */ + bezt->vec[0][0] -= len / width; + bezt->vec[2][0] += len / width; + } + else if (tangent) { + float vec[2]; + + copy_v2_v2(vec, tangent); + + vec[0] *= width; + vec[1] *= height; + + mul_v2_fl(vec, len / len_v2(vec)); + + vec[0] /= width; + vec[1] /= height; + + sub_v2_v2(bezt->vec[0], vec); + add_v2_v2(bezt->vec[2], vec); + + if (reference_adjacent) { + BKE_mask_calc_handle_adjacent_interp(mask, spline, new_point, u); + } + } + else { + + /* calculating auto handles works much nicer */ +#if 0 + /* next points are aligning in the direction of previous/next point */ + MaskSplinePoint *point; + float v1[2], v2[2], vec[2]; + float dir = 1.0f; + + if (new_point == spline->points) { + point = new_point + 1; + dir = -1.0f; + } + else + point = new_point - 1; + + if (spline->tot_point < 3) { + v1[0] = point->bezt.vec[1][0] * width; + v1[1] = point->bezt.vec[1][1] * height; + + v2[0] = new_point->bezt.vec[1][0] * width; + v2[1] = new_point->bezt.vec[1][1] * height; + } + else { + if (new_point == spline->points) { + v1[0] = spline->points[1].bezt.vec[1][0] * width; + v1[1] = spline->points[1].bezt.vec[1][1] * height; + + v2[0] = spline->points[spline->tot_point - 1].bezt.vec[1][0] * width; + v2[1] = spline->points[spline->tot_point - 1].bezt.vec[1][1] * height; + } + else { + v1[0] = spline->points[0].bezt.vec[1][0] * width; + v1[1] = spline->points[0].bezt.vec[1][1] * height; + + v2[0] = spline->points[spline->tot_point - 2].bezt.vec[1][0] * width; + v2[1] = spline->points[spline->tot_point - 2].bezt.vec[1][1] * height; + } + } + + sub_v2_v2v2(vec, v1, v2); + mul_v2_fl(vec, len * dir / len_v2(vec)); + + vec[0] /= width; + vec[1] /= height; + + add_v2_v2(bezt->vec[0], vec); + sub_v2_v2(bezt->vec[2], vec); +#else + BKE_mask_calc_handle_point_auto(mask, spline, new_point, TRUE); + BKE_mask_calc_handle_adjacent_interp(mask, spline, new_point, u); + +#endif + } + + BKE_mask_parent_init(&new_point->parent); + + /* select new point */ + MASKPOINT_SEL_ALL(new_point); + ED_mask_select_flush_all(mask); +} + + +/* **** add extrude vertex **** */ + +static void finSelectedSplinePoint(MaskLayer *masklay, MaskSpline **spline, MaskSplinePoint **point, short check_active) +{ + MaskSpline *cur_spline = masklay->splines.first; + + *spline = NULL; + *point = NULL; + + if (check_active) { + if (masklay->act_spline && masklay->act_point) { + *spline = masklay->act_spline; + *point = masklay->act_point; + return; + } + } + + while (cur_spline) { + int i; + + for (i = 0; i < cur_spline->tot_point; i++) { + MaskSplinePoint *cur_point = &cur_spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(cur_point)) { + if (*spline != NULL && *spline != cur_spline) { + *spline = NULL; + *point = NULL; + return; + } + else if (*point) { + *point = NULL; + } + else { + *spline = cur_spline; + *point = cur_point; + } + } + } + + cur_spline = cur_spline->next; + } +} + +/* **** add subdivide vertex **** */ + +static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index) +{ + MaskSplinePoint *new_point_array; + + new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); + + memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1)); + memcpy(new_point_array + point_index + 2, spline->points + point_index + 1, + sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1)); + + MEM_freeN(spline->points); + spline->points = new_point_array; + spline->tot_point++; +} + +static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2]) +{ + MaskLayer *masklay; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + const float threshold = 9; + float tangent[2]; + float u; + + if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &masklay, &spline, &point, &u, tangent)) { + MaskSplinePoint *new_point; + int point_index = point - spline->points; + + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + mask_spline_add_point_at_index(spline, point_index); + + new_point = &spline->points[point_index + 1]; + + setup_vertex_point(C, mask, spline, new_point, co, tangent, u, NULL, TRUE); + + /* TODO - we could pass the spline! */ + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index + 1, TRUE, TRUE); + + masklay->act_point = new_point; + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return TRUE; + } + + return FALSE; +} + +static int add_vertex_extrude(bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) +{ + MaskSpline *spline; + MaskSplinePoint *point; + MaskSplinePoint *new_point = NULL, *ref_point = NULL; + + /* check on which side we want to add the point */ + int point_index; + float tangent_point[2]; + float tangent_co[2]; + int do_cyclic_correct = FALSE; + int do_recalc_src = FALSE; /* when extruding from endpoints only */ + int do_prev; /* use prev point rather then next?? */ + + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + if (!masklay) { + return FALSE; + } + else { + finSelectedSplinePoint(masklay, &spline, &point, TRUE); + } + + point_index = (point - spline->points); + + MASKPOINT_DESEL_ALL(point); + + if ((spline->flag & MASK_SPLINE_CYCLIC) || + (point_index > 0 && point_index != spline->tot_point - 1)) + { + BKE_mask_calc_tangent_polyline(mask, spline, point, tangent_point); + sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]); + + if (dot_v2v2(tangent_point, tangent_co) < 0.0f) { + do_prev = TRUE; + } + else { + do_prev = FALSE; + } + } + else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == 0)) { + do_prev = TRUE; + do_recalc_src = TRUE; + } + else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == spline->tot_point - 1)) { + do_prev = FALSE; + do_recalc_src = TRUE; + } + else { + /* should never get here */ + BLI_assert(0); + } + + /* use the point before the active one */ + if (do_prev) { + point_index--; + if (point_index < 0) { + point_index += spline->tot_point; /* wrap index */ + if ((spline->flag & MASK_SPLINE_CYCLIC) == 0) { + do_cyclic_correct = TRUE; + point_index = 0; + } + } + } + +// print_v2("", tangent_point); +// printf("%d\n", point_index); + + mask_spline_add_point_at_index(spline, point_index); + + if (do_cyclic_correct) { + ref_point = &spline->points[point_index + 1]; + new_point = &spline->points[point_index]; + *ref_point = *new_point; + memset(new_point, 0, sizeof(*new_point)); + } + else { + ref_point = &spline->points[point_index]; + new_point = &spline->points[point_index + 1]; + } + + masklay->act_point = new_point; + + setup_vertex_point(C, mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE); + + if (masklay->splines_shapes.first) { + point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); + } + + if (do_recalc_src) { + /* TODO, update keyframes in time */ + BKE_mask_calc_handle_point_auto(mask, spline, ref_point, FALSE); + } + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return TRUE; +} + +static int add_vertex_new(bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) +{ + MaskSpline *spline; + MaskSplinePoint *point; + MaskSplinePoint *new_point = NULL, *ref_point = NULL; + + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + if (!masklay) { + /* if there's no masklay currently operationg on, create new one */ + masklay = BKE_mask_layer_new(mask, ""); + mask->masklay_act = mask->masklay_tot - 1; + spline = NULL; + point = NULL; + } + else { + finSelectedSplinePoint(masklay, &spline, &point, TRUE); + } + + if (!spline) { + /* no selected splines in active masklay, create new spline */ + spline = BKE_mask_spline_add(masklay); + } + + masklay->act_spline = spline; + new_point = spline->points; + + masklay->act_point = new_point; + + setup_vertex_point(C, mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE); + + { + int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); + } + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return TRUE; +} + +static int add_vertex_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + float co[2]; + + masklay = BKE_mask_layer_active(mask); + + if (masklay && masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + masklay = NULL; + } + + RNA_float_get_array(op->ptr, "location", co); + + if (masklay && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { + + /* cheap trick - double click for cyclic */ + MaskSpline *spline = masklay->act_spline; + MaskSplinePoint *point = masklay->act_point; + + int is_sta = (point == spline->points); + int is_end = (point == &spline->points[spline->tot_point - 1]); + + /* then check are we overlapping the mouse */ + if ((is_sta || is_end) && equals_v2v2(co, point->bezt.vec[1])) { + if (spline->flag & MASK_SPLINE_CYCLIC) { + /* nothing to do */ + return OPERATOR_CANCELLED; + } + else { + /* recalc the connecting point as well to make a nice even curve */ + MaskSplinePoint *point_other = is_end ? spline->points : &spline->points[spline->tot_point - 1]; + spline->flag |= MASK_SPLINE_CYCLIC; + + /* TODO, update keyframes in time */ + BKE_mask_calc_handle_point_auto(mask, spline, point, FALSE); + BKE_mask_calc_handle_point_auto(mask, spline, point_other, FALSE); + + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + return OPERATOR_FINISHED; + } + } + + if (!add_vertex_subdivide(C, mask, co)) { + if (!add_vertex_extrude(C, mask, masklay, co)) { + return OPERATOR_CANCELLED; + } + } + } + else { + if (!add_vertex_subdivide(C, mask, co)) { + if (!add_vertex_new(C, mask, masklay, co)) { + return OPERATOR_CANCELLED; + } + } + } + + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + return OPERATOR_FINISHED; +} + +static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return add_vertex_exec(C, op); +} + +void MASK_OT_add_vertex(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Vertex"; + ot->description = "Add vertex to active spline"; + ot->idname = "MASK_OT_add_vertex"; + + /* api callbacks */ + ot->exec = add_vertex_exec; + ot->invoke = add_vertex_invoke; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} + +/******************** add feather vertex *********************/ + +static int add_feather_vertex_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + const float threshold = 9; + float co[2], u; + + RNA_float_get_array(op->ptr, "location", co); + + point = ED_mask_point_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL); + if (point) + return OPERATOR_FINISHED; + + if (find_nearest_diff_point(C, mask, co, threshold, TRUE, &masklay, &spline, &point, &u, NULL)) { + Scene *scene = CTX_data_scene(C); + float w = BKE_mask_point_weight(spline, point, u); + + BKE_mask_point_add_uw(point, u, w); + + BKE_mask_update_display(mask, scene->r.cfra); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +static int add_feather_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return add_feather_vertex_exec(C, op); +} + +void MASK_OT_add_feather_vertex(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add feather Vertex"; + ot->description = "Add vertex to feather"; + ot->idname = "MASK_OT_add_feather_vertex"; + + /* api callbacks */ + ot->exec = add_feather_vertex_exec; + ot->invoke = add_feather_vertex_invoke; + ot->poll = ED_maskediting_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c index 96d645569c5..0b8551ddd4c 100644 --- a/source/blender/editors/mask/mask_edit.c +++ b/source/blender/editors/mask/mask_edit.c @@ -193,9 +193,11 @@ void ED_operatortypes_mask(void) WM_operatortype_append(MASK_OT_layer_new); WM_operatortype_append(MASK_OT_layer_remove); - /* geometry */ + /* add */ WM_operatortype_append(MASK_OT_add_vertex); WM_operatortype_append(MASK_OT_add_feather_vertex); + + /* geometry */ WM_operatortype_append(MASK_OT_switch_direction); WM_operatortype_append(MASK_OT_delete); diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index f2e862a7d8b..70f13abd44f 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -38,13 +38,14 @@ struct wmOperatorType; /* internal exports only */ +/* mask_add.c */ +void MASK_OT_add_vertex(struct wmOperatorType *ot); +void MASK_OT_add_feather_vertex(struct wmOperatorType *ot); + /* mask_ops.c */ void MASK_OT_new(struct wmOperatorType *ot); void MASK_OT_layer_new(struct wmOperatorType *ot); void MASK_OT_layer_remove(struct wmOperatorType *ot); - -void MASK_OT_add_vertex(struct wmOperatorType *ot); -void MASK_OT_add_feather_vertex(struct wmOperatorType *ot); void MASK_OT_cyclic_toggle(struct wmOperatorType *ot); void MASK_OT_slide_point(struct wmOperatorType *ot); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 7dc486fe40c..cf3a72bdc78 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -59,68 +59,6 @@ /******************** utility functions *********************/ -static float projection_on_spline(MaskSpline *spline, MaskSplinePoint *point, float start_u, const float co[2]) -{ - const float proj_eps = 1e-3; - const float proj_eps_squared = proj_eps * proj_eps; - const int N = 1000; - float u = -1.0f, du = 1.0f / N, u1 = start_u, u2 = start_u; - float ang = -1.0f; - - while (u1 > 0.0f || u2 < 1.0f) { - float n1[2], n2[2], co1[2], co2[2]; - float v1[2], v2[2]; - float ang1, ang2; - - if (u1 >= 0.0f) { - BKE_mask_point_segment_co(spline, point, u1, co1); - BKE_mask_point_normal(spline, point, u1, n1); - sub_v2_v2v2(v1, co, co1); - - if (len_squared_v2(v1) > proj_eps_squared) { - ang1 = angle_v2v2(v1, n1); - if (ang1 > M_PI / 2.0f) - ang1 = M_PI - ang1; - - if (ang < 0.0f || ang1 < ang) { - ang = ang1; - u = u1; - } - } - else { - u = u1; - break; - } - } - - if (u2 <= 1.0f) { - BKE_mask_point_segment_co(spline, point, u2, co2); - BKE_mask_point_normal(spline, point, u2, n2); - sub_v2_v2v2(v2, co, co2); - - if (len_squared_v2(v2) > proj_eps_squared) { - ang2 = angle_v2v2(v2, n2); - if (ang2 > M_PI / 2.0f) - ang2 = M_PI - ang2; - - if (ang2 < ang) { - ang = ang2; - u = u2; - } - } - else { - u = u2; - break; - } - } - - u1 -= du; - u2 += du; - } - - return u; -} - MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float normal_co[2], int threshold, MaskLayer **masklay_r, MaskSpline **spline_r, int *is_handle_r, float *score) @@ -314,123 +252,6 @@ int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], in return FALSE; } -static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_co[2], int threshold, int feather, - MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r, - float *u_r, float tangent[2]) -{ - MaskLayer *masklay, *point_masklay; - MaskSpline *point_spline; - MaskSplinePoint *point = NULL; - float dist, co[2]; - int width, height; - float u; - float scalex, scaley, aspx, aspy; - - ED_mask_size(C, &width, &height); - ED_mask_aspect(C, &aspx, &aspy); - ED_mask_pixelspace_factor(C, &scalex, &scaley); - - co[0] = normal_co[0] * scalex; - co[1] = normal_co[1] * scaley; - - for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { - MaskSpline *spline; - - if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { - continue; - } - - for (spline = masklay->splines.first; spline; spline = spline->next) { - int i; - - for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *cur_point = &spline->points[i]; - float *diff_points; - int tot_diff_point; - - diff_points = BKE_mask_point_segment_diff_with_resolution(spline, cur_point, width, height, - &tot_diff_point); - - if (diff_points) { - int i, tot_feather_point, tot_point; - float *feather_points = NULL, *points; - - if (feather) { - feather_points = BKE_mask_point_segment_feather_diff_with_resolution(spline, cur_point, - width, height, - &tot_feather_point); - - points = feather_points; - tot_point = tot_feather_point; - } - else { - points = diff_points; - tot_point = tot_diff_point; - } - - for (i = 0; i < tot_point - 1; i++) { - float cur_dist, a[2], b[2]; - - a[0] = points[2 * i] * scalex; - a[1] = points[2 * i + 1] * scaley; - - b[0] = points[2 * i + 2] * scalex; - b[1] = points[2 * i + 3] * scaley; - - cur_dist = dist_to_line_segment_v2(co, a, b); - - if (point == NULL || cur_dist < dist) { - if (tangent) - sub_v2_v2v2(tangent, &diff_points[2 * i + 2], &diff_points[2 * i]); - - point_masklay = masklay; - point_spline = spline; - point = cur_point; - dist = cur_dist; - u = (float)i / tot_point; - - } - } - - if (feather_points) - MEM_freeN(feather_points); - - MEM_freeN(diff_points); - } - } - } - } - - if (point && dist < threshold) { - if (masklay_r) - *masklay_r = point_masklay; - - if (spline_r) - *spline_r = point_spline; - - if (point_r) - *point_r = point; - - if (u_r) { - u = projection_on_spline(point_spline, point, u, normal_co); - - *u_r = u; - } - - return TRUE; - } - - if (masklay_r) - *masklay_r = NULL; - - if (spline_r) - *spline_r = NULL; - - if (point_r) - *point_r = NULL; - - return FALSE; -} /******************** create new mask *********************/ @@ -829,7 +650,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) add_v2_v2v2(offco, data->feather, dco); if (data->uw) { - float u = projection_on_spline(data->spline, data->point, data->uw->u, offco); + float u = BKE_mask_spline_project_co(data->spline, data->point, data->uw->u, offco); if (u > 0.0f && u < 1.0f) { data->uw->u = u; @@ -943,535 +764,6 @@ void MASK_OT_slide_point(wmOperatorType *ot) RNA_def_boolean(ot->srna, "slide_feather", 0, "Slide Feather", "First try to slide slide feather instead of vertex"); } -/******************** add vertex *********************/ - -static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point, - const float point_co[2], const float tangent[2], const float u, - MaskSplinePoint *reference_point, const short reference_adjacent) -{ - MaskSplinePoint *prev_point = NULL; - MaskSplinePoint *next_point = NULL; - BezTriple *bezt; - int width, height; - float co[3]; - const float len = 20.0; /* default length of handle in pixel space */ - - copy_v2_v2(co, point_co); - co[2] = 0.0f; - - ED_mask_size(C, &width, &height); - - /* point coordinate */ - bezt = &new_point->bezt; - - bezt->h1 = bezt->h2 = HD_ALIGN; - - if (reference_point) { - bezt->h1 = bezt->h2 = MAX2(reference_point->bezt.h2, reference_point->bezt.h1); - } - else if (reference_adjacent) { - if (spline->tot_point != 1) { - int index = (int)(new_point - spline->points); - prev_point = &spline->points[(index - 1) % spline->tot_point]; - next_point = &spline->points[(index + 1) % spline->tot_point]; - - bezt->h1 = bezt->h2 = MAX2(prev_point->bezt.h2, next_point->bezt.h1); - - /* note, we may want to copy other attributes later, radius? pressure? color? */ - } - } - - copy_v3_v3(bezt->vec[0], co); - copy_v3_v3(bezt->vec[1], co); - copy_v3_v3(bezt->vec[2], co); - - /* initial offset for handles */ - if (spline->tot_point == 1) { - /* first point of splien is aligned horizontally */ - bezt->vec[0][0] -= len / width; - bezt->vec[2][0] += len / width; - } - else if (tangent) { - float vec[2]; - - copy_v2_v2(vec, tangent); - - vec[0] *= width; - vec[1] *= height; - - mul_v2_fl(vec, len / len_v2(vec)); - - vec[0] /= width; - vec[1] /= height; - - sub_v2_v2(bezt->vec[0], vec); - add_v2_v2(bezt->vec[2], vec); - - if (reference_adjacent) { - BKE_mask_calc_handle_adjacent_interp(mask, spline, new_point, u); - } - } - else { - - /* calculating auto handles works much nicer */ -#if 0 - /* next points are aligning in the direction of previous/next point */ - MaskSplinePoint *point; - float v1[2], v2[2], vec[2]; - float dir = 1.0f; - - if (new_point == spline->points) { - point = new_point + 1; - dir = -1.0f; - } - else - point = new_point - 1; - - if (spline->tot_point < 3) { - v1[0] = point->bezt.vec[1][0] * width; - v1[1] = point->bezt.vec[1][1] * height; - - v2[0] = new_point->bezt.vec[1][0] * width; - v2[1] = new_point->bezt.vec[1][1] * height; - } - else { - if (new_point == spline->points) { - v1[0] = spline->points[1].bezt.vec[1][0] * width; - v1[1] = spline->points[1].bezt.vec[1][1] * height; - - v2[0] = spline->points[spline->tot_point - 1].bezt.vec[1][0] * width; - v2[1] = spline->points[spline->tot_point - 1].bezt.vec[1][1] * height; - } - else { - v1[0] = spline->points[0].bezt.vec[1][0] * width; - v1[1] = spline->points[0].bezt.vec[1][1] * height; - - v2[0] = spline->points[spline->tot_point - 2].bezt.vec[1][0] * width; - v2[1] = spline->points[spline->tot_point - 2].bezt.vec[1][1] * height; - } - } - - sub_v2_v2v2(vec, v1, v2); - mul_v2_fl(vec, len * dir / len_v2(vec)); - - vec[0] /= width; - vec[1] /= height; - - add_v2_v2(bezt->vec[0], vec); - sub_v2_v2(bezt->vec[2], vec); -#else - BKE_mask_calc_handle_point_auto(mask, spline, new_point, TRUE); - BKE_mask_calc_handle_adjacent_interp(mask, spline, new_point, u); - -#endif - } - - BKE_mask_parent_init(&new_point->parent); - - /* select new point */ - MASKPOINT_SEL_ALL(new_point); - ED_mask_select_flush_all(mask); -} - -/* **** add subdivide vertex **** */ - -static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index) -{ - MaskSplinePoint *new_point_array; - - new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); - - memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1)); - memcpy(new_point_array + point_index + 2, spline->points + point_index + 1, - sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1)); - - MEM_freeN(spline->points); - spline->points = new_point_array; - spline->tot_point++; -} - -static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2]) -{ - MaskLayer *masklay; - MaskSpline *spline; - MaskSplinePoint *point = NULL; - const float threshold = 9; - float tangent[2]; - float u; - - if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &masklay, &spline, &point, &u, tangent)) { - MaskSplinePoint *new_point; - int point_index = point - spline->points; - - ED_mask_select_toggle_all(mask, SEL_DESELECT); - - mask_spline_add_point_at_index(spline, point_index); - - new_point = &spline->points[point_index + 1]; - - setup_vertex_point(C, mask, spline, new_point, co, tangent, u, NULL, TRUE); - - /* TODO - we could pass the spline! */ - BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index + 1, TRUE, TRUE); - - masklay->act_point = new_point; - - WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); - - return TRUE; - } - - return FALSE; -} - -/* **** add extrude vertex **** */ - -static void finSelectedSplinePoint(MaskLayer *masklay, MaskSpline **spline, MaskSplinePoint **point, short check_active) -{ - MaskSpline *cur_spline = masklay->splines.first; - - *spline = NULL; - *point = NULL; - - if (check_active) { - if (masklay->act_spline && masklay->act_point) { - *spline = masklay->act_spline; - *point = masklay->act_point; - return; - } - } - - while (cur_spline) { - int i; - - for (i = 0; i < cur_spline->tot_point; i++) { - MaskSplinePoint *cur_point = &cur_spline->points[i]; - - if (MASKPOINT_ISSEL_ANY(cur_point)) { - if (*spline != NULL && *spline != cur_spline) { - *spline = NULL; - *point = NULL; - return; - } - else if (*point) { - *point = NULL; - } - else { - *spline = cur_spline; - *point = cur_point; - } - } - } - - cur_spline = cur_spline->next; - } -} - -static int add_vertex_extrude(bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) -{ - MaskSpline *spline; - MaskSplinePoint *point; - MaskSplinePoint *new_point = NULL, *ref_point = NULL; - - /* check on which side we want to add the point */ - int point_index; - float tangent_point[2]; - float tangent_co[2]; - int do_cyclic_correct = FALSE; - int do_recalc_src = FALSE; /* when extruding from endpoints only */ - int do_prev; /* use prev point rather then next?? */ - - ED_mask_select_toggle_all(mask, SEL_DESELECT); - - if (!masklay) { - return FALSE; - } - else { - finSelectedSplinePoint(masklay, &spline, &point, TRUE); - } - - point_index = (point - spline->points); - - MASKPOINT_DESEL_ALL(point); - - if ((spline->flag & MASK_SPLINE_CYCLIC) || - (point_index > 0 && point_index != spline->tot_point - 1)) - { - BKE_mask_calc_tangent_polyline(mask, spline, point, tangent_point); - sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]); - - if (dot_v2v2(tangent_point, tangent_co) < 0.0f) { - do_prev = TRUE; - } - else { - do_prev = FALSE; - } - } - else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == 0)) { - do_prev = TRUE; - do_recalc_src = TRUE; - } - else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == spline->tot_point - 1)) { - do_prev = FALSE; - do_recalc_src = TRUE; - } - else { - /* should never get here */ - BLI_assert(0); - } - - /* use the point before the active one */ - if (do_prev) { - point_index--; - if (point_index < 0) { - point_index += spline->tot_point; /* wrap index */ - if ((spline->flag & MASK_SPLINE_CYCLIC) == 0) { - do_cyclic_correct = TRUE; - point_index = 0; - } - } - } - -// print_v2("", tangent_point); -// printf("%d\n", point_index); - - mask_spline_add_point_at_index(spline, point_index); - - if (do_cyclic_correct) { - ref_point = &spline->points[point_index + 1]; - new_point = &spline->points[point_index]; - *ref_point = *new_point; - memset(new_point, 0, sizeof(*new_point)); - } - else { - ref_point = &spline->points[point_index]; - new_point = &spline->points[point_index + 1]; - } - - masklay->act_point = new_point; - - setup_vertex_point(C, mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE); - - if (masklay->splines_shapes.first) { - point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); - BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); - } - - if (do_recalc_src) { - /* TODO, update keyframes in time */ - BKE_mask_calc_handle_point_auto(mask, spline, ref_point, FALSE); - } - - WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); - - return TRUE; -} - -static int add_vertex_new(bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) -{ - MaskSpline *spline; - MaskSplinePoint *point; - MaskSplinePoint *new_point = NULL, *ref_point = NULL; - - ED_mask_select_toggle_all(mask, SEL_DESELECT); - - if (!masklay) { - /* if there's no masklay currently operationg on, create new one */ - masklay = BKE_mask_layer_new(mask, ""); - mask->masklay_act = mask->masklay_tot - 1; - spline = NULL; - point = NULL; - } - else { - finSelectedSplinePoint(masklay, &spline, &point, TRUE); - } - - if (!spline) { - /* no selected splines in active masklay, create new spline */ - spline = BKE_mask_spline_add(masklay); - } - - masklay->act_spline = spline; - new_point = spline->points; - - masklay->act_point = new_point; - - setup_vertex_point(C, mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE); - - { - int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); - BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); - } - - WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); - - return TRUE; -} - -static int add_vertex_exec(bContext *C, wmOperator *op) -{ - Mask *mask = CTX_data_edit_mask(C); - MaskLayer *masklay; - - float co[2]; - - masklay = BKE_mask_layer_active(mask); - - if (masklay && masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { - masklay = NULL; - } - - RNA_float_get_array(op->ptr, "location", co); - - if (masklay && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { - - /* cheap trick - double click for cyclic */ - MaskSpline *spline = masklay->act_spline; - MaskSplinePoint *point = masklay->act_point; - - int is_sta = (point == spline->points); - int is_end = (point == &spline->points[spline->tot_point - 1]); - - /* then check are we overlapping the mouse */ - if ((is_sta || is_end) && equals_v2v2(co, point->bezt.vec[1])) { - if (spline->flag & MASK_SPLINE_CYCLIC) { - /* nothing to do */ - return OPERATOR_CANCELLED; - } - else { - /* recalc the connecting point as well to make a nice even curve */ - MaskSplinePoint *point_other = is_end ? spline->points : &spline->points[spline->tot_point - 1]; - spline->flag |= MASK_SPLINE_CYCLIC; - - /* TODO, update keyframes in time */ - BKE_mask_calc_handle_point_auto(mask, spline, point, FALSE); - BKE_mask_calc_handle_point_auto(mask, spline, point_other, FALSE); - - /* TODO: only update this spline */ - BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); - - WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); - return OPERATOR_FINISHED; - } - } - - if (!add_vertex_subdivide(C, mask, co)) { - if (!add_vertex_extrude(C, mask, masklay, co)) { - return OPERATOR_CANCELLED; - } - } - } - else { - if (!add_vertex_subdivide(C, mask, co)) { - if (!add_vertex_new(C, mask, masklay, co)) { - return OPERATOR_CANCELLED; - } - } - } - - /* TODO: only update this spline */ - BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); - - return OPERATOR_FINISHED; -} - -static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - float co[2]; - - ED_mask_mouse_pos(C, event, co); - - RNA_float_set_array(op->ptr, "location", co); - - return add_vertex_exec(C, op); -} - -void MASK_OT_add_vertex(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Add Vertex"; - ot->description = "Add vertex to active spline"; - ot->idname = "MASK_OT_add_vertex"; - - /* api callbacks */ - ot->exec = add_vertex_exec; - ot->invoke = add_vertex_invoke; - ot->poll = ED_maskediting_mask_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, - "Location", "Location of vertex in normalized space", -1.0f, 1.0f); -} - -/******************** add feather vertex *********************/ - -static int add_feather_vertex_exec(bContext *C, wmOperator *op) -{ - Mask *mask = CTX_data_edit_mask(C); - MaskLayer *masklay; - MaskSpline *spline; - MaskSplinePoint *point = NULL; - const float threshold = 9; - float co[2], u; - - RNA_float_get_array(op->ptr, "location", co); - - point = ED_mask_point_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL); - if (point) - return OPERATOR_FINISHED; - - if (find_nearest_diff_point(C, mask, co, threshold, TRUE, &masklay, &spline, &point, &u, NULL)) { - Scene *scene = CTX_data_scene(C); - float w = BKE_mask_point_weight(spline, point, u); - - BKE_mask_point_add_uw(point, u, w); - - BKE_mask_update_display(mask, scene->r.cfra); - - WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); - - DAG_id_tag_update(&mask->id, 0); - - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED; -} - -static int add_feather_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - float co[2]; - - ED_mask_mouse_pos(C, event, co); - - RNA_float_set_array(op->ptr, "location", co); - - return add_feather_vertex_exec(C, op); -} - -void MASK_OT_add_feather_vertex(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Add feather Vertex"; - ot->description = "Add vertex to feather"; - ot->idname = "MASK_OT_add_feather_vertex"; - - /* api callbacks */ - ot->exec = add_feather_vertex_exec; - ot->invoke = add_feather_vertex_invoke; - ot->poll = ED_maskediting_mask_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, - "Location", "Location of vertex in normalized space", -1.0f, 1.0f); -} - /******************** toggle cyclic *********************/ static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) From f8266d5a4b0d76faad90df8a285c1a070ecd8e9e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Jun 2012 14:35:45 +0000 Subject: [PATCH 167/360] dont extrude from active-unselected mask-spline verts. --- source/blender/editors/mask/mask_add.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c index 62675635b7b..c2c2ebbfe42 100644 --- a/source/blender/editors/mask/mask_add.c +++ b/source/blender/editors/mask/mask_add.c @@ -317,7 +317,7 @@ static void finSelectedSplinePoint(MaskLayer *masklay, MaskSpline **spline, Mask *point = NULL; if (check_active) { - if (masklay->act_spline && masklay->act_point) { + if (masklay->act_spline && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { *spline = masklay->act_spline; *point = masklay->act_point; return; @@ -415,8 +415,6 @@ static int add_vertex_extrude(bContext *C, Mask *mask, MaskLayer *masklay, const int do_recalc_src = FALSE; /* when extruding from endpoints only */ int do_prev; /* use prev point rather then next?? */ - ED_mask_select_toggle_all(mask, SEL_DESELECT); - if (!masklay) { return FALSE; } @@ -424,6 +422,8 @@ static int add_vertex_extrude(bContext *C, Mask *mask, MaskLayer *masklay, const finSelectedSplinePoint(masklay, &spline, &point, TRUE); } + ED_mask_select_toggle_all(mask, SEL_DESELECT); + point_index = (point - spline->points); MASKPOINT_DESEL_ALL(point); @@ -507,8 +507,6 @@ static int add_vertex_new(bContext *C, Mask *mask, MaskLayer *masklay, const flo MaskSplinePoint *point; MaskSplinePoint *new_point = NULL, *ref_point = NULL; - ED_mask_select_toggle_all(mask, SEL_DESELECT); - if (!masklay) { /* if there's no masklay currently operationg on, create new one */ masklay = BKE_mask_layer_new(mask, ""); @@ -520,6 +518,8 @@ static int add_vertex_new(bContext *C, Mask *mask, MaskLayer *masklay, const flo finSelectedSplinePoint(masklay, &spline, &point, TRUE); } + ED_mask_select_toggle_all(mask, SEL_DESELECT); + if (!spline) { /* no selected splines in active masklay, create new spline */ spline = BKE_mask_spline_add(masklay); From 276701502a6a55be8e447a728914406150e7b7c0 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Fri, 8 Jun 2012 17:42:17 +0000 Subject: [PATCH 168/360] Make planar tracking much faster. - This makes planar tracking around 2-3x or more faster than before, by rearranging how the sampling is done. Previously, the source patch was sampled repeatedly on every optimizer iteration; this was done for implementation speed, but was wasteful in computation. - This also contains some additions to Ceres to help deailing with mixed numeric / automatic differentation. In particular, there is now a "Chain::Rule" operator that facilitates calling a function that takes Jet arguments, yet does numeric derivatives internally. This is used to mix the numeric differentation of the images with the warp parameters, passed as jets by Ceres to the warp functor. There is also a new "JetOps" object for doing operations on types which may or may not be jets, such as scaling the derivative part only, or extracting the scalar part of a jet. The Ceres patches are aimed at upstream. - A new function for sampling a patch is now part of the track_region.h API; this will get used to make the preview widget properly show what is getting tracked. Currently the preview widget does not handle perspective tracks. Known issues: This patch introduces a bug such that the "Minimum Correlation" flag does not work; if it is enabled, tracking aborts immediately. The workaround for now is to disable the correlation checking, and examine your tracks carefully. A fix will get added shortly. --- extern/libmv/libmv/image/sample.h | 29 +- extern/libmv/libmv/tracking/track_region.cc | 297 ++++++++++-------- extern/libmv/libmv/tracking/track_region.h | 10 + .../third_party/ceres/include/ceres/jet.h | 84 +++++ 4 files changed, 286 insertions(+), 134 deletions(-) diff --git a/extern/libmv/libmv/image/sample.h b/extern/libmv/libmv/image/sample.h index e842747e6d4..7bcbe5b0401 100644 --- a/extern/libmv/libmv/image/sample.h +++ b/extern/libmv/libmv/image/sample.h @@ -37,15 +37,15 @@ inline T SampleNearest(const Array3D &image, static inline void LinearInitAxis(float fx, int width, int *x1, int *x2, float *dx1, float *dx2) { - const int ix = int(fx); + const int ix = static_cast(fx); if (ix < 0) { *x1 = 0; *x2 = 0; *dx1 = 1; *dx2 = 0; - } else if (ix > width-2) { - *x1 = width-1; - *x2 = width-1; + } else if (ix > width - 2) { + *x1 = width - 1; + *x2 = width - 1; *dx1 = 1; *dx2 = 0; } else { @@ -74,6 +74,27 @@ inline T SampleLinear(const Array3D &image, float y, float x, int v = 0) { dy2 * ( dx1 * im21 + dx2 * im22 )); } +/// Linear interpolation, of all channels. The sample is assumed to have the +/// same size as the number of channels in image. +template +inline void SampleLinear(const Array3D &image, float y, float x, T *sample) { + int x1, y1, x2, y2; + float dx1, dy1, dx2, dy2; + + LinearInitAxis(y, image.Height(), &y1, &y2, &dy1, &dy2); + LinearInitAxis(x, image.Width(), &x1, &x2, &dx1, &dx2); + + for (int i = 0; i < image.Depth(); ++i) { + const T im11 = image(y1, x1, i); + const T im12 = image(y1, x2, i); + const T im21 = image(y2, x1, i); + const T im22 = image(y2, x2, i); + + sample[i] = T(dy1 * ( dx1 * im11 + dx2 * im12 ) + + dy2 * ( dx1 * im21 + dx2 * im22 )); + } +} + // Downsample all channels by 2. If the image has odd width or height, the last // row or column is ignored. // FIXME(MatthiasF): this implementation shouldn't be in an interface file diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index 62cc43205d0..bcfb976fc68 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -43,6 +43,10 @@ namespace libmv { +using ceres::Jet; +using ceres::JetOps; +using ceres::Chain; + TrackRegionOptions::TrackRegionOptions() : mode(TRANSLATION), minimum_correlation(0), @@ -77,70 +81,30 @@ bool AllInBounds(const FloatImage &image, return true; } -// Because C++03 doesn't support partial template specializations for -// functions, but at the same time member function specializations are not -// supported, the sample function must be inside a template-specialized class -// with a non-templated static member. - // The "AutoDiff::Sample()" function allows sampling an image at an x, y // position such that if x and y are jets, then the derivative information is // correctly propagated. - -// Empty default template. template -struct AutoDiff { - // Sample only the image when the coordinates are scalars. - static T Sample(const FloatImage &image_and_gradient, - const T &x, const T &y) { - return SampleLinear(image_and_gradient, y, x, 0); - } +static T SampleWithDerivative(const FloatImage &image_and_gradient, + const T &x, + const T &y) { + float scalar_x = JetOps::GetScalar(x); + float scalar_y = JetOps::GetScalar(y); - static void SetScalarPart(double scalar, T *value) { - *value = scalar; + // Note that sample[1] and sample[2] will be uninitialized in the scalar + // case, but that is not an issue because the Chain::Rule below will not read + // the uninitialized values. + float sample[3]; + if (JetOps::IsScalar()) { + // For the scalar case, only sample the image. + sample[0] = SampleLinear(image_and_gradient, scalar_y, scalar_x, 0); + } else { + // For the derivative case, sample the gradient as well. + SampleLinear(image_and_gradient, scalar_y, scalar_x, sample); } - static void ScaleDerivative(double scale_by, T *value) { - // For double, there is no derivative to scale. - } -}; - -// Sample the image and gradient when the coordinates are jets, applying the -// jacobian appropriately to propagate the derivatives from the coordinates. -template -struct AutoDiff > { - static ceres::Jet Sample(const FloatImage &image_and_gradient, - const ceres::Jet &x, - const ceres::Jet &y) { - // Sample the image and its derivatives in x and y. One way to think of - // this is that the image is a scalar function with a single vector - // argument, xy, of dimension 2. Call this s(xy). - const T s = SampleLinear(image_and_gradient, y.a, x.a, 0); - const T dsdx = SampleLinear(image_and_gradient, y.a, x.a, 1); - const T dsdy = SampleLinear(image_and_gradient, y.a, x.a, 2); - - // However, xy is itself a function of another variable ("z"); xy(z) = - // [x(z), y(z)]^T. What this function needs to return is "s", but with the - // derivative with respect to z attached to the jet. So combine the - // derivative part of x and y's jets to form a Jacobian matrix between x, y - // and z (i.e. dxy/dz). - Eigen::Matrix dxydz; - dxydz.row(0) = x.v.transpose(); - dxydz.row(1) = y.v.transpose(); - - // Now apply the chain rule to obtain ds/dz. Combine the derivative with - // the scalar part to obtain s with full derivative information. - ceres::Jet jet_s; - jet_s.a = s; - jet_s.v = Matrix(dsdx, dsdy) * dxydz; - return jet_s; - } - - static void SetScalarPart(double scalar, ceres::Jet *value) { - value->a = scalar; - } - static void ScaleDerivative(double scale_by, ceres::Jet *value) { - value->v *= scale_by; - } -}; + T xy[2] = { x, y }; + return Chain::Rule(sample[0], sample + 1, xy); +} template class BoundaryCheckingCallback : public ceres::IterationCallback { @@ -188,36 +152,73 @@ class WarpCostFunctor { canonical_to_image1_(canonical_to_image1), num_samples_x_(num_samples_x), num_samples_y_(num_samples_y), - warp_(warp) {} + warp_(warp), + pattern_and_gradient_(num_samples_y_, num_samples_x_, 3), + pattern_positions_(num_samples_y_, num_samples_x_, 2), + pattern_mask_(num_samples_y_, num_samples_x_, 1) { + ComputeCanonicalPatchAndNormalizer(); + } + + void ComputeCanonicalPatchAndNormalizer() { + src_mean_ = 0.0; + double num_samples = 0.0; + for (int r = 0; r < num_samples_y_; ++r) { + for (int c = 0; c < num_samples_x_; ++c) { + // Compute the position; cache it. + Vec3 image_position = canonical_to_image1_ * Vec3(c, r, 1); + image_position /= image_position(2); + pattern_positions_(r, c, 0) = image_position(0); + pattern_positions_(r, c, 1) = image_position(1); + + // Sample the pattern and gradients. + SampleLinear(image_and_gradient1_, + image_position(1), // Sample is r, c. + image_position(0), + &pattern_and_gradient_(r, c, 0)); + + // Sample sample the mask. + double mask_value = 1.0; + if (options_.image1_mask != NULL) { + SampleLinear(*options_.image1_mask, + image_position(1), + image_position(0), + &pattern_mask_(r, c, 0)); + mask_value = pattern_mask_(r, c); + } + src_mean_ += pattern_and_gradient_(r, c, 0) * mask_value; + num_samples += mask_value; + } + } + src_mean_ /= num_samples; + } template bool operator()(const T *warp_parameters, T *residuals) const { + if (options_.image1_mask != NULL) { + VLOG(2) << "Using a mask."; + } for (int i = 0; i < Warp::NUM_PARAMETERS; ++i) { VLOG(2) << "warp_parameters[" << i << "]: " << warp_parameters[i]; } - T src_mean = T(1.0); T dst_mean = T(1.0); if (options_.use_normalized_intensities) { - ComputeNormalizingCoefficients(warp_parameters, - &src_mean, - &dst_mean); + ComputeNormalizingCoefficient(warp_parameters, + &dst_mean); } int cursor = 0; for (int r = 0; r < num_samples_y_; ++r) { for (int c = 0; c < num_samples_x_; ++c) { - // Compute the location of the source pixel (via homography). - Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1); - image1_position /= image1_position(2); - + // Use the pre-computed image1 position. + Vec2 image1_position(pattern_positions_(r, c, 0), + pattern_positions_(r, c, 1)); + // Sample the mask early; if it's zero, this pixel has no effect. This // allows early bailout from the expensive sampling that happens below. double mask_value = 1.0; if (options_.image1_mask != NULL) { - mask_value = AutoDiff::Sample(*options_.image1_mask, - image1_position[0], - image1_position[1]); + mask_value = pattern_mask_(r, c); if (mask_value == 0.0) { residuals[cursor++] = T(0.0); continue; @@ -233,54 +234,61 @@ class WarpCostFunctor { &image2_position[1]); // Sample the destination, propagating derivatives. - T dst_sample = AutoDiff::Sample(image_and_gradient2_, - image2_position[0], - image2_position[1]); + T dst_sample = SampleWithDerivative(image_and_gradient2_, + image2_position[0], + image2_position[1]); // Sample the source. This is made complicated by ESM mode. T src_sample; - if (options_.use_esm) { + if (0 && options_.use_esm && !JetOps::IsScalar()) { // In ESM mode, the derivative of the source is also taken into // account. This changes the linearization in a way that causes // better convergence. Copy the derivative of the warp parameters // onto the jets for the image1 position. This is the ESM hack. - T image1_position_x = image2_position[0]; - T image1_position_y = image2_position[1]; - AutoDiff::SetScalarPart(image1_position[0], &image1_position_x); - AutoDiff::SetScalarPart(image1_position[1], &image1_position_y); - src_sample = AutoDiff::Sample(image_and_gradient1_, - image1_position_x, - image1_position_y); + T image1_position_jet[2] = { + image2_position[0], // Order is x, y. This matches the + image2_position[1] // derivative order in the patch. + }; + JetOps::SetScalar(image1_position[0], image1_position_jet + 0); + JetOps::SetScalar(image1_position[1], image1_position_jet + 1); + + // Now that the image1 positions have the jets applied from the + // image2 position (the ESM hack), chain the image gradients to + // obtain a sample with the derivative with respect to the warp + // parameters attached. + src_sample = Chain::Rule(pattern_and_gradient_(r, c), + &pattern_and_gradient_(r, c, 1), + image1_position_jet); // The jacobians for these should be averaged. Due to the subtraction // below, flip the sign of the src derivative so that the effect // after subtraction of the jets is that they are averaged. - AutoDiff::ScaleDerivative(-0.5, &src_sample); - AutoDiff::ScaleDerivative(0.5, &dst_sample); + JetOps::ScaleDerivative(-0.5, &src_sample); + JetOps::ScaleDerivative(0.5, &dst_sample); } else { // This is the traditional, forward-mode KLT solution. - src_sample = T(AutoDiff::Sample(image_and_gradient1_, - image1_position[0], - image1_position[1])); + src_sample = T(pattern_and_gradient_(r, c)); } + //LG << "src_sample: " << src_sample; + // Normalize the samples by the mean values of each signal. The typical // light model assumes multiplicative intensity changes with changing // light, so this is a reasonable choice. Note that dst_mean has // derivative information attached thanks to autodiff. if (options_.use_normalized_intensities) { - src_sample /= src_mean; + src_sample /= T(src_mean_); dst_sample /= dst_mean; } + //LG << "dst_sample: " << dst_sample; + // The difference is the error. T error = src_sample - dst_sample; // Weight the error by the mask, if one is present. if (options_.image1_mask != NULL) { - error *= T(AutoDiff::Sample(*options_.image1_mask, - image1_position[0], - image1_position[1])); + error *= T(mask_value); } residuals[cursor++] = error; } @@ -290,26 +298,22 @@ class WarpCostFunctor { // For normalized matching, the average and template - void ComputeNormalizingCoefficients(const T *warp_parameters, - T *src_mean, - T *dst_mean) const { + void ComputeNormalizingCoefficient(const T *warp_parameters, + T *dst_mean) const { - *src_mean = T(0.0); *dst_mean = T(0.0); double num_samples = 0.0; for (int r = 0; r < num_samples_y_; ++r) { for (int c = 0; c < num_samples_x_; ++c) { - // Compute the location of the source pixel (via homography). - Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1); - image1_position /= image1_position(2); + // Use the pre-computed image1 position. + Vec2 image1_position(pattern_positions_(r, c, 0), + pattern_positions_(r, c, 1)); // Sample the mask early; if it's zero, this pixel has no effect. This // allows early bailout from the expensive sampling that happens below. double mask_value = 1.0; if (options_.image1_mask != NULL) { - mask_value = AutoDiff::Sample(*options_.image1_mask, - image1_position[0], - image1_position[1]); + mask_value = pattern_mask_(r, c); if (mask_value == 0.0) { continue; } @@ -328,31 +332,20 @@ class WarpCostFunctor { // TODO(keir): This accumulation can, surprisingly, be done as a // pre-pass by using integral images. This is complicated by the need // to store the jets in the integral image, but it is possible. - T dst_sample = AutoDiff::Sample(image_and_gradient2_, - image2_position[0], - image2_position[1]); - - // Sample the source. - // TODO(keir): There is no reason to do this inside the loop; - // precompute this and reuse it. - T src_sample = T(AutoDiff::Sample(image_and_gradient1_, - image1_position[0], - image1_position[1])); + T dst_sample = SampleWithDerivative(image_and_gradient2_, + image2_position[0], + image2_position[1]); // Weight the sample by the mask, if one is present. if (options_.image1_mask != NULL) { - src_sample *= T(mask_value); dst_sample *= T(mask_value); } - *src_mean += src_sample; *dst_mean += dst_sample; num_samples += mask_value; } } - *src_mean /= T(num_samples); *dst_mean /= T(num_samples); - LG << "Normalization for src:" << *src_mean; LG << "Normalization for dst:" << *dst_mean; } @@ -369,16 +362,23 @@ class WarpCostFunctor { double sX = 0, sY = 0, sXX = 0, sYY = 0, sXY = 0; // Due to masking, it's important to account for fractional samples. - // Samples with a 50% mask get counted as a half sample. + // For example, samples with a 50% mask are counted as a half sample. double num_samples = 0; for (int r = 0; r < num_samples_y_; ++r) { for (int c = 0; c < num_samples_x_; ++c) { - // Compute the location of the source pixel (via homography). - // TODO(keir): Cache these projections. - Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1); - image1_position /= image1_position(2); + // Use the pre-computed image1 position. + Vec2 image1_position(pattern_positions_(r, c, 0), + pattern_positions_(r, c, 1)); + double mask_value = 1.0; + if (options_.image1_mask != NULL) { + mask_value = pattern_mask_(r, c); + if (mask_value == 0.0) { + continue; + } + } + // Compute the location of the destination pixel. double image2_position[2]; warp_.Forward(warp_parameters, @@ -387,19 +387,13 @@ class WarpCostFunctor { &image2_position[0], &image2_position[1]); - double x = AutoDiff::Sample(image_and_gradient2_, - image2_position[0], - image2_position[1]); - - double y = AutoDiff::Sample(image_and_gradient1_, - image1_position[0], - image1_position[1]); + double x = pattern_and_gradient_(r, c); + double y = SampleLinear(image_and_gradient2_, + image2_position[0], + image2_position[1]); // Weight the signals by the mask, if one is present. if (options_.image1_mask != NULL) { - double mask_value = AutoDiff::Sample(*options_.image1_mask, - image1_position[0], - image1_position[1]); x *= mask_value; y *= mask_value; num_samples += mask_value; @@ -439,6 +433,15 @@ class WarpCostFunctor { int num_samples_x_; int num_samples_y_; const Warp &warp_; + double src_mean_; + FloatImage pattern_and_gradient_; + + // This contains the position from where the cached pattern samples were + // taken from. This is also used to warp from src to dest without going from + // canonical pixels to src first. + FloatImage pattern_positions_; + + FloatImage pattern_mask_; }; // Compute the warp from rectangular coordinates, where one corner is the @@ -1073,6 +1076,9 @@ void TemplatedTrackRegion(const FloatImage &image1, << x2[i] << ", " << y2[i] << "); (dx, dy): (" << (x2[i] - x1[i]) << ", " << (y2[i] - y1[i]) << ")."; } + if (options.use_normalized_intensities) { + LG << "Using normalized intensities."; + } // Bail early if the points are already outside. if (!AllInBounds(image1, x1, y1)) { @@ -1232,7 +1238,6 @@ void TrackRegion(const FloatImage &image1, result); \ return; \ } - HANDLE_MODE(TRANSLATION, TranslationWarp); HANDLE_MODE(TRANSLATION_SCALE, TranslationScaleWarp); HANDLE_MODE(TRANSLATION_ROTATION, TranslationRotationWarp); @@ -1242,4 +1247,36 @@ void TrackRegion(const FloatImage &image1, #undef HANDLE_MODE } +bool SamplePlanarPatch(const FloatImage &image, + const double *xs, const double *ys, + int num_samples_x, int num_samples_y, + FloatImage *patch) { + // Bail early if the points are outside the image. + if (!AllInBounds(image, xs, ys)) { + LG << "Can't sample patch: out of bounds."; + return false; + } + + // Make the patch have the appropriate size, and match the depth of image. + patch->Resize(num_samples_y, num_samples_x, image.Depth()); + + // Compute the warp from rectangular coordinates. + Mat3 canonical_homography = ComputeCanonicalHomography(xs, ys, + num_samples_x, + num_samples_y); + + // Walk over the coordinates in the canonical space, sampling from the image + // in the original space and copying the result into the patch. + for (int r = 0; r < num_samples_y; ++r) { + for (int c = 0; c < num_samples_x; ++c) { + Vec3 image_position = canonical_homography * Vec3(c, r, 1); + image_position /= image_position(2); + SampleLinear(image, image_position(1), + image_position(0), + &(*patch)(r, c, 0)); + } + } + return true; +} + } // namespace libmv diff --git a/extern/libmv/libmv/tracking/track_region.h b/extern/libmv/libmv/tracking/track_region.h index 4a1427a6b9f..ca21090e7c0 100644 --- a/extern/libmv/libmv/tracking/track_region.h +++ b/extern/libmv/libmv/tracking/track_region.h @@ -113,6 +113,16 @@ void TrackRegion(const FloatImage &image1, double *x2, double *y2, TrackRegionResult *result); +// Sample a "canonical" version of the passed planar patch, using bilinear +// sampling. The passed corners must be within the image, possibly with a small +// amount of slop, perhaps 2 pixels, around the edges (so e.g. a corner of the +// patch cannot lie directly on the edge of the image). Four corners are always +// required. All channels are interpolated. +bool SamplePlanarPatch(const FloatImage &image, + const double *xs, const double *ys, + int num_samples_x, int num_samples_y, + FloatImage *patch); + } // namespace libmv #endif // LIBMV_TRACKING_TRACK_REGION_H_ diff --git a/extern/libmv/third_party/ceres/include/ceres/jet.h b/extern/libmv/third_party/ceres/include/ceres/jet.h index f73c6988951..264861735ed 100644 --- a/extern/libmv/third_party/ceres/include/ceres/jet.h +++ b/extern/libmv/third_party/ceres/include/ceres/jet.h @@ -199,6 +199,18 @@ struct Jet { v[k] = T(1.0); } + /* + + // Construct from an array where the first element is the scalar. + // This is templated to support converting from other data types. + template + Jet(const D* scalar_and_derivatives) { + a = T(scalar_and_derivatives[0]); + v = Eigen::Map >( + scalar_and_derivatives + 1, N).cast(); + } + */ + // Compound operators Jet& operator+=(const Jet &y) { *this = *this + y; @@ -638,6 +650,78 @@ inline std::ostream &operator<<(std::ostream &s, const Jet& z) { return s << "[" << z.a << " ; " << z.v.transpose() << "]"; } +// A jet traits class to make it easier to work with mixed auto / numeric diff. +template +struct JetOps { + static bool IsScalar() { + return true; + } + static T GetScalar(const T& t) { + return t; + } + static void SetScalar(const T& scalar, T* t) { + *t = scalar; + } + static void ScaleDerivative(double scale_by, T *value) { + // For double, there is no derivative to scale. + } +}; + +template +struct JetOps > { + static bool IsScalar() { + return false; + } + static T GetScalar(const Jet& t) { + return t.a; + } + static void SetScalar(const T& scalar, Jet* t) { + t->a = scalar; + } + static void ScaleDerivative(double scale_by, Jet *value) { + value->v *= scale_by; + } +}; + +template +struct Chain { + static ArgumentType Rule(const FunctionType &f, + const FunctionType dfdx[kNumArgs], + const ArgumentType x[kNumArgs]) { + // In the default case of scalars, there's nothing to do since there are no + // derivatives to propagate. + return f; + } +}; + +// XXX Add documentation here! +template +struct Chain > { + static Jet Rule(const FunctionType &f, + const FunctionType dfdx[kNumArgs], + const Jet x[kNumArgs]) { + // x is itself a function of another variable ("z"); what this function + // needs to return is "f", but with the derivative with respect to z + // attached to the jet. So combine the derivative part of x's jets to form + // a Jacobian matrix between x and z (i.e. dx/dz). + Eigen::Matrix dxdz; + for (int i = 0; i < kNumArgs; ++i) { + dxdz.row(i) = x[i].v.transpose(); + } + + // Map the input gradient dfdx into an Eigen row vector. + Eigen::Map > + vector_dfdx(dfdx, 1, kNumArgs); + + // Now apply the chain rule to obtain df/dz. Combine the derivative with + // the scalar part to obtain f with full derivative information. + Jet jet_f; + jet_f.a = f; + jet_f.v = vector_dfdx.template cast() * dxdz; // Also known as dfdz. + return jet_f; + } +}; + } // namespace ceres namespace Eigen { From f9be7fca1747218323cc53a52842374229cdff4a Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Sat, 9 Jun 2012 06:55:21 +0000 Subject: [PATCH 169/360] Planar tracker polish. - Fixes the correlation checking code that was broken in the previous commit. The bug was a transpose error. - Fixes a memory leak of the warp functor, found by Sameer. - Various cleanups done at Sameer's suggestion. Thanks to Sameer Agarwal for a code review. --- extern/libmv/libmv/image/sample.h | 45 +++++++------ extern/libmv/libmv/tracking/track_region.cc | 70 +++++++++++---------- extern/libmv/libmv/tracking/track_region.h | 8 +-- 3 files changed, 61 insertions(+), 62 deletions(-) diff --git a/extern/libmv/libmv/image/sample.h b/extern/libmv/libmv/image/sample.h index 7bcbe5b0401..04a5748ea44 100644 --- a/extern/libmv/libmv/image/sample.h +++ b/extern/libmv/libmv/image/sample.h @@ -34,25 +34,22 @@ inline T SampleNearest(const Array3D &image, return image(i, j, v); } -static inline void LinearInitAxis(float fx, int width, - int *x1, int *x2, - float *dx1, float *dx2) { - const int ix = static_cast(fx); +inline void LinearInitAxis(float x, int size, + int *x1, int *x2, + float *dx) { + const int ix = static_cast(x); if (ix < 0) { *x1 = 0; *x2 = 0; - *dx1 = 1; - *dx2 = 0; - } else if (ix > width - 2) { - *x1 = width - 1; - *x2 = width - 1; - *dx1 = 1; - *dx2 = 0; + *dx = 1.0; + } else if (ix > size - 2) { + *x1 = size - 1; + *x2 = size - 1; + *dx = 1.0; } else { *x1 = ix; - *x2 = *x1 + 1; - *dx1 = *x2 - fx; - *dx2 = 1 - *dx1; + *x2 = ix + 1; + *dx = *x2 - x; } } @@ -60,18 +57,18 @@ static inline void LinearInitAxis(float fx, int width, template inline T SampleLinear(const Array3D &image, float y, float x, int v = 0) { int x1, y1, x2, y2; - float dx1, dy1, dx2, dy2; + float dx, dy; - LinearInitAxis(y, image.Height(), &y1, &y2, &dy1, &dy2); - LinearInitAxis(x, image.Width(), &x1, &x2, &dx1, &dx2); + LinearInitAxis(y, image.Height(), &y1, &y2, &dy); + LinearInitAxis(x, image.Width(), &x1, &x2, &dx); const T im11 = image(y1, x1, v); const T im12 = image(y1, x2, v); const T im21 = image(y2, x1, v); const T im22 = image(y2, x2, v); - return T(dy1 * ( dx1 * im11 + dx2 * im12 ) + - dy2 * ( dx1 * im21 + dx2 * im22 )); + return T( dy * ( dx * im11 + (1.0 - dx) * im12 ) + + (1 - dy) * ( dx * im21 + (1.0 - dx) * im22 )); } /// Linear interpolation, of all channels. The sample is assumed to have the @@ -79,10 +76,10 @@ inline T SampleLinear(const Array3D &image, float y, float x, int v = 0) { template inline void SampleLinear(const Array3D &image, float y, float x, T *sample) { int x1, y1, x2, y2; - float dx1, dy1, dx2, dy2; + float dx, dy; - LinearInitAxis(y, image.Height(), &y1, &y2, &dy1, &dy2); - LinearInitAxis(x, image.Width(), &x1, &x2, &dx1, &dx2); + LinearInitAxis(y, image.Height(), &y1, &y2, &dy); + LinearInitAxis(x, image.Width(), &x1, &x2, &dx); for (int i = 0; i < image.Depth(); ++i) { const T im11 = image(y1, x1, i); @@ -90,8 +87,8 @@ inline void SampleLinear(const Array3D &image, float y, float x, T *sample) { const T im21 = image(y2, x1, i); const T im22 = image(y2, x2, i); - sample[i] = T(dy1 * ( dx1 * im11 + dx2 * im12 ) + - dy2 * ( dx1 * im21 + dx2 * im22 )); + sample[i] = T( dy * ( dx * im11 + (1.0 - dx) * im12 ) + + (1 - dy) * ( dx * im21 + (1.0 - dx) * im22 )); } } diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index bcfb976fc68..b9e4f883e78 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -81,9 +81,9 @@ bool AllInBounds(const FloatImage &image, return true; } -// The "AutoDiff::Sample()" function allows sampling an image at an x, y -// position such that if x and y are jets, then the derivative information is -// correctly propagated. +// Sample the image at position (x, y) but use the gradient, if present, to +// propagate derivatives from x and y. This is needed to integrate the numeric +// image gradients with Ceres's autodiff framework. template static T SampleWithDerivative(const FloatImage &image_and_gradient, const T &x, @@ -172,7 +172,7 @@ class WarpCostFunctor { // Sample the pattern and gradients. SampleLinear(image_and_gradient1_, - image_position(1), // Sample is r, c. + image_position(1), // SampleLinear is r, c. image_position(0), &pattern_and_gradient_(r, c, 0)); @@ -180,7 +180,7 @@ class WarpCostFunctor { double mask_value = 1.0; if (options_.image1_mask != NULL) { SampleLinear(*options_.image1_mask, - image_position(1), + image_position(1), // SampleLinear is r, c. image_position(0), &pattern_mask_(r, c, 0)); mask_value = pattern_mask_(r, c); @@ -216,6 +216,16 @@ class WarpCostFunctor { // Sample the mask early; if it's zero, this pixel has no effect. This // allows early bailout from the expensive sampling that happens below. + // + // Note that partial masks are not short circuited. To see why short + // circuiting produces bitwise-exact same results, consider that the + // residual for each pixel is + // + // residual = mask * (src - dst) , + // + // and for jets, multiplying by a scalar multiplies the derivative + // components by the scalar as well. Therefore, if the mask is exactly + // zero, then so too will the final residual and derivatives. double mask_value = 1.0; if (options_.image1_mask != NULL) { mask_value = pattern_mask_(r, c); @@ -240,7 +250,7 @@ class WarpCostFunctor { // Sample the source. This is made complicated by ESM mode. T src_sample; - if (0 && options_.use_esm && !JetOps::IsScalar()) { + if (options_.use_esm && !JetOps::IsScalar()) { // In ESM mode, the derivative of the source is also taken into // account. This changes the linearization in a way that causes // better convergence. Copy the derivative of the warp parameters @@ -270,8 +280,6 @@ class WarpCostFunctor { src_sample = T(pattern_and_gradient_(r, c)); } - //LG << "src_sample: " << src_sample; - // Normalize the samples by the mean values of each signal. The typical // light model assumes multiplicative intensity changes with changing // light, so this is a reasonable choice. Note that dst_mean has @@ -281,8 +289,6 @@ class WarpCostFunctor { dst_sample /= dst_mean; } - //LG << "dst_sample: " << dst_sample; - // The difference is the error. T error = src_sample - dst_sample; @@ -389,8 +395,8 @@ class WarpCostFunctor { double x = pattern_and_gradient_(r, c); double y = SampleLinear(image_and_gradient2_, - image2_position[0], - image2_position[1]); + image2_position[1], // SampleLinear is r, c. + image2_position[0]); // Weight the signals by the mask, if one is present. if (options_.image1_mask != NULL) { @@ -1111,13 +1117,14 @@ void TemplatedTrackRegion(const FloatImage &image1, x1, y1, x2, y2); for (int i = 0; i < 4; ++i) { LG << "P" << i << ": (" << x1[i] << ", " << y1[i] << "); brute (" - << x2[i] << ", " << y2[i] << "); (dx, dy): (" << (x2[i] - x1[i]) << ", " - << (y2[i] - y1[i]) << ")."; + << x2[i] << ", " << y2[i] << "); (dx, dy): (" << (x2[i] - x1[i]) + << ", " << (y2[i] - y1[i]) << ")."; } } // Prepare the initial warp parameters from the four correspondences. - // Note: This must happen after the brute initialization runs. + // Note: This must happen after the brute initialization runs, since the + // brute initialization mutates x2 and y2 in place. Warp warp(x1, y1, x2, y2); // Decide how many samples to use in the x and y dimensions. @@ -1125,22 +1132,6 @@ void TemplatedTrackRegion(const FloatImage &image1, int num_samples_y; PickSampling(x1, y1, x2, y2, &num_samples_x, &num_samples_y); - ceres::Solver::Options solver_options; - solver_options.linear_solver_type = ceres::DENSE_QR; - solver_options.max_num_iterations = options.max_iterations; - solver_options.update_state_every_iteration = true; - solver_options.parameter_tolerance = 1e-16; - solver_options.function_tolerance = 1e-16; - - // TODO(keir): Consider removing these options before committing. - solver_options.numeric_derivative_relative_step_size = 1e-3; - solver_options.check_gradients = false; - solver_options.gradient_check_relative_precision = 1e-10; - solver_options.minimizer_progress_to_stdout = false; - - // Prevent the corners from going outside the destination image. - BoundaryCheckingCallback callback(image2, warp, x1, y1); - solver_options.callbacks.push_back(&callback); // Compute the warp from rectangular coordinates. Mat3 canonical_homography = ComputeCanonicalHomography(x1, y1, @@ -1158,9 +1149,7 @@ void TemplatedTrackRegion(const FloatImage &image1, warp); // Construct the problem with a single residual. - ceres::Problem::Options problem_options; - problem_options.cost_function_ownership = ceres::DO_NOT_TAKE_OWNERSHIP; - ceres::Problem problem(problem_options); + ceres::Problem problem; problem.AddResidualBlock( new ceres::AutoDiffCostFunction< WarpCostFunctor, @@ -1170,6 +1159,19 @@ void TemplatedTrackRegion(const FloatImage &image1, NULL, warp.parameters); + // Configure the solve. + ceres::Solver::Options solver_options; + solver_options.linear_solver_type = ceres::DENSE_QR; + solver_options.max_num_iterations = options.max_iterations; + solver_options.update_state_every_iteration = true; + solver_options.parameter_tolerance = 1e-16; + solver_options.function_tolerance = 1e-16; + + // Prevent the corners from going outside the destination image. + BoundaryCheckingCallback callback(image2, warp, x1, y1); + solver_options.callbacks.push_back(&callback); + + // Run the solve. ceres::Solver::Summary summary; ceres::Solve(solver_options, &problem, &summary); diff --git a/extern/libmv/libmv/tracking/track_region.h b/extern/libmv/libmv/tracking/track_region.h index ca21090e7c0..c23cde6000f 100644 --- a/extern/libmv/libmv/tracking/track_region.h +++ b/extern/libmv/libmv/tracking/track_region.h @@ -114,10 +114,10 @@ void TrackRegion(const FloatImage &image1, TrackRegionResult *result); // Sample a "canonical" version of the passed planar patch, using bilinear -// sampling. The passed corners must be within the image, possibly with a small -// amount of slop, perhaps 2 pixels, around the edges (so e.g. a corner of the -// patch cannot lie directly on the edge of the image). Four corners are always -// required. All channels are interpolated. +// sampling. The passed corners must be within the image, and have at least two +// pixels of border around them. (so e.g. a corner of the patch cannot lie +// directly on the edge of the image). Four corners are always required. All +// channels are interpolated. bool SamplePlanarPatch(const FloatImage &image, const double *xs, const double *ys, int num_samples_x, int num_samples_y, From 039acbbfef112e140a47dcab05a40d732d293deb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 9 Jun 2012 11:14:36 +0000 Subject: [PATCH 170/360] Homography correction for track preview widget Use homography transformation for pattern displayed in track preview widget. Sampling of this pattern happens to resolution of preview widget itself, which implied some bigger changes in how scopes are working: - Instead of real pattern store search area in BKE_movieclip_update_scopes, which is later used for sampling pattern. - Sampling of pattern happens in ui_draw_but_TRACKPREVIEW from search area which allows to sample it to actual resolution of preview widget. - If size of preview widget is not changing, this sampled pattern wouldn't be re-sampled until scopes are tagged to update. There are some issues with pattern sampling which seems to happen SamplePlanarPatch, changing linear sampling to nearest removes that unwanted 1px offset. Left commented saving of sampled image in ui_draw_but_TRACKPREVIEW which should help figuring the issue out. --- extern/libmv/libmv-capi.cpp | 46 ++- extern/libmv/libmv-capi.h | 5 + extern/libmv/libmv/tracking/track_region.cc | 10 +- extern/libmv/libmv/tracking/track_region.h | 3 +- source/blender/blenkernel/BKE_tracking.h | 10 +- source/blender/blenkernel/intern/movieclip.c | 26 +- source/blender/blenkernel/intern/tracking.c | 298 +++++++++--------- source/blender/blenloader/intern/readfile.c | 1 + .../operations/COM_KeyingScreenOperation.cpp | 2 +- .../editors/interface/interface_draw.c | 84 +++-- .../blender/editors/space_clip/space_clip.c | 4 + source/blender/makesdna/DNA_movieclip_types.h | 3 + .../nodes/node_composite_keyingscreen.c | 2 +- 13 files changed, 264 insertions(+), 230 deletions(-) diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index eba4698f198..ffa065f08fe 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -163,15 +163,30 @@ libmv_RegionTracker *libmv_bruteRegionTrackerNew(int half_window_size, double mi return (libmv_RegionTracker *)brute_region_tracker; } -static void floatBufToImage(const float *buf, int width, int height, libmv::FloatImage *image) +static void floatBufToImage(const float *buf, int width, int height, int channels, libmv::FloatImage *image) { - int x, y, a = 0; + int x, y, k, a = 0; - image->resize(height, width); + image->Resize(height, width, channels); for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { - (*image)(y, x, 0) = buf[a++]; + for (k = 0; k < channels; k++) { + (*image)(y, x, k) = buf[a++]; + } + } + } +} + +static void imageToFloatBuf(const libmv::FloatImage *image, int channels, float *buf) +{ + int x, y, k, a = 0; + + for (y = 0; y < image->Height(); y++) { + for (x = 0; x < image->Width(); x++) { + for (k = 0; k < channels; k++) { + buf[a++] = (*image)(y, x, k); + } } } } @@ -307,8 +322,8 @@ int libmv_regionTrackerTrack(libmv_RegionTracker *libmv_tracker, const float *im libmv::RegionTracker *region_tracker = (libmv::RegionTracker *)libmv_tracker; libmv::FloatImage old_patch, new_patch; - floatBufToImage(ima1, width, height, &old_patch); - floatBufToImage(ima2, width, height, &new_patch); + floatBufToImage(ima1, width, height, 1, &old_patch); + floatBufToImage(ima2, width, height, 1, &new_patch); #if !defined(DUMP_FAILURE) && !defined(DUMP_ALWAYS) return region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2); @@ -385,8 +400,8 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, /* Convert from raw float buffers to libmv's FloatImage. */ libmv::FloatImage old_patch, new_patch; - floatBufToImage(image1, width, height, &old_patch); - floatBufToImage(image2, width, height, &new_patch); + floatBufToImage(image1, width, height, 1, &old_patch); + floatBufToImage(image2, width, height, 1, &new_patch); libmv::TrackRegionResult track_region_result; libmv::TrackRegion(old_patch, new_patch, xx1, yy1, track_region_options, xx2, yy2, &track_region_result); @@ -420,6 +435,21 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, return tracking_result; } +void libmv_samplePlanarPatch(const float *image, int width, int height, + int channels, const double *xs, const double *ys, + int num_samples_x, int num_samples_y, float *patch, + double *warped_position_x, double *warped_position_y) +{ + libmv::FloatImage libmv_image, libmv_patch; + + floatBufToImage(image, width, height, channels, &libmv_image); + + libmv::SamplePlanarPatch(libmv_image, xs, ys, num_samples_x, num_samples_y, + &libmv_patch, warped_position_x, warped_position_y); + + imageToFloatBuf(&libmv_patch, channels, patch); +} + /* ************ Tracks ************ */ libmv_Tracks *libmv_tracksNew(void) diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index bbd8f0c30d0..6f4b5dea384 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -71,6 +71,11 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, struct libmv_trackRegionResult *result, double *x2, double *y2); +void libmv_samplePlanarPatch(const float *image, int width, int height, + int channels, const double *xs, const double *ys, + int num_samples_x, int num_samples_y, float *patch, + double *warped_position_x, double *warped_position_y); + /* Tracks */ struct libmv_Tracks *libmv_tracksNew(void); void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y); diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index b9e4f883e78..679646c4c37 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -1252,7 +1252,8 @@ void TrackRegion(const FloatImage &image1, bool SamplePlanarPatch(const FloatImage &image, const double *xs, const double *ys, int num_samples_x, int num_samples_y, - FloatImage *patch) { + FloatImage *patch, + double *warped_position_x, double *warped_position_y) { // Bail early if the points are outside the image. if (!AllInBounds(image, xs, ys)) { LG << "Can't sample patch: out of bounds."; @@ -1278,6 +1279,13 @@ bool SamplePlanarPatch(const FloatImage &image, &(*patch)(r, c, 0)); } } + + Vec3 warped_position = canonical_homography.inverse() * Vec3(xs[4], ys[4], 1); + warped_position /= warped_position(2); + + *warped_position_x = warped_position(0); + *warped_position_y = warped_position(1); + return true; } diff --git a/extern/libmv/libmv/tracking/track_region.h b/extern/libmv/libmv/tracking/track_region.h index c23cde6000f..04e7c7e1403 100644 --- a/extern/libmv/libmv/tracking/track_region.h +++ b/extern/libmv/libmv/tracking/track_region.h @@ -121,7 +121,8 @@ void TrackRegion(const FloatImage &image1, bool SamplePlanarPatch(const FloatImage &image, const double *xs, const double *ys, int num_samples_x, int num_samples_y, - FloatImage *patch); + FloatImage *patch, + double *warped_position_x, double *warped_position_y); } // namespace libmv diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 25723b8b0e8..8c28dd93a5e 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -71,13 +71,13 @@ void BKE_tracking_clear_path(struct MovieTrackingTrack *track, int ref_frame, in void BKE_tracking_join_tracks(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); void BKE_tracking_free(struct MovieTracking *tracking); +struct ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, + struct ImBuf *struct_ibuf, struct MovieTrackingMarker *marker, + int num_samples_x, int num_samples_y, float pos[2]); struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker, int margin, int anchored, - float pos[2], int origin[2]); -struct ImBuf *BKE_tracking_get_pattern_color_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker, int anchored); + struct MovieTrackingMarker *marker, int anchored, int disable_channels); struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker); + struct MovieTrackingMarker *marker, int anchored, int disable_channels); struct ImBuf *BKE_tracking_track_mask_get(struct MovieTracking *tracking, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int width, int height); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 244d2888fc6..8b91ee29c59 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1032,6 +1032,11 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip scopes->track_preview = NULL; } + if (scopes->track_search) { + IMB_freeImBuf(scopes->track_search); + scopes->track_search = NULL; + } + scopes->marker = NULL; scopes->track = NULL; @@ -1052,7 +1057,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip scopes->track_disabled = FALSE; if (ibuf && (ibuf->rect || ibuf->rect_float)) { - ImBuf *tmpibuf; + ImBuf *search_ibuf; MovieTrackingMarker undist_marker = *marker; if (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { @@ -1070,17 +1075,18 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip undist_marker.pos[1] /= height * aspy; } - /* NOTE: margin should be kept in sync with value from ui_draw_but_TRACKPREVIEW */ - tmpibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 3 /* margin */, - 1 /* anchor */, scopes->track_pos, NULL); + search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, &undist_marker, TRUE, TRUE); - if (tmpibuf->rect_float) - IMB_rect_from_float(tmpibuf); + if (!search_ibuf->rect_float) { + /* sampling happens in float buffer */ + IMB_float_from_rect(search_ibuf); + } - if (tmpibuf->rect) - scopes->track_preview = tmpibuf; - else - IMB_freeImBuf(tmpibuf); + scopes->undist_marker = undist_marker; + scopes->track_search = search_ibuf; + + scopes->frame_width = ibuf->x; + scopes->frame_height = ibuf->y; } IMB_freeImBuf(ibuf); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 01e464e77a8..1d4ed2c8c40 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -84,10 +84,11 @@ static struct { * window relative coordinates in pixels, and "frame_unified" are unified 0..1 * coordinates relative to the entire frame. */ -static void unified_to_pixel(const ImBuf *ibuf, const float unified_coords[2], float pixel_coords[2]) +static void unified_to_pixel(int frame_width, int frame_height, + const float unified_coords[2], float pixel_coords[2]) { - pixel_coords[0] = unified_coords[0] * ibuf->x; - pixel_coords[1] = unified_coords[1] * ibuf->y; + pixel_coords[0] = unified_coords[0] * frame_width; + pixel_coords[1] = unified_coords[1] * frame_height; } static void marker_to_frame_unified(const MovieTrackingMarker *marker, const float marker_unified_coords[2], @@ -97,52 +98,117 @@ static void marker_to_frame_unified(const MovieTrackingMarker *marker, const flo frame_unified_coords[1] = marker_unified_coords[1] + marker->pos[1]; } -static void marker_unified_to_frame_pixel_coordinates(const ImBuf *ibuf, const MovieTrackingMarker *marker, +static void marker_unified_to_frame_pixel_coordinates(int frame_width, int frame_height, + const MovieTrackingMarker *marker, const float marker_unified_coords[2], float frame_pixel_coords[2]) { marker_to_frame_unified(marker, marker_unified_coords, frame_pixel_coords); - unified_to_pixel(ibuf, frame_pixel_coords, frame_pixel_coords); + unified_to_pixel(frame_width, frame_height, frame_pixel_coords, frame_pixel_coords); } -static void get_search_origin_frame_pixel(const ImBuf *ibuf, const MovieTrackingMarker *marker, float frame_pixel[2]) +static void get_search_origin_frame_pixel(int frame_width, int frame_height, + const MovieTrackingMarker *marker, float frame_pixel[2]) { /* Get the lower left coordinate of the search window and snap to pixel coordinates */ - marker_unified_to_frame_pixel_coordinates(ibuf, marker, marker->search_min, frame_pixel); + marker_unified_to_frame_pixel_coordinates(frame_width, frame_height, marker, marker->search_min, frame_pixel); frame_pixel[0] = (int)frame_pixel[0]; frame_pixel[1] = (int)frame_pixel[1]; } #ifdef WITH_LIBMV -static void pixel_to_unified(const ImBuf *ibuf, const float pixel_coords[2], float unified_coords[2]) +static void pixel_to_unified(int frame_width, int frame_height, const float pixel_coords[2], float unified_coords[2]) { - unified_coords[0] = pixel_coords[0] / ibuf->x; - unified_coords[1] = pixel_coords[1] / ibuf->y; + unified_coords[0] = pixel_coords[0] / frame_width; + unified_coords[1] = pixel_coords[1] / frame_height; } -static void marker_unified_to_search_pixel(const ImBuf *ibuf, const MovieTrackingMarker *marker, +static void marker_unified_to_search_pixel(int frame_width, int frame_height, + const MovieTrackingMarker *marker, const float marker_unified[2], float search_pixel[2]) { float frame_pixel[2]; float search_origin_frame_pixel[2]; - marker_unified_to_frame_pixel_coordinates(ibuf, marker, marker_unified, frame_pixel); - get_search_origin_frame_pixel(ibuf, marker, search_origin_frame_pixel); + marker_unified_to_frame_pixel_coordinates(frame_width, frame_height, marker, marker_unified, frame_pixel); + get_search_origin_frame_pixel(frame_width, frame_height, marker, search_origin_frame_pixel); sub_v2_v2v2(search_pixel, frame_pixel, search_origin_frame_pixel); } -static void search_pixel_to_marker_unified(const ImBuf *ibuf, const MovieTrackingMarker *marker, +static void search_pixel_to_marker_unified(int frame_width, int frame_height, + const MovieTrackingMarker *marker, const float search_pixel[2], float marker_unified[2]) { float frame_unified[2]; float search_origin_frame_pixel[2]; - get_search_origin_frame_pixel(ibuf, marker, search_origin_frame_pixel); + get_search_origin_frame_pixel(frame_width, frame_height, marker, search_origin_frame_pixel); add_v2_v2v2(frame_unified, search_pixel, search_origin_frame_pixel); - pixel_to_unified(ibuf, frame_unified, frame_unified); + pixel_to_unified(frame_width, frame_height, frame_unified, frame_unified); /* marker pos is in frame unified */ sub_v2_v2v2(marker_unified, frame_unified, marker->pos); } + +/* Each marker has 5 coordinates associated with it that get warped with + * tracking: the four corners ("pattern_corners"), and the cernter ("pos"). + * This function puts those 5 points into the appropriate frame for tracking + * (the "search" coordinate frame). + */ +static void get_marker_coords_for_tracking(int frame_width, int frame_height, + const MovieTrackingMarker *marker, + double search_pixel_x[5], double search_pixel_y[5]) +{ + int i; + float unified_coords[2]; + float pixel_coords[2]; + + /* Convert the corners into search space coordinates. */ + for (i = 0; i < 4; i++) { + marker_unified_to_search_pixel(frame_width, frame_height, marker, marker->pattern_corners[i], pixel_coords); + search_pixel_x[i] = pixel_coords[0]; + search_pixel_y[i] = pixel_coords[1]; + } + /* Convert the center position (aka "pos"); this is the origin */ + unified_coords[0] = 0.0; + unified_coords[1] = 0.0; + marker_unified_to_search_pixel(frame_width, frame_height, marker, unified_coords, pixel_coords); + + search_pixel_x[4] = pixel_coords[0]; + search_pixel_y[4] = pixel_coords[1]; +} + +/* Inverse of above. */ +static void set_marker_coords_from_tracking(int frame_width, int frame_height, MovieTrackingMarker *marker, + const double search_pixel_x[5], const double search_pixel_y[5]) +{ + int i; + float marker_unified[2]; + float search_pixel[2]; + + /* Convert the corners into search space coordinates. */ + for (i = 0; i < 4; i++) { + search_pixel[0] = search_pixel_x[i]; + search_pixel[1] = search_pixel_y[i]; + search_pixel_to_marker_unified(frame_width, frame_height, marker, search_pixel, marker->pattern_corners[i]); + } + + /* Convert the center position (aka "pos"); this is the origin */ + search_pixel[0] = search_pixel_x[4]; + search_pixel[1] = search_pixel_y[4]; + search_pixel_to_marker_unified(frame_width, frame_height, marker, search_pixel, marker_unified); + + /* If the tracker tracked nothing, then "marker_unified" would be zero. + * Otherwise, the entire patch shifted, and that delta should be applied to + * all the coordinates. + */ + for (i = 0; i < 4; i++) { + marker->pattern_corners[i][0] -= marker_unified[0]; + marker->pattern_corners[i][1] -= marker_unified[1]; + } + + marker->pos[0] += marker_unified[0]; + marker->pos[1] += marker_unified[1]; +} #endif /*********************** common functions *************************/ @@ -1178,102 +1244,75 @@ static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int g track->flag & TRACK_DISABLE_GREEN, track->flag & TRACK_DISABLE_BLUE, grayscale); } -static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - float min[2], float max[2], int margin, int anchored, - int grayscale, float pos[2], int origin[2]) +ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, + ImBuf *search_ibuf, MovieTrackingMarker *marker, + int num_samples_x, int num_samples_y, float pos[2]) { - ImBuf *tmpibuf; - int x, y; - int x1, y1, w, h; - float mpos[2]; + ImBuf *pattern_ibuf; + double src_pixel_x[5], src_pixel_y[5]; + double warped_position_x, warped_position_y; - copy_v2_v2(mpos, marker->pos); - if (anchored) - add_v2_v2(mpos, track->offset); + pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); + pattern_ibuf->profile = IB_PROFILE_LINEAR_RGB; - if (pos) - zero_v2(pos); - - x = mpos[0]*ibuf->x; - y = mpos[1]*ibuf->y; - - w = (max[0] - min[0]) * ibuf->x; - h = (max[1] - min[1]) * ibuf->y; - - /* dimensions should be odd */ - w = w | 1; - h = h | 1; - - x1 = x - (int)(w * (-min[0] / (max[0] - min[0]))); - y1 = y - (int)(h * (-min[1] / (max[1] - min[1]))); - - if (ibuf->rect_float) - tmpibuf = IMB_allocImBuf(w + margin * 2, h + margin * 2, 32, IB_rectfloat); - else - tmpibuf = IMB_allocImBuf(w + margin * 2, h + margin * 2, 32, IB_rect); - - tmpibuf->profile = ibuf->profile; - - IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1 - margin, y1 - margin, w + margin * 2, h + margin * 2); - - if (pos != NULL) { - pos[0] = mpos[0] * ibuf->x - x1 + margin; - pos[1] = mpos[1] * ibuf->y - y1 + margin; + if (!search_ibuf->rect_float) { + IMB_float_from_rect(search_ibuf); } - if (origin != NULL) { - origin[0] = x1 - margin; - origin[1] = y1 - margin; + get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y); + + libmv_samplePlanarPatch(search_ibuf->rect_float, search_ibuf->x, search_ibuf->y, 4, + src_pixel_x, src_pixel_y, num_samples_x, + num_samples_y, pattern_ibuf->rect_float, + &warped_position_x, &warped_position_y); + + if (pos) { + pos[0] = warped_position_x; + pos[1] = warped_position_y; } - if (grayscale) { - if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || - (track->flag & TRACK_DISABLE_RED) || - (track->flag & TRACK_DISABLE_GREEN) || - (track->flag & TRACK_DISABLE_BLUE)) - { - disable_imbuf_channels(tmpibuf, track, TRUE /* grayscale */); - } - } - - return tmpibuf; + return pattern_ibuf; } ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int margin, int anchored, float pos[2], int origin[2]) + int anchored, int disable_channels) { + ImBuf *pattern_ibuf, *search_ibuf; float pat_min[2], pat_max[2]; + int num_samples_x, num_samples_y; - /* XXX: need to do real quad sampling here, but currently just assume - * corners represents quad pattern - */ BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - return get_area_imbuf(ibuf, track, marker, pat_min, pat_max, margin, anchored, TRUE, pos, origin); + num_samples_x = (pat_max[0] - pat_min[0]) * ibuf->x; + num_samples_y = (pat_max[1] - pat_min[1]) * ibuf->y; + + search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels); + + pattern_ibuf = BKE_tracking_sample_pattern_imbuf(ibuf->x, ibuf->y, search_ibuf, marker, + num_samples_x, num_samples_y, NULL); + + IMB_freeImBuf(search_ibuf); + + return pattern_ibuf; } -ImBuf *BKE_tracking_get_pattern_color_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int anchored) -{ - float pat_min[2], pat_max[2]; - - /* see comment above */ - BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - - return get_area_imbuf(ibuf, track, marker, pat_min, pat_max, 0, anchored, FALSE, NULL, NULL); -} - -ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker) +ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int anchored, int disable_channels) { ImBuf *searchibuf; int x, y, w, h; float search_origin[2]; - get_search_origin_frame_pixel(ibuf, marker, search_origin); + get_search_origin_frame_pixel(ibuf->x, ibuf->y, marker, search_origin); x = search_origin[0]; y = search_origin[1]; + if (anchored) { + x += track->offset[0] * ibuf->x; + y += track->offset[1] * ibuf->y; + } + w = (marker->search_max[0] - marker->search_min[0]) * ibuf->x; h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y; @@ -1282,12 +1321,14 @@ ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mov IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h); - if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || - (track->flag & TRACK_DISABLE_RED) || - (track->flag & TRACK_DISABLE_GREEN) || - (track->flag & TRACK_DISABLE_BLUE)) - { - disable_imbuf_channels(searchibuf, track, FALSE); + if (disable_channels) { + if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || + (track->flag & TRACK_DISABLE_RED) || + (track->flag & TRACK_DISABLE_GREEN) || + (track->flag & TRACK_DISABLE_BLUE)) + { + disable_imbuf_channels(searchibuf, track, TRUE); + } } return searchibuf; @@ -1424,7 +1465,7 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT float *gray_pixels; int width, height; - searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker); + searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, FALSE, TRUE); width = searchibuf->x; height = searchibuf->y; @@ -1448,66 +1489,6 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT return gray_pixels; } -/* Each marker has 5 coordinates associated with it that get warped with - * tracking: the four corners ("pattern_corners"), and the cernter ("pos"). - * This function puts those 5 points into the appropriate frame for tracking - * (the "search" coordinate frame). - */ -static void get_marker_coords_for_tracking(const ImBuf *ibuf, const MovieTrackingMarker *marker, - double search_pixel_x[5], double search_pixel_y[5]) -{ - int i; - float unified_coords[2]; - float pixel_coords[2]; - - /* Convert the corners into search space coordinates. */ - for (i = 0; i < 4; i++) { - marker_unified_to_search_pixel(ibuf, marker, marker->pattern_corners[i], pixel_coords); - search_pixel_x[i] = pixel_coords[0]; - search_pixel_y[i] = pixel_coords[1]; - } - /* Convert the center position (aka "pos"); this is the origin */ - unified_coords[0] = 0.0; - unified_coords[1] = 0.0; - marker_unified_to_search_pixel(ibuf, marker, unified_coords, pixel_coords); - - search_pixel_x[4] = pixel_coords[0]; - search_pixel_y[4] = pixel_coords[1]; -} - -/* Inverse of above. */ -static void set_marker_coords_from_tracking(const ImBuf *ibuf, MovieTrackingMarker *marker, - const double search_pixel_x[5], const double search_pixel_y[5]) -{ - int i; - float marker_unified[2]; - float search_pixel[2]; - - /* Convert the corners into search space coordinates. */ - for (i = 0; i < 4; i++) { - search_pixel[0] = search_pixel_x[i]; - search_pixel[1] = search_pixel_y[i]; - search_pixel_to_marker_unified(ibuf, marker, search_pixel, marker->pattern_corners[i]); - } - - /* Convert the center position (aka "pos"); this is the origin */ - search_pixel[0] = search_pixel_x[4]; - search_pixel[1] = search_pixel_y[4]; - search_pixel_to_marker_unified(ibuf, marker, search_pixel, marker_unified); - - /* If the tracker tracked nothing, then "marker_unified" would be zero. - * Otherwise, the entire patch shifted, and that delta should be applied to - * all the coordinates. - */ - for (i = 0; i < 4; i++) { - marker->pattern_corners[i][0] -= marker_unified[0]; - marker->pattern_corners[i][1] -= marker_unified[1]; - } - - marker->pos[0] += marker_unified[0]; - marker->pos[1] += marker_unified[1]; -} - static unsigned char *get_ucharbuf(ImBuf *ibuf) { int x, y; @@ -1633,6 +1614,8 @@ int BKE_tracking_next(MovieTrackingContext *context) int curfra = BKE_movieclip_remap_scene_to_clip_frame(context->clip, context->user.framenr); int a, ok = FALSE, map_size; + int frame_width, frame_height; + map_size = tracks_map_size(context->tracks_map); /* nothing to track, avoid unneeded frames reading to save time and memory */ @@ -1649,6 +1632,9 @@ int BKE_tracking_next(MovieTrackingContext *context) if (!destination_ibuf) return FALSE; + frame_width = destination_ibuf->x; + frame_height = destination_ibuf->y; + #pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1) for (a = 0; a < map_size; a++) { TrackContext *track_context = NULL; @@ -1739,8 +1725,8 @@ int BKE_tracking_next(MovieTrackingContext *context) options.sigma = 0.9; /* Convert the marker corners and center into pixel coordinates in the search/destination images. */ - get_marker_coords_for_tracking(destination_ibuf, &track_context->marker, src_pixel_x, src_pixel_y); - get_marker_coords_for_tracking(destination_ibuf, marker, dst_pixel_x, dst_pixel_y); + get_marker_coords_for_tracking(frame_width, frame_height, &track_context->marker, src_pixel_x, src_pixel_y); + get_marker_coords_for_tracking(frame_width, frame_height, marker, dst_pixel_x, dst_pixel_y); /* Run the tracker! */ tracked = libmv_trackRegion(&options, @@ -1755,7 +1741,7 @@ int BKE_tracking_next(MovieTrackingContext *context) if (tracked && !onbound) { memset(&marker_new, 0, sizeof(marker_new)); marker_new = *marker; - set_marker_coords_from_tracking(destination_ibuf, &marker_new, dst_pixel_x, dst_pixel_y); + set_marker_coords_from_tracking(frame_width, frame_height, &marker_new, dst_pixel_x, dst_pixel_y); marker_new.flag |= MARKER_TRACKED; marker_new.framenr = nextfra; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a36645510c3..a1d255e67e8 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5362,6 +5362,7 @@ static void lib_link_screen(FileData *fd, Main *main) sclip->clip = newlibadr_us(fd, sc->id.lib, sclip->clip); sclip->mask = newlibadr_us(fd, sc->id.lib, sclip->mask); + sclip->scopes.track_search = NULL; sclip->scopes.track_preview = NULL; sclip->draw_context = NULL; sclip->scopes.ok = 0; diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp index 4f6abdcbc22..1bb0d90c1db 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -116,7 +116,7 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri while (track) { VoronoiSite *site = &sites[i]; MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenumber); - ImBuf *pattern_ibuf = BKE_tracking_get_pattern_color_imbuf(ibuf, track, marker, TRUE); + ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE); int j; zero_v3(site->color); diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index a0b418c1a9a..d652fe4a569 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -43,6 +43,7 @@ #include "BKE_colortools.h" #include "BKE_texture.h" +#include "BKE_tracking.h" #include "IMB_imbuf.h" @@ -1480,36 +1481,10 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); } -static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float track_pos[2], int width, float height, int margin) -{ - ImBuf *scaleibuf; - const float scalex = ((float)ibuf->x - 2 * margin) / width; - const float scaley = ((float)ibuf->y - 2 * margin) / height; - /* NOTE: 1.0f = 0.5f for integer coordinate coorrection (center of pixel vs. left bottom corner of bixel) - * and 0.5f for centering image in preview (cross is draving at exact center of widget so image - * should be shifted by half of pixel for correct centering) - sergey */ - float off_x = (int)track_pos[0] - track_pos[0] + 1.0f; - float off_y = (int)track_pos[1] - track_pos[1] + 1.0f; - int x, y; - - scaleibuf = IMB_allocImBuf(width, height, 32, IB_rect); - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - float src_x = scalex * (x) + margin - off_x; - float src_y = scaley * (y) + margin - off_y; - - bicubic_interpolation(ibuf, scaleibuf, src_x, src_y, x, y); - } - } - - return scaleibuf; -} - void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) { rctf rect; - int ok = 0; + int ok = 0, width, height; GLint scissor[4]; MovieClipScopes *scopes = (MovieClipScopes *)but->poin; @@ -1518,6 +1493,9 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc rect.ymin = (float)recti->ymin + SCOPE_RESIZE_PAD + 2; rect.ymax = (float)recti->ymax - 1; + width = rect.xmax - rect.xmin + 1; + height = rect.ymax - rect.ymin; + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1535,40 +1513,52 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc ok = 1; } - else if (scopes->track_preview) { - /* additional margin around image */ - /* NOTE: should be kept in sync with value from BKE_movieclip_update_scopes */ - const int margin = 3; - float zoomx, zoomy, track_pos[2], off_x, off_y; - int a, width, height; + else if ((!scopes->track_preview) || + (scopes->track_preview->x != width || scopes->track_preview->y != height)) + { + ImBuf *tmpibuf; + + if (scopes->track_preview) + IMB_freeImBuf(scopes->track_preview); + + tmpibuf = BKE_tracking_sample_pattern_imbuf(scopes->frame_width, scopes->frame_height, + scopes->track_search, &scopes->undist_marker, + width, height, scopes->track_pos); + + if (tmpibuf->rect_float) + IMB_rect_from_float(tmpibuf); + + // XXX: for debug only + // tmpibuf->ftype = PNG; + // IMB_saveiff(tmpibuf, "sample.png", IB_rect); + + if (tmpibuf->rect) + scopes->track_preview = tmpibuf; + else + IMB_freeImBuf(tmpibuf); + } + + if (!ok && scopes->track_preview) { + float track_pos[2]; + int a; ImBuf *drawibuf; glPushMatrix(); - track_pos[0] = scopes->track_pos[0] - margin; - track_pos[1] = scopes->track_pos[1] - margin; + track_pos[0] = scopes->track_pos[0]; + track_pos[1] = scopes->track_pos[1]; /* draw content of pattern area */ glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, scissor[2], scissor[3]); - width = rect.xmax - rect.xmin + 1; - height = rect.ymax - rect.ymin; - if (width > 0 && height > 0) { - zoomx = (float)width / (scopes->track_preview->x - 2 * margin); - zoomy = (float)height / (scopes->track_preview->y - 2 * margin); - - off_x = ((int)track_pos[0] - track_pos[0] + 0.5f) * zoomx; - off_y = ((int)track_pos[1] - track_pos[1] + 0.5f) * zoomy; - - drawibuf = scale_trackpreview_ibuf(scopes->track_preview, track_pos, width, height, margin); + drawibuf = scopes->track_preview; glaDrawPixelsSafe(rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y, drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); - IMB_freeImBuf(drawibuf); /* draw cross for pizel position */ - glTranslatef(off_x + rect.xmin + track_pos[0] * zoomx, off_y + rect.ymin + track_pos[1] * zoomy, 0.f); + glTranslatef(rect.xmin + track_pos[0], rect.ymin + track_pos[1], 0.f); glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, rect.xmax - rect.xmin, diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index a49319abd20..54724881e37 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -306,6 +306,9 @@ static void clip_free(SpaceLink *sl) if (sc->scopes.track_preview) IMB_freeImBuf(sc->scopes.track_preview); + if (sc->scopes.track_search) + IMB_freeImBuf(sc->scopes.track_search); + ED_space_clip_free_texture_buffer(sc); } @@ -323,6 +326,7 @@ static SpaceLink *clip_duplicate(SpaceLink *sl) SpaceClip *scn = MEM_dupallocN(sl); /* clear or remove stuff from old */ + scn->scopes.track_search = NULL; scn->scopes.track_preview = NULL; scn->scopes.ok = FALSE; scn->draw_context = NULL; diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h index fd7046854ff..b9d63167700 100644 --- a/source/blender/makesdna/DNA_movieclip_types.h +++ b/source/blender/makesdna/DNA_movieclip_types.h @@ -92,6 +92,9 @@ typedef struct MovieClip { typedef struct MovieClipScopes { int ok; /* 1 means scopes are ok and recalculation is unneeded */ int track_preview_height; /* height of track preview widget */ + int frame_width, frame_height; /* width and height of frame for which scopes are calculated */ + struct MovieTrackingMarker undist_marker; /* undistorted position of marker used for pattern sampling */ + struct ImBuf *track_search; /* search area of a track */ struct ImBuf *track_preview; /* ImBuf displayed in track preview */ float track_pos[2]; /* sub-pizel position of marker in track ImBuf */ short track_disabled; /* active track is disabled, special notifier should be drawn */ diff --git a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c index b7ce621a9e1..6149285fdbc 100644 --- a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c +++ b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c @@ -91,7 +91,7 @@ static void compute_gradient_screen(RenderData *rd, NodeKeyingScreenData *keying while (track) { VoronoiSite *site = &sites[i]; MovieTrackingMarker *marker = BKE_tracking_get_marker(track, rd->cfra); - ImBuf *pattern_ibuf = BKE_tracking_get_pattern_color_imbuf(ibuf, track, marker, TRUE); + ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE); int j; zero_v3(site->color); From 5fe661792c230ac97d85477354a01e3d7aa1149a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 9 Jun 2012 11:34:22 +0000 Subject: [PATCH 171/360] Fixed crash in previous commit when track preview is drawing for missed frame --- source/blender/blenkernel/intern/tracking.c | 2 +- source/blender/editors/interface/interface_draw.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 1d4ed2c8c40..938bff81470 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1246,7 +1246,7 @@ static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int g ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, ImBuf *search_ibuf, MovieTrackingMarker *marker, - int num_samples_x, int num_samples_y, float pos[2]) + int num_samples_x, int num_samples_y, float pos[2]) { ImBuf *pattern_ibuf; double src_pixel_x[5], src_pixel_y[5]; diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index d652fe4a569..6f6de0cc418 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1513,8 +1513,9 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc ok = 1; } - else if ((!scopes->track_preview) || - (scopes->track_preview->x != width || scopes->track_preview->y != height)) + else if ((scopes->track_search) && + ((!scopes->track_preview) || + (scopes->track_preview->x != width || scopes->track_preview->y != height))) { ImBuf *tmpibuf; From 6b13203a9ca59c0b066327781e7fc3f4bd7dd9cf Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 9 Jun 2012 17:15:38 +0000 Subject: [PATCH 172/360] Changes to keying nodes: - Replace FastGaussian blur with GaussianBokeh blur which should give better results. - Changes a bit formula of saturation which in some cases gives better result. Also included (commented out) original formula which was also checked by Brecht and which gave better result in some other cases. - Made clipping white/black temporal dependent, so hopefully it wouldn't destroy gradients on edges. --- source/blender/compositor/CMakeLists.txt | 2 + .../compositor/nodes/COM_KeyingNode.cpp | 35 +++++-- .../blender/compositor/nodes/COM_KeyingNode.h | 1 + .../operations/COM_KeyingClipOperation.cpp | 95 +++++++++++++++++++ .../operations/COM_KeyingClipOperation.h | 50 ++++++++++ .../operations/COM_KeyingOperation.cpp | 56 +++++------ .../operations/COM_KeyingOperation.h | 5 - source/blender/makesrna/intern/rna_nodetree.c | 2 +- 8 files changed, 200 insertions(+), 46 deletions(-) create mode 100644 source/blender/compositor/operations/COM_KeyingClipOperation.cpp create mode 100644 source/blender/compositor/operations/COM_KeyingClipOperation.h diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index c71168b2d2e..6fc938c192c 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -333,6 +333,8 @@ set(SRC operations/COM_KeyingScreenOperation.h operations/COM_KeyingDespillOperation.cpp operations/COM_KeyingDespillOperation.h + operations/COM_KeyingClipOperation.cpp + operations/COM_KeyingClipOperation.h operations/COM_ColorSpillOperation.cpp operations/COM_ColorSpillOperation.h diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index 9e29a99293e..2bc502a5f86 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -27,12 +27,13 @@ #include "COM_KeyingOperation.h" #include "COM_KeyingDespillOperation.h" +#include "COM_KeyingClipOperation.h" #include "COM_SeparateChannelOperation.h" #include "COM_CombineChannelsOperation.h" #include "COM_ConvertRGBToYCCOperation.h" #include "COM_ConvertYCCToRGBOperation.h" -#include "COM_FastGaussianBlurOperation.h" +#include "COM_GaussianBokehBlurOperation.h" #include "COM_SetValueOperation.h" #include "COM_DilateErodeOperation.h" @@ -72,8 +73,9 @@ OutputSocket *KeyingNode::setupPreBlur(ExecutionSystem *graph, InputSocket *inpu setValueOperation->setValue(1.0f); graph->addOperation(setValueOperation); - FastGaussianBlurOperation *blurOperation = new FastGaussianBlurOperation(); + GaussianBokehBlurOperation *blurOperation = new GaussianBokehBlurOperation(); blurOperation->setData(&preBlurData); + blurOperation->setQuality(COM_QUALITY_HIGH); addLink(graph, separateOperation->getOutputSocket(0), blurOperation->getInputSocket(0)); addLink(graph, setValueOperation->getOutputSocket(0), blurOperation->getInputSocket(1)); @@ -104,8 +106,9 @@ OutputSocket *KeyingNode::setupPostBlur(ExecutionSystem *graph, OutputSocket *po setValueOperation->setValue(1.0f); graph->addOperation(setValueOperation); - FastGaussianBlurOperation *blurOperation = new FastGaussianBlurOperation(); + GaussianBokehBlurOperation *blurOperation = new GaussianBokehBlurOperation(); blurOperation->setData(&postBlurData); + blurOperation->setQuality(COM_QUALITY_HIGH); addLink(graph, postBLurInput, blurOperation->getInputSocket(0)); addLink(graph, setValueOperation->getOutputSocket(0), blurOperation->getInputSocket(1)); @@ -149,6 +152,20 @@ OutputSocket *KeyingNode::setupDespill(ExecutionSystem *graph, OutputSocket *des return despillOperation->getOutputSocket(0); } +OutputSocket *KeyingNode::setupClip(ExecutionSystem *graph, OutputSocket *clipInput, float clipBlack, float clipWhite) +{ + KeyingClipOperation *clipOperation = new KeyingClipOperation(); + + clipOperation->setClipBlack(clipBlack); + clipOperation->setClipWhite(clipWhite); + + addLink(graph, clipInput, clipOperation->getInputSocket(0)); + + graph->addOperation(clipOperation); + + return clipOperation->getOutputSocket(0); +} + void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *inputImage = this->getInputSocket(0); @@ -163,9 +180,6 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext * /* keying operation */ KeyingOperation *keyingOperation = new KeyingOperation(); - keyingOperation->setClipBlack(keying_data->clip_black); - keyingOperation->setClipWhite(keying_data->clip_white); - inputScreen->relinkConnections(keyingOperation->getInputSocket(1), 1, graph); if (keying_data->blur_pre) { @@ -180,11 +194,14 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext * graph->addOperation(keyingOperation); + postprocessedMatte = keyingOperation->getOutputSocket(); + + if (keying_data->clip_black > 0.0f || keying_data->clip_white< 1.0f) + postprocessedMatte = setupClip(graph, postprocessedMatte, keying_data->clip_black, keying_data->clip_white); + /* apply blur on matte if needed */ if (keying_data->blur_post) - postprocessedMatte = setupPostBlur(graph, keyingOperation->getOutputSocket(), keying_data->blur_post); - else - postprocessedMatte = keyingOperation->getOutputSocket(); + postprocessedMatte = setupPostBlur(graph, postprocessedMatte, keying_data->blur_post); /* matte dilate/erode */ if (keying_data->dilate_distance != 0) { diff --git a/source/blender/compositor/nodes/COM_KeyingNode.h b/source/blender/compositor/nodes/COM_KeyingNode.h index 894d0ddc095..9d4067ce599 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.h +++ b/source/blender/compositor/nodes/COM_KeyingNode.h @@ -37,6 +37,7 @@ protected: OutputSocket *setupPostBlur(ExecutionSystem *graph, OutputSocket *postBLurInput, int size); OutputSocket *setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance); OutputSocket *setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, InputSocket *inputSrceen, float factor); + OutputSocket *setupClip(ExecutionSystem *graph, OutputSocket *clipInput, float clipBlack, float clipWhite); public: KeyingNode(bNode *editorNode); void convertToOperations(ExecutionSystem *graph, CompositorContext *context); diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp new file mode 100644 index 00000000000..559d282f613 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_KeyingClipOperation.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" + +KeyingClipOperation::KeyingClipOperation(): NodeOperation() +{ + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + + this->clipBlack = 0.0f; + this->clipWhite = 1.0f; + + this->pixelReader = NULL; +} + +void KeyingClipOperation::initExecution() +{ + this->pixelReader = this->getInputSocketReader(0); +} + +void KeyingClipOperation::deinitExecution() +{ + this->pixelReader = NULL; +} + +void KeyingClipOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +{ + const int delta = 3; + + float pixelColor[4]; + int width = this->getWidth(), height = this->getHeight(); + int count_black = 0, count_white = 0; + int i, j; + + this->pixelReader->read(pixelColor, x, y, sampler, inputBuffers); + + for (i = -delta + 1; i < delta; i++) { + for (j = -delta + 1; j < delta; j++) { + int cx = x + j, cy = y + i; + + if (i == 0 && j == 0) + continue; + + if (cx >= 0 && cx < width && cy >= 0 && cy < height) { + float value[4]; + + this->pixelReader->read(value, cx, cy, sampler, inputBuffers); + + if (value[0] < 0.4f) + count_black++; + else if (value[0] > 0.6f) + count_white++; + } + } + } + + color[0] = pixelColor[0]; + + if (count_black >= 22 || count_white >= 22) { + if (count_black >= 4 || count_white >= 4) { + if (color[0] < this->clipBlack) + color[0] = 0.0f; + else if (color[0] >= this->clipWhite) + color[0] = 1.0f; + else + color[0] = (color[0] - this->clipBlack) / (this->clipWhite - this->clipBlack); + } + } +} diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.h b/source/blender/compositor/operations/COM_KeyingClipOperation.h new file mode 100644 index 00000000000..1141e0b47ab --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.h @@ -0,0 +1,50 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#ifndef _COM_KeyingClipOperation_h +#define _COM_KeyingClipOperation_h + +#include "COM_NodeOperation.h" + +/** + * Class with implementation of black/white clipping for keying node + */ +class KeyingClipOperation : public NodeOperation { +protected: + SocketReader *pixelReader; + float clipBlack; + float clipWhite; + +public: + KeyingClipOperation(); + + void initExecution(); + void deinitExecution(); + + void setClipBlack(float value) {this->clipBlack = value;} + void setClipWhite(float value) {this->clipWhite = value;} + + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp index 5f1c9d0640d..7d7ac378bed 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp @@ -28,26 +28,33 @@ #include "BLI_listbase.h" #include "BLI_math.h" -static int get_pixel_primary_channel(float *pixel) +static int get_pixel_primary_channel(float pixelColor[4]) { - float max_value = MAX3(pixel[0], pixel[1], pixel[2]); + float max_value = MAX3(pixelColor[0], pixelColor[1], pixelColor[2]); - if (max_value == pixel[0]) + if (max_value == pixelColor[0]) return 0; - else if (max_value == pixel[1]) + else if (max_value == pixelColor[1]) return 1; return 2; } -static float get_pixel_saturation(float *pixel, float screen_balance) +static float get_pixel_saturation(float pixelColor[4], float screen_balance, int primary_channel) { - float min = MIN3(pixel[0], pixel[1], pixel[2]); - float max = MAX3(pixel[0], pixel[1], pixel[2]); - float mid = pixel[0] + pixel[1] + pixel[2] - min - max; - float val = (1.0f - screen_balance) * min + screen_balance * mid; + int other_1 = (primary_channel + 1) % 3; + int other_2 = (primary_channel + 2) % 3; - return (max - val) * (1.0f - val) * (1.0f - val); + float min = MIN2(pixelColor[other_1], pixelColor[other_2]); + float max = MAX2(pixelColor[other_1], pixelColor[other_2]); + float val = screen_balance * min + (1.0f - screen_balance) * max; + + // original formula, also used by brecht + // works a bit crappy in areas with values > 1.0 + // return (pixelColor[primary_channel] - val) * fabsf(1.0f - val); + + // sergey's test formula + return pixelColor[1] - (pixelColor[0] + pixelColor[1]) * 0.5f; } KeyingOperation::KeyingOperation(): NodeOperation() @@ -57,8 +64,6 @@ KeyingOperation::KeyingOperation(): NodeOperation() this->addOutputSocket(COM_DT_VALUE); this->screenBalance = 0.5f; - this->clipBlack = 0.0f; - this->clipWhite = 1.0f; this->pixelReader = NULL; this->screenReader = NULL; @@ -84,31 +89,20 @@ void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler this->pixelReader->read(pixelColor, x, y, sampler, inputBuffers); this->screenReader->read(screenColor, x, y, sampler, inputBuffers); - float saturation = get_pixel_saturation(pixelColor, this->screenBalance); - float screen_saturation = get_pixel_saturation(screenColor, this->screenBalance); - int primary_channel = get_pixel_primary_channel(pixelColor); - int screen_primary_channel = get_pixel_primary_channel(screenColor); + int primary_channel = get_pixel_primary_channel(screenColor); - if (primary_channel != screen_primary_channel) { - /* different main channel means pixel is on foreground */ + float saturation = get_pixel_saturation(pixelColor, this->screenBalance, primary_channel); + float screen_saturation = get_pixel_saturation(screenColor, this->screenBalance, primary_channel); + + if (saturation < 0) { color[0] = 1.0f; } - else if (saturation >= screen_saturation) { - /* saturation of main channel is more than screen, definitely a background */ + else if (saturation >= screen_saturation) { color[0] = 0.0f; } else { - float distance; + float distance = 1.0f - saturation / screen_saturation; - distance = 1.0f - saturation / screen_saturation; - - color[0] = distance * distance; - - if (color[0] < this->clipBlack) - color[0] = 0.0f; - else if (color[0] >= this->clipWhite) - color[0] = 1.0f; - else - color[0] = (color[0] - this->clipBlack) / (this->clipWhite - this->clipBlack); + color[0] = distance; } } diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h index 546ff355573..0ce6481b835 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.h +++ b/source/blender/compositor/operations/COM_KeyingOperation.h @@ -39,8 +39,6 @@ protected: SocketReader *pixelReader; SocketReader *screenReader; float screenBalance; - float clipBlack; - float clipWhite; public: KeyingOperation(); @@ -48,9 +46,6 @@ public: void initExecution(); void deinitExecution(); - void setClipBlack(float value) {this->clipBlack = value;} - void setClipWhite(float value) {this->clipWhite = value;} - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); }; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index e97f3195f47..7567d40d9a5 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3095,7 +3095,7 @@ static void def_cmp_keying(StructRNA *srna) RNA_def_struct_sdna_from(srna, "NodeKeyingData", "storage"); - prop = RNA_def_property(srna, "despill_factor", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "despill_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "despill_factor"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Despill", ""); From 1acd2c58b6ea1bdce3b50385d5955eb4b50b4a93 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 9 Jun 2012 18:19:41 +0000 Subject: [PATCH 173/360] Actually that was an error in on of test formulas. Stick back to original one. --- .../blender/compositor/operations/COM_KeyingOperation.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp index 7d7ac378bed..a31b49c4a5c 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp @@ -49,12 +49,7 @@ static float get_pixel_saturation(float pixelColor[4], float screen_balance, int float max = MAX2(pixelColor[other_1], pixelColor[other_2]); float val = screen_balance * min + (1.0f - screen_balance) * max; - // original formula, also used by brecht - // works a bit crappy in areas with values > 1.0 - // return (pixelColor[primary_channel] - val) * fabsf(1.0f - val); - - // sergey's test formula - return pixelColor[1] - (pixelColor[0] + pixelColor[1]) * 0.5f; + return (pixelColor[primary_channel] - val) * fabsf(1.0f - val); } KeyingOperation::KeyingOperation(): NodeOperation() From a8bae06dc4c7e4181d9ee16ee23866b8eeba56ff Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 9 Jun 2012 18:26:26 +0000 Subject: [PATCH 174/360] Looks like some kind of merge error happened here which i didn't notice. Corrected! --- .../operations/COM_KeyingClipOperation.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp index 559d282f613..1c92e76c51a 100644 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp @@ -83,13 +83,11 @@ void KeyingClipOperation::executePixel(float *color, float x, float y, PixelSamp color[0] = pixelColor[0]; if (count_black >= 22 || count_white >= 22) { - if (count_black >= 4 || count_white >= 4) { - if (color[0] < this->clipBlack) - color[0] = 0.0f; - else if (color[0] >= this->clipWhite) - color[0] = 1.0f; - else - color[0] = (color[0] - this->clipBlack) / (this->clipWhite - this->clipBlack); - } + if (color[0] < this->clipBlack) + color[0] = 0.0f; + else if (color[0] >= this->clipWhite) + color[0] = 1.0f; + else + color[0] = (color[0] - this->clipBlack) / (this->clipWhite - this->clipBlack); } } From 1c42677e6c393ea650569b4da1bc0148805fbcd7 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Sat, 9 Jun 2012 18:45:54 +0000 Subject: [PATCH 175/360] Formatting fixes in Ceres. --- .../third_party/ceres/include/ceres/autodiff_cost_function.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h index da9ee2c7993..e86d6993864 100644 --- a/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h +++ b/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h @@ -163,7 +163,7 @@ class AutoDiffCostFunction : explicit AutoDiffCostFunction(CostFunctor* functor) : functor_(functor) { CHECK_NE(M, DYNAMIC) << "Can't run the fixed-size constructor if the " - << "number of residuals is set to ceres::DYNAMIC."; + << "number of residuals is set to ceres::DYNAMIC."; } // Takes ownership of functor. Ignores the template-provided number of @@ -174,7 +174,7 @@ class AutoDiffCostFunction : AutoDiffCostFunction(CostFunctor* functor, int num_residuals) : functor_(functor) { CHECK_EQ(M, DYNAMIC) << "Can't run the dynamic-size constructor if the " - << "number of residuals is not ceres::DYNAMIC."; + << "number of residuals is not ceres::DYNAMIC."; SizedCostFunction::set_num_residuals(num_residuals); } From a844adc9c2a5c513f3a8b8de5a029aaffdd96d34 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Sat, 9 Jun 2012 18:58:51 +0000 Subject: [PATCH 176/360] Add new warp regularization scheme for planar tracking. This adds a new term to the tracking cost function that restricts how much the optimizer can warp the patch (as opposed to merely adjusting the translation). This should reduce the "jumpiness" that is sometimes seen when doing non-"Loc" tracks. It is disabled in this commit; a subsequent commit will add controls to the tracking dialog for this. --- extern/libmv/libmv/tracking/track_region.cc | 145 ++++++++++++++++---- extern/libmv/libmv/tracking/track_region.h | 17 +++ 2 files changed, 139 insertions(+), 23 deletions(-) diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index 679646c4c37..e65ead50c80 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -56,6 +56,7 @@ TrackRegionOptions::TrackRegionOptions() use_normalized_intensities(false), sigma(0.9), num_extra_points(0), + regularization_coefficient(0.0), image1_mask(NULL) { } @@ -137,9 +138,9 @@ class BoundaryCheckingCallback : public ceres::IterationCallback { }; template -class WarpCostFunctor { +class PixelDifferenceCostFunctor { public: - WarpCostFunctor(const TrackRegionOptions &options, + PixelDifferenceCostFunctor(const TrackRegionOptions &options, const FloatImage &image_and_gradient1, const FloatImage &image_and_gradient2, const Mat3 &canonical_to_image1, @@ -450,6 +451,79 @@ class WarpCostFunctor { FloatImage pattern_mask_; }; +template +class WarpRegularizingCostFunctor { + public: + WarpRegularizingCostFunctor(const TrackRegionOptions &options, + const double *x1, + const double *y1, + const double *x2_original, + const double *y2_original, + const Warp &warp) + : options_(options), + x1_(x1), + y1_(y1), + x2_original_(x2_original), + y2_original_(y2_original), + warp_(warp) { + // Compute the centroid of the first guess quad. + // TODO(keir): Use Quad class here. + original_centroid_[0] = 0.0; + original_centroid_[1] = 0.0; + for (int i = 0; i < 4; ++i) { + original_centroid_[0] += x2_original[i]; + original_centroid_[1] += y2_original[i]; + } + original_centroid_[0] /= 4; + original_centroid_[1] /= 4; + } + + template + bool operator()(const T *warp_parameters, T *residuals) const { + T dst_centroid[2] = { T(0.0), T(0.0) }; + for (int i = 0; i < 4; ++i) { + T image1_position[2] = { T(x1_[i]), T(y1_[i]) }; + T image2_position[2]; + warp_.Forward(warp_parameters, + T(x1_[i]), + T(y1_[i]), + &image2_position[0], + &image2_position[1]); + + // Subtract the positions. Note that this ignores the centroids. + residuals[2 * i + 0] = image2_position[0] - image1_position[0]; + residuals[2 * i + 1] = image2_position[1] - image1_position[1]; + + // Accumulate the dst centroid. + dst_centroid[0] += image2_position[0]; + dst_centroid[1] += image2_position[1]; + } + dst_centroid[0] /= T(4.0); + dst_centroid[1] /= T(4.0); + + // Adjust for the centroids. + for (int i = 0; i < 4; ++i) { + residuals[2 * i + 0] += T(original_centroid_[0]) - dst_centroid[0]; + residuals[2 * i + 1] += T(original_centroid_[1]) - dst_centroid[1]; + } + + // Reweight the residuals. + for (int i = 0; i < 8; ++i) { + residuals[i] *= T(options_.regularization_coefficient); + } + + return true; + } + + const TrackRegionOptions &options_; + const double *x1_; + const double *y1_; + const double *x2_original_; + const double *y2_original_; + double original_centroid_[2]; + const Warp &warp_; +}; + // Compute the warp from rectangular coordinates, where one corner is the // origin, and the opposite corner is at (num_samples_x, num_samples_y). Mat3 ComputeCanonicalHomography(const double *x1, @@ -1097,6 +1171,14 @@ void TemplatedTrackRegion(const FloatImage &image1, } // TODO(keir): Check quads to ensure there is some area. + // Keep a copy of the "original" guess for regularization. + double x2_original[4]; + double y2_original[4]; + for (int i = 0; i < 4; ++i) { + x2_original[i] = x2[i]; + y2_original[i] = y2[i]; + } + // Prepare the image and gradient. Array3Df image_and_gradient1; Array3Df image_and_gradient2; @@ -1138,26 +1220,43 @@ void TemplatedTrackRegion(const FloatImage &image1, num_samples_x, num_samples_y); - // Construct the warp cost function. AutoDiffCostFunction takes ownership. - WarpCostFunctor *warp_cost_function = - new WarpCostFunctor(options, - image_and_gradient1, - image_and_gradient2, - canonical_homography, - num_samples_x, - num_samples_y, - warp); - - // Construct the problem with a single residual. ceres::Problem problem; - problem.AddResidualBlock( - new ceres::AutoDiffCostFunction< - WarpCostFunctor, - ceres::DYNAMIC, - Warp::NUM_PARAMETERS>(warp_cost_function, - num_samples_x * num_samples_y), - NULL, - warp.parameters); + + // Construct the warp cost function. AutoDiffCostFunction takes ownership. + PixelDifferenceCostFunctor *pixel_difference_cost_function = + new PixelDifferenceCostFunctor(options, + image_and_gradient1, + image_and_gradient2, + canonical_homography, + num_samples_x, + num_samples_y, + warp); + problem.AddResidualBlock( + new ceres::AutoDiffCostFunction< + PixelDifferenceCostFunctor, + ceres::DYNAMIC, + Warp::NUM_PARAMETERS>(pixel_difference_cost_function, + num_samples_x * num_samples_y), + NULL, + warp.parameters); + + // Construct the regularizing cost function + if (options.regularization_coefficient != 0.0) { + WarpRegularizingCostFunctor *regularizing_warp_cost_function = + new WarpRegularizingCostFunctor(options, + x1, y2, + x2_original, + y2_original, + warp); + + problem.AddResidualBlock( + new ceres::AutoDiffCostFunction< + WarpRegularizingCostFunctor, + 8 /* num_residuals */, + Warp::NUM_PARAMETERS>(regularizing_warp_cost_function), + NULL, + warp.parameters); + } // Configure the solve. ceres::Solver::Options solver_options; @@ -1208,8 +1307,8 @@ void TemplatedTrackRegion(const FloatImage &image1, // Otherwise, run a final correlation check. if (options.minimum_correlation > 0.0) { - result->correlation = warp_cost_function-> - PearsonProductMomentCorrelationCoefficient(warp.parameters); + result->correlation = pixel_difference_cost_function-> + PearsonProductMomentCorrelationCoefficient(warp.parameters); if (result->correlation < options.minimum_correlation) { LG << "Failing with insufficient correlation."; result->termination = TrackRegionResult::INSUFFICIENT_CORRELATION; diff --git a/extern/libmv/libmv/tracking/track_region.h b/extern/libmv/libmv/tracking/track_region.h index 04e7c7e1403..0de11239da6 100644 --- a/extern/libmv/libmv/tracking/track_region.h +++ b/extern/libmv/libmv/tracking/track_region.h @@ -73,6 +73,23 @@ struct TrackRegionOptions { // because the actual warp parameters are not exposed. int num_extra_points; + // For motion models other than translation, the optimizer sometimes has + // trouble deciding what to do around flat areas in the cost function. This + // leads to the optimizer picking poor solutions near the minimum. Visually, + // the effect is that the quad corners jiggle around, even though the center + // of the patch is well estimated. regularization_coefficient controls a term + // in the sum of squared error cost that makes it expensive for the optimizer + // to pick a warp that changes the shape of the patch dramatically (e.g. + // rotating, scaling, skewing, etc). + // + // In particular it adds an 8-residual cost function to the optimization, + // where each corner induces 2 residuals: the difference between the warped + // and the initial guess. However, the patch centroids are subtracted so that + // only patch distortions are penalized. + // + // If zero, no regularization is used. + double regularization_coefficient; + // If non-null, this is used as the pattern mask. It should match the size of // image1, even though only values inside the image1 quad are examined. The // values must be in the range 0.0 to 0.1. From 7bb79e777dd44d3d919a15b37d1bf4863c8d2856 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Sat, 9 Jun 2012 19:22:39 +0000 Subject: [PATCH 177/360] Change libmv's bilinear sampling to assume the same pixel conventions as Blender. This fixes the preview widget, and should make tracking slightly more accurate. --- extern/libmv/libmv/image/sample.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/extern/libmv/libmv/image/sample.h b/extern/libmv/libmv/image/sample.h index 04a5748ea44..a8850effeab 100644 --- a/extern/libmv/libmv/image/sample.h +++ b/extern/libmv/libmv/image/sample.h @@ -59,6 +59,10 @@ inline T SampleLinear(const Array3D &image, float y, float x, int v = 0) { int x1, y1, x2, y2; float dx, dy; + // Take the upper left corner as integer pixel positions. + x -= 0.5; + y -= 0.5; + LinearInitAxis(y, image.Height(), &y1, &y2, &dy); LinearInitAxis(x, image.Width(), &x1, &x2, &dx); @@ -78,6 +82,10 @@ inline void SampleLinear(const Array3D &image, float y, float x, T *sample) { int x1, y1, x2, y2; float dx, dy; + // Take the upper left corner as integer pixel positions. + x -= 0.5; + y -= 0.5; + LinearInitAxis(y, image.Height(), &y1, &y2, &dy); LinearInitAxis(x, image.Width(), &x1, &x2, &dx); From fddeabeccf002d4e272fa5e5265f66a81a1ccbb7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 10 Jun 2012 12:23:44 +0000 Subject: [PATCH 178/360] Somehow this files were missed in one of merges --- doc/python_api/examples/bpy.ops.2.py | 18 ++++++++++++++++++ doc/python_api/examples/bpy.ops.3.py | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 doc/python_api/examples/bpy.ops.2.py create mode 100644 doc/python_api/examples/bpy.ops.3.py diff --git a/doc/python_api/examples/bpy.ops.2.py b/doc/python_api/examples/bpy.ops.2.py new file mode 100644 index 00000000000..86b7438888c --- /dev/null +++ b/doc/python_api/examples/bpy.ops.2.py @@ -0,0 +1,18 @@ +""" +Overriding Context +++++++++++++++++++ + +It is possible to override context members that the operator sees, so that they +act on specified rather than the selected or active data, or to execute an +operator in the different part of the user interface. + +The context overrides are passed as a dictionary, with keys matching the context +member names in bpy.context. For example to override bpy.context.active_object, +you would pass {'active_object': object}. +""" + +# remove all objects in scene rather than the selected ones +import bpy +override = {'selected_bases': list(bpy.context.scene.object_bases)} +bpy.ops.object.delete(override) + diff --git a/doc/python_api/examples/bpy.ops.3.py b/doc/python_api/examples/bpy.ops.3.py new file mode 100644 index 00000000000..0b5bcafe5be --- /dev/null +++ b/doc/python_api/examples/bpy.ops.3.py @@ -0,0 +1,18 @@ +""" +It is also possible to run an operator in a particular part of the user +interface. For this we need to pass the window, screen, area and sometimes +a region. +""" + +# maximize 3d view in all windows +import bpy + +for window in bpy.context.window_manager.windows: + screen = window.screen + + for area in screen.areas: + if area.type == 'VIEW_3D': + override = {'window': window, 'screen': screen, 'area': area} + bpy.ops.screen.screen_full_area(override) + break + From e32fdad570e62910dd4d0e1e6b9b1ec5b53c4d4f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 10 Jun 2012 12:31:07 +0000 Subject: [PATCH 179/360] Synchronize changes with trunk --- .../scripts/presets/operator/wm.collada_export/second_life.py | 1 + 1 file changed, 1 insertion(+) diff --git a/release/scripts/presets/operator/wm.collada_export/second_life.py b/release/scripts/presets/operator/wm.collada_export/second_life.py index 5e04903470b..151c4e55652 100644 --- a/release/scripts/presets/operator/wm.collada_export/second_life.py +++ b/release/scripts/presets/operator/wm.collada_export/second_life.py @@ -4,4 +4,5 @@ op = bpy.context.active_operator op.selected = True op.apply_modifiers = True op.include_bone_children = False +op.use_object_instantiation = False op.second_life = True From 39a97467d40ffb8c78a90c9c5f81e2e3068789d1 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 10 Jun 2012 13:25:04 +0000 Subject: [PATCH 180/360] Remove old preset which was corrected to Nicok D3S --- release/scripts/presets/camera/Nikon_D35.py | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 release/scripts/presets/camera/Nikon_D35.py diff --git a/release/scripts/presets/camera/Nikon_D35.py b/release/scripts/presets/camera/Nikon_D35.py deleted file mode 100644 index e6dc62dc100..00000000000 --- a/release/scripts/presets/camera/Nikon_D35.py +++ /dev/null @@ -1,4 +0,0 @@ -import bpy -bpy.context.object.data.sensor_width = 36.0 -bpy.context.object.data.sensor_height = 23.9 -bpy.context.object.data.sensor_fit = 'HORIZONTAL' From ecbd2842dce7e8cd058f9c7088de902cc791041d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 10 Jun 2012 17:41:04 +0000 Subject: [PATCH 181/360] Add screen balance into interface Could be helpful to be played around. Default value is 0.5, Most probably this default value should be set manually for older files. --- source/blender/compositor/nodes/COM_KeyingNode.cpp | 2 ++ source/blender/compositor/operations/COM_KeyingOperation.h | 2 ++ source/blender/editors/space_node/drawnode.c | 1 + source/blender/makesdna/DNA_node_types.h | 1 + source/blender/makesrna/intern/rna_nodetree.c | 6 ++++++ .../blender/nodes/composite/nodes/node_composite_keying.c | 1 + 6 files changed, 13 insertions(+) diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index 2bc502a5f86..05d4738de94 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -180,6 +180,8 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext * /* keying operation */ KeyingOperation *keyingOperation = new KeyingOperation(); + keyingOperation->setScreenBalance(keying_data->screen_balance); + inputScreen->relinkConnections(keyingOperation->getInputSocket(1), 1, graph); if (keying_data->blur_pre) { diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h index 0ce6481b835..1232d008ac8 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.h +++ b/source/blender/compositor/operations/COM_KeyingOperation.h @@ -46,6 +46,8 @@ public: void initExecution(); void deinitExecution(); + void setScreenBalance(float value) {this->screenBalance = value;} + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); }; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index aed282e4a4a..afaa7ac8a28 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2446,6 +2446,7 @@ static void node_composit_buts_keying(uiLayout *layout, bContext *UNUSED(C), Poi /* bNode *node= ptr->data; */ /* UNUSED */ uiItemR(layout, ptr, "blur_pre", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "screen_balance", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "despill_factor", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "clip_black", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "clip_white", 0, NULL, ICON_NONE); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index a441936e054..cfc8ba526fa 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -633,6 +633,7 @@ typedef struct NodeKeyingScreenData { } NodeKeyingScreenData; typedef struct NodeKeyingData { + float screen_balance; float despill_factor; float clip_black, clip_white; int dilate_distance; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 7567d40d9a5..96258eff9c5 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3095,6 +3095,12 @@ static void def_cmp_keying(StructRNA *srna) RNA_def_struct_sdna_from(srna, "NodeKeyingData", "storage"); + prop = RNA_def_property(srna, "screen_balance", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "screen_balance"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Screen Balance", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + prop = RNA_def_property(srna, "despill_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "despill_factor"); RNA_def_property_range(prop, 0.0f, 1.0f); diff --git a/source/blender/nodes/composite/nodes/node_composite_keying.c b/source/blender/nodes/composite/nodes/node_composite_keying.c index b5f9b823ac2..16a9168e406 100644 --- a/source/blender/nodes/composite/nodes/node_composite_keying.c +++ b/source/blender/nodes/composite/nodes/node_composite_keying.c @@ -196,6 +196,7 @@ static void node_composit_init_keying(bNodeTree *UNUSED(ntree), bNode* node, bNo data = MEM_callocN(sizeof(NodeKeyingData), "node keying data"); + data->screen_balance = 0.5f; data->despill_factor = 1.0f; data->clip_black = 0.0f; data->clip_white = 1.0f; From b57403eebcf741fe72017ddebe268e1ed2e9d856 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 10 Jun 2012 18:15:28 +0000 Subject: [PATCH 182/360] Make keying clamping operation complex so it might directly access input buffer Seems to give quite noticeable speedup, but there's sometimes strange artifacts showing as darker lines placed in along some kind of tiles. Not sure what causes them yet. --- .../operations/COM_KeyingClipOperation.cpp | 37 +++++++++---------- .../operations/COM_KeyingClipOperation.h | 8 ++-- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp index 1c92e76c51a..38d67a76c72 100644 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp @@ -36,29 +36,30 @@ KeyingClipOperation::KeyingClipOperation(): NodeOperation() this->clipBlack = 0.0f; this->clipWhite = 1.0f; - this->pixelReader = NULL; + this->setComplex(true); } -void KeyingClipOperation::initExecution() +void *KeyingClipOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { - this->pixelReader = this->getInputSocketReader(0); + void *buffer = getInputOperation(0)->initializeTileData(rect, memoryBuffers); + + return buffer; } -void KeyingClipOperation::deinitExecution() -{ - this->pixelReader = NULL; -} - -void KeyingClipOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void KeyingClipOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { const int delta = 3; - float pixelColor[4]; - int width = this->getWidth(), height = this->getHeight(); + MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + float *buffer = inputBuffer->getBuffer(); + + int bufferWidth = inputBuffer->getWidth(); + int bufferHeight = inputBuffer->getHeight(); + int count_black = 0, count_white = 0; int i, j; - this->pixelReader->read(pixelColor, x, y, sampler, inputBuffers); + int srcIndex = (y * bufferWidth + x) * 4; for (i = -delta + 1; i < delta; i++) { for (j = -delta + 1; j < delta; j++) { @@ -67,20 +68,18 @@ void KeyingClipOperation::executePixel(float *color, float x, float y, PixelSamp if (i == 0 && j == 0) continue; - if (cx >= 0 && cx < width && cy >= 0 && cy < height) { - float value[4]; + if (cx >= 0 && cx < bufferWidth && cy >= 0 && cy < bufferHeight) { + int bufferIndex = (cy * bufferWidth + cx) * 4; - this->pixelReader->read(value, cx, cy, sampler, inputBuffers); - - if (value[0] < 0.4f) + if (buffer[bufferIndex] < 0.4f) count_black++; - else if (value[0] > 0.6f) + else if (buffer[bufferIndex] > 0.6f) count_white++; } } } - color[0] = pixelColor[0]; + color[0] = buffer[srcIndex]; if (count_black >= 22 || count_white >= 22) { if (color[0] < this->clipBlack) diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.h b/source/blender/compositor/operations/COM_KeyingClipOperation.h index 1141e0b47ab..4eab7d6b0e3 100644 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.h +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.h @@ -31,20 +31,18 @@ */ class KeyingClipOperation : public NodeOperation { protected: - SocketReader *pixelReader; float clipBlack; float clipWhite; public: KeyingClipOperation(); - void initExecution(); - void deinitExecution(); - void setClipBlack(float value) {this->clipBlack = value;} void setClipWhite(float value) {this->clipWhite = value;} - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); }; #endif From 51d9bf725dd8892b339f56553f8734aeefb17354 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 Jun 2012 19:59:02 +0000 Subject: [PATCH 183/360] style cleanup --- intern/itasc/kdl/frames.inl | 4 +- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenkernel/BKE_tracking.h | 60 +- source/blender/blenkernel/intern/tracking.c | 151 +- source/blender/blenlib/BLI_pbvh.h | 10 +- source/blender/blenlib/intern/pbvh.c | 80 +- .../blender/editors/gpencil/gpencil_buttons.c | 2 +- .../editors/interface/interface_draw.c | 4 +- source/blender/editors/sculpt_paint/sculpt.c | 66 +- .../blender/editors/space_clip/clip_buttons.c | 58 +- .../editors/space_clip/clip_dopesheet_draw.c | 44 +- source/blender/editors/space_clip/clip_draw.c | 228 +- .../editors/space_clip/clip_graph_draw.c | 10 +- .../editors/space_clip/clip_graph_ops.c | 34 +- .../blender/editors/space_clip/clip_intern.h | 30 +- .../blender/editors/space_clip/clip_utils.c | 32 +- .../blender/editors/space_clip/space_clip.c | 32 +- .../blender/editors/space_clip/tracking_ops.c | 158 +- source/blender/editors/transform/transform.c | 1504 ++++++------- .../editors/transform/transform_conversions.c | 1920 ++++++++--------- .../editors/transform/transform_generics.c | 546 ++--- .../blender/editors/transform/transform_ops.c | 130 +- source/blender/makesdna/DNA_movieclip_types.h | 110 +- source/blender/makesdna/DNA_space_types.h | 352 +-- source/blender/makesdna/DNA_tracking_types.h | 202 +- source/blender/makesrna/RNA_access.h | 16 +- source/blender/makesrna/intern/rna_modifier.c | 4 +- source/blender/makesrna/intern/rna_space.c | 12 +- source/blender/makesrna/intern/rna_tracking.c | 249 +-- 29 files changed, 3027 insertions(+), 3023 deletions(-) diff --git a/intern/itasc/kdl/frames.inl b/intern/itasc/kdl/frames.inl index 65c6148cd8e..a09b532762b 100644 --- a/intern/itasc/kdl/frames.inl +++ b/intern/itasc/kdl/frames.inl @@ -20,8 +20,8 @@ * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin Street, * - * Fifth Floor, Boston, MA 02110-1301, USA. * + * Foundation, Inc., 51 Franklin Street, * + * Fifth Floor, Boston, MA 02110-1301, USA. * * * ***************************************************************************/ diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index b833bc44201..faa996b9888 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -49,7 +49,7 @@ extern "C" { /* used by packaging tools */ /* can be left blank, otherwise a,b,c... etc with no quotes */ -#define BLENDER_VERSION_CHAR a +#define BLENDER_VERSION_CHAR a /* alpha/beta/rc/release, docs use this */ #define BLENDER_VERSION_CYCLE alpha diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 8c28dd93a5e..a13674cd6e5 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -113,7 +113,7 @@ void BKE_tracking_clipboard_paste_tracks(struct MovieTracking *tracking, struct /* 2D tracking */ struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user, - short backwards, short sequence); + short backwards, short sequence); void BKE_tracking_context_free(struct MovieTrackingContext *context); void BKE_tracking_sync(struct MovieTrackingContext *context); void BKE_tracking_sync_user(struct MovieClipUser *user, struct MovieTrackingContext *context); @@ -123,15 +123,15 @@ int BKE_tracking_next(struct MovieTrackingContext *context); int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, struct MovieTrackingObject *object, char *error_msg, int error_size); -struct MovieReconstructContext* BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking, - struct MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height); +struct MovieReconstructContext *BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking, + struct MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height); void BKE_tracking_reconstruction_context_free(struct MovieReconstructContext *context); void BKE_tracking_solve_reconstruction(struct MovieReconstructContext *context, short *stop, short *do_update, float *progress, char *stats_message, int message_size); int BKE_tracking_finish_reconstruction(struct MovieReconstructContext *context, struct MovieTracking *tracking); struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking, - struct MovieTrackingObject *object, int framenr); + struct MovieTrackingObject *object, int framenr); void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking, struct MovieTrackingObject *object, int framenr, float mat[4][4]); @@ -172,39 +172,39 @@ void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area); void BKE_tracking_dopesheet_tag_update(struct MovieTracking *tracking); void BKE_tracking_dopesheet_update(struct MovieTracking *tracking, int sort_method, int inverse); -#define TRACK_SELECTED(track) ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT) +#define TRACK_SELECTED(track) ((track)->flag & SELECT || (track)->pat_flag & SELECT || (track)->search_flag & SELECT) -#define TRACK_AREA_SELECTED(track, area) ((area)==TRACK_AREA_POINT ? (track)->flag&SELECT : \ - ((area)==TRACK_AREA_PAT ? (track)->pat_flag&SELECT : \ - (track)->search_flag&SELECT)) +#define TRACK_AREA_SELECTED(track, area) ((area) == TRACK_AREA_POINT ? (track)->flag & SELECT : \ + ((area) == TRACK_AREA_PAT ? (track)->pat_flag & SELECT : \ + (track)->search_flag & SELECT)) -#define TRACK_VIEW_SELECTED(sc, track) ((((track)->flag & TRACK_HIDDEN)==0) && \ - ( TRACK_AREA_SELECTED(track, TRACK_AREA_POINT) || \ - (((sc)->flag & SC_SHOW_MARKER_PATTERN) && TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) || \ - (((sc)->flag & SC_SHOW_MARKER_SEARCH) && TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)))) +#define TRACK_VIEW_SELECTED(sc, track) ((((track)->flag & TRACK_HIDDEN) == 0) && \ + (TRACK_AREA_SELECTED(track, TRACK_AREA_POINT) || \ + (((sc)->flag & SC_SHOW_MARKER_PATTERN) && TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) || \ + (((sc)->flag & SC_SHOW_MARKER_SEARCH) && TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)))) -#define MARKER_VISIBLE(sc, track, marker) (((marker)->flag & MARKER_DISABLED)==0 || ((sc)->flag & SC_HIDE_DISABLED)==0 || (sc->clip->tracking.act_track == track)) +#define MARKER_VISIBLE(sc, track, marker) (((marker)->flag & MARKER_DISABLED) == 0 || ((sc)->flag & SC_HIDE_DISABLED) == 0 || (sc->clip->tracking.act_track == track)) -#define TRACK_CLEAR_UPTO 0 -#define TRACK_CLEAR_REMAINED 1 -#define TRACK_CLEAR_ALL 2 +#define TRACK_CLEAR_UPTO 0 +#define TRACK_CLEAR_REMAINED 1 +#define TRACK_CLEAR_ALL 2 -#define CLAMP_PAT_DIM 1 -#define CLAMP_PAT_POS 2 -#define CLAMP_SEARCH_DIM 3 -#define CLAMP_SEARCH_POS 4 +#define CLAMP_PAT_DIM 1 +#define CLAMP_PAT_POS 2 +#define CLAMP_SEARCH_DIM 3 +#define CLAMP_SEARCH_POS 4 -#define TRACK_AREA_NONE -1 -#define TRACK_AREA_POINT 1 -#define TRACK_AREA_PAT 2 -#define TRACK_AREA_SEARCH 4 +#define TRACK_AREA_NONE -1 +#define TRACK_AREA_POINT 1 +#define TRACK_AREA_PAT 2 +#define TRACK_AREA_SEARCH 4 -#define TRACK_AREA_ALL (TRACK_AREA_POINT|TRACK_AREA_PAT|TRACK_AREA_SEARCH) +#define TRACK_AREA_ALL (TRACK_AREA_POINT | TRACK_AREA_PAT | TRACK_AREA_SEARCH) -#define TRACK_SORT_NONE -1 -#define TRACK_SORT_NAME 0 -#define TRACK_SORT_LONGEST 1 -#define TRACK_SORT_TOTAL 2 -#define TRACK_SORT_AVERAGE_ERROR 3 +#define TRACK_SORT_NONE -1 +#define TRACK_SORT_NAME 0 +#define TRACK_SORT_LONGEST 1 +#define TRACK_SORT_TOTAL 2 +#define TRACK_SORT_AVERAGE_ERROR 3 #endif diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index bbb70bb77ff..b4ee4f733e7 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -39,7 +39,7 @@ #include "DNA_gpencil_types.h" #include "DNA_camera_types.h" #include "DNA_movieclip_types.h" -#include "DNA_object_types.h" /* SELECT */ +#include "DNA_object_types.h" /* SELECT */ #include "DNA_scene_types.h" #include "BLI_utildefines.h" @@ -401,7 +401,7 @@ MovieTrackingMarker *BKE_tracking_insert_marker(MovieTrackingTrack *track, Movie track->markersnr++; if (track->markers) - track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr); + track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr); else track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers"); @@ -567,7 +567,7 @@ void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int actio while (a < track->markersnr) { if (track->markers[a].framenr > ref_frame) { track->markersnr = a; - track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr); + track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr); break; } @@ -586,7 +586,7 @@ void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int actio memmove(track->markers, track->markers + a, (track->markersnr - a) * sizeof(MovieTrackingMarker)); track->markersnr = track->markersnr - a; - track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr); + track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr); break; } @@ -707,8 +707,8 @@ void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack MEM_freeN(dst_track->markers); - dst_track->markers = MEM_callocN(i*sizeof(MovieTrackingMarker), "tracking joined tracks"); - memcpy(dst_track->markers, markers, i*sizeof(MovieTrackingMarker)); + dst_track->markers = MEM_callocN(i * sizeof(MovieTrackingMarker), "tracking joined tracks"); + memcpy(dst_track->markers, markers, i * sizeof(MovieTrackingMarker)); dst_track->markersnr = i; @@ -877,10 +877,10 @@ static TracksMap *tracks_map_new(const char *object_name, int is_camera, int num map->num_tracks = num_tracks; map->customdata_size = customdata_size; - map->tracks = MEM_callocN(sizeof(MovieTrackingTrack)*num_tracks, "TrackingsMap tracks"); + map->tracks = MEM_callocN(sizeof(MovieTrackingTrack) * num_tracks, "TrackingsMap tracks"); if (customdata_size) - map->customdata = MEM_callocN(customdata_size*num_tracks, "TracksMap customdata"); + map->customdata = MEM_callocN(customdata_size * num_tracks, "TracksMap customdata"); map->hash = BLI_ghash_ptr_new("TracksMap hash"); @@ -897,7 +897,7 @@ static void tracks_map_get(TracksMap *map, int index, MovieTrackingTrack **track *track = &map->tracks[index]; if (map->customdata) - *customdata = &map->customdata[index*map->customdata_size]; + *customdata = &map->customdata[index * map->customdata_size]; } static void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *customdata) @@ -909,7 +909,7 @@ static void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *c map->tracks[map->ptr] = new_track; if (customdata) - memcpy(&map->customdata[map->ptr*map->customdata_size], customdata, map->customdata_size); + memcpy(&map->customdata[map->ptr * map->customdata_size], customdata, map->customdata_size); BLI_ghash_insert(map->hash, &map->tracks[map->ptr], track); @@ -982,10 +982,10 @@ static void tracks_map_merge(TracksMap *map, MovieTracking *tracking) BLI_ghash_remove(map->hash, track, NULL, NULL); /* XXX: are we actually need this */ BLI_ghash_insert(map->hash, track, new_track); - if (replace_sel) /* update current selection in clip */ + if (replace_sel) /* update current selection in clip */ tracking->act_track = new_track; - if (replace_rot) /* update track used for rotation stabilization */ + if (replace_rot) /* update track used for rotation stabilization */ tracking->stabilization.rot_track = new_track; BLI_addtail(&tracks, new_track); @@ -1020,7 +1020,7 @@ static void tracks_map_merge(TracksMap *map, MovieTracking *tracking) *old_tracks = new_tracks; } -static void tracks_map_free(TracksMap *map, void (*customdata_free) (void *customdata)) +static void tracks_map_free(TracksMap *map, void (*customdata_free)(void *customdata)) { int i = 0; @@ -1028,7 +1028,7 @@ static void tracks_map_free(TracksMap *map, void (*customdata_free) (void *custo for (i = 0; i < map->num_tracks; i++) { if (map->customdata && customdata_free) - customdata_free(&map->customdata[i*map->customdata_size]); + customdata_free(&map->customdata[i * map->customdata_size]); BKE_tracking_free_track(&map->tracks[i]); } @@ -1159,7 +1159,7 @@ static void track_context_free(void *customdata) MEM_freeN(track_context->search_area); #else - (void) track_context; + (void)track_context; #endif } @@ -1195,16 +1195,16 @@ void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disab for (y = 0; y < ibuf->y; y++) { for (x = 0; x < ibuf->x; x++) { - int pixel = ibuf->x*y + x; + int pixel = ibuf->x * y + x; if (ibuf->rect_float) { - float *rrgbf = ibuf->rect_float + pixel*4; + float *rrgbf = ibuf->rect_float + pixel * 4; float r = disable_red ? 0.0f : rrgbf[0]; float g = disable_green ? 0.0f : rrgbf[1]; float b = disable_blue ? 0.0f : rrgbf[2]; if (grayscale) { - float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale; + float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale; rrgbf[0] = rrgbf[1] = rrgbf[2] = gray; } @@ -1215,13 +1215,13 @@ void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disab } } else { - char *rrgb = (char*)ibuf->rect + pixel*4; + char *rrgb = (char *)ibuf->rect + pixel * 4; char r = disable_red ? 0 : rrgb[0]; char g = disable_green ? 0 : rrgb[1]; char b = disable_blue ? 0 : rrgb[2]; if (grayscale) { - float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale; + float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale; rrgb[0] = rrgb[1] = rrgb[2] = gray; } @@ -1241,7 +1241,7 @@ void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disab static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale) { BKE_tracking_disable_imbuf_channels(ibuf, track->flag & TRACK_DISABLE_RED, - track->flag & TRACK_DISABLE_GREEN, track->flag & TRACK_DISABLE_BLUE, grayscale); + track->flag & TRACK_DISABLE_GREEN, track->flag & TRACK_DISABLE_BLUE, grayscale); } ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, @@ -1297,7 +1297,7 @@ ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, } ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int anchored, int disable_channels) + int anchored, int disable_channels) { ImBuf *pattern_ibuf, *search_ibuf; float pat_min[2], pat_max[2]; @@ -1499,11 +1499,11 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT if (searchibuf->rect_float) { float_rgba_to_gray(searchibuf->rect_float, gray_pixels, width * height, - 0.2126f, 0.7152f, 0.0722f); + 0.2126f, 0.7152f, 0.0722f); } else { uint8_rgba_to_float_gray((unsigned char *)searchibuf->rect, gray_pixels, width * height, - 0.2126f, 0.7152f, 0.0722f); + 0.2126f, 0.7152f, 0.0722f); } IMB_freeImBuf(searchibuf); @@ -1522,13 +1522,13 @@ static unsigned char *get_ucharbuf(ImBuf *ibuf) int pixel = ibuf->x * y + x; if (ibuf->rect_float) { - const float *rrgbf = ibuf->rect_float + pixel*4; + const float *rrgbf = ibuf->rect_float + pixel * 4; const float grey_f = 0.2126f * rrgbf[0] + 0.7152f * rrgbf[1] + 0.0722f * rrgbf[2]; *cp = FTOCHAR(grey_f); } else { - const unsigned char *rrgb = (unsigned char*)ibuf->rect + pixel * 4; + const unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4; *cp = 0.2126f * rrgb[0] + 0.7152f * rrgb[1] + 0.0722f * rrgb[2]; } @@ -1737,10 +1737,10 @@ int BKE_tracking_next(MovieTrackingContext *context) options.motion_model = track->motion_model; options.use_brute = - ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) != 0); + ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) != 0); options.use_normalization = - ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) != 0); + ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) != 0); options.num_iterations = 50; options.minimum_correlation = track->minimum_correlation; @@ -1801,6 +1801,9 @@ int BKE_tracking_next(MovieTrackingContext *context) } ok = TRUE; +#else + (void)frame_height; + (void)frame_width; #endif } } @@ -1862,7 +1865,7 @@ static struct libmv_Tracks *create_libmv_tracks(ListBase *tracksbase, int width, if ((marker->flag & MARKER_DISABLED) == 0) { libmv_tracksInsert(tracks, marker->framenr, tracknr, - marker->pos[0] * width, marker->pos[1] * height); + marker->pos[0] * width, marker->pos[1] * height); } } @@ -2079,7 +2082,7 @@ int BKE_tracking_can_reconstruct(MovieTracking *tracking, MovieTrackingObject *o #endif } -MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking *tracking, MovieTrackingObject *object, +MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking *tracking, MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height) { MovieReconstructContext *context = MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data"); @@ -2129,7 +2132,7 @@ MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking * context->efra = efra; #ifdef WITH_LIBMV - context->tracks = create_libmv_tracks(tracksbase, width, height*aspy); + context->tracks = create_libmv_tracks(tracksbase, width, height * aspy); context->keyframe1 = keyframe1; context->keyframe2 = keyframe2; context->refine_flags = get_refine_intrinsics_flags(tracking, object); @@ -2155,7 +2158,7 @@ void BKE_tracking_reconstruction_context_free(MovieReconstructContext *context) { #ifdef WITH_LIBMV if (context->reconstruction) - libmv_destroyReconstruction(context->reconstruction); + libmv_destroyReconstruction(context->reconstruction); libmv_tracksDestroy(context->tracks); #endif @@ -2207,19 +2210,19 @@ void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short * if (context->motion_flag & TRACKING_MOTION_MODAL) { context->reconstruction = libmv_solveModal(context->tracks, - context->focal_length, - context->principal_point[0], context->principal_point[1], - context->k1, context->k2, context->k3, - solve_reconstruction_update_cb, &progressdata); + context->focal_length, + context->principal_point[0], context->principal_point[1], + context->k1, context->k2, context->k3, + solve_reconstruction_update_cb, &progressdata); } else { context->reconstruction = libmv_solveReconstruction(context->tracks, - context->keyframe1, context->keyframe2, - context->refine_flags, - context->focal_length, - context->principal_point[0], context->principal_point[1], - context->k1, context->k2, context->k3, - solve_reconstruction_update_cb, &progressdata); + context->keyframe1, context->keyframe2, + context->refine_flags, + context->focal_length, + context->principal_point[0], context->principal_point[1], + context->k1, context->k2, context->k3, + solve_reconstruction_update_cb, &progressdata); } error = libmv_reprojectionError(context->reconstruction); @@ -2362,7 +2365,7 @@ MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *t reconstruction = BKE_tracking_object_reconstruction(tracking, object); a = reconstruction_camera_index(reconstruction, framenr, FALSE); - if (a ==-1) + if (a == -1) return NULL; return &reconstruction->cameras[a]; @@ -2766,8 +2769,8 @@ static void calculate_stabdata(MovieTracking *tracking, int framenr, float width *scale = (stab->scale - 1.0f) * stab->scaleinf + 1.0f; *angle = 0.0f; - loc[0] = (firstmedian[0] - median[0]) *width * (*scale); - loc[1] = (firstmedian[1] - median[1]) *height * (*scale); + loc[0] = (firstmedian[0] - median[0]) * width * (*scale); + loc[1] = (firstmedian[1] - median[1]) * height * (*scale); mul_v2_fl(loc, stab->locinf); @@ -2815,7 +2818,7 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, track = tracking->tracks.first; while (track) { if (track->flag & TRACK_USE_2D_STAB || - ((stab->flag & TRACKING_STABILIZE_ROTATION) && track == stab->rot_track)) + ((stab->flag & TRACKING_STABILIZE_ROTATION) && track == stab->rot_track)) { sfra = MIN2(sfra, track->markers[0].framenr); efra = MAX2(efra, track->markers[track->markersnr - 1].framenr); @@ -2876,23 +2879,23 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, h = (float)height / 2.0f; } - E = -w*co + h*si; - F = -h*co - w*si; + E = -w * co + h * si; + F = -h * co - w * si; if ((i % 2) == (j % 2)) { - G = -w*co - h*si; - H = h*co - w*si; + G = -w * co - h * si; + H = h * co - w * si; } else { - G = w*co + h*si; - H = -h*co + w*si; + G = w * co + h * si; + H = -h * co + w * si; } I = F - H; J = G - E; - K = G*F - E*H; + K = G * F - E * H; - S = (-w*I - h*J) / (dx*I + dy*J + K); + S = (-w * I - h * J) / (dx * I + dy * J + K); scale = MAX2(scale, S); } @@ -2914,7 +2917,7 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, return stab->scale; } -static ImBuf* stabilize_alloc_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill) +static ImBuf *stabilize_alloc_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill) { int flags; @@ -3021,7 +3024,7 @@ ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, stab->scaleibuf = scaleibuf; IMB_rectcpy(scaleibuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); - IMB_scalefastImBuf(scaleibuf, ibuf->x*tscale, ibuf->y*tscale); + IMB_scalefastImBuf(scaleibuf, ibuf->x * tscale, ibuf->y * tscale); ibuf = scaleibuf; } @@ -3038,7 +3041,7 @@ ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, else { float mat[4][4]; int i, j, filter = tracking->stabilization.filter; - void (*interpolation) (struct ImBuf*, struct ImBuf*, float, float, int, int) = NULL; + void (*interpolation)(struct ImBuf *, struct ImBuf *, float, float, int, int) = NULL; BKE_tracking_stabdata_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat); invert_m4(mat); @@ -3054,7 +3057,7 @@ ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, interpolation = neareast_interpolation; for (j = 0; j < tmpibuf->y; j++) { - for (i = 0; i < tmpibuf->x;i++) { + for (i = 0; i < tmpibuf->x; i++) { float vec[3] = {i, j, 0}; mul_v3_m4v3(vec, mat, vec); @@ -3102,9 +3105,9 @@ void BKE_tracking_stabdata_to_mat4(int width, int height, float aspect, cmat[3][1] = (float)height / 2.0f; invert_m4_m4(icmat, cmat); - size_to_mat4(smat, svec); /* scale matrix */ - add_v2_v2(lmat[3], loc); /* translation matrix */ - rotate_m4(rmat, 'Z', angle); /* rotation matrix */ + size_to_mat4(smat, svec); /* scale matrix */ + add_v2_v2(lmat[3], loc); /* translation matrix */ + rotate_m4(rmat, 'Z', angle); /* rotation matrix */ /* compose transformation matrix */ mul_serie_m4(mat, lmat, cmat, amat, rmat, iamat, smat, icmat, NULL); @@ -3142,13 +3145,13 @@ void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking * #ifdef WITH_LIBMV if (!distortion->intrinsics) { distortion->intrinsics = libmv_CameraIntrinsicsNew(camera->focal, - camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, width, height * aspy); + camera->principal[0], camera->principal[1] * aspy, + camera->k1, camera->k2, camera->k3, width, height * aspy); } else { libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal, - camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, width, height * aspy); + camera->principal[0], camera->principal[1] * aspy, + camera->k1, camera->k2, camera->k3, width, height * aspy); } #else (void) distortion; @@ -3172,13 +3175,13 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * #ifdef WITH_LIBMV if (undistort) { libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics, - ibuf->rect_float, resibuf->rect_float, - ibuf->x, ibuf->y, overscan, ibuf->channels); + ibuf->rect_float, resibuf->rect_float, + ibuf->x, ibuf->y, overscan, ibuf->channels); } else { libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics, - ibuf->rect_float, resibuf->rect_float, - ibuf->x, ibuf->y, overscan, ibuf->channels); + ibuf->rect_float, resibuf->rect_float, + ibuf->x, ibuf->y, overscan, ibuf->channels); } #endif @@ -3187,14 +3190,14 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * else { #ifdef WITH_LIBMV if (undistort) { - libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics, - (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect, - ibuf->x, ibuf->y, overscan, ibuf->channels); + libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics, + (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect, + ibuf->x, ibuf->y, overscan, ibuf->channels); } else { libmv_CameraIntrinsicsDistortByte(distortion->intrinsics, - (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect, - ibuf->x, ibuf->y, overscan, ibuf->channels); + (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect, + ibuf->x, ibuf->y, overscan, ibuf->channels); } #endif } diff --git a/source/blender/blenlib/BLI_pbvh.h b/source/blender/blenlib/BLI_pbvh.h index dbfa08219bd..6c0d547fe6f 100644 --- a/source/blender/blenlib/BLI_pbvh.h +++ b/source/blender/blenlib/BLI_pbvh.h @@ -82,13 +82,13 @@ void BLI_pbvh_search_gather(PBVH *bvh, * it's up to the callback to find the primitive within the leaves that is * hit first */ -void BLI_pbvh_raycast(PBVH * bvh, BLI_pbvh_HitOccludedCallback cb, void *data, +void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data, const float ray_start[3], const float ray_normal[3], - int original); + int original); -int BLI_pbvh_node_raycast(PBVH * bvh, PBVHNode * node, float (*origco)[3], +int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], const float ray_start[3], const float ray_normal[3], - float *dist); + float *dist); /* Drawing */ @@ -214,7 +214,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, #define BLI_pbvh_vertex_iter_begin(bvh, node, vi, mode) \ pbvh_vertex_iter_init(bvh, node, &vi, mode); \ - \ + \ for (vi.i = 0, vi.g = 0; vi.g < vi.totgrid; vi.g++) { \ if (vi.grids) { \ vi.width = vi.gridsize; \ diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c index 5361682caa4..409a9f88f39 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenlib/intern/pbvh.c @@ -1140,17 +1140,17 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode) switch (bvh->type) { case PBVH_GRIDS: node->draw_buffers = - GPU_build_grid_buffers(node->prim_indices, - node->totprim, - bvh->grid_hidden, - bvh->gridkey.grid_size); + GPU_build_grid_buffers(node->prim_indices, + node->totprim, + bvh->grid_hidden, + bvh->gridkey.grid_size); break; case PBVH_FACES: node->draw_buffers = - GPU_build_mesh_buffers(node->face_vert_indices, - bvh->faces, bvh->verts, - node->prim_indices, - node->totprim); + GPU_build_mesh_buffers(node->face_vert_indices, + bvh->faces, bvh->verts, + node->prim_indices, + node->totprim); break; } @@ -1478,7 +1478,7 @@ static int ray_aabb_intersect(PBVHNode *node, void *data_v) void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data, const float ray_start[3], const float ray_normal[3], - int original) + int original) { RaycastData rcd; @@ -1495,9 +1495,9 @@ void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data, } static int ray_face_intersection(const float ray_start[3], - const float ray_normal[3], + const float ray_normal[3], const float *t0, const float *t1, - const float *t2, const float *t3, + const float *t2, const float *t3, float *fdist) { float dist; @@ -1514,9 +1514,9 @@ static int ray_face_intersection(const float ray_start[3], } static int pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node, - float (*origco)[3], - const float ray_start[3], - const float ray_normal[3], float *dist) + float (*origco)[3], + const float ray_start[3], + const float ray_normal[3], float *dist) { const MVert *vert = bvh->verts; const int *faces = node->prim_indices; @@ -1532,20 +1532,20 @@ static int pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node, if (origco) { /* intersect with backuped original coordinates */ hit |= ray_face_intersection(ray_start, ray_normal, - origco[face_verts[0]], - origco[face_verts[1]], - origco[face_verts[2]], - f->v4 ? origco[face_verts[3]] : NULL, - dist); + origco[face_verts[0]], + origco[face_verts[1]], + origco[face_verts[2]], + f->v4 ? origco[face_verts[3]] : NULL, + dist); } else { /* intersect with current coordinates */ hit |= ray_face_intersection(ray_start, ray_normal, - vert[f->v1].co, - vert[f->v2].co, - vert[f->v3].co, - f->v4 ? vert[f->v4].co : NULL, - dist); + vert[f->v1].co, + vert[f->v2].co, + vert[f->v3].co, + f->v4 ? vert[f->v4].co : NULL, + dist); } } @@ -1553,9 +1553,9 @@ static int pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node, } static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node, - float (*origco)[3], - const float ray_start[3], - const float ray_normal[3], float *dist) + float (*origco)[3], + const float ray_start[3], + const float ray_normal[3], float *dist) { int totgrid = node->totprim; int gridsize = bvh->gridkey.grid_size; @@ -1580,19 +1580,19 @@ static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node, if (origco) { hit |= ray_face_intersection(ray_start, ray_normal, - origco[y * gridsize + x], - origco[y * gridsize + x + 1], - origco[(y + 1) * gridsize + x + 1], - origco[(y + 1) * gridsize + x], - dist); + origco[y * gridsize + x], + origco[y * gridsize + x + 1], + origco[(y + 1) * gridsize + x + 1], + origco[(y + 1) * gridsize + x], + dist); } else { hit |= ray_face_intersection(ray_start, ray_normal, - CCG_grid_elem_co(&bvh->gridkey, grid, x, y), - CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y), - CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1), - CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1), - dist); + CCG_grid_elem_co(&bvh->gridkey, grid, x, y), + CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y), + CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1), + CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1), + dist); } } } @@ -1606,7 +1606,7 @@ static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node, int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], const float ray_start[3], const float ray_normal[3], - float *dist) + float *dist) { int hit = 0; @@ -1616,11 +1616,11 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], switch (bvh->type) { case PBVH_FACES: hit |= pbvh_faces_node_raycast(bvh, node, origco, - ray_start, ray_normal, dist); + ray_start, ray_normal, dist); break; case PBVH_GRIDS: hit |= pbvh_grids_node_raycast(bvh, node, origco, - ray_start, ray_normal, dist); + ray_start, ray_normal, dist); break; } diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index b59f3756819..c8d03bcbf2f 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -237,7 +237,7 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin PointerRNA gpd_ptr; bGPDlayer *gpl; uiLayout *col, *row; - SpaceClip *sc= CTX_wm_space_clip(C); + SpaceClip *sc = CTX_wm_space_clip(C); short v3d_stroke_opts = STROKE_OPTS_NORMAL; const short is_v3d = CTX_wm_view3d(C) != NULL; diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index f368e7cf4c7..7b69e820467 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1542,7 +1542,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc } else if ((scopes->track_search) && ((!scopes->track_preview) || - (scopes->track_preview->x != width || scopes->track_preview->y != height))) + (scopes->track_preview->x != width || scopes->track_preview->y != height))) { ImBuf *tmpibuf; @@ -1686,7 +1686,7 @@ void ui_dropshadow(rctf *rct, float radius, float aspect, float alpha, int UNUSE int i; float rad; float a; - float dalpha = alpha * 2.0f/255.0f, calpha; + float dalpha = alpha * 2.0f / 255.0f, calpha; glEnable(GL_BLEND); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 66ad05aec7e..98735139136 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -919,7 +919,7 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod /* Grab brush requires to test on original data (see r33888 and * bug #25371) */ original = (paint_brush(&sd->paint)->sculpt_tool == SCULPT_TOOL_GRAB ? - TRUE : ss->cache->original); + TRUE : ss->cache->original); (void)sd; /* unused w/o openmp */ @@ -991,7 +991,7 @@ static void calc_sculpt_normal(Sculpt *sd, Object *ob, case SCULPT_DISP_DIR_VIEW: ED_view3d_global_to_vector(ss->cache->vc->rv3d, ss->cache->vc->rv3d->twmat[3], - an); + an); break; case SCULPT_DISP_DIR_X: @@ -1117,21 +1117,21 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob) static int brush_needs_sculpt_normal(const Brush *brush) { return ((ELEM(brush->sculpt_tool, - SCULPT_TOOL_GRAB, - SCULPT_TOOL_SNAKE_HOOK) && - ((brush->normal_weight > 0) || - (brush->flag & BRUSH_FRONTFACE))) || + SCULPT_TOOL_GRAB, + SCULPT_TOOL_SNAKE_HOOK) && + ((brush->normal_weight > 0) || + (brush->flag & BRUSH_FRONTFACE))) || - ELEM7(brush->sculpt_tool, - SCULPT_TOOL_BLOB, - SCULPT_TOOL_CREASE, - SCULPT_TOOL_DRAW, - SCULPT_TOOL_LAYER, - SCULPT_TOOL_NUDGE, - SCULPT_TOOL_ROTATE, - SCULPT_TOOL_THUMB) || + ELEM7(brush->sculpt_tool, + SCULPT_TOOL_BLOB, + SCULPT_TOOL_CREASE, + SCULPT_TOOL_DRAW, + SCULPT_TOOL_LAYER, + SCULPT_TOOL_NUDGE, + SCULPT_TOOL_ROTATE, + SCULPT_TOOL_THUMB) || - (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)); + (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)); } /* For the smooth brush, uses the neighboring vertices around vert to calculate @@ -1432,14 +1432,14 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) for (n = 0; n < totnode; n++) { - switch(type) { + switch (type) { case PBVH_GRIDS: do_multires_smooth_brush(sd, ss, nodes[n], strength, - smooth_mask); + smooth_mask); break; case PBVH_FACES: do_mesh_smooth_brush(sd, ss, nodes[n], strength, - smooth_mask); + smooth_mask); break; } } @@ -1532,7 +1532,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) /* offset vertex */ float fade = tex_strength(ss, brush, vd.co, test.dist, ss->cache->sculpt_normal_symm, vd.no, - vd.fno, *vd.mask); + vd.fno, *vd.mask); mul_v3_v3fl(proxy[vd.i], offset, fade); @@ -1588,7 +1588,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod /* offset vertex */ const float fade = tex_strength(ss, brush, vd.co, test.dist, ss->cache->sculpt_normal_symm, - vd.no, vd.fno, *vd.mask); + vd.no, vd.fno, *vd.mask); float val1[3]; float val2[3]; @@ -1726,7 +1726,7 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode if (sculpt_brush_test(&test, vd.co)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist, ss->cache->sculpt_normal_symm, - vd.no, vd.fno, *vd.mask); + vd.no, vd.fno, *vd.mask); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1775,7 +1775,7 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to if (sculpt_brush_test(&test, vd.co)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist, ss->cache->sculpt_normal_symm, - vd.no, vd.fno, *vd.mask); + vd.no, vd.fno, *vd.mask); mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -1823,7 +1823,7 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode if (sculpt_brush_test(&test, origco[vd.i])) { const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist, ss->cache->sculpt_normal_symm, - origno[vd.i], NULL, *vd.mask); + origno[vd.i], NULL, *vd.mask); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1876,7 +1876,7 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod if (sculpt_brush_test(&test, origco[vd.i])) { const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist, ss->cache->sculpt_normal_symm, - origno[vd.i], NULL, *vd.mask); + origno[vd.i], NULL, *vd.mask); mul_v3_m4v3(proxy[vd.i], m, origco[vd.i]); sub_v3_v3(proxy[vd.i], origco[vd.i]); @@ -1929,7 +1929,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode if (sculpt_brush_test(&test, origco[vd.i])) { const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist, ss->cache->sculpt_normal_symm, - vd.no, vd.fno, *vd.mask); + vd.no, vd.fno, *vd.mask); float *disp = &layer_disp[vd.i]; float val[3]; @@ -3585,15 +3585,15 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, one of smooth brush, autosmooth, mask smooth, or shift-key smooth) */ static int sculpt_any_smooth_mode(const Brush *brush, - StrokeCache *cache, - int stroke_mode) + StrokeCache *cache, + int stroke_mode) { return ((stroke_mode == BRUSH_STROKE_SMOOTH) || - (cache && cache->alt_smooth) || - (brush->sculpt_tool == SCULPT_TOOL_SMOOTH) || - (brush->autosmooth_factor > 0) || - ((brush->sculpt_tool == SCULPT_TOOL_MASK) && - (brush->mask_tool == BRUSH_MASK_SMOOTH))); + (cache && cache->alt_smooth) || + (brush->sculpt_tool == SCULPT_TOOL_SMOOTH) || + (brush->autosmooth_factor > 0) || + ((brush->sculpt_tool == SCULPT_TOOL_MASK) && + (brush->mask_tool == BRUSH_MASK_SMOOTH))); } static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob) @@ -3605,7 +3605,7 @@ static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob) Brush *brush = paint_brush(&sd->paint); sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob, - sculpt_any_smooth_mode(brush, ss->cache, 0)); + sculpt_any_smooth_mode(brush, ss->cache, 0)); } } diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index ca2ae6e8461..66fa2aed862 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -59,7 +59,7 @@ #include "WM_api.h" #include "WM_types.h" -#include "clip_intern.h" // own include +#include "clip_intern.h" /* own include */ /* Panels */ @@ -165,7 +165,7 @@ void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname) block = uiLayoutAbsoluteBlock(layout); - scopes->track_preview_height = (scopes->track_preview_height <= UI_UNIT_Y)?UI_UNIT_Y : scopes->track_preview_height; + scopes->track_preview_height = (scopes->track_preview_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->track_preview_height; uiDefBut(block, TRACKPREVIEW, 0, "", rect.xmin, rect.ymin, rect.xmax - rect.xmin, scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); @@ -173,27 +173,27 @@ void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname) /********************* Marker Template ************************/ -#define B_MARKER_POS 3 -#define B_MARKER_OFFSET 4 -#define B_MARKER_PAT_DIM 5 -#define B_MARKER_SEARCH_POS 6 -#define B_MARKER_SEARCH_DIM 7 -#define B_MARKER_FLAG 8 +#define B_MARKER_POS 3 +#define B_MARKER_OFFSET 4 +#define B_MARKER_PAT_DIM 5 +#define B_MARKER_SEARCH_POS 6 +#define B_MARKER_SEARCH_DIM 7 +#define B_MARKER_FLAG 8 typedef struct { - int compact; /* compact mode */ + int compact; /* compact mode */ MovieClip *clip; - MovieClipUser *user; /* user of clip */ + MovieClipUser *user; /* user of clip */ MovieTrackingTrack *track; MovieTrackingMarker *marker; - int framenr; /* current frame number */ - float marker_pos[2]; /* position of marker in pixel coords */ - float marker_pat[2]; /* position and dimensions of marker pattern in pixel coords */ - float track_offset[2]; /* offset of "parenting" point */ - float marker_search_pos[2], marker_search[2]; /* position and dimensions of marker search in pixel coords */ - int marker_flag; /* marker's flags */ + int framenr; /* current frame number */ + float marker_pos[2]; /* position of marker in pixel coords */ + float marker_pat[2]; /* position and dimensions of marker pattern in pixel coords */ + float track_offset[2]; /* offset of "parenting" point */ + float marker_search_pos[2], marker_search[2]; /* position and dimensions of marker search in pixel coords */ + int marker_flag; /* marker's flags */ } MarkerUpdateCb; static void to_pixel_space(float r[2], float a[2], int width, int height) @@ -205,7 +205,7 @@ static void to_pixel_space(float r[2], float a[2], int width, int height) static void marker_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg)) { - MarkerUpdateCb *cb = (MarkerUpdateCb*) arg_cb; + MarkerUpdateCb *cb = (MarkerUpdateCb *) arg_cb; MovieTrackingMarker *marker; if (!cb->compact) @@ -220,7 +220,7 @@ static void marker_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg)) static void marker_block_handler(bContext *C, void *arg_cb, int event) { - MarkerUpdateCb *cb = (MarkerUpdateCb*) arg_cb; + MarkerUpdateCb *cb = (MarkerUpdateCb *) arg_cb; MovieTrackingMarker *marker; int width, height, ok = FALSE; @@ -431,7 +431,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P tip = "Marker is enabled at current frame"; uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG, "Enabled", 10, 190, 145, 19, &cb->marker_flag, - 0, 0, 0, 0, tip); + 0, 0, 0, 0, tip); col = uiLayoutColumn(layout, 1); uiLayoutSetActive(col, (cb->marker_flag & MARKER_DISABLED) == 0); @@ -441,31 +441,31 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P uiDefBut(block, LABEL, 0, "Position:", 0, 190, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_POS, "X:", 10, 171, 145, 19, &cb->marker_pos[0], - -10*width, 10.0*width, step, digits, "X-position of marker at frame in screen coordinates"); + -10 * width, 10.0 * width, step, digits, "X-position of marker at frame in screen coordinates"); uiDefButF(block, NUM, B_MARKER_POS, "Y:", 165, 171, 145, 19, &cb->marker_pos[1], - -10*height, 10.0*height, step, digits, "Y-position of marker at frame in screen coordinates"); + -10 * height, 10.0 * height, step, digits, "Y-position of marker at frame in screen coordinates"); uiDefBut(block, LABEL, 0, "Offset:", 0, 152, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_OFFSET, "X:", 10, 133, 145, 19, &cb->track_offset[0], - -10*width, 10.0*width, step, digits, "X-offset to parenting point"); + -10 * width, 10.0 * width, step, digits, "X-offset to parenting point"); uiDefButF(block, NUM, B_MARKER_OFFSET, "Y:", 165, 133, 145, 19, &cb->track_offset[1], - -10*height, 10.0*height, step, digits, "Y-offset to parenting point"); + -10 * height, 10.0 * height, step, digits, "Y-offset to parenting point"); uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->marker_pat[0], 3.0f, - 10.0*width, step, digits, "Width of marker's pattern in screen coordinates"); + 10.0 * width, step, digits, "Width of marker's pattern in screen coordinates"); uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->marker_pat[1], 3.0f, - 10.0*height, step, digits, "Height of marker's pattern in screen coordinates"); + 10.0 * height, step, digits, "Height of marker's pattern in screen coordinates"); uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->marker_search_pos[0], - -width, width, step, digits, "X-position of search at frame relative to marker's position"); + -width, width, step, digits, "X-position of search at frame relative to marker's position"); uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->marker_search_pos[1], - -height, height, step, digits, "X-position of search at frame relative to marker's position"); + -height, height, step, digits, "X-position of search at frame relative to marker's position"); uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->marker_search[0], 3.0f, - 10.0*width, step, digits, "Width of marker's search in screen soordinates"); + 10.0 * width, step, digits, "Width of marker's search in screen soordinates"); uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->marker_search[1], 3.0f, - 10.0*height, step, digits, "Height of marker's search in screen soordinates"); + 10.0 * height, step, digits, "Height of marker's search in screen soordinates"); uiBlockEndAlign(block); } diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index 67609fee653..e9ea70cafea 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -30,7 +30,7 @@ */ #include "DNA_movieclip_types.h" -#include "DNA_object_types.h" /* SELECT */ +#include "DNA_object_types.h" /* SELECT */ #include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -61,7 +61,7 @@ #include "RNA_access.h" -#include "clip_intern.h" // own include +#include "clip_intern.h" /* own include */ static void track_channel_color(MovieTrackingTrack *track, float default_color[3], float color[3]) { @@ -83,10 +83,10 @@ static void draw_keyframe_shape(float x, float y, float xscale, float yscale, sh { /* coordinates for diamond shape */ static const float _unit_diamond_shape[4][2] = { - {0.0f, 1.0f}, /* top vert */ - {1.0f, 0.0f}, /* mid-right */ - {0.0f, -1.0f}, /* bottom vert */ - {-1.0f, 0.0f} /* mid-left */ + {0.0f, 1.0f}, /* top vert */ + {1.0f, 0.0f}, /* mid-right */ + {0.0f, -1.0f}, /* bottom vert */ + {-1.0f, 0.0f} /* mid-left */ }; static GLuint displist1 = 0; static GLuint displist2 = 0; @@ -95,26 +95,26 @@ static void draw_keyframe_shape(float x, float y, float xscale, float yscale, sh /* initialize 2 display lists for diamond shape - one empty, one filled */ if (displist1 == 0) { displist1 = glGenLists(1); - glNewList(displist1, GL_COMPILE); + glNewList(displist1, GL_COMPILE); - glBegin(GL_LINE_LOOP); - glVertex2fv(_unit_diamond_shape[0]); - glVertex2fv(_unit_diamond_shape[1]); - glVertex2fv(_unit_diamond_shape[2]); - glVertex2fv(_unit_diamond_shape[3]); - glEnd(); + glBegin(GL_LINE_LOOP); + glVertex2fv(_unit_diamond_shape[0]); + glVertex2fv(_unit_diamond_shape[1]); + glVertex2fv(_unit_diamond_shape[2]); + glVertex2fv(_unit_diamond_shape[3]); + glEnd(); glEndList(); } if (displist2 == 0) { displist2 = glGenLists(1); - glNewList(displist2, GL_COMPILE); + glNewList(displist2, GL_COMPILE); - glBegin(GL_QUADS); - glVertex2fv(_unit_diamond_shape[0]); - glVertex2fv(_unit_diamond_shape[1]); - glVertex2fv(_unit_diamond_shape[2]); - glVertex2fv(_unit_diamond_shape[3]); - glEnd(); + glBegin(GL_QUADS); + glVertex2fv(_unit_diamond_shape[0]); + glVertex2fv(_unit_diamond_shape[1]); + glVertex2fv(_unit_diamond_shape[2]); + glVertex2fv(_unit_diamond_shape[3]); + glEnd(); glEndList(); } @@ -210,7 +210,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) if (start_frame != end_frame) { glRectf(start_frame, (float) y - STRIP_HEIGHT_HALF, - end_frame, (float) y + STRIP_HEIGHT_HALF); + end_frame, (float) y + STRIP_HEIGHT_HALF); draw_keyframe_shape(start_frame, y, xscale, yscale, sel, alpha); draw_keyframe_shape(end_frame, y, xscale, yscale, sel, alpha); } @@ -309,7 +309,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) font_height = BLF_height(fontid, track->name); BLF_position(fontid, v2d->cur.xmin + CHANNEL_PAD, - y - font_height / 2.0f, 0.0f); + y - font_height / 2.0f, 0.0f); BLF_draw(fontid, track->name, strlen(track->name)); } diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 2e16a9095f0..a9b23d5b939 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -32,7 +32,7 @@ #include "DNA_gpencil_types.h" #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" -#include "DNA_object_types.h" /* SELECT */ +#include "DNA_object_types.h" /* SELECT */ #include "DNA_mask_types.h" #include "MEM_guardedalloc.h" @@ -69,7 +69,7 @@ #include "BLF_api.h" -#include "clip_intern.h" // own include +#include "clip_intern.h" // own include /*********************** main area drawing *************************/ @@ -277,10 +277,10 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, glScalef(zoomx, zoomy, 1.0f); glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); - glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f); - glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height); - glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height); + glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); + glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f); + glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height); + glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height); glEnd(); glPopMatrix(); @@ -320,10 +320,10 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, glMultMatrixf(sc->stabmat); glBegin(GL_LINE_LOOP); - glVertex2f(0.0f, 0.0f); - glVertex2f(width, 0.0f); - glVertex2f(width, height); - glVertex2f(0.0f, height); + glVertex2f(0.0f, 0.0f); + glVertex2f(width, 0.0f); + glVertex2f(width, height); + glVertex2f(0.0f, height); glEnd(); glPopMatrix(); @@ -399,17 +399,17 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin if (TRACK_VIEW_SELECTED(sc, track)) { glPointSize(5.0f); glBegin(GL_POINTS); - for (i = a; i < b; i++) { - if (i != curindex) - glVertex2f(path[i][0], path[i][1]); - } + for (i = a; i < b; i++) { + if (i != curindex) + glVertex2f(path[i][0], path[i][1]); + } glEnd(); } glLineWidth(3.0f); glBegin(GL_LINE_STRIP); - for (i = a; i < b; i++) - glVertex2f(path[i][0], path[i][1]); + for (i = a; i < b; i++) + glVertex2f(path[i][0], path[i][1]); glEnd(); glLineWidth(1.0f); } @@ -419,25 +419,25 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin if (TRACK_VIEW_SELECTED(sc, track)) { glPointSize(3.0f); glBegin(GL_POINTS); - for (i = a; i < b; i++) { - if (i == count + 1) - UI_ThemeColor(TH_PATH_AFTER); + for (i = a; i < b; i++) { + if (i == count + 1) + UI_ThemeColor(TH_PATH_AFTER); - if (i != curindex) - glVertex2f(path[i][0], path[i][1]); - } + if (i != curindex) + glVertex2f(path[i][0], path[i][1]); + } glEnd(); } UI_ThemeColor(TH_PATH_BEFORE); glBegin(GL_LINE_STRIP); - for (i = a; i < b; i++) { - if (i == count + 1) - UI_ThemeColor(TH_PATH_AFTER); + for (i = a; i < b; i++) { + if (i == count + 1) + UI_ThemeColor(TH_PATH_AFTER); - glVertex2f(path[i][0], path[i][1]); - } + glVertex2f(path[i][0], path[i][1]); + } glEnd(); glPointSize(1.0f); } @@ -470,24 +470,24 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT if (tiny) glPointSize(3.0f); else glPointSize(4.0f); glBegin(GL_POINTS); - glVertex2f(pos[0], pos[1]); + glVertex2f(pos[0], pos[1]); glEnd(); glPointSize(1.0f); } else { if (!tiny) glLineWidth(3.0f); glBegin(GL_LINES); - glVertex2f(pos[0] + px[0]*2, pos[1]); - glVertex2f(pos[0] + px[0]*8, pos[1]); + glVertex2f(pos[0] + px[0] * 2, pos[1]); + glVertex2f(pos[0] + px[0] * 8, pos[1]); - glVertex2f(pos[0] - px[0]*2, pos[1]); - glVertex2f(pos[0] - px[0]*8, pos[1]); + glVertex2f(pos[0] - px[0] * 2, pos[1]); + glVertex2f(pos[0] - px[0] * 8, pos[1]); - glVertex2f(pos[0], pos[1] - px[1]*2); - glVertex2f(pos[0], pos[1] - px[1]*8); + glVertex2f(pos[0], pos[1] - px[1] * 2); + glVertex2f(pos[0], pos[1] - px[1] * 8); - glVertex2f(pos[0], pos[1] + px[1]*2); - glVertex2f(pos[0], pos[1] + px[1]*8); + glVertex2f(pos[0], pos[1] + px[1] * 2); + glVertex2f(pos[0], pos[1] + px[1] * 8); glEnd(); if (!tiny) glLineWidth(1.0f); } @@ -502,10 +502,10 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT if (sc->flag & SC_SHOW_MARKER_PATTERN) { glBegin(GL_LINE_LOOP); - glVertex2fv(marker->pattern_corners[0]); - glVertex2fv(marker->pattern_corners[1]); - glVertex2fv(marker->pattern_corners[2]); - glVertex2fv(marker->pattern_corners[3]); + glVertex2fv(marker->pattern_corners[0]); + glVertex2fv(marker->pattern_corners[1]); + glVertex2fv(marker->pattern_corners[2]); + glVertex2fv(marker->pattern_corners[3]); glEnd(); } @@ -513,10 +513,10 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0); if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) { glBegin(GL_LINE_LOOP); - glVertex2f(marker->search_min[0], marker->search_min[1]); - glVertex2f(marker->search_max[0], marker->search_min[1]); - glVertex2f(marker->search_max[0], marker->search_max[1]); - glVertex2f(marker->search_min[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_max[1]); glEnd(); } glPopMatrix(); @@ -546,7 +546,7 @@ static void track_colors(MovieTrackingTrack *track, int act, float col[3], float } static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, - float marker_pos[2], int width, int height, int act, int sel) + float marker_pos[2], int width, int height, int act, int sel) { int tiny = sc->flag & SC_SHOW_TINY_MARKER; int show_search = 0; @@ -588,7 +588,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra glPointSize(2.0f); glBegin(GL_POINTS); - glVertex2f(pos[0], pos[1]); + glVertex2f(pos[0], pos[1]); glEnd(); if (!tiny) @@ -596,17 +596,17 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } else { glBegin(GL_LINES); - glVertex2f(pos[0] + px[0]*3, pos[1]); - glVertex2f(pos[0] + px[0]*7, pos[1]); + glVertex2f(pos[0] + px[0] * 3, pos[1]); + glVertex2f(pos[0] + px[0] * 7, pos[1]); - glVertex2f(pos[0] - px[0]*3, pos[1]); - glVertex2f(pos[0] - px[0]*7, pos[1]); + glVertex2f(pos[0] - px[0] * 3, pos[1]); + glVertex2f(pos[0] - px[0] * 7, pos[1]); - glVertex2f(pos[0], pos[1] - px[1]*3); - glVertex2f(pos[0], pos[1] - px[1]*7); + glVertex2f(pos[0], pos[1] - px[1] * 3); + glVertex2f(pos[0], pos[1] - px[1] * 7); - glVertex2f(pos[0], pos[1] + px[1]*3); - glVertex2f(pos[0], pos[1] + px[1]*7); + glVertex2f(pos[0], pos[1] + px[1] * 3); + glVertex2f(pos[0], pos[1] + px[1] * 7); glEnd(); glColor3f(0.0f, 0.0f, 0.0f); @@ -616,8 +616,8 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra glLogicOp(GL_NOR); glBegin(GL_LINES); - glVertex2fv(pos); - glVertex2fv(marker_pos); + glVertex2fv(pos); + glVertex2fv(marker_pos); glEnd(); glDisable(GL_COLOR_LOGIC_OP); @@ -656,16 +656,16 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } glBegin(GL_LINE_LOOP); - glVertex2fv(marker->pattern_corners[0]); - glVertex2fv(marker->pattern_corners[1]); - glVertex2fv(marker->pattern_corners[2]); - glVertex2fv(marker->pattern_corners[3]); + glVertex2fv(marker->pattern_corners[0]); + glVertex2fv(marker->pattern_corners[1]); + glVertex2fv(marker->pattern_corners[2]); + glVertex2fv(marker->pattern_corners[3]); glEnd(); } /* search */ show_search = TRACK_VIEW_SELECTED(sc, track) && - ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0); + ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0); if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) { if (track->flag & TRACK_LOCKED) { if (act) @@ -689,10 +689,10 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } glBegin(GL_LINE_LOOP); - glVertex2f(marker->search_min[0], marker->search_min[1]); - glVertex2f(marker->search_max[0], marker->search_min[1]); - glVertex2f(marker->search_max[0], marker->search_max[1]); - glVertex2f(marker->search_min[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_max[1]); glEnd(); } @@ -733,10 +733,10 @@ static void draw_marker_slide_square(float x, float y, float dx, float dy, int o } glBegin(GL_QUADS); - glVertex3f(x - tdx, y + tdy, 0.0f); - glVertex3f(x + tdx, y + tdy, 0.0f); - glVertex3f(x + tdx, y - tdy, 0.0f); - glVertex3f(x - tdx, y - tdy, 0.0f); + glVertex3f(x - tdx, y + tdy, 0.0f); + glVertex3f(x + tdx, y + tdy, 0.0f); + glVertex3f(x + tdx, y - tdy, 0.0f); + glVertex3f(x - tdx, y - tdy, 0.0f); glEnd(); } @@ -753,9 +753,9 @@ static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int } glBegin(GL_TRIANGLES); - glVertex3f(x, y, 0.0f); - glVertex3f(x - tdx, y, 0.0f); - glVertex3f(x, y + tdy, 0.0f); + glVertex3f(x, y, 0.0f); + glVertex3f(x - tdx, y, 0.0f); + glVertex3f(x, y + tdy, 0.0f); glEnd(); } @@ -874,7 +874,7 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } if ((sc->flag & SC_SHOW_MARKER_SEARCH) && - ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) + ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) { dx = marker->search_min[0]; dy = marker->search_min[1]; @@ -893,8 +893,8 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra mul_m4_v3(sc->stabmat, pos); - pos[0] = pos[0]*zoomx; - pos[1] = pos[1]*zoomy - fontsize; + pos[0] = pos[0] * zoomx; + pos[1] = pos[1] * zoomy - fontsize; if (marker->flag & MARKER_DISABLED) strcpy(state, "disabled"); @@ -934,8 +934,8 @@ static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx y = -v2d->cur.ymin / (v2d->cur.ymax - v2d->cur.ymin); /* convert proportional distances to screen coordinates */ - *regionx = v2d->mask.xmin + x*(v2d->mask.xmax - v2d->mask.xmin); - *regiony = v2d->mask.ymin + y*(v2d->mask.ymax - v2d->mask.ymin); + *regionx = v2d->mask.xmin + x * (v2d->mask.xmax - v2d->mask.xmin); + *regiony = v2d->mask.ymin + y * (v2d->mask.ymax - v2d->mask.ymin); } static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, @@ -987,7 +987,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, /* undistort */ if (count) { - marker_pos = MEM_callocN(2*sizeof(float)*count, "draw_tracking_tracks marker_pos"); + marker_pos = MEM_callocN(2 * sizeof(float) * count, "draw_tracking_tracks marker_pos"); track = tracksbase->first; fp = marker_pos; @@ -1121,10 +1121,10 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); - if (undistort) - glVertex3f(pos[0] / width, pos[1] / (height * aspy), 0); - else - glVertex3f(npos[0] / width, npos[1] / (height * aspy), 0); + if (undistort) + glVertex3f(pos[0] / width, pos[1] / (height * aspy), 0); + else + glVertex3f(npos[0] / width, npos[1] / (height * aspy), 0); glEnd(); } } @@ -1260,7 +1260,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, BKE_tracking_apply_intrinsics(tracking, pos, grid[i][j]); grid[i][j][0] /= width; - grid[i][j][1] /= height*aspy; + grid[i][j][1] /= height * aspy; pos[0] += dx; } @@ -1273,17 +1273,17 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, for (i = 0; i <= n; i++) { glBegin(GL_LINE_STRIP); - for (j = 0; j <= n; j++) { - glVertex2fv(grid[i][j]); - } + for (j = 0; j <= n; j++) { + glVertex2fv(grid[i][j]); + } glEnd(); } for (j = 0; j <= n; j++) { glBegin(GL_LINE_STRIP); - for (i = 0; i <= n; i++) { - glVertex2fv(grid[i][j]); - } + for (i = 0; i <= n; i++) { + glVertex2fv(grid[i][j]); + } glEnd(); } } @@ -1328,40 +1328,40 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, if (stroke->flag & GP_STROKE_2DSPACE) { if (stroke->totpoints > 1) { glBegin(GL_LINE_STRIP); - for (i = 0; i < stroke->totpoints - 1; i++) { - float npos[2], dpos[2], len; - int steps; + for (i = 0; i < stroke->totpoints - 1; i++) { + float npos[2], dpos[2], len; + int steps; - pos[0] = (stroke->points[i].x + offsx) * width; - pos[1] = (stroke->points[i].y + offsy) * height * aspy; + pos[0] = (stroke->points[i].x + offsx) * width; + pos[1] = (stroke->points[i].y + offsy) * height * aspy; - npos[0] = (stroke->points[i + 1].x + offsx) * width; - npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy; + npos[0] = (stroke->points[i + 1].x + offsx) * width; + npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy; - len = len_v2v2(pos, npos); - steps = ceil(len / 5.0f); + len = len_v2v2(pos, npos); + steps = ceil(len / 5.0f); - /* we want to distort only long straight lines */ - if (stroke->totpoints == 2) { - BKE_tracking_invert_intrinsics(tracking, pos, pos); - BKE_tracking_invert_intrinsics(tracking, npos, npos); - } - - sub_v2_v2v2(dpos, npos, pos); - mul_v2_fl(dpos, 1.0f / steps); - - for (j = 0; j <= steps; j++) { - BKE_tracking_apply_intrinsics(tracking, pos, tpos); - glVertex2f(tpos[0] / width, tpos[1] / (height*aspy)); - - add_v2_v2(pos, dpos); - } + /* we want to distort only long straight lines */ + if (stroke->totpoints == 2) { + BKE_tracking_invert_intrinsics(tracking, pos, pos); + BKE_tracking_invert_intrinsics(tracking, npos, npos); } + + sub_v2_v2v2(dpos, npos, pos); + mul_v2_fl(dpos, 1.0f / steps); + + for (j = 0; j <= steps; j++) { + BKE_tracking_apply_intrinsics(tracking, pos, tpos); + glVertex2f(tpos[0] / width, tpos[1] / (height * aspy)); + + add_v2_v2(pos, dpos); + } + } glEnd(); } else if (stroke->totpoints == 1) { glBegin(GL_POINTS); - glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy); + glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy); glEnd(); } } diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 8d30242c128..7da5dae1b50 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -31,7 +31,7 @@ #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" -#include "DNA_object_types.h" /* SELECT */ +#include "DNA_object_types.h" /* SELECT */ #include "MEM_guardedalloc.h" @@ -57,7 +57,7 @@ #include "BLF_api.h" -#include "clip_intern.h" // own include +#include "clip_intern.h" // own include static void draw_curve_knot(float x, float y, float xscale, float yscale, float hsize) { @@ -88,7 +88,7 @@ static void draw_curve_knot(float x, float y, float xscale, float yscale, float } static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track), - MovieTrackingMarker *UNUSED(marker), int UNUSED(coord), int scene_framenr, float val) + MovieTrackingMarker *UNUSED(marker), int UNUSED(coord), int scene_framenr, float val) { glVertex2f(scene_framenr, val); } @@ -123,7 +123,7 @@ void tracking_segment_end_cb(void *UNUSED(userdata)) } static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int coord, int scene_framenr, float val) + MovieTrackingMarker *marker, int coord, int scene_framenr, float val) { struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } *data = userdata; int sel = 0, sel_flag; @@ -167,7 +167,7 @@ static void draw_tracks_curves(View2D *v2d, SpaceClip *sc) /* draw graph lines */ glEnable(GL_BLEND); clip_graph_tracking_values_iterate(sc, act_track, tracking_segment_point_cb, - tracking_segment_start_cb, tracking_segment_end_cb); + tracking_segment_start_cb, tracking_segment_end_cb); glDisable(GL_BLEND); /* selected knot handles on top of curves */ diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index 79e199a8f06..9af67a2b104 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -29,7 +29,7 @@ * \ingroup spclip */ -#include "DNA_object_types.h" /* SELECT */ +#include "DNA_object_types.h" /* SELECT */ #include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -57,7 +57,7 @@ #include "UI_view2d.h" -#include "clip_intern.h" // own include +#include "clip_intern.h" // own include /******************** common graph-editing utilities ********************/ @@ -96,16 +96,16 @@ static void toggle_selection_cb(void *userdata, MovieTrackingMarker *marker) /******************** mouse select operator ********************/ typedef struct { - int coord, /* coordinate index of found entuty (0 = X-axis, 1 = Y-axis) */ - has_prev; /* if there's valid coordinate of previous point of curve segment */ + int coord, /* coordinate index of found entuty (0 = X-axis, 1 = Y-axis) */ + has_prev; /* if there's valid coordinate of previous point of curve segment */ - float min_dist, /* minimal distance between mouse and currently found entuty */ - mouse_co[2], /* mouse coordinate */ - prev_co[2], /* coordinate of previeous point of segment */ - min_co[2]; /* coordinate of entity with minimal distance */ + float min_dist, /* minimal distance between mouse and currently found entuty */ + mouse_co[2], /* mouse coordinate */ + prev_co[2], /* coordinate of previeous point of segment */ + min_co[2]; /* coordinate of entity with minimal distance */ - MovieTrackingTrack *track; /* nearest found track */ - MovieTrackingMarker *marker; /* nearest found marker */ + MovieTrackingTrack *track; /* nearest found track */ + MovieTrackingMarker *marker; /* nearest found marker */ } MouseSelectUserData; static void find_nearest_tracking_segment_cb(void *userdata, MovieTrackingTrack *track, @@ -261,7 +261,7 @@ static int mouse_select(bContext *C, float co[2], int extend) static int select_exec(bContext *C, wmOperator *op) { float co[2]; - int extend = RNA_boolean_get(op->ptr, "extend"); + int extend = RNA_boolean_get(op->ptr, "extend"); RNA_float_get_array(op->ptr, "location", co); @@ -296,9 +296,9 @@ void CLIP_OT_graph_select(wmOperatorType *ot) /* properties */ RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, - "Location", "Mouse location to select nearest entity", -100.0f, 100.0f); + "Location", "Mouse location to select nearest entity", -100.0f, 100.0f); RNA_def_boolean(ot->srna, "extend", 0, - "Extend", "Extend selection rather than clearing the existing selection"); + "Extend", "Extend selection rather than clearing the existing selection"); } /********************** border select operator *********************/ @@ -671,10 +671,10 @@ static int graph_disable_markers_exec(bContext *C, wmOperator *op) void CLIP_OT_graph_disable_markers(wmOperatorType *ot) { static EnumPropertyItem actions_items[] = { - {0, "DISABLE", 0, "Disable", "Disable selected markers"}, - {1, "ENABLE", 0, "Enable", "Enable selected markers"}, - {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"}, - {0, NULL, 0, NULL, NULL} + {0, "DISABLE", 0, "Disable", "Disable selected markers"}, + {1, "ENABLE", 0, "Enable", "Enable selected markers"}, + {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index 6908e488157..dd1addd715c 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -43,18 +43,18 @@ struct SpaceClip; struct wmOperatorType; /* channel heights */ -#define CHANNEL_FIRST -UI_UNIT_Y -#define CHANNEL_HEIGHT UI_UNIT_Y -#define CHANNEL_HEIGHT_HALF (UI_UNIT_Y / 2.0f) -#define CHANNEL_SKIP 2 -#define CHANNEL_STEP (CHANNEL_HEIGHT + CHANNEL_SKIP) +#define CHANNEL_FIRST -UI_UNIT_Y +#define CHANNEL_HEIGHT UI_UNIT_Y +#define CHANNEL_HEIGHT_HALF (UI_UNIT_Y / 2.0f) +#define CHANNEL_SKIP 2 +#define CHANNEL_STEP (CHANNEL_HEIGHT + CHANNEL_SKIP) -#define CHANNEL_PAD 4 +#define CHANNEL_PAD 4 /* extra padding for lengths (to go under scrollers) */ -#define EXTRA_SCROLL_PAD 100.0f +#define EXTRA_SCROLL_PAD 100.0f -#define STRIP_HEIGHT_HALF 5 +#define STRIP_HEIGHT_HALF 5 /* internal exports only */ @@ -110,17 +110,17 @@ void ED_clip_tool_props_register(struct ARegionType *art); /* clip_utils.c */ void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc, struct MovieTrackingTrack *track, void *userdata, - void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), - void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord), - void (*segment_end) (void *userdata)); + void (*func)(void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), + void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord), + void (*segment_end)(void *userdata)); void clip_graph_tracking_values_iterate(struct SpaceClip *sc, void *userdata, - void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), - void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord), - void (*segment_end) (void *userdata)); + void (*func)(void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), + void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord), + void (*segment_end)(void *userdata)); void clip_graph_tracking_iterate(struct SpaceClip *sc, void *userdata, - void (*func) (void *userdata, struct MovieTrackingMarker *marker)); + void (*func)(void *userdata, struct MovieTrackingMarker *marker)); void clip_delete_track(struct bContext *C, struct MovieClip *clip, struct ListBase *tracksbase, struct MovieTrackingTrack *track); void clip_delete_marker(struct bContext *C, struct MovieClip *clip, struct ListBase *tracksbase, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker); diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 6b69f316880..8175a84e188 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -30,7 +30,7 @@ */ #include "DNA_scene_types.h" -#include "DNA_object_types.h" /* SELECT */ +#include "DNA_object_types.h" /* SELECT */ #include "MEM_guardedalloc.h" @@ -61,12 +61,12 @@ #include "UI_resources.h" #include "UI_view2d.h" -#include "clip_intern.h" // own include +#include "clip_intern.h" // own include void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack *track, void *userdata, - void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), - void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord), - void (*segment_end) (void *userdata)) + void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), + void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord), + void (*segment_end)(void *userdata)) { MovieClip *clip = ED_space_clip(sc); int width, height, coord; @@ -122,9 +122,9 @@ void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack } void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata, - void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), - void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord), - void (*segment_end) (void *userdata)) + void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), + void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord), + void (*segment_end)(void *userdata)) { MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; @@ -142,7 +142,7 @@ void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata, } void clip_graph_tracking_iterate(SpaceClip *sc, void *userdata, - void (*func) (void *userdata, MovieTrackingMarker *marker)) + void (*func)(void *userdata, MovieTrackingMarker *marker)) { MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; @@ -244,11 +244,11 @@ void clip_draw_cfra(SpaceClip *sc, ARegion *ar, Scene *scene) glLineWidth(2.0); glBegin(GL_LINE_STRIP); - vec[1] = v2d->cur.ymin; - glVertex2fv(vec); + vec[1] = v2d->cur.ymin; + glVertex2fv(vec); - vec[1] = v2d->cur.ymax; - glVertex2fv(vec); + vec[1] = v2d->cur.ymax; + glVertex2fv(vec); glEnd(); glLineWidth(1.0); @@ -272,10 +272,10 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene) /* currently clip editor supposes that editing clip length is equal to scene frame range */ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); - glColor4f(0.0f, 0.0f, 0.0f, 0.4f); + glColor4f(0.0f, 0.0f, 0.0f, 0.4f); - glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax); - glRectf((float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); + glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax); + glRectf((float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); glDisable(GL_BLEND); UI_ThemeColorShade(TH_BACK, -60); diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 54724881e37..6409ad6b171 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -35,7 +35,7 @@ #include "DNA_scene_types.h" #include "DNA_mask_types.h" #include "DNA_movieclip_types.h" -#include "DNA_view3d_types.h" /* for pivot point */ +#include "DNA_view3d_types.h" /* for pivot point */ #include "MEM_guardedalloc.h" @@ -71,7 +71,7 @@ #include "RNA_access.h" -#include "clip_intern.h" // own include +#include "clip_intern.h" /* own include */ static void init_preview_region(const bContext *C, ARegion *ar) { @@ -299,7 +299,7 @@ static SpaceLink *clip_new(const bContext *C) /* not spacelink itself */ static void clip_free(SpaceLink *sl) { - SpaceClip *sc = (SpaceClip*) sl; + SpaceClip *sc = (SpaceClip *) sl; sc->clip = NULL; @@ -397,7 +397,7 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) } break; case NC_SCREEN: - switch (wmn->data) { + switch (wmn->data) { case ND_ANIMPLAY: case ND_GPENCIL: ED_area_tag_redraw(sa); @@ -634,17 +634,17 @@ static void clip_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CLIP_OT_slide_marker", LEFTMOUSE, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "CLIP_OT_disable_markers", DKEY, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set(kmi->ptr, "action", 2); /* toggle */ + RNA_enum_set(kmi->ptr, "action", 2); /* toggle */ /* tracks */ WM_keymap_add_item(keymap, "CLIP_OT_delete_track", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "CLIP_OT_delete_track", XKEY, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "CLIP_OT_lock_tracks", LKEY, KM_PRESS, KM_CTRL, 0); - RNA_enum_set(kmi->ptr, "action", 0); /* lock */ + RNA_enum_set(kmi->ptr, "action", 0); /* lock */ kmi = WM_keymap_add_item(keymap, "CLIP_OT_lock_tracks", LKEY, KM_PRESS, KM_ALT, 0); - RNA_enum_set(kmi->ptr, "action", 1); /* unlock */ + RNA_enum_set(kmi->ptr, "action", 1); /* unlock */ kmi = WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "unselected", FALSE); @@ -733,7 +733,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) /* tracks */ kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_disable_markers", DKEY, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set(kmi->ptr, "action", 2); /* toggle */ + RNA_enum_set(kmi->ptr, "action", 2); /* toggle */ transform_keymap_for_space(keyconf, keymap, SPACE_CLIP); @@ -742,7 +742,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) keymap = WM_keymap_find(keyconf, "Clip Dopesheet Editor", SPACE_CLIP, 0); kmi = WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_select_channel", ACTIONMOUSE, KM_PRESS, 0, 0); - RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */ + RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */ } const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL}; @@ -1161,7 +1161,7 @@ static void clip_main_area_listener(ARegion *ar, wmNotifier *wmn) case NC_SCREEN: if (wmn->data == ND_GPENCIL) ED_region_tag_redraw(ar); - break; + break; } } @@ -1205,7 +1205,7 @@ static void graph_area_draw(const bContext *C, ARegion *ar) UI_view2d_view_restore(C); /* scrollers */ - unitx = (sc->flag & SC_SHOW_SECONDS)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES; + unitx = (sc->flag & SC_SHOW_SECONDS) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES; unity = V2D_UNIT_VALUES; scrollers = UI_view2d_scrollers_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP); UI_view2d_scrollers_draw(C, v2d, scrollers); @@ -1232,7 +1232,7 @@ static void dopesheet_area_draw(const bContext *C, ARegion *ar) UI_view2d_view_ortho(v2d); /* time grid */ - unit = (sc->flag & SC_SHOW_SECONDS)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES; + unit = (sc->flag & SC_SHOW_SECONDS) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES; grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy); UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL); @@ -1331,10 +1331,10 @@ static void clip_header_area_listener(ARegion *ar, wmNotifier *wmn) case ND_TOOLSETTINGS: /* TODO - should do this when in mask mode only but no datas available */ // if (sc->mode == SC_MODE_MASKEDIT) - { - ED_region_tag_redraw(ar); - } - break; + { + ED_region_tag_redraw(ar); + } + break; } break; } diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index f6e9622f0a5..3a195805c53 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -35,7 +35,7 @@ #include "DNA_constraint_types.h" #include "DNA_gpencil_types.h" #include "DNA_movieclip_types.h" -#include "DNA_object_types.h" /* SELECT */ +#include "DNA_object_types.h" /* SELECT */ #include "DNA_scene_types.h" #include "BLI_utildefines.h" @@ -77,7 +77,7 @@ #include "UI_view2d.h" -#include "clip_intern.h" // own include +#include "clip_intern.h" // own include static float dist_to_crns(float co[2], float pos[2], float crns[4][2]); @@ -154,7 +154,7 @@ void CLIP_OT_add_marker(wmOperatorType *ot) /* properties */ RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, - "Location", "Location of marker on frame", -1.0f, 1.0f); + "Location", "Location of marker on frame", -1.0f, 1.0f); } /********************** delete track operator *********************/ @@ -251,9 +251,9 @@ void CLIP_OT_delete_marker(wmOperatorType *ot) /********************** slide marker operator *********************/ -#define SLIDE_ACTION_POS 0 -#define SLIDE_ACTION_SIZE 1 -#define SLIDE_ACTION_OFFSET 2 +#define SLIDE_ACTION_POS 0 +#define SLIDE_ACTION_SIZE 1 +#define SLIDE_ACTION_OFFSET 2 typedef struct { int area, action; @@ -271,7 +271,7 @@ typedef struct { static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, wmEvent *event, - int area, int corner, int action, int width, int height) + int area, int corner, int action, int width, int height) { SlideMarkerData *data = MEM_callocN(sizeof(SlideMarkerData), "slide marker data"); int framenr = ED_space_clip_clip_framenr(sc); @@ -301,7 +301,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra copy_v2_v2(data->soff, track->offset); - data->smarkers = MEM_callocN(sizeof(*data->smarkers)*track->markersnr, "slide marekrs"); + data->smarkers = MEM_callocN(sizeof(*data->smarkers) * track->markersnr, "slide marekrs"); for (a = 0; a < track->markersnr; a++) copy_v2_v2(data->smarkers[a], track->markers[a].pos); } @@ -318,7 +318,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra } if ((area == TRACK_AREA_SEARCH) || - (area == TRACK_AREA_PAT && action != SLIDE_ACTION_OFFSET)) + (area == TRACK_AREA_PAT && action != SLIDE_ACTION_OFFSET)) { if (data->corners) { memcpy(data->scorners, data->corners, sizeof(data->scorners)); @@ -647,7 +647,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) data->accurate = event->val == KM_PRESS; - /* no break! update area size */ + /* no break! update area size */ case MOUSEMOVE: mdelta[0] = event->mval[0] - data->mval[0]; @@ -807,7 +807,7 @@ void CLIP_OT_slide_marker(wmOperatorType *ot) /* properties */ RNA_def_float_vector(ot->srna, "offset", 2, NULL, -FLT_MAX, FLT_MAX, - "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX); + "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX); } /********************** mouse select operator *********************/ @@ -901,8 +901,8 @@ static float dist_to_crns(float co[2], float pos[2], float crns[4][2]) { float d1, d2, d3, d4; float p[2] = {co[0] - pos[0], co[1] - pos[1]}; - float *v1 = crns[0], *v2 = crns[1], - *v3 = crns[2], *v4 = crns[3]; + float *v1 = crns[0], *v2 = crns[1]; + float *v3 = crns[2], *v4 = crns[3]; d1 = dist_to_line_segment_v2(p, v1, v2); d2 = dist_to_line_segment_v2(p, v2, v3); @@ -927,7 +927,7 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbas /* distance to marker point */ d1 = sqrtf((co[0] - marker->pos[0] - cur->offset[0]) * (co[0] - marker->pos[0] - cur->offset[0]) + - (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); + (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); /* distance to pattern boundbox */ if (sc->flag & SC_SHOW_MARKER_PATTERN) @@ -959,7 +959,7 @@ static int mouse_select(bContext *C, float co[2], int extend) MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); - MovieTrackingTrack *track = NULL; /* selected marker */ + MovieTrackingTrack *track = NULL; /* selected marker */ track = find_nearest_track(sc, tracksbase, co); @@ -1053,9 +1053,9 @@ void CLIP_OT_select(wmOperatorType *ot) /* properties */ RNA_def_boolean(ot->srna, "extend", 0, - "Extend", "Extend selection rather than clearing the existing selection"); + "Extend", "Extend selection rather than clearing the existing selection"); RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, - "Location", "Mouse location in normalized coordinates, 0.0 to 1.0 is within the image bounds", -100.0f, 100.0f); + "Location", "Mouse location in normalized coordinates, 0.0 to 1.0 is within the image bounds", -100.0f, 100.0f); } /********************** border select operator *********************/ @@ -1234,10 +1234,10 @@ static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], f /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */ float x, y; - x = (marker->pos[0] - offset[0])*ellipse[0]; - y = (marker->pos[1] - offset[1])*ellipse[1]; + x = (marker->pos[0] - offset[0]) * ellipse[0]; + y = (marker->pos[1] - offset[1]) * ellipse[1]; - return x*x + y*y < 1.0f; + return x * x + y * y < 1.0f; } static int circle_select_exec(bContext *C, wmOperator *op) @@ -1325,7 +1325,7 @@ static int select_all_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *track = NULL; /* selected track */ + MovieTrackingTrack *track = NULL; /* selected track */ MovieTrackingMarker *marker; ListBase *tracksbase = BKE_tracking_get_tracks(tracking); int action = RNA_enum_get(op->ptr, "action"); @@ -1477,14 +1477,14 @@ static int select_groped_exec(bContext *C, wmOperator *op) void CLIP_OT_select_grouped(wmOperatorType *ot) { static EnumPropertyItem select_group_items[] = { - {0, "KEYFRAMED", 0, "Keyframed tracks", "Select all keyframed tracks"}, - {1, "ESTIMATED", 0, "Estimated tracks", "Select all estimated tracks"}, - {2, "TRACKED", 0, "Tracked tracks", "Select all tracked tracks"}, - {3, "LOCKED", 0, "Locked tracks", "Select all locked tracks"}, - {4, "DISABLED", 0, "Disabled tracks", "Select all disabled tracks"}, - {5, "COLOR", 0, "Tracks with same color", "Select all tracks with same color as active track"}, - {6, "FAILED", 0, "Failed Tracks", "Select all tracks which failed to be reconstructed"}, - {0, NULL, 0, NULL, NULL} + {0, "KEYFRAMED", 0, "Keyframed tracks", "Select all keyframed tracks"}, + {1, "ESTIMATED", 0, "Estimated tracks", "Select all estimated tracks"}, + {2, "TRACKED", 0, "Tracked tracks", "Select all tracked tracks"}, + {3, "LOCKED", 0, "Locked tracks", "Select all locked tracks"}, + {4, "DISABLED", 0, "Disabled tracks", "Select all disabled tracks"}, + {5, "COLOR", 0, "Tracks with same color", "Select all tracks with same color as active track"}, + {6, "FAILED", 0, "Failed Tracks", "Select all tracks which failed to be reconstructed"}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ @@ -1506,11 +1506,11 @@ void CLIP_OT_select_grouped(wmOperatorType *ot) /********************** track operator *********************/ typedef struct TrackMarkersJob { - struct MovieTrackingContext *context; /* tracking context */ - int sfra, efra, lastfra; /* Start, end and recently tracked frames */ - int backwards; /* Backwards tracking flag */ - MovieClip *clip; /* Clip which is tracking */ - float delay; /* Delay in milliseconds to allow tracking at fixed FPS */ + struct MovieTrackingContext *context; /* tracking context */ + int sfra, efra, lastfra; /* Start, end and recently tracked frames */ + int backwards; /* Backwards tracking flag */ + MovieClip *clip; /* Clip which is tracking */ + float delay; /* Delay in milliseconds to allow tracking at fixed FPS */ struct Main *main; struct Scene *scene; @@ -1693,7 +1693,7 @@ static void track_markers_startjob(void *tmv, short *stop, short *do_update, flo PIL_sleep_ms(tmj->delay - (float)exec_time); } else if (!BKE_tracking_next(tmj->context)) - break; + break; *do_update = TRUE; *progress = (float)(framenr - tmj->sfra) / (tmj->efra - tmj->sfra); @@ -1926,7 +1926,7 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op scj->user = sc->user; scj->context = BKE_tracking_reconstruction_context_new(tracking, object, - settings->keyframe1, settings->keyframe2, width, height); + settings->keyframe1, settings->keyframe2, width, height); tracking->stats = MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats"); @@ -1946,7 +1946,7 @@ static void solve_camera_startjob(void *scv, short *stop, short *do_update, floa SolveCameraJob *scj = (SolveCameraJob *)scv; BKE_tracking_solve_reconstruction(scj->context, stop, do_update, progress, - scj->stats_message, sizeof(scj->stats_message)); + scj->stats_message, sizeof(scj->stats_message)); } static void solve_camera_freejob(void *scv) @@ -1979,7 +1979,7 @@ static void solve_camera_freejob(void *scv) /* set blender camera focal length so result would look fine there */ if (scene->camera) { - Camera *camera = (Camera*)scene->camera->data; + Camera *camera = (Camera *)scene->camera->data; int width, height; BKE_movieclip_get_size(clip, &scj->user, &width, &height); @@ -2190,10 +2190,10 @@ static int clear_track_path_exec(bContext *C, wmOperator *op) void CLIP_OT_clear_track_path(wmOperatorType *ot) { static EnumPropertyItem clear_path_actions[] = { - {TRACK_CLEAR_UPTO, "UPTO", 0, "Clear up-to", "Clear path up to current frame"}, - {TRACK_CLEAR_REMAINED, "REMAINED", 0, "Clear remained", "Clear path at remaining frames (after current)"}, - {TRACK_CLEAR_ALL, "ALL", 0, "Clear all", "Clear the whole path"}, - {0, NULL, 0, NULL, NULL} + {TRACK_CLEAR_UPTO, "UPTO", 0, "Clear up-to", "Clear path up to current frame"}, + {TRACK_CLEAR_REMAINED, "REMAINED", 0, "Clear remained", "Clear path at remaining frames (after current)"}, + {TRACK_CLEAR_ALL, "ALL", 0, "Clear all", "Clear the whole path"}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ @@ -2249,10 +2249,10 @@ static int disable_markers_exec(bContext *C, wmOperator *op) void CLIP_OT_disable_markers(wmOperatorType *ot) { static EnumPropertyItem actions_items[] = { - {0, "DISABLE", 0, "Disable", "Disable selected markers"}, - {1, "ENABLE", 0, "Enable", "Enable selected markers"}, - {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"}, - {0, NULL, 0, NULL, NULL} + {0, "DISABLE", 0, "Disable", "Disable selected markers"}, + {1, "ENABLE", 0, "Enable", "Enable selected markers"}, + {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ @@ -2498,11 +2498,11 @@ void CLIP_OT_set_origin(wmOperatorType *ot) /********************** set floor operator *********************/ static void set_axis(Scene *scene, Object *ob, MovieClip *clip, MovieTrackingObject *tracking_object, - MovieTrackingTrack *track, char axis) + MovieTrackingTrack *track, char axis) { Object *camera = get_camera_with_movieclip(scene, clip); int is_camera = tracking_object->flag & TRACKING_OBJECT_CAMERA; - int flip = FALSE; + int flip = FALSE; float mat[4][4], vec[3], obmat[4][4], dvec[3]; BKE_object_to_mat4(ob, obmat); @@ -2625,7 +2625,7 @@ static int set_plane_exec(bContext *C, wmOperator *op) float rot[4][4] = {{0.0f, 0.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 0.0f}, - {0.0f, 0.0f, 0.0f, 1.0f}}; /* 90 degrees Y-axis rotation matrix */ + {0.0f, 0.0f, 0.0f, 1.0f}}; /* 90 degrees Y-axis rotation matrix */ if (count_selected_bundles(C) != 3) { BKE_report(op->reports, RPT_ERROR, "Three tracks with bundles are needed to orient the floor"); @@ -2723,9 +2723,9 @@ static int set_plane_exec(bContext *C, wmOperator *op) void CLIP_OT_set_plane(wmOperatorType *ot) { static EnumPropertyItem plane_items[] = { - {0, "FLOOR", 0, "Floor", "Set floor plane"}, - {1, "WALL", 0, "Wall", "Set wall plane"}, - {0, NULL, 0, NULL, NULL} + {0, "FLOOR", 0, "Floor", "Set floor plane"}, + {1, "WALL", 0, "Wall", "Set wall plane"}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ @@ -2795,9 +2795,9 @@ static int set_axis_exec(bContext *C, wmOperator *op) void CLIP_OT_set_axis(wmOperatorType *ot) { static EnumPropertyItem axis_actions[] = { - {0, "X", 0, "X", "Align bundle align X axis"}, - {1, "Y", 0, "Y", "Align bundle align Y axis"}, - {0, NULL, 0, NULL, NULL} + {0, "X", 0, "X", "Align bundle align X axis"}, + {1, "Y", 0, "Y", "Align bundle align Y axis"}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ @@ -2927,7 +2927,7 @@ void CLIP_OT_set_scale(wmOperatorType *ot) /* properties */ RNA_def_float(ot->srna, "distance", 0.0f, -FLT_MAX, FLT_MAX, - "Distance", "Distance between selected tracks", -100.0f, 100.0f); + "Distance", "Distance between selected tracks", -100.0f, 100.0f); } /********************** set solution scale operator *********************/ @@ -2983,7 +2983,7 @@ void CLIP_OT_set_solution_scale(wmOperatorType *ot) /* properties */ RNA_def_float(ot->srna, "distance", 0.0f, -FLT_MAX, FLT_MAX, - "Distance", "Distance between selected tracks", -100.0f, 100.0f); + "Distance", "Distance between selected tracks", -100.0f, 100.0f); } /********************** set principal center operator *********************/ @@ -3177,7 +3177,7 @@ static int detect_features_exec(bContext *C, wmOperator *op) } BKE_tracking_detect_fast(tracking, tracksbase, ibuf, framenr, margin, - min_trackability, min_distance, layer, place_outside_layer); + min_trackability, min_distance, layer, place_outside_layer); IMB_freeImBuf(ibuf); @@ -3189,10 +3189,10 @@ static int detect_features_exec(bContext *C, wmOperator *op) void CLIP_OT_detect_features(wmOperatorType *ot) { static EnumPropertyItem placement_items[] = { - {0, "FRAME", 0, "Whole Frame", "Place markers across the whole frame"}, - {1, "INSIDE_GPENCIL", 0, "Inside grease pencil", "Place markers only inside areas outlined with grease pencil"}, - {2, "OUTSIDE_GPENCIL", 0, "Outside grease pencil", "Place markers only outside areas outlined with grease pencil"}, - {0, NULL, 0, NULL, NULL} + {0, "FRAME", 0, "Whole Frame", "Place markers across the whole frame"}, + {1, "INSIDE_GPENCIL", 0, "Inside grease pencil", "Place markers only inside areas outlined with grease pencil"}, + {2, "OUTSIDE_GPENCIL", 0, "Outside grease pencil", "Place markers only outside areas outlined with grease pencil"}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ @@ -3225,7 +3225,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) int pos = RNA_enum_get(op->ptr, "position"); int delta; - if (pos <= 1) { /* jump to path */ + if (pos <= 1) { /* jump to path */ track = BKE_tracking_active_track(&clip->tracking); if (!track) @@ -3243,7 +3243,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) sc->user.framenr += delta; } } - else { /* to to failed frame */ + else { /* to to failed frame */ if (clip->tracking.reconstruction.flag & TRACKING_RECONSTRUCTED) { int a = ED_space_clip_clip_framenr(sc); MovieTracking *tracking = &clip->tracking; @@ -3284,11 +3284,11 @@ static int frame_jump_exec(bContext *C, wmOperator *op) void CLIP_OT_frame_jump(wmOperatorType *ot) { static EnumPropertyItem position_items[] = { - {0, "PATHSTART", 0, "Path Start", "Jump to start of current path"}, - {1, "PATHEND", 0, "Path End", "Jump to end of current path"}, - {2, "FAILEDPREV", 0, "Previous Failed", "Jump to previous failed frame"}, - {2, "FAILNEXT", 0, "Next Failed", "Jump to next failed frame"}, - {0, NULL, 0, NULL, NULL} + {0, "PATHSTART", 0, "Path Start", "Jump to start of current path"}, + {1, "PATHEND", 0, "Path End", "Jump to end of current path"}, + {2, "FAILEDPREV", 0, "Previous Failed", "Jump to previous failed frame"}, + {2, "FAILNEXT", 0, "Next Failed", "Jump to next failed frame"}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ @@ -3392,10 +3392,10 @@ static int lock_tracks_exec(bContext *C, wmOperator *op) void CLIP_OT_lock_tracks(wmOperatorType *ot) { static EnumPropertyItem actions_items[] = { - {0, "LOCK", 0, "Lock", "Lock selected tracks"}, - {1, "UNLOCK", 0, "Unlock", "Unlock selected tracks"}, - {2, "TOGGLE", 0, "Toggle", "Toggle locked flag for selected tracks"}, - {0, NULL, 0, NULL, NULL} + {0, "LOCK", 0, "Lock", "Lock selected tracks"}, + {1, "UNLOCK", 0, "Unlock", "Unlock selected tracks"}, + {2, "TOGGLE", 0, "Toggle", "Toggle locked flag for selected tracks"}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ @@ -3660,7 +3660,7 @@ static int is_track_clean(MovieTrackingTrack *track, int frames, int del) int markersnr = track->markersnr; if (del) - new_markers = MEM_callocN(markersnr*sizeof(MovieTrackingMarker), "track cleaned markers"); + new_markers = MEM_callocN(markersnr * sizeof(MovieTrackingMarker), "track cleaned markers"); for (a = 0; a < markersnr; a++) { int end = 0; @@ -3767,7 +3767,7 @@ static int clean_tracks_exec(bContext *C, wmOperator *op) int ok = 1; ok = (is_track_clean(track, frames, action == TRACKING_CLEAN_DELETE_SEGMENT)) && - (error == 0.0f || (track->flag & TRACK_HAS_BUNDLE) == 0 || track->error < error); + (error == 0.0f || (track->flag & TRACK_HAS_BUNDLE) == 0 || track->error < error); if (!ok) { if (action == TRACKING_CLEAN_SELECT) { @@ -3821,10 +3821,10 @@ static int clean_tracks_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even void CLIP_OT_clean_tracks(wmOperatorType *ot) { static EnumPropertyItem actions_items[] = { - {TRACKING_CLEAN_SELECT, "SELECT", 0, "Select", "Select unclean tracks"}, - {TRACKING_CLEAN_DELETE_TRACK, "DELETE_TRACK", 0, "Delete Track", "Delete unclean tracks"}, - {TRACKING_CLEAN_DELETE_SEGMENT, "DELETE_SEGMENTS", 0, "Delete Segments", "Delete unclean segments of tracks"}, - {0, NULL, 0, NULL, NULL} + {TRACKING_CLEAN_SELECT, "SELECT", 0, "Select", "Select unclean tracks"}, + {TRACKING_CLEAN_DELETE_TRACK, "DELETE_TRACK", 0, "Delete Track", "Delete unclean tracks"}, + {TRACKING_CLEAN_DELETE_SEGMENT, "DELETE_SEGMENTS", 0, "Delete Segments", "Delete unclean segments of tracks"}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index d41294c7875..3710ef1d30d 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -51,7 +51,7 @@ #include "DNA_meshdata_types.h" #include "DNA_mask_types.h" #include "DNA_movieclip_types.h" -#include "DNA_scene_types.h" /* PET modes */ +#include "DNA_scene_types.h" /* PET modes */ #include "RNA_access.h" @@ -105,7 +105,7 @@ static int doEdgeSlide(TransInfo *t, float perc); void setTransformViewMatrices(TransInfo *t) { - if (t->spacetype==SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) { + if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d = t->ar->regiondata; copy_m4_m4(t->viewmat, rv3d->viewmat); @@ -129,12 +129,12 @@ static void convertViewVec2D(View2D *v2d, float vec[3], int dx, int dy) { float divx, divy; - divx= v2d->mask.xmax - v2d->mask.xmin; - divy= v2d->mask.ymax - v2d->mask.ymin; + divx = v2d->mask.xmax - v2d->mask.xmin; + divy = v2d->mask.ymax - v2d->mask.ymin; - vec[0]= (v2d->cur.xmax - v2d->cur.xmin) * dx / divx; - vec[1]= (v2d->cur.ymax - v2d->cur.ymin) * dy / divy; - vec[2]= 0.0f; + vec[0] = (v2d->cur.xmax - v2d->cur.xmin) * dx / divx; + vec[1] = (v2d->cur.ymax - v2d->cur.ymin) * dy / divy; + vec[2] = 0.0f; } void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) @@ -145,7 +145,7 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) mval_f[1] = dy; ED_view3d_win_to_delta(t->ar, mval_f, r_vec); } - else if (t->spacetype==SPACE_IMAGE) { + else if (t->spacetype == SPACE_IMAGE) { float aspx, aspy; convertViewVec2D(t->view, r_vec, dx, dy); @@ -160,17 +160,17 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) { convertViewVec2D(&t->ar->v2d, r_vec, dx, dy); } - else if (t->spacetype==SPACE_CLIP) { + else if (t->spacetype == SPACE_CLIP) { View2D *v2d = t->view; float divx, divy; float mulx, muly; float aspx = 1.0f, aspy = 1.0f; - divx = v2d->mask.xmax-v2d->mask.xmin; - divy = v2d->mask.ymax-v2d->mask.ymin; + divx = v2d->mask.xmax - v2d->mask.xmin; + divy = v2d->mask.ymax - v2d->mask.ymin; - mulx = (v2d->cur.xmax-v2d->cur.xmin); - muly = (v2d->cur.ymax-v2d->cur.ymin); + mulx = (v2d->cur.xmax - v2d->cur.xmin); + muly = (v2d->cur.ymax - v2d->cur.ymin); if (t->options & CTX_MASK) { /* clamp w/h, mask only */ @@ -201,18 +201,18 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) void projectIntView(TransInfo *t, const float vec[3], int adr[2]) { - if (t->spacetype==SPACE_VIEW3D) { + if (t->spacetype == SPACE_VIEW3D) { if (t->ar->regiontype == RGN_TYPE_WINDOW) project_int_noclip(t->ar, vec, adr); } - else if (t->spacetype==SPACE_IMAGE) { + else if (t->spacetype == SPACE_IMAGE) { float aspx, aspy, v[2]; ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); - v[0]= vec[0]/aspx; - v[1]= vec[1]/aspy; + v[0] = vec[0] / aspx; + v[1] = vec[1] / aspy; - UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr+1); + UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr + 1); } else if (t->spacetype == SPACE_ACTION) { int out[2] = {0, 0}; @@ -222,32 +222,32 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) if (sact->flag & SACTION_DRAWTIME) { //vec[0] = vec[0]/((t->scene->r.frs_sec / t->scene->r.frs_sec_base)); /* same as below */ - UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out+1); + UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out + 1); } else #endif { - UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out+1); + UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out + 1); } - adr[0]= out[0]; - adr[1]= out[1]; + adr[0] = out[0]; + adr[1] = out[1]; } else if (ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) { int out[2] = {0, 0}; - UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out+1); - adr[0]= out[0]; - adr[1]= out[1]; + UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out + 1); + adr[0] = out[0]; + adr[1] = out[1]; } - else if (t->spacetype==SPACE_SEQ) { /* XXX not tested yet, but should work */ + else if (t->spacetype == SPACE_SEQ) { /* XXX not tested yet, but should work */ int out[2] = {0, 0}; - UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out+1); - adr[0]= out[0]; - adr[1]= out[1]; + UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out + 1); + adr[0] = out[0]; + adr[1] = out[1]; } - else if (t->spacetype==SPACE_CLIP) { + else if (t->spacetype == SPACE_CLIP) { float v[2]; float aspx = 1.0f, aspy = 1.0f; @@ -261,7 +261,7 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) v[0] /= aspx; v[1] /= aspy; - UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr+1); + UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr + 1); } } @@ -294,11 +294,11 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2]) void applyAspectRatio(TransInfo *t, float vec[2]) { - if ((t->spacetype==SPACE_IMAGE) && (t->mode==TFM_TRANSLATION)) { - SpaceImage *sima= t->sa->spacedata.first; + if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION)) { + SpaceImage *sima = t->sa->spacedata.first; float aspx, aspy; - if ((sima->flag & SI_COORDFLOATS)==0) { + if ((sima->flag & SI_COORDFLOATS) == 0) { int width, height; ED_space_image_size(sima, &width, &height); @@ -310,7 +310,7 @@ void applyAspectRatio(TransInfo *t, float vec[2]) vec[0] /= aspx; vec[1] /= aspy; } - else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) { + else if ((t->spacetype == SPACE_CLIP) && (t->mode == TFM_TRANSLATION)) { if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { SpaceClip *sc = t->sa->spacedata.first; float aspx, aspy; @@ -334,11 +334,11 @@ void applyAspectRatio(TransInfo *t, float vec[2]) void removeAspectRatio(TransInfo *t, float vec[2]) { - if ((t->spacetype==SPACE_IMAGE) && (t->mode==TFM_TRANSLATION)) { - SpaceImage *sima= t->sa->spacedata.first; + if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION)) { + SpaceImage *sima = t->sa->spacedata.first; float aspx, aspy; - if ((sima->flag & SI_COORDFLOATS)==0) { + if ((sima->flag & SI_COORDFLOATS) == 0) { int width, height; ED_space_image_size(sima, &width, &height); @@ -350,7 +350,7 @@ void removeAspectRatio(TransInfo *t, float vec[2]) vec[0] *= aspx; vec[1] *= aspy; } - else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) { + else if ((t->spacetype == SPACE_CLIP) && (t->mode == TFM_TRANSLATION)) { if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { SpaceClip *sc = t->sa->spacedata.first; float aspx = 1.0f, aspy = 1.0f; @@ -373,55 +373,55 @@ static void viewRedrawForce(const bContext *C, TransInfo *t) if (t->spacetype == SPACE_VIEW3D) { /* Do we need more refined tags? */ if (t->flag & T_POSE) - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); else - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); /* for realtime animation record - send notifiers recognised by animation editors */ // XXX: is this notifier a lame duck? if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) - WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL); } else if (t->spacetype == SPACE_ACTION) { //SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; - WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL); + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } else if (t->spacetype == SPACE_IPO) { //SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first; - WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL); + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } else if (t->spacetype == SPACE_NLA) { - WM_event_add_notifier(C, NC_ANIMATION|ND_NLA|NA_EDITED, NULL); + WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL); } else if (t->spacetype == SPACE_NODE) { //ED_area_tag_redraw(t->sa); - WM_event_add_notifier(C, NC_SPACE|ND_SPACE_NODE_VIEW, NULL); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); } else if (t->spacetype == SPACE_SEQ) { - WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, NULL); } - else if (t->spacetype==SPACE_IMAGE) { + else if (t->spacetype == SPACE_IMAGE) { // XXX how to deal with lock? - SpaceImage *sima= (SpaceImage*)t->sa->spacedata.first; - if (sima->lock) WM_event_add_notifier(C, NC_GEOM|ND_DATA, t->obedit->data); + SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first; + if (sima->lock) WM_event_add_notifier(C, NC_GEOM | ND_DATA, t->obedit->data); else ED_area_tag_redraw(t->sa); } - else if (t->spacetype==SPACE_CLIP) { - SpaceClip *sc = (SpaceClip*)t->sa->spacedata.first; + else if (t->spacetype == SPACE_CLIP) { + SpaceClip *sc = (SpaceClip *)t->sa->spacedata.first; if (ED_space_clip_show_trackedit(sc)) { MovieClip *clip = ED_space_clip(sc); /* objects could be parented to tracking data, so send this for viewport refresh */ - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); } else if (ED_space_clip_show_maskedit(sc)) { Mask *mask = ED_space_clip_mask(sc); - WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); } } } @@ -433,19 +433,19 @@ static void viewRedrawPost(bContext *C, TransInfo *t) if (t->spacetype == SPACE_VIEW3D) { /* if autokeying is enabled, send notifiers that keyframes were added */ if (IS_AUTOKEY_ON(t->scene)) - WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL); + WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); /* XXX temp, first hack to get auto-render in compositor work (ton) */ - WM_event_add_notifier(C, NC_SCENE|ND_TRANSFORM_DONE, CTX_data_scene(C)); + WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM_DONE, CTX_data_scene(C)); } #if 0 // TRANSFORM_FIX_ME - if (t->spacetype==SPACE_VIEW3D) { + if (t->spacetype == SPACE_VIEW3D) { allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWVIEW3D, 0); } - else if (t->spacetype==SPACE_IMAGE) { + else if (t->spacetype == SPACE_IMAGE) { allqueue(REDRAWIMAGE, 0); allqueue(REDRAWVIEW3D, 0); } @@ -469,7 +469,7 @@ void BIF_selectOrientation(void) #if 0 // TRANSFORM_FIX_ME short val; char *str_menu = BIF_menustringTransformOrientation("Orientation"); - val= pupmenu(str_menu); + val = pupmenu(str_menu); MEM_freeN(str_menu); if (val >= 0) { @@ -497,8 +497,8 @@ static void view_editmove(unsigned short UNUSED(event)) switch (event) { case WHEELUPMOUSE: - if ( G.qual & LR_SHIFTKEY ) { - if ( G.qual & LR_ALTKEY ) { + if (G.qual & LR_SHIFTKEY) { + if (G.qual & LR_ALTKEY) { G.qual &= ~LR_SHIFTKEY; persptoetsen(PAD2); G.qual |= LR_SHIFTKEY; @@ -507,8 +507,8 @@ static void view_editmove(unsigned short UNUSED(event)) persptoetsen(PAD2); } } - else if ( G.qual & LR_CTRLKEY ) { - if ( G.qual & LR_ALTKEY ) { + else if (G.qual & LR_CTRLKEY) { + if (G.qual & LR_ALTKEY) { G.qual &= ~LR_CTRLKEY; persptoetsen(PAD4); G.qual |= LR_CTRLKEY; @@ -525,8 +525,8 @@ static void view_editmove(unsigned short UNUSED(event)) refresh = 1; break; case WHEELDOWNMOUSE: - if ( G.qual & LR_SHIFTKEY ) { - if ( G.qual & LR_ALTKEY ) { + if (G.qual & LR_SHIFTKEY) { + if (G.qual & LR_ALTKEY) { G.qual &= ~LR_SHIFTKEY; persptoetsen(PAD8); G.qual |= LR_SHIFTKEY; @@ -535,8 +535,8 @@ static void view_editmove(unsigned short UNUSED(event)) persptoetsen(PAD8); } } - else if ( G.qual & LR_CTRLKEY ) { - if ( G.qual & LR_ALTKEY ) { + else if (G.qual & LR_CTRLKEY) { + if (G.qual & LR_ALTKEY) { G.qual &= ~LR_CTRLKEY; persptoetsen(PAD6); G.qual |= LR_CTRLKEY; @@ -562,27 +562,27 @@ static void view_editmove(unsigned short UNUSED(event)) /* ************************************************* */ /* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ -#define TFM_MODAL_CANCEL 1 -#define TFM_MODAL_CONFIRM 2 -#define TFM_MODAL_TRANSLATE 3 -#define TFM_MODAL_ROTATE 4 -#define TFM_MODAL_RESIZE 5 -#define TFM_MODAL_SNAP_INV_ON 6 -#define TFM_MODAL_SNAP_INV_OFF 7 -#define TFM_MODAL_SNAP_TOGGLE 8 -#define TFM_MODAL_AXIS_X 9 -#define TFM_MODAL_AXIS_Y 10 -#define TFM_MODAL_AXIS_Z 11 -#define TFM_MODAL_PLANE_X 12 -#define TFM_MODAL_PLANE_Y 13 -#define TFM_MODAL_PLANE_Z 14 -#define TFM_MODAL_CONS_OFF 15 -#define TFM_MODAL_ADD_SNAP 16 -#define TFM_MODAL_REMOVE_SNAP 17 +#define TFM_MODAL_CANCEL 1 +#define TFM_MODAL_CONFIRM 2 +#define TFM_MODAL_TRANSLATE 3 +#define TFM_MODAL_ROTATE 4 +#define TFM_MODAL_RESIZE 5 +#define TFM_MODAL_SNAP_INV_ON 6 +#define TFM_MODAL_SNAP_INV_OFF 7 +#define TFM_MODAL_SNAP_TOGGLE 8 +#define TFM_MODAL_AXIS_X 9 +#define TFM_MODAL_AXIS_Y 10 +#define TFM_MODAL_AXIS_Z 11 +#define TFM_MODAL_PLANE_X 12 +#define TFM_MODAL_PLANE_Y 13 +#define TFM_MODAL_PLANE_Z 14 +#define TFM_MODAL_CONS_OFF 15 +#define TFM_MODAL_ADD_SNAP 16 +#define TFM_MODAL_REMOVE_SNAP 17 /* 18 and 19 used by numinput, defined in transform.h * */ -#define TFM_MODAL_PROPSIZE_UP 20 -#define TFM_MODAL_PROPSIZE_DOWN 21 +#define TFM_MODAL_PROPSIZE_UP 20 +#define TFM_MODAL_PROPSIZE_DOWN 21 #define TFM_MODAL_AUTOIK_LEN_INC 22 #define TFM_MODAL_AUTOIK_LEN_DEC 23 @@ -590,42 +590,43 @@ static void view_editmove(unsigned short UNUSED(event)) #define TFM_MODAL_EDGESLIDE_DOWN 25 /* called in transform_ops.c, on each regeneration of keymaps */ -wmKeyMap* transform_modal_keymap(wmKeyConfig *keyconf) +wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf) { static EnumPropertyItem modal_items[] = { - {TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, - {TFM_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, - {TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Translate", ""}, - {TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""}, - {TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""}, - {TFM_MODAL_SNAP_INV_ON, "SNAP_INV_ON", 0, "Invert Snap On", ""}, - {TFM_MODAL_SNAP_INV_OFF, "SNAP_INV_OFF", 0, "Invert Snap Off", ""}, - {TFM_MODAL_SNAP_TOGGLE, "SNAP_TOGGLE", 0, "Snap Toggle", ""}, - {TFM_MODAL_AXIS_X, "AXIS_X", 0, "Orientation X axis", ""}, - {TFM_MODAL_AXIS_Y, "AXIS_Y", 0, "Orientation Y axis", ""}, - {TFM_MODAL_AXIS_Z, "AXIS_Z", 0, "Orientation Z axis", ""}, - {TFM_MODAL_PLANE_X, "PLANE_X", 0, "Orientation X plane", ""}, - {TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Orientation Y plane", ""}, - {TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Orientation Z plane", ""}, - {TFM_MODAL_CONS_OFF, "CONS_OFF", 0, "Remove Constraints", ""}, - {TFM_MODAL_ADD_SNAP, "ADD_SNAP", 0, "Add Snap Point", ""}, - {TFM_MODAL_REMOVE_SNAP, "REMOVE_SNAP", 0, "Remove Last Snap Point", ""}, - {NUM_MODAL_INCREMENT_UP, "INCREMENT_UP", 0, "Numinput Increment Up", ""}, - {NUM_MODAL_INCREMENT_DOWN, "INCREMENT_DOWN", 0, "Numinput Increment Down", ""}, - {TFM_MODAL_PROPSIZE_UP, "PROPORTIONAL_SIZE_UP", 0, "Increase Proportional Influence", ""}, - {TFM_MODAL_PROPSIZE_DOWN, "PROPORTIONAL_SIZE_DOWN", 0, "Decrease Proportional Influence", ""}, - {TFM_MODAL_AUTOIK_LEN_INC, "AUTOIK_CHAIN_LEN_UP", 0, "Increase Max AutoIK Chain Length", ""}, - {TFM_MODAL_AUTOIK_LEN_DEC, "AUTOIK_CHAIN_LEN_DOWN", 0, "Decrease Max AutoIK Chain Length", ""}, - {TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select next Edge Slide Edge", ""}, - {TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select previous Edge Slide Edge", ""}, - {0, NULL, 0, NULL, NULL}}; + {TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, + {TFM_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, + {TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Translate", ""}, + {TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""}, + {TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""}, + {TFM_MODAL_SNAP_INV_ON, "SNAP_INV_ON", 0, "Invert Snap On", ""}, + {TFM_MODAL_SNAP_INV_OFF, "SNAP_INV_OFF", 0, "Invert Snap Off", ""}, + {TFM_MODAL_SNAP_TOGGLE, "SNAP_TOGGLE", 0, "Snap Toggle", ""}, + {TFM_MODAL_AXIS_X, "AXIS_X", 0, "Orientation X axis", ""}, + {TFM_MODAL_AXIS_Y, "AXIS_Y", 0, "Orientation Y axis", ""}, + {TFM_MODAL_AXIS_Z, "AXIS_Z", 0, "Orientation Z axis", ""}, + {TFM_MODAL_PLANE_X, "PLANE_X", 0, "Orientation X plane", ""}, + {TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Orientation Y plane", ""}, + {TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Orientation Z plane", ""}, + {TFM_MODAL_CONS_OFF, "CONS_OFF", 0, "Remove Constraints", ""}, + {TFM_MODAL_ADD_SNAP, "ADD_SNAP", 0, "Add Snap Point", ""}, + {TFM_MODAL_REMOVE_SNAP, "REMOVE_SNAP", 0, "Remove Last Snap Point", ""}, + {NUM_MODAL_INCREMENT_UP, "INCREMENT_UP", 0, "Numinput Increment Up", ""}, + {NUM_MODAL_INCREMENT_DOWN, "INCREMENT_DOWN", 0, "Numinput Increment Down", ""}, + {TFM_MODAL_PROPSIZE_UP, "PROPORTIONAL_SIZE_UP", 0, "Increase Proportional Influence", ""}, + {TFM_MODAL_PROPSIZE_DOWN, "PROPORTIONAL_SIZE_DOWN", 0, "Decrease Proportional Influence", ""}, + {TFM_MODAL_AUTOIK_LEN_INC, "AUTOIK_CHAIN_LEN_UP", 0, "Increase Max AutoIK Chain Length", ""}, + {TFM_MODAL_AUTOIK_LEN_DEC, "AUTOIK_CHAIN_LEN_DOWN", 0, "Decrease Max AutoIK Chain Length", ""}, + {TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select next Edge Slide Edge", ""}, + {TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select previous Edge Slide Edge", ""}, + {0, NULL, 0, NULL, NULL} + }; - wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "Transform Modal Map"); + wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Transform Modal Map"); /* this function is called for each spacetype, only needs to add map once */ if (keymap && keymap->modal_items) return NULL; - keymap= WM_modalkeymap_add(keyconf, "Transform Modal Map", modal_items); + keymap = WM_modalkeymap_add(keyconf, "Transform Modal Map", modal_items); /* items for modal map */ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CANCEL); @@ -695,8 +696,7 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm msg1[sizeof(msg1) - 2] = axis; msg2[sizeof(msg2) - 2] = axis; msg3[sizeof(msg3) - 2] = axis; - constraint_plane = ((CON_AXIS0 | CON_AXIS1 | CON_AXIS2) & - (~constraint_axis)); + constraint_plane = ((CON_AXIS0 | CON_AXIS1 | CON_AXIS2) & (~constraint_axis)); if (edit_2d && (key_type != ZKEY)) { if (cmode == axis) { @@ -733,7 +733,7 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm int transformEvent(TransInfo *t, wmEvent *event) { - float mati[3][3]= MAT3_UNITY; + float mati[3][3] = MAT3_UNITY; char cmode = constraintModeToChar(t); int handled = 1; @@ -770,7 +770,7 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case TFM_MODAL_TRANSLATE: /* only switch when... */ - if ( ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) { + if (ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) { resetTransRestrictions(t); restoreTransObjects(t); initTranslation(t); @@ -789,7 +789,7 @@ int transformEvent(TransInfo *t, wmEvent *event) case TFM_MODAL_ROTATE: /* only switch when... */ if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) { - if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { + if (ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { resetTransRestrictions(t); @@ -808,7 +808,7 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case TFM_MODAL_RESIZE: /* only switch when... */ - if ( ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) { + if (ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) { resetTransRestrictions(t); restoreTransObjects(t); initResize(t); @@ -838,7 +838,7 @@ int transformEvent(TransInfo *t, wmEvent *event) t->redraw |= TREDRAW_HARD; break; case TFM_MODAL_AXIS_X: - if ((t->flag & T_NO_CONSTRAINT)==0) { + if ((t->flag & T_NO_CONSTRAINT) == 0) { if (cmode == 'X') { stopConstraint(t); } @@ -854,7 +854,7 @@ int transformEvent(TransInfo *t, wmEvent *event) } break; case TFM_MODAL_AXIS_Y: - if ((t->flag & T_NO_CONSTRAINT)==0) { + if ((t->flag & T_NO_CONSTRAINT) == 0) { if (cmode == 'Y') { stopConstraint(t); } @@ -870,7 +870,7 @@ int transformEvent(TransInfo *t, wmEvent *event) } break; case TFM_MODAL_AXIS_Z: - if ((t->flag & (T_NO_CONSTRAINT|T_2D_EDIT))== 0) { + if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) { if (cmode == 'Z') { stopConstraint(t); } @@ -881,40 +881,40 @@ int transformEvent(TransInfo *t, wmEvent *event) } break; case TFM_MODAL_PLANE_X: - if ((t->flag & (T_NO_CONSTRAINT|T_2D_EDIT))== 0) { + if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) { if (cmode == 'X') { stopConstraint(t); } else { - setUserConstraint(t, t->current_orientation, (CON_AXIS1|CON_AXIS2), "locking %s X"); + setUserConstraint(t, t->current_orientation, (CON_AXIS1 | CON_AXIS2), "locking %s X"); } t->redraw |= TREDRAW_HARD; } break; case TFM_MODAL_PLANE_Y: - if ((t->flag & (T_NO_CONSTRAINT|T_2D_EDIT))== 0) { + if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) { if (cmode == 'Y') { stopConstraint(t); } else { - setUserConstraint(t, t->current_orientation, (CON_AXIS0|CON_AXIS2), "locking %s Y"); + setUserConstraint(t, t->current_orientation, (CON_AXIS0 | CON_AXIS2), "locking %s Y"); } t->redraw |= TREDRAW_HARD; } break; case TFM_MODAL_PLANE_Z: - if ((t->flag & (T_NO_CONSTRAINT|T_2D_EDIT))== 0) { + if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) { if (cmode == 'Z') { stopConstraint(t); } else { - setUserConstraint(t, t->current_orientation, (CON_AXIS0|CON_AXIS1), "locking %s Z"); + setUserConstraint(t, t->current_orientation, (CON_AXIS0 | CON_AXIS1), "locking %s Z"); } t->redraw |= TREDRAW_HARD; } break; case TFM_MODAL_CONS_OFF: - if ((t->flag & T_NO_CONSTRAINT)==0) { + if ((t->flag & T_NO_CONSTRAINT) == 0) { stopConstraint(t); t->redraw |= TREDRAW_HARD; } @@ -929,16 +929,16 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case TFM_MODAL_PROPSIZE_UP: if (t->flag & T_PROP_EDIT) { - t->prop_size*= 1.1f; - if (t->spacetype==SPACE_VIEW3D && t->persp != RV3D_ORTHO) - t->prop_size= MIN2(t->prop_size, ((View3D *)t->view)->far); + t->prop_size *= 1.1f; + if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) + t->prop_size = MIN2(t->prop_size, ((View3D *)t->view)->far); calculatePropRatio(t); } t->redraw |= TREDRAW_HARD; break; case TFM_MODAL_PROPSIZE_DOWN: if (t->flag & T_PROP_EDIT) { - t->prop_size*= 0.90909090f; + t->prop_size *= 0.90909090f; calculatePropRatio(t); } t->redraw |= TREDRAW_HARD; @@ -968,170 +968,170 @@ int transformEvent(TransInfo *t, wmEvent *event) /* else do non-mapped events */ else if (event->val == KM_PRESS) { switch (event->type) { - case RIGHTMOUSE: - t->state = TRANS_CANCEL; - break; - /* enforce redraw of transform when modifiers are used */ - case LEFTSHIFTKEY: - case RIGHTSHIFTKEY: - t->modifiers |= MOD_CONSTRAINT_PLANE; - t->redraw |= TREDRAW_HARD; - break; + case RIGHTMOUSE: + t->state = TRANS_CANCEL; + break; + /* enforce redraw of transform when modifiers are used */ + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + t->modifiers |= MOD_CONSTRAINT_PLANE; + t->redraw |= TREDRAW_HARD; + break; - case SPACEKEY: - if ((t->spacetype==SPACE_VIEW3D) && event->alt) { + case SPACEKEY: + if ((t->spacetype == SPACE_VIEW3D) && event->alt) { #if 0 // TRANSFORM_FIX_ME - int mval[2]; + int mval[2]; - getmouseco_sc(mval); - BIF_selectOrientation(); - calc_manipulator_stats(curarea); - copy_m3_m4(t->spacemtx, G.vd->twmat); - warp_pointer(mval[0], mval[1]); + getmouseco_sc(mval); + BIF_selectOrientation(); + calc_manipulator_stats(curarea); + copy_m3_m4(t->spacemtx, G.vd->twmat); + warp_pointer(mval[0], mval[1]); #endif - } - else { - t->state = TRANS_CONFIRM; - } - break; - - case MIDDLEMOUSE: - if ((t->flag & T_NO_CONSTRAINT)==0) { - /* exception for switching to dolly, or trackball, in camera view */ - if (t->flag & T_CAMERA) { - if (t->mode==TFM_TRANSLATION) - setLocalConstraint(t, (CON_AXIS2), "along local Z"); - else if (t->mode==TFM_ROTATION) { - restoreTransObjects(t); - initTrackball(t); - } } else { - t->modifiers |= MOD_CONSTRAINT_SELECT; - if (t->con.mode & CON_APPLY) { - stopConstraint(t); + t->state = TRANS_CONFIRM; + } + break; + + case MIDDLEMOUSE: + if ((t->flag & T_NO_CONSTRAINT) == 0) { + /* exception for switching to dolly, or trackball, in camera view */ + if (t->flag & T_CAMERA) { + if (t->mode == TFM_TRANSLATION) + setLocalConstraint(t, (CON_AXIS2), "along local Z"); + else if (t->mode == TFM_ROTATION) { + restoreTransObjects(t); + initTrackball(t); + } } else { - if (event->shift) { - initSelectConstraint(t, t->spacemtx); + t->modifiers |= MOD_CONSTRAINT_SELECT; + if (t->con.mode & CON_APPLY) { + stopConstraint(t); } else { - /* bit hackish... but it prevents mmb select to print the orientation from menu */ - strcpy(t->spacename, "global"); - initSelectConstraint(t, mati); + if (event->shift) { + initSelectConstraint(t, t->spacemtx); + } + else { + /* bit hackish... but it prevents mmb select to print the orientation from menu */ + strcpy(t->spacename, "global"); + initSelectConstraint(t, mati); + } + postSelectConstraint(t); } - postSelectConstraint(t); } + t->redraw |= TREDRAW_HARD; } - t->redraw |= TREDRAW_HARD; - } - break; - case ESCKEY: - t->state = TRANS_CANCEL; - break; - case PADENTER: - case RETKEY: - t->state = TRANS_CONFIRM; - break; - case GKEY: - /* only switch when... */ - if ( ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) { - resetTransRestrictions(t); - restoreTransObjects(t); - initTranslation(t); - initSnapping(t, NULL); // need to reinit after mode change - t->redraw |= TREDRAW_HARD; - } - break; - case SKEY: - /* only switch when... */ - if ( ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) { - resetTransRestrictions(t); - restoreTransObjects(t); - initResize(t); - initSnapping(t, NULL); // need to reinit after mode change - t->redraw |= TREDRAW_HARD; - } - break; - case RKEY: - /* only switch when... */ - if (!(t->options & CTX_TEXTURE)) { - if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { - + break; + case ESCKEY: + t->state = TRANS_CANCEL; + break; + case PADENTER: + case RETKEY: + t->state = TRANS_CONFIRM; + break; + case GKEY: + /* only switch when... */ + if (ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) { resetTransRestrictions(t); - - if (t->mode == TFM_ROTATION) { - restoreTransObjects(t); - initTrackball(t); - } - else { - restoreTransObjects(t); - initRotation(t); - } + restoreTransObjects(t); + initTranslation(t); initSnapping(t, NULL); // need to reinit after mode change t->redraw |= TREDRAW_HARD; } - } - break; - case CKEY: - if (event->alt) { - t->flag ^= T_PROP_CONNECTED; - sort_trans_data_dist(t); - calculatePropRatio(t); - t->redraw= 1; - } - else { - stopConstraint(t); - t->redraw |= TREDRAW_HARD; - } - break; - case XKEY: - case YKEY: - case ZKEY: - transform_event_xyz_constraint(t, event->type, cmode); - break; - case OKEY: - if (t->flag & T_PROP_EDIT && event->shift) { - t->prop_mode = (t->prop_mode + 1) % PROP_MODE_MAX; - calculatePropRatio(t); - t->redraw |= TREDRAW_HARD; - } - break; - case PADPLUSKEY: - if (event->alt && t->flag & T_PROP_EDIT) { - t->prop_size *= 1.1f; - if (t->spacetype==SPACE_VIEW3D && t->persp != RV3D_ORTHO) - t->prop_size= MIN2(t->prop_size, ((View3D *)t->view)->far); - calculatePropRatio(t); - } - t->redraw= 1; - break; - case PAGEUPKEY: - case WHEELDOWNMOUSE: - if (t->flag & T_AUTOIK) { - transform_autoik_update(t, 1); - } - else view_editmove(event->type); - t->redraw= 1; - break; - case PADMINUS: - if (event->alt && t->flag & T_PROP_EDIT) { - t->prop_size*= 0.90909090f; - calculatePropRatio(t); - } - t->redraw= 1; - break; - case PAGEDOWNKEY: - case WHEELUPMOUSE: - if (t->flag & T_AUTOIK) { - transform_autoik_update(t, -1); - } - else view_editmove(event->type); - t->redraw= 1; - break; - default: - handled = 0; - break; + break; + case SKEY: + /* only switch when... */ + if (ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) { + resetTransRestrictions(t); + restoreTransObjects(t); + initResize(t); + initSnapping(t, NULL); // need to reinit after mode change + t->redraw |= TREDRAW_HARD; + } + break; + case RKEY: + /* only switch when... */ + if (!(t->options & CTX_TEXTURE)) { + if (ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { + + resetTransRestrictions(t); + + if (t->mode == TFM_ROTATION) { + restoreTransObjects(t); + initTrackball(t); + } + else { + restoreTransObjects(t); + initRotation(t); + } + initSnapping(t, NULL); // need to reinit after mode change + t->redraw |= TREDRAW_HARD; + } + } + break; + case CKEY: + if (event->alt) { + t->flag ^= T_PROP_CONNECTED; + sort_trans_data_dist(t); + calculatePropRatio(t); + t->redraw = 1; + } + else { + stopConstraint(t); + t->redraw |= TREDRAW_HARD; + } + break; + case XKEY: + case YKEY: + case ZKEY: + transform_event_xyz_constraint(t, event->type, cmode); + break; + case OKEY: + if (t->flag & T_PROP_EDIT && event->shift) { + t->prop_mode = (t->prop_mode + 1) % PROP_MODE_MAX; + calculatePropRatio(t); + t->redraw |= TREDRAW_HARD; + } + break; + case PADPLUSKEY: + if (event->alt && t->flag & T_PROP_EDIT) { + t->prop_size *= 1.1f; + if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) + t->prop_size = MIN2(t->prop_size, ((View3D *)t->view)->far); + calculatePropRatio(t); + } + t->redraw = 1; + break; + case PAGEUPKEY: + case WHEELDOWNMOUSE: + if (t->flag & T_AUTOIK) { + transform_autoik_update(t, 1); + } + else view_editmove(event->type); + t->redraw = 1; + break; + case PADMINUS: + if (event->alt && t->flag & T_PROP_EDIT) { + t->prop_size *= 0.90909090f; + calculatePropRatio(t); + } + t->redraw = 1; + break; + case PAGEDOWNKEY: + case WHEELUPMOUSE: + if (t->flag & T_AUTOIK) { + transform_autoik_update(t, -1); + } + else view_editmove(event->type); + t->redraw = 1; + break; + default: + handled = 0; + break; } // Numerical input events @@ -1141,30 +1141,30 @@ int transformEvent(TransInfo *t, wmEvent *event) t->redraw |= handleSnapping(t, event); } - else if (event->val==KM_RELEASE) { + else if (event->val == KM_RELEASE) { switch (event->type) { - case LEFTSHIFTKEY: - case RIGHTSHIFTKEY: - t->modifiers &= ~MOD_CONSTRAINT_PLANE; - t->redraw |= TREDRAW_HARD; - break; - - case MIDDLEMOUSE: - if ((t->flag & T_NO_CONSTRAINT)==0) { - t->modifiers &= ~MOD_CONSTRAINT_SELECT; - postSelectConstraint(t); + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + t->modifiers &= ~MOD_CONSTRAINT_PLANE; t->redraw |= TREDRAW_HARD; - } - break; + break; + + case MIDDLEMOUSE: + if ((t->flag & T_NO_CONSTRAINT) == 0) { + t->modifiers &= ~MOD_CONSTRAINT_SELECT; + postSelectConstraint(t); + t->redraw |= TREDRAW_HARD; + } + break; // case LEFTMOUSE: // case RIGHTMOUSE: // if (WM_modal_tweak_exit(event, t->event_type)) //// if (t->options & CTX_TWEAK) // t->state = TRANS_CONFIRM; // break; - default: - handled = 0; - break; + default: + handled = 0; + break; } /* confirm transform if launch key is released after mouse move */ @@ -1197,11 +1197,11 @@ int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int c t->mode = TFM_DUMMY; - initTransInfo(C, t, NULL, NULL); // internal data, mouse, vectors + initTransInfo(C, t, NULL, NULL); // internal data, mouse, vectors - createTransData(C, t); // make TransData structs from selection + createTransData(C, t); // make TransData structs from selection - t->around = centerMode; // override userdefined mode + t->around = centerMode; // override userdefined mode if (t->total == 0) { success = FALSE; @@ -1305,7 +1305,7 @@ static void drawArc(float size, float angle_start, float angle_end, int segments glBegin(GL_LINE_STRIP); - for ( angle = angle_start; angle < angle_end; angle += delta) { + for (angle = angle_start; angle < angle_end; angle += delta) { glVertex2f(cosf(angle) * size, sinf(angle) * size); } glVertex2f(cosf(angle_end) * size, sinf(angle_end) * size); @@ -1315,35 +1315,35 @@ static void drawArc(float size, float angle_start, float angle_end, int segments static int helpline_poll(bContext *C) { - ARegion *ar= CTX_wm_region(C); + ARegion *ar = CTX_wm_region(C); - if (ar && ar->regiontype==RGN_TYPE_WINDOW) + if (ar && ar->regiontype == RGN_TYPE_WINDOW) return 1; return 0; } static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) { - TransInfo *t = (TransInfo*)customdata; + TransInfo *t = (TransInfo *)customdata; if (t->helpline != HLP_NONE && !(t->flag & T_USES_MANIPULATOR)) { float vecrot[3], cent[2]; int mval[2]; - mval[0]= x; - mval[1]= y; + mval[0] = x; + mval[1] = y; copy_v3_v3(vecrot, t->center); if (t->flag & T_EDIT) { - Object *ob= t->obedit; + Object *ob = t->obedit; if (ob) mul_m4_v3(ob->obmat, vecrot); } else if (t->flag & T_POSE) { - Object *ob=t->poseobj; + Object *ob = t->poseobj; if (ob) mul_m4_v3(ob->obmat, vecrot); } - projectFloatView(t, vecrot, cent); // no overflow in extreme cases + projectFloatView(t, vecrot, cent); // no overflow in extreme cases glPushMatrix(); @@ -1388,67 +1388,67 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) glLineWidth(1.0); break; case HLP_ANGLE: - { - float dx = t->mval[0] - cent[0], dy = t->mval[1] - cent[1]; - float angle = atan2f(dy, dx); - float dist = sqrtf(dx*dx + dy*dy); - float delta_angle = MIN2(15.0f / dist, (float)M_PI/4.0f); - float spacing_angle = MIN2(5.0f / dist, (float)M_PI/12.0f); - UI_ThemeColor(TH_WIRE); + { + float dx = t->mval[0] - cent[0], dy = t->mval[1] - cent[1]; + float angle = atan2f(dy, dx); + float dist = sqrtf(dx * dx + dy * dy); + float delta_angle = MIN2(15.0f / dist, (float)M_PI / 4.0f); + float spacing_angle = MIN2(5.0f / dist, (float)M_PI / 12.0f); + UI_ThemeColor(TH_WIRE); - setlinestyle(3); - glBegin(GL_LINE_STRIP); - glVertex2iv(t->mval); - glVertex2fv(cent); - glEnd(); + setlinestyle(3); + glBegin(GL_LINE_STRIP); + glVertex2iv(t->mval); + glVertex2fv(cent); + glEnd(); - glTranslatef(cent[0] - t->mval[0] + mval[0], cent[1] - t->mval[1] + mval[1], 0); + glTranslatef(cent[0] - t->mval[0] + mval[0], cent[1] - t->mval[1] + mval[1], 0); - setlinestyle(0); - glLineWidth(3.0); - drawArc(dist, angle - delta_angle, angle - spacing_angle, 10); - drawArc(dist, angle + spacing_angle, angle + delta_angle, 10); + setlinestyle(0); + glLineWidth(3.0); + drawArc(dist, angle - delta_angle, angle - spacing_angle, 10); + drawArc(dist, angle + spacing_angle, angle + delta_angle, 10); - glPushMatrix(); + glPushMatrix(); - glTranslatef(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0); - glRotatef(RAD2DEGF(angle - delta_angle), 0, 0, 1); + glTranslatef(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0); + glRotatef(RAD2DEGF(angle - delta_angle), 0, 0, 1); - drawArrowHead(DOWN, 5); + drawArrowHead(DOWN, 5); - glPopMatrix(); + glPopMatrix(); - glTranslatef(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0); - glRotatef(RAD2DEGF(angle + delta_angle), 0, 0, 1); + glTranslatef(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0); + glRotatef(RAD2DEGF(angle + delta_angle), 0, 0, 1); - drawArrowHead(UP, 5); + drawArrowHead(UP, 5); - glLineWidth(1.0); - break; - } - case HLP_TRACKBALL: - { - unsigned char col[3], col2[3]; - UI_GetThemeColor3ubv(TH_GRID, col); + glLineWidth(1.0); + break; + } + case HLP_TRACKBALL: + { + unsigned char col[3], col2[3]; + UI_GetThemeColor3ubv(TH_GRID, col); - glTranslatef(mval[0], mval[1], 0); + glTranslatef(mval[0], mval[1], 0); - glLineWidth(3.0); + glLineWidth(3.0); - UI_make_axis_color(col, col2, 'X'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'X'); + glColor3ubv((GLubyte *)col2); - drawArrow(RIGHT, 5, 10, 5); - drawArrow(LEFT, 5, 10, 5); + drawArrow(RIGHT, 5, 10, 5); + drawArrow(LEFT, 5, 10, 5); - UI_make_axis_color(col, col2, 'Y'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'Y'); + glColor3ubv((GLubyte *)col2); - drawArrow(UP, 5, 10, 5); - drawArrow(DOWN, 5, 10, 5); - glLineWidth(1.0); - break; - } + drawArrow(UP, 5, 10, 5); + drawArrow(DOWN, 5, 10, 5); + glLineWidth(1.0); + break; + } } glPopMatrix(); @@ -1482,12 +1482,12 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) PropertyRNA *prop; // Save back mode in case we're in the generic operator - if ((prop= RNA_struct_find_property(op->ptr, "mode"))) { + if ((prop = RNA_struct_find_property(op->ptr, "mode"))) { RNA_property_enum_set(op->ptr, prop, t->mode); } - if ((prop= RNA_struct_find_property(op->ptr, "value"))) { - float *values= (t->flag & T_AUTOVALUES) ? t->auto_values : t->values; + if ((prop = RNA_struct_find_property(op->ptr, "value"))) { + float *values = (t->flag & T_AUTOVALUES) ? t->auto_values : t->values; if (RNA_property_array_check(prop)) { RNA_property_float_set_array(op->ptr, prop, values); } @@ -1497,8 +1497,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) } /* convert flag to enum */ - switch (t->flag & (T_PROP_EDIT|T_PROP_CONNECTED)) { - case (T_PROP_EDIT|T_PROP_CONNECTED): + switch (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) { + case (T_PROP_EDIT | T_PROP_CONNECTED): proportional = PROP_EDIT_CONNECTED; break; case T_PROP_EDIT: @@ -1658,7 +1658,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int else unit_m3(t->spacemtx); - createTransData(C, t); // make TransData structs from selection + createTransData(C, t); // make TransData structs from selection if (t->total == 0) { postTrans(C, t); @@ -1698,114 +1698,114 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int initMouseInput(t, &t->mouse, t->center2d, t->imval); switch (mode) { - case TFM_TRANSLATION: - initTranslation(t); - break; - case TFM_ROTATION: - initRotation(t); - break; - case TFM_RESIZE: - initResize(t); - break; - case TFM_SKIN_RESIZE: - initSkinResize(t); - break; - case TFM_TOSPHERE: - initToSphere(t); - break; - case TFM_SHEAR: - initShear(t); - break; - case TFM_WARP: - initWarp(t); - break; - case TFM_SHRINKFATTEN: - initShrinkFatten(t); - break; - case TFM_TILT: - initTilt(t); - break; - case TFM_CURVE_SHRINKFATTEN: - initCurveShrinkFatten(t); - break; - case TFM_MASK_SHRINKFATTEN: - initMaskShrinkFatten(t); - break; - case TFM_TRACKBALL: - initTrackball(t); - break; - case TFM_PUSHPULL: - initPushPull(t); - break; - case TFM_CREASE: - initCrease(t); - break; - case TFM_BONESIZE: - { /* used for both B-Bone width (bonesize) as for deform-dist (envelope) */ - bArmature *arm= t->poseobj->data; - if (arm->drawtype==ARM_ENVELOPE) + case TFM_TRANSLATION: + initTranslation(t); + break; + case TFM_ROTATION: + initRotation(t); + break; + case TFM_RESIZE: + initResize(t); + break; + case TFM_SKIN_RESIZE: + initSkinResize(t); + break; + case TFM_TOSPHERE: + initToSphere(t); + break; + case TFM_SHEAR: + initShear(t); + break; + case TFM_WARP: + initWarp(t); + break; + case TFM_SHRINKFATTEN: + initShrinkFatten(t); + break; + case TFM_TILT: + initTilt(t); + break; + case TFM_CURVE_SHRINKFATTEN: + initCurveShrinkFatten(t); + break; + case TFM_MASK_SHRINKFATTEN: + initMaskShrinkFatten(t); + break; + case TFM_TRACKBALL: + initTrackball(t); + break; + case TFM_PUSHPULL: + initPushPull(t); + break; + case TFM_CREASE: + initCrease(t); + break; + case TFM_BONESIZE: + { /* used for both B-Bone width (bonesize) as for deform-dist (envelope) */ + bArmature *arm = t->poseobj->data; + if (arm->drawtype == ARM_ENVELOPE) initBoneEnvelope(t); else initBoneSize(t); } break; - case TFM_BONE_ENVELOPE: - initBoneEnvelope(t); - break; - case TFM_EDGE_SLIDE: - initEdgeSlide(t); - break; - case TFM_BONE_ROLL: - initBoneRoll(t); - break; - case TFM_TIME_TRANSLATE: - initTimeTranslate(t); - break; - case TFM_TIME_SLIDE: - initTimeSlide(t); - break; - case TFM_TIME_SCALE: - initTimeScale(t); - break; - case TFM_TIME_DUPLICATE: - /* same as TFM_TIME_EXTEND, but we need the mode info for later - * so that duplicate-culling will work properly - */ - if (ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) - initTranslation(t); - else + case TFM_BONE_ENVELOPE: + initBoneEnvelope(t); + break; + case TFM_EDGE_SLIDE: + initEdgeSlide(t); + break; + case TFM_BONE_ROLL: + initBoneRoll(t); + break; + case TFM_TIME_TRANSLATE: initTimeTranslate(t); - t->mode = mode; - break; - case TFM_TIME_EXTEND: - /* now that transdata has been made, do like for TFM_TIME_TRANSLATE (for most Animation - * Editors because they have only 1D transforms for time values) or TFM_TRANSLATION - * (for Graph/NLA Editors only since they uses 'standard' transforms to get 2D movement) - * depending on which editor this was called from - */ - if (ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) - initTranslation(t); - else - initTimeTranslate(t); - break; - case TFM_BAKE_TIME: - initBakeTime(t); - break; - case TFM_MIRROR: - initMirror(t); - break; - case TFM_BEVEL: - initBevel(t); - break; - case TFM_BWEIGHT: - initBevelWeight(t); - break; - case TFM_ALIGN: - initAlign(t); - break; - case TFM_SEQ_SLIDE: - initSeqSlide(t); - break; + break; + case TFM_TIME_SLIDE: + initTimeSlide(t); + break; + case TFM_TIME_SCALE: + initTimeScale(t); + break; + case TFM_TIME_DUPLICATE: + /* same as TFM_TIME_EXTEND, but we need the mode info for later + * so that duplicate-culling will work properly + */ + if (ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) + initTranslation(t); + else + initTimeTranslate(t); + t->mode = mode; + break; + case TFM_TIME_EXTEND: + /* now that transdata has been made, do like for TFM_TIME_TRANSLATE (for most Animation + * Editors because they have only 1D transforms for time values) or TFM_TRANSLATION + * (for Graph/NLA Editors only since they uses 'standard' transforms to get 2D movement) + * depending on which editor this was called from + */ + if (ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) + initTranslation(t); + else + initTimeTranslate(t); + break; + case TFM_BAKE_TIME: + initBakeTime(t); + break; + case TFM_MIRROR: + initMirror(t); + break; + case TFM_BEVEL: + initBevel(t); + break; + case TFM_BWEIGHT: + initBevelWeight(t); + break; + case TFM_ALIGN: + initAlign(t); + break; + case TFM_SEQ_SLIDE: + initSeqSlide(t); + break; } if (t->state == TRANS_CANCEL) { @@ -1816,13 +1816,13 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int /* overwrite initial values if operator supplied a non-null vector */ if ((prop = RNA_struct_find_property(op->ptr, "value")) && RNA_property_is_set(op->ptr, prop)) { - float values[4]= {0}; /* in case value isn't length 4, avoid uninitialized memory */ + float values[4] = {0}; /* in case value isn't length 4, avoid uninitialized memory */ if (RNA_property_array_check(prop)) { RNA_float_get_array(op->ptr, "value", values); } else { - values[0]= RNA_float_get(op->ptr, "value"); + values[0] = RNA_float_get(op->ptr, "value"); } copy_v4_v4(t->values, values); @@ -1915,11 +1915,11 @@ int transformEnd(bContext *C, TransInfo *t) /* handle restoring objects */ if (t->state == TRANS_CANCEL) { /* exception, edge slide transformed UVs too */ - if (t->mode==TFM_EDGE_SLIDE) + if (t->mode == TFM_EDGE_SLIDE) doEdgeSlide(t, 0.0f); exit_code = OPERATOR_CANCELLED; - restoreTransObjects(t); // calls recalcData() + restoreTransObjects(t); // calls recalcData() } else { exit_code = OPERATOR_FINISHED; @@ -1943,7 +1943,7 @@ int transformEnd(bContext *C, TransInfo *t) // if (t->undostr) ED_undo_push(C, t->undostr); // else ED_undo_push(C, transform_to_undostr(t)); } - t->undostr= NULL; + t->undostr = NULL; viewRedrawForce(C, t); } @@ -1958,31 +1958,31 @@ int transformEnd(bContext *C, TransInfo *t) static void protectedTransBits(short protectflag, float *vec) { if (protectflag & OB_LOCK_LOCX) - vec[0]= 0.0f; + vec[0] = 0.0f; if (protectflag & OB_LOCK_LOCY) - vec[1]= 0.0f; + vec[1] = 0.0f; if (protectflag & OB_LOCK_LOCZ) - vec[2]= 0.0f; + vec[2] = 0.0f; } static void protectedSizeBits(short protectflag, float *size) { if (protectflag & OB_LOCK_SCALEX) - size[0]= 1.0f; + size[0] = 1.0f; if (protectflag & OB_LOCK_SCALEY) - size[1]= 1.0f; + size[1] = 1.0f; if (protectflag & OB_LOCK_SCALEZ) - size[2]= 1.0f; + size[2] = 1.0f; } static void protectedRotateBits(short protectflag, float *eul, float *oldeul) { if (protectflag & OB_LOCK_ROTX) - eul[0]= oldeul[0]; + eul[0] = oldeul[0]; if (protectflag & OB_LOCK_ROTY) - eul[1]= oldeul[1]; + eul[1] = oldeul[1]; if (protectflag & OB_LOCK_ROTZ) - eul[2]= oldeul[2]; + eul[2] = oldeul[2]; } @@ -1991,19 +1991,19 @@ static void protectedRotateBits(short protectflag, float *eul, float *oldeul) static void protectedAxisAngleBits(short protectflag, float axis[3], float *angle, float oldAxis[3], float oldAngle) { /* check that protection flags are set */ - if ((protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) == 0) + if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0) return; if (protectflag & OB_LOCK_ROT4D) { /* axis-angle getting limited as 4D entities that they are... */ if (protectflag & OB_LOCK_ROTW) - *angle= oldAngle; + *angle = oldAngle; if (protectflag & OB_LOCK_ROTX) - axis[0]= oldAxis[0]; + axis[0] = oldAxis[0]; if (protectflag & OB_LOCK_ROTY) - axis[1]= oldAxis[1]; + axis[1] = oldAxis[1]; if (protectflag & OB_LOCK_ROTZ) - axis[2]= oldAxis[2]; + axis[2] = oldAxis[2]; } else { /* axis-angle get limited with euler... */ @@ -2013,18 +2013,18 @@ static void protectedAxisAngleBits(short protectflag, float axis[3], float *angl axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, oldAxis, oldAngle); if (protectflag & OB_LOCK_ROTX) - eul[0]= oldeul[0]; + eul[0] = oldeul[0]; if (protectflag & OB_LOCK_ROTY) - eul[1]= oldeul[1]; + eul[1] = oldeul[1]; if (protectflag & OB_LOCK_ROTZ) - eul[2]= oldeul[2]; + eul[2] = oldeul[2]; eulO_to_axis_angle(axis, angle, eul, EULER_ORDER_DEFAULT); /* when converting to axis-angle, we need a special exception for the case when there is no axis */ if (IS_EQF(axis[0], axis[1]) && IS_EQF(axis[1], axis[2])) { /* for now, rotate around y-axis then (so that it simply becomes the roll) */ - axis[1]= 1.0f; + axis[1] = 1.0f; } } } @@ -2033,37 +2033,37 @@ static void protectedAxisAngleBits(short protectflag, float axis[3], float *angl static void protectedQuaternionBits(short protectflag, float *quat, float *oldquat) { /* check that protection flags are set */ - if ((protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) == 0) + if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0) return; if (protectflag & OB_LOCK_ROT4D) { /* quaternions getting limited as 4D entities that they are... */ if (protectflag & OB_LOCK_ROTW) - quat[0]= oldquat[0]; + quat[0] = oldquat[0]; if (protectflag & OB_LOCK_ROTX) - quat[1]= oldquat[1]; + quat[1] = oldquat[1]; if (protectflag & OB_LOCK_ROTY) - quat[2]= oldquat[2]; + quat[2] = oldquat[2]; if (protectflag & OB_LOCK_ROTZ) - quat[3]= oldquat[3]; + quat[3] = oldquat[3]; } else { /* quaternions get limited with euler... (compatibility mode) */ float eul[3], oldeul[3], nquat[4], noldquat[4]; float qlen; - qlen= normalize_qt_qt(nquat, quat); + qlen = normalize_qt_qt(nquat, quat); normalize_qt_qt(noldquat, oldquat); quat_to_eul(eul, nquat); quat_to_eul(oldeul, noldquat); if (protectflag & OB_LOCK_ROTX) - eul[0]= oldeul[0]; + eul[0] = oldeul[0]; if (protectflag & OB_LOCK_ROTY) - eul[1]= oldeul[1]; + eul[1] = oldeul[1]; if (protectflag & OB_LOCK_ROTZ) - eul[2]= oldeul[2]; + eul[2] = oldeul[2]; eul_to_quat(quat, eul); @@ -2071,7 +2071,7 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu mul_qt_fl(quat, qlen); /* quaternions flip w sign to accumulate rotations correctly */ - if ( (nquat[0]<0.0f && quat[0]>0.0f) || (nquat[0]>0.0f && quat[0]<0.0f) ) { + if ( (nquat[0] < 0.0f && quat[0] > 0.0f) || (nquat[0] > 0.0f && quat[0] < 0.0f) ) { mul_qt_fl(quat, -1.0f); } } @@ -2082,22 +2082,22 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu static void constraintTransLim(TransInfo *t, TransData *td) { if (td->con) { - bConstraintTypeInfo *ctiLoc= get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT); - bConstraintTypeInfo *ctiDist= get_constraint_typeinfo(CONSTRAINT_TYPE_DISTLIMIT); + bConstraintTypeInfo *ctiLoc = get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT); + bConstraintTypeInfo *ctiDist = get_constraint_typeinfo(CONSTRAINT_TYPE_DISTLIMIT); - bConstraintOb cob= {NULL}; + bConstraintOb cob = {NULL}; bConstraint *con; float ctime = (float)(t->scene->r.cfra); /* Make a temporary bConstraintOb for using these limit constraints - * - they only care that cob->matrix is correctly set ;-) + * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ unit_m4(cob.matrix); copy_v3_v3(cob.matrix[3], td->loc); /* Evaluate valid constraints */ - for (con= td->con; con; con= con->next) { + for (con = td->con; con; con = con->next) { bConstraintTypeInfo *cti = NULL; ListBase targets = {NULL, NULL}; float tmat[4][4]; @@ -2108,16 +2108,16 @@ static void constraintTransLim(TransInfo *t, TransData *td) /* only use it if it's tagged for this purpose (and the right type) */ if (con->type == CONSTRAINT_TYPE_LOCLIMIT) { - bLocLimitConstraint *data= con->data; + bLocLimitConstraint *data = con->data; - if ((data->flag2 & LIMIT_TRANSFORM)==0) + if ((data->flag2 & LIMIT_TRANSFORM) == 0) continue; cti = ctiLoc; } else if (con->type == CONSTRAINT_TYPE_DISTLIMIT) { - bDistLimitConstraint *data= con->data; + bDistLimitConstraint *data = con->data; - if ((data->flag & LIMITDIST_TRANSFORM)==0) + if ((data->flag & LIMITDIST_TRANSFORM) == 0) continue; cti = ctiDist; } @@ -2160,7 +2160,7 @@ static void constraintTransLim(TransInfo *t, TransData *td) static void constraintob_from_transdata(bConstraintOb *cob, TransData *td) { /* Make a temporary bConstraintOb for use by limit constraints - * - they only care that cob->matrix is correctly set ;-) + * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ memset(cob, 0, sizeof(bConstraintOb)); @@ -2168,8 +2168,8 @@ static void constraintob_from_transdata(bConstraintOb *cob, TransData *td) if (td->ext->rotOrder == ROT_MODE_QUAT) { /* quats */ /* objects and bones do normalization first too, otherwise - * we don't necessarily end up with a rotation matrix, and - * then conversion back to quat gives a different result */ + * we don't necessarily end up with a rotation matrix, and + * then conversion back to quat gives a different result */ float quat[4]; normalize_qt_qt(quat, td->ext->quat); quat_to_mat4(cob->matrix, quat); @@ -2188,24 +2188,24 @@ static void constraintob_from_transdata(bConstraintOb *cob, TransData *td) static void constraintRotLim(TransInfo *UNUSED(t), TransData *td) { if (td->con) { - bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT); + bConstraintTypeInfo *cti = get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT); bConstraintOb cob; bConstraint *con; int do_limit = FALSE; /* Evaluate valid constraints */ - for (con= td->con; con; con= con->next) { + for (con = td->con; con; con = con->next) { /* only consider constraint if enabled */ if (con->flag & CONSTRAINT_DISABLE) continue; if (con->enforce == 0.0f) continue; /* we're only interested in Limit-Rotation constraints */ if (con->type == CONSTRAINT_TYPE_ROTLIMIT) { - bRotLimitConstraint *data= con->data; + bRotLimitConstraint *data = con->data; float tmat[4][4]; /* only use it if it's tagged for this purpose */ - if ((data->flag2 & LIMIT_TRANSFORM)==0) + if ((data->flag2 & LIMIT_TRANSFORM) == 0) continue; /* skip incompatable spacetypes */ @@ -2258,12 +2258,12 @@ static void constraintRotLim(TransInfo *UNUSED(t), TransData *td) static void constraintSizeLim(TransInfo *t, TransData *td) { if (td->con && td->ext) { - bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT); - bConstraintOb cob= {NULL}; + bConstraintTypeInfo *cti = get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT); + bConstraintOb cob = {NULL}; bConstraint *con; /* Make a temporary bConstraintOb for using these limit constraints - * - they only care that cob->matrix is correctly set ;-) + * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) { @@ -2279,18 +2279,18 @@ static void constraintSizeLim(TransInfo *t, TransData *td) } /* Evaluate valid constraints */ - for (con= td->con; con; con= con->next) { + for (con = td->con; con; con = con->next) { /* only consider constraint if enabled */ if (con->flag & CONSTRAINT_DISABLE) continue; if (con->enforce == 0.0f) continue; /* we're only interested in Limit-Scale constraints */ if (con->type == CONSTRAINT_TYPE_SIZELIMIT) { - bSizeLimitConstraint *data= con->data; + bSizeLimitConstraint *data = con->data; float tmat[4][4]; /* only use it if it's tagged for this purpose */ - if ((data->flag2 & LIMIT_TRANSFORM)==0) + if ((data->flag2 & LIMIT_TRANSFORM) == 0) continue; /* do space conversions */ @@ -2381,8 +2381,8 @@ void initWarp(TransInfo *t) mid_v3_v3v3(t->center, min, max); - if (max[0] == min[0]) max[0] += 0.1f; /* not optimal, but flipping is better than invalid garbage (i.e. division by zero!) */ - t->val= (max[0]-min[0])/2.0f; /* t->val is X dimension projected boundbox */ + if (max[0] == min[0]) max[0] += 0.1f; /* not optimal, but flipping is better than invalid garbage (i.e. division by zero!) */ + t->val = (max[0] - min[0]) / 2.0f; /* t->val is X dimension projected boundbox */ } int handleEventWarp(TransInfo *t, wmEvent *event) @@ -2409,7 +2409,7 @@ int Warp(TransInfo *t, const int UNUSED(mval[2])) int i; char str[50]; - curs= give_cursor(t->scene, t->view); + curs = give_cursor(t->scene, t->view); /* * gcursor is the one used for helpline. * It has to be in the same space as the drawing loop @@ -2469,18 +2469,18 @@ int Warp(TransInfo *t, const int UNUSED(mval[2])) mul_m4_v3(t->viewmat, vec); sub_v3_v3(vec, t->viewmat[3]); - dist= vec[0]-cursor[0]; + dist = vec[0] - cursor[0]; /* t->val is X dimension projected boundbox */ - phi0= (circumfac*dist/t->val); + phi0 = (circumfac * dist / t->val); - vec[1]= (vec[1]-cursor[1]); + vec[1] = (vec[1] - cursor[1]); - co= (float)cos(phi0); - si= (float)sin(phi0); - loc[0]= -si*vec[1]+cursor[0]; - loc[1]= co*vec[1]+cursor[1]; - loc[2]= vec[2]; + co = (float)cos(phi0); + si = (float)sin(phi0); + loc[0] = -si * vec[1] + cursor[0]; + loc[1] = co * vec[1] + cursor[1]; + loc[2] = vec[2]; mul_m4_v3(t->viewinv, loc); sub_v3_v3(loc, t->viewinv[3]); @@ -2533,7 +2533,7 @@ int handleEventShear(TransInfo *t, wmEvent *event) // Use customData pointer to signal Shear direction if (t->customData == NULL) { initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE); - t->customData = (void*)1; + t->customData = (void *)1; } else { initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); @@ -2591,7 +2591,7 @@ int Shear(TransInfo *t, const int UNUSED(mval[2])) mul_m3_m3m3(tmat, smat, persmat); mul_m3_m3m3(totmat, persinv, tmat); - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -2654,7 +2654,7 @@ void initResize(TransInfo *t) static void headerResize(TransInfo *t, float vec[3], char *str) { char tvec[60]; - char *spos= str; + char *spos = str; if (hasNumInput(&t->num)) { outputNumInput(&(t->num), tvec); } @@ -2666,14 +2666,14 @@ static void headerResize(TransInfo *t, float vec[3], char *str) if (t->con.mode & CON_APPLY) { switch (t->num.idx_max) { - case 0: - spos += sprintf(spos, "Scale: %s%s %s", &tvec[0], t->con.text, t->proptext); - break; - case 1: - spos += sprintf(spos, "Scale: %s : %s%s %s", &tvec[0], &tvec[20], t->con.text, t->proptext); - break; - case 2: - spos += sprintf(spos, "Scale: %s : %s : %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); + case 0: + spos += sprintf(spos, "Scale: %s%s %s", &tvec[0], t->con.text, t->proptext); + break; + case 1: + spos += sprintf(spos, "Scale: %s : %s%s %s", &tvec[0], &tvec[20], t->con.text, t->proptext); + break; + case 2: + spos += sprintf(spos, "Scale: %s : %s : %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); } } else { @@ -2683,15 +2683,15 @@ static void headerResize(TransInfo *t, float vec[3], char *str) spos += sprintf(spos, "Scale X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); } - if (t->flag & (T_PROP_EDIT|T_PROP_CONNECTED)) { + if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) { spos += sprintf(spos, " Proportional size: %.2f", t->prop_size); } (void)spos; } -#define SIGN(a) (a<-FLT_EPSILON?1:a>FLT_EPSILON?2:3) -#define VECSIGNFLIP(a, b) ((SIGN(a[0]) & SIGN(b[0]))==0 || (SIGN(a[1]) & SIGN(b[1]))==0 || (SIGN(a[2]) & SIGN(b[2]))==0) +#define SIGN(a) (a<-FLT_EPSILON ? 1 : a>FLT_EPSILON ? 2 : 3) +#define VECSIGNFLIP(a, b) ((SIGN(a[0]) & SIGN(b[0])) == 0 || (SIGN(a[1]) & SIGN(b[1])) == 0 || (SIGN(a[2]) & SIGN(b[2])) == 0) /* smat is reference matrix, only scaled */ static void TransMat3ToSize(float mat[][3], float smat[][3], float *size) @@ -2699,16 +2699,16 @@ static void TransMat3ToSize(float mat[][3], float smat[][3], float *size) float vec[3]; copy_v3_v3(vec, mat[0]); - size[0]= normalize_v3(vec); + size[0] = normalize_v3(vec); copy_v3_v3(vec, mat[1]); - size[1]= normalize_v3(vec); + size[1] = normalize_v3(vec); copy_v3_v3(vec, mat[2]); - size[2]= normalize_v3(vec); + size[2] = normalize_v3(vec); /* first tried with dotproduct... but the sign flip is crucial */ - if ( VECSIGNFLIP(mat[0], smat[0]) ) size[0]= -size[0]; - if ( VECSIGNFLIP(mat[1], smat[1]) ) size[1]= -size[1]; - if ( VECSIGNFLIP(mat[2], smat[2]) ) size[2]= -size[2]; + if (VECSIGNFLIP(mat[0], smat[0]) ) size[0] = -size[0]; + if (VECSIGNFLIP(mat[1], smat[1]) ) size[1] = -size[1]; + if (VECSIGNFLIP(mat[2], smat[2]) ) size[2] = -size[2]; } @@ -2731,10 +2731,10 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) /* local constraint shouldn't alter center */ if ((t->around == V3D_LOCAL) && - ( (t->flag & (T_OBJECT|T_POSE)) || - ((t->flag & T_EDIT) && (t->settings->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE))) || - (t->obedit && t->obedit->type == OB_ARMATURE)) - ) + ( (t->flag & (T_OBJECT | T_POSE)) || + ((t->flag & T_EDIT) && (t->settings->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_FACE))) || + (t->obedit && t->obedit->type == OB_ARMATURE)) + ) { copy_v3_v3(center, td->center); } @@ -2748,7 +2748,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) if (td->ext) { float fsize[3]; - if (t->flag & (T_OBJECT|T_TEXTURE|T_POSE)) { + if (t->flag & (T_OBJECT | T_TEXTURE | T_POSE)) { float obsizemat[3][3]; // Reorient the size mat to fit the oriented object. mul_m3_m3m3(obsizemat, tmat, td->axismtx); @@ -2762,19 +2762,19 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) protectedSizeBits(td->protectflag, fsize); - if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't resize objects itself + if ((t->flag & T_V3D_ALIGN) == 0) { // align mode doesn't resize objects itself if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) { /* scale val and reset size */ - *td->val = td->ival * (1 + (fsize[0] - 1) * td->factor); + *td->val = td->ival * (1 + (fsize[0] - 1) * td->factor); td->ext->size[0] = td->ext->isize[0]; td->ext->size[1] = td->ext->isize[1]; td->ext->size[2] = td->ext->isize[2]; - } + } else { /* Reset val if SINGLESIZE but using a constraint */ if (td->flag & TD_SINGLESIZE) - *td->val = td->ival; + *td->val = td->ival; td->ext->size[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor); td->ext->size[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor); @@ -2801,7 +2801,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) mul_v3_fl(vec, td->factor); - if (t->flag & (T_OBJECT|T_POSE)) { + if (t->flag & (T_OBJECT | T_POSE)) { mul_m3_v3(td->smtx, vec); } @@ -2820,8 +2820,8 @@ int Resize(TransInfo *t, const int mval[2]) char str[200]; /* for manipulator, center handle, the scaling can't be done relative to center */ - if ( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) { - ratio = 1.0f - ((t->imval[0] - mval[0]) + (t->imval[1] - mval[1]))/100.0f; + if ( (t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) { + ratio = 1.0f - ((t->imval[0] - mval[0]) + (t->imval[1] - mval[1])) / 100.0f; } else { ratio = t->values[0]; @@ -2850,11 +2850,11 @@ int Resize(TransInfo *t, const int mval[2]) t->con.applySize(t, NULL, mat); } - copy_m3_m3(t->mat, mat); // used in manipulator + copy_m3_m3(t->mat, mat); // used in manipulator headerResize(t, size, str); - for (i = 0, td=t->data; i < t->total; i++, td++) { + for (i = 0, td = t->data; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -2871,7 +2871,7 @@ int Resize(TransInfo *t, const int mval[2]) if (t->con.applySize) t->con.applySize(t, NULL, mat); - for (i = 0, td=t->data; i < t->total; i++, td++) + for (i = 0, td = t->data; i < t->total; i++, td++) ElementResize(t, td, mat); } @@ -2996,7 +2996,7 @@ void initToSphere(TransInfo *t) t->flag |= T_NO_CONSTRAINT; // Calculate average radius - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { t->val += len_v3v3(t->center, td->iloc); } @@ -3038,7 +3038,7 @@ int ToSphere(TransInfo *t, const int UNUSED(mval[2])) } - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { float tratio; if (td->flag & TD_NOACTION) break; @@ -3086,7 +3086,7 @@ void initRotation(TransInfo *t) t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; - t->snap[1] = (float)((5.0/180)*M_PI); + t->snap[1] = (float)((5.0 / 180) * M_PI); t->snap[2] = t->snap[1] * 0.2f; t->num.increment = 1.0f; @@ -3108,8 +3108,8 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* local constraint shouldn't alter center */ if (around == V3D_LOCAL) { - if ( (t->flag & (T_OBJECT|T_POSE)) || - (t->settings->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE)) || + if ( (t->flag & (T_OBJECT | T_POSE)) || + (t->settings->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_FACE)) || (t->obedit && t->obedit->type == OB_ARMATURE)) { center = td->center; @@ -3136,7 +3136,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short if (td->flag & TD_USEQUAT) { mul_serie_m3(fmat, td->mtx, mat, td->smtx, NULL, NULL, NULL, NULL, NULL); - mat3_to_quat(quat, fmat); // Actual transform + mat3_to_quat(quat, fmat); // Actual transform if (td->ext->quat) { mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat); @@ -3168,9 +3168,9 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short if ((td->flag & TD_NO_LOC) == 0) { sub_v3_v3v3(vec, td->center, center); - mul_m3_v3(pmtx, vec); // To Global space - mul_m3_v3(mat, vec); // Applying rotation - mul_m3_v3(imtx, vec); // To Local space + mul_m3_v3(pmtx, vec); // To Global space + mul_m3_v3(mat, vec); // Applying rotation + mul_m3_v3(imtx, vec); // To Local space add_v3_v3(vec, center); /* vec now is the location where the object has to be */ @@ -3182,12 +3182,12 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* do nothing */ } else if (td->flag & TD_PBONE_LOCAL_MTX_C) { - mul_m3_v3(pmtx, vec); // To Global space - mul_m3_v3(td->ext->l_smtx, vec);// To Pose space (Local Location) + mul_m3_v3(pmtx, vec); // To Global space + mul_m3_v3(td->ext->l_smtx, vec); // To Pose space (Local Location) } else { - mul_m3_v3(pmtx, vec); // To Global space - mul_m3_v3(td->smtx, vec);// To Pose space + mul_m3_v3(pmtx, vec); // To Global space + mul_m3_v3(td->smtx, vec); // To Pose space } protectedTransBits(td->protectflag, vec); @@ -3202,7 +3202,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short * and ElementRotation() might be called in Translation context (with align snapping), * we need to be sure to actually use the *rotation* matrix here... * So no other way than storing it in some dedicated members of td->ext! */ - if ((t->flag & T_V3D_ALIGN)==0) { /* align mode doesn't rotate objects itself */ + if ((t->flag & T_V3D_ALIGN) == 0) { /* align mode doesn't rotate objects itself */ /* euler or quaternion/axis-angle? */ if (td->ext->rotOrder == ROT_MODE_QUAT) { mul_serie_m3(fmat, td->ext->r_mtx, mat, td->ext->r_smtx, NULL, NULL, NULL, NULL, NULL); @@ -3271,11 +3271,11 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short constraintTransLim(t, td); /* rotation */ - if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself + if ((t->flag & T_V3D_ALIGN) == 0) { // align mode doesn't rotate objects itself /* euler or quaternion? */ if ((td->ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) { mul_serie_m3(fmat, td->mtx, mat, td->smtx, NULL, NULL, NULL, NULL, NULL); - mat3_to_quat(quat, fmat); // Actual transform + mat3_to_quat(quat, fmat); // Actual transform mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat); /* this function works on end result */ @@ -3288,7 +3288,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle); mul_serie_m3(fmat, td->mtx, mat, td->smtx, NULL, NULL, NULL, NULL, NULL); - mat3_to_quat(quat, fmat); // Actual transform + mat3_to_quat(quat, fmat); // Actual transform mul_qt_qtqt(tquat, quat, iquat); quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat); @@ -3331,7 +3331,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) vec_rot_to_mat3(mat, axis, angle); - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -3353,7 +3353,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) int Rotation(TransInfo *t, const int UNUSED(mval[2])) { - char str[128], *spos= str; + char str[128], *spos = str; float final; @@ -3378,16 +3378,16 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2])) outputNumInput(&(t->num), c); - spos+= sprintf(spos, "Rot: %s %s %s", &c[0], t->con.text, t->proptext); + spos += sprintf(spos, "Rot: %s %s %s", &c[0], t->con.text, t->proptext); /* Clamp between -180 and 180 */ - final= angle_wrap_rad(DEG2RADF(final)); + final = angle_wrap_rad(DEG2RADF(final)); } else { spos += sprintf(spos, "Rot: %.2f%s %s", RAD2DEGF(final), t->con.text, t->proptext); } - if (t->flag & (T_PROP_EDIT|T_PROP_CONNECTED)) { + if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) { spos += sprintf(spos, " Proportional size: %.2f", t->prop_size); } (void)spos; @@ -3416,7 +3416,7 @@ void initTrackball(TransInfo *t) t->idx_max = 1; t->num.idx_max = 1; t->snap[0] = 0.0f; - t->snap[1] = (float)((5.0/180)*M_PI); + t->snap[1] = (float)((5.0 / 180) * M_PI); t->snap[2] = t->snap[1] * 0.2f; t->num.increment = 1.0f; @@ -3435,7 +3435,7 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a mul_m3_m3m3(mat, smat, totmat); - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -3455,7 +3455,7 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a int Trackball(TransInfo *t, const int UNUSED(mval[2])) { - char str[128], *spos= str; + char str[128], *spos = str; float axis1[3], axis2[3]; float mat[3][3], totmat[3][3], smat[3][3]; float phi[2]; @@ -3486,7 +3486,7 @@ int Trackball(TransInfo *t, const int UNUSED(mval[2])) spos += sprintf(spos, "Trackball: %.2f %.2f %s", RAD2DEGF(phi[0]), RAD2DEGF(phi[1]), t->proptext); } - if (t->flag & (T_PROP_EDIT|T_PROP_CONNECTED)) { + if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) { spos += sprintf(spos, " Proportional size: %.2f", t->prop_size); } (void)spos; @@ -3522,7 +3522,7 @@ void initTranslation(TransInfo *t) initMouseInputMode(t, &t->mouse, INPUT_VECTOR); - t->idx_max = (t->flag & T_2D_EDIT)? 1: 2; + t->idx_max = (t->flag & T_2D_EDIT) ? 1 : 2; t->num.flag = 0; t->num.idx_max = t->idx_max; @@ -3550,7 +3550,7 @@ void initTranslation(TransInfo *t) static void headerTranslation(TransInfo *t, float vec[3], char *str) { - char *spos= str; + char *spos = str; char tvec[60]; char distvec[20]; char autoik[20]; @@ -3568,10 +3568,10 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) dist = len_v3(vec); if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) { - int i, do_split= t->scene->unit.flag & USER_UNIT_OPT_SPLIT ? 1:0; + int i, do_split = t->scene->unit.flag & USER_UNIT_OPT_SPLIT ? 1 : 0; - for (i=0; i<3; i++) - bUnit_AsString(&tvec[i*20], 20, dvec[i]*t->scene->unit.scale_length, 4, t->scene->unit.system, B_UNIT_LENGTH, do_split, 1); + for (i = 0; i < 3; i++) + bUnit_AsString(&tvec[i * 20], 20, dvec[i] * t->scene->unit.scale_length, 4, t->scene->unit.system, B_UNIT_LENGTH, do_split, 1); } else { sprintf(&tvec[0], "%.4f", dvec[0]); @@ -3581,33 +3581,33 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) } if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) - bUnit_AsString(distvec, sizeof(distvec), dist*t->scene->unit.scale_length, 4, t->scene->unit.system, B_UNIT_LENGTH, t->scene->unit.flag & USER_UNIT_OPT_SPLIT, 0); - else if ( dist > 1e10f || dist < -1e10f ) /* prevent string buffer overflow */ + bUnit_AsString(distvec, sizeof(distvec), dist * t->scene->unit.scale_length, 4, t->scene->unit.system, B_UNIT_LENGTH, t->scene->unit.flag & USER_UNIT_OPT_SPLIT, 0); + else if (dist > 1e10f || dist < -1e10f) /* prevent string buffer overflow */ sprintf(distvec, "%.4e", dist); else sprintf(distvec, "%.4f", dist); if (t->flag & T_AUTOIK) { - short chainlen= t->settings->autoik_chainlen; + short chainlen = t->settings->autoik_chainlen; if (chainlen) sprintf(autoik, "AutoIK-Len: %d", chainlen); else - autoik[0]= '\0'; + autoik[0] = '\0'; } else - autoik[0]= '\0'; + autoik[0] = '\0'; if (t->con.mode & CON_APPLY) { switch (t->num.idx_max) { - case 0: - spos += sprintf(spos, "D: %s (%s)%s %s %s", &tvec[0], distvec, t->con.text, t->proptext, &autoik[0]); - break; - case 1: - spos += sprintf(spos, "D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext, &autoik[0]); - break; - case 2: - spos += sprintf(spos, "D: %s D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]); + case 0: + spos += sprintf(spos, "D: %s (%s)%s %s %s", &tvec[0], distvec, t->con.text, t->proptext, &autoik[0]); + break; + case 1: + spos += sprintf(spos, "D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext, &autoik[0]); + break; + case 2: + spos += sprintf(spos, "D: %s D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]); } } else { @@ -3617,7 +3617,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) spos += sprintf(spos, "Dx: %s Dy: %s Dz: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]); } - if (t->flag & (T_PROP_EDIT|T_PROP_CONNECTED)) { + if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) { spos += sprintf(spos, " Proportional size: %.2f", t->prop_size); } (void)spos; @@ -3629,7 +3629,7 @@ static void applyTranslation(TransInfo *t, float vec[3]) float tvec[3]; int i; - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -3733,7 +3733,7 @@ int Translation(TransInfo *t, const int UNUSED(mval[2])) void initShrinkFatten(TransInfo *t) { // If not in mesh edit mode, fallback to Resize - if (t->obedit==NULL || t->obedit->type != OB_MESH) { + if (t->obedit == NULL || t->obedit->type != OB_MESH) { initResize(t); } else { @@ -3785,7 +3785,7 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) t->values[0] = distance; - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -3818,12 +3818,12 @@ void initTilt(TransInfo *t) t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; - t->snap[1] = (float)((5.0/180)*M_PI); + t->snap[1] = (float)((5.0 / 180) * M_PI); t->snap[2] = t->snap[1] * 0.2f; t->num.increment = t->snap[1]; - t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; + t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } @@ -3855,7 +3855,7 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2])) sprintf(str, "Tilt: %.2f %s", RAD2DEGF(final), t->proptext); } - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -3922,7 +3922,7 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) sprintf(str, "Shrink/Fatten: %3f", ratio); } - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -3930,7 +3930,7 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) continue; if (td->val) { - *td->val= td->ival*ratio; + *td->val = td->ival * ratio; /* apply PET */ *td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival); if (*td->val <= 0.0f) *td->val = 0.001f; @@ -3990,7 +3990,7 @@ int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) sprintf(str, "Shrink/Fatten: %3f", ratio); } - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -4064,7 +4064,7 @@ int PushPull(TransInfo *t, const int UNUSED(mval[2])) t->con.applyRot(t, NULL, axis, NULL); } - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -4137,28 +4137,28 @@ int handleEventBevel(TransInfo *t, wmEvent *event) if (!G.editBMesh) return 0; switch (event->type) { - case MIDDLEMOUSE: - G.editBMesh->options ^= BME_BEVEL_VERT; - t->state = TRANS_CANCEL; - return 1; - //case PADPLUSKEY: - // G.editBMesh->options ^= BME_BEVEL_RES; - // G.editBMesh->res += 1; - // if (G.editBMesh->res > 4) { - // G.editBMesh->res = 4; - // } - // t->state = TRANS_CANCEL; - // return 1; - //case PADMINUS: - // G.editBMesh->options ^= BME_BEVEL_RES; - // G.editBMesh->res -= 1; - // if (G.editBMesh->res < 0) { - // G.editBMesh->res = 0; - // } - // t->state = TRANS_CANCEL; - // return 1; - default: - return 0; + case MIDDLEMOUSE: + G.editBMesh->options ^= BME_BEVEL_VERT; + t->state = TRANS_CANCEL; + return 1; + //case PADPLUSKEY: + // G.editBMesh->options ^= BME_BEVEL_RES; + // G.editBMesh->res += 1; + // if (G.editBMesh->res > 4) { + // G.editBMesh->res = 4; + // } + // t->state = TRANS_CANCEL; + // return 1; + //case PADMINUS: + // G.editBMesh->options ^= BME_BEVEL_RES; + // G.editBMesh->res -= 1; + // if (G.editBMesh->res < 0) { + // G.editBMesh->res = 0; + // } + // t->state = TRANS_CANCEL; + // return 1; + default: + return 0; } } return 0; @@ -4195,7 +4195,7 @@ int Bevel(TransInfo *t, const int UNUSED(mval[2])) } if (distance < 0) distance = -distance; - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->axismtx[1][0] > 0 && distance > td->axismtx[1][0]) { d = td->axismtx[1][0]; } @@ -4229,7 +4229,7 @@ void initBevelWeight(TransInfo *t) t->num.increment = t->snap[1]; - t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; + t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } int BevelWeight(TransInfo *t, const int UNUSED(mval[2])) @@ -4267,7 +4267,7 @@ int BevelWeight(TransInfo *t, const int UNUSED(mval[2])) sprintf(str, "Bevel Weight: %.3f %s", weight, t->proptext); } - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -4302,7 +4302,7 @@ void initCrease(TransInfo *t) t->num.increment = t->snap[1]; - t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; + t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } int Crease(TransInfo *t, const int UNUSED(mval[2])) @@ -4340,7 +4340,7 @@ int Crease(TransInfo *t, const int UNUSED(mval[2])) sprintf(str, "Crease: %.3f %s", crease, t->proptext); } - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -4418,11 +4418,11 @@ static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3]) } /* we've tucked the scale in loc */ - oldy= td->iloc[1]; + oldy = td->iloc[1]; size_to_mat3(sizemat, td->iloc); mul_m3_m3m3(tmat, tmat, sizemat); mat3_to_size(td->loc, tmat); - td->loc[1]= oldy; + td->loc[1] = oldy; } int BoneSize(TransInfo *t, const int mval[2]) @@ -4435,8 +4435,8 @@ int BoneSize(TransInfo *t, const int mval[2]) // TRANSFORM_FIX_ME MOVE TO MOUSE INPUT /* for manipulator, center handle, the scaling can't be done relative to center */ - if ((t->flag & T_USES_MANIPULATOR) && t->con.mode==0) { - ratio = 1.0f - ((t->imval[0] - mval[0]) + (t->imval[1] - mval[1]))/100.0f; + if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) { + ratio = 1.0f - ((t->imval[0] - mval[0]) + (t->imval[1] - mval[1])) / 100.0f; } else { ratio = t->values[0]; @@ -4457,11 +4457,11 @@ int BoneSize(TransInfo *t, const int mval[2]) t->con.applySize(t, NULL, mat); } - copy_m3_m3(t->mat, mat); // used in manipulator + copy_m3_m3(t->mat, mat); // used in manipulator headerBoneSize(t, size, str); - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -4496,7 +4496,7 @@ void initBoneEnvelope(TransInfo *t) t->num.increment = t->snap[1]; - t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; + t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) @@ -4523,7 +4523,7 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) sprintf(str, "Envelope: %3f", ratio); } - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -4533,9 +4533,9 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) if (td->val) { /* if the old/original value was 0.0f, then just use ratio */ if (td->ival) - *td->val= td->ival*ratio; + *td->val = td->ival * ratio; else - *td->val= ratio; + *td->val = ratio; } } @@ -4565,7 +4565,7 @@ static BMLoop *get_next_loop(BMVert *v, BMLoop *l, { BMLoop *firstl; float a[3] = {0.0f, 0.0f, 0.0f}, n[3] = {0.0f, 0.0f, 0.0f}; - int i=0; + int i = 0; firstl = l; do { @@ -4823,7 +4823,7 @@ static int createSlideVerts(TransInfo *t) sv->down = BM_edge_other_vert(l->e, v); } - v2=v, v = BM_edge_other_vert(e, v); + v2 = v, v = BM_edge_other_vert(e, v); e1 = e; e = get_other_edge(v, e); @@ -4880,8 +4880,8 @@ static int createSlideVerts(TransInfo *t) /* search cross edges for visible edge to the mouse cursor, * then use the shared vertex to calculate screen vector*/ dis2 = -1.0f; - for (i=0; i<2; i++) { - v = i?e->v1:e->v2; + for (i = 0; i < 2; i++) { + v = i ? e->v1 : e->v2; BM_ITER_ELEM (e2, &iter2, v, BM_EDGES_OF_VERT) { if (BM_elem_flag_test(e2, BM_ELEM_SELECT)) continue; @@ -4923,7 +4923,7 @@ static int createSlideVerts(TransInfo *t) /*create copies of faces for customdata projection*/ sv_array = sld->sv; - for (i=0; itotsv; i++, sv_array++) { + for (i = 0; i < sld->totsv; i++, sv_array++) { BMIter fiter, liter; BMFace *f; BMLoop *l; @@ -4999,7 +4999,7 @@ void projectSVData(TransInfo *t, int final) BLI_smallhash_init(&visit); - for (i=0, sv = sld->sv; i < sld->totsv; sv++, i++) { + for (i = 0, sv = sld->sv; i < sld->totsv; sv++, i++) { BMIter fiter; BMFace *f; @@ -5065,7 +5065,7 @@ void projectSVData(TransInfo *t, int final) BMEdge *e_sel; BM_ITER_ELEM (e_sel, &eiter, l->v, BM_EDGES_OF_VERT) { - if (BM_elem_flag_test(e_sel, BM_ELEM_SELECT)) {; + if (BM_elem_flag_test(e_sel, BM_ELEM_SELECT)) { break; } } @@ -5131,7 +5131,7 @@ void freeSlideTempFaces(SlideData *sld) BMFace *copyf; copyf = BLI_smallhash_iternew(&sld->origfaces, &hiter, NULL); - for (; copyf; copyf=BLI_smallhash_iternext(&hiter, NULL)) { + for (; copyf; copyf = BLI_smallhash_iternext(&hiter, NULL)) { BM_face_verts_kill(sld->em->bm, copyf); } @@ -5152,7 +5152,7 @@ void freeSlideVerts(TransInfo *t) LinkNode *look = sld->vertlist; GHash *vertgh = sld->vhash; while (look) { - sv = BLI_ghash_lookup(vertgh, (EditVert*)look->link); + sv = BLI_ghash_lookup(vertgh, (EditVert *)look->link); if (sv != NULL) { sv->up->f &= !SELECT; sv->down->f &= !SELECT; @@ -5188,7 +5188,7 @@ void initEdgeSlide(TransInfo *t) t->handleEvent = handleEventEdgeSlide; if (!createSlideVerts(t)) { - t->state= TRANS_CANCEL; + t->state = TRANS_CANCEL; return; } @@ -5211,7 +5211,7 @@ void initEdgeSlide(TransInfo *t) t->num.increment = t->snap[1]; - t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; + t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } int handleEventEdgeSlide(struct TransInfo *t, struct wmEvent *event) @@ -5340,7 +5340,7 @@ static int doEdgeSlide(TransInfo *t, float perc) sld->perc = perc; sv = svlist; - for (i=0; itotsv; i++, sv++) { + for (i = 0; i < sld->totsv; i++, sv++) { if (sld->is_proportional == FALSE) { TransDataSlideVert *curr_sv = &sld->sv[sld->curr_sv_index]; float cur_sel = curr_sv->edge_len; @@ -5405,11 +5405,11 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2])) outputNumInput(&(t->num), c); BLI_snprintf(str, sizeof(str), "Edge Slide: %s (E)ven: %s, (F)lipped: %s", - &c[0], !is_proportional ? "ON" : "OFF", flipped ? "ON" : "OFF" ); + &c[0], !is_proportional ? "ON" : "OFF", flipped ? "ON" : "OFF"); } else { BLI_snprintf(str, sizeof(str), "Edge Slide: %.2f (E)ven: %s, (F)lipped: %s", - final, !is_proportional ? "ON" : "OFF", flipped ? "ON" : "OFF" ); + final, !is_proportional ? "ON" : "OFF", flipped ? "ON" : "OFF"); } CLAMP(final, -1.0f, 1.0f); @@ -5443,12 +5443,12 @@ void initBoneRoll(TransInfo *t) t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; - t->snap[1] = (float)((5.0/180)*M_PI); + t->snap[1] = (float)((5.0 / 180) * M_PI); t->snap[2] = t->snap[1] * 0.2f; t->num.increment = 1.0f; - t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; + t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } int BoneRoll(TransInfo *t, const int UNUSED(mval[2])) @@ -5523,11 +5523,11 @@ int BakeTime(TransInfo *t, const int mval[2]) if (t->mouse.precision) { /* calculate ratio for shiftkey pos, and for total, and blend these for precision */ - time= (float)(t->center2d[0] - t->mouse.precision_mval[0]) * fac; - time+= 0.1f*((float)(t->center2d[0]*fac - mval[0]) -time); + time = (float)(t->center2d[0] - t->mouse.precision_mval[0]) * fac; + time += 0.1f * ((float)(t->center2d[0] * fac - mval[0]) - time); } else { - time = (float)(t->center2d[0] - mval[0])*fac; + time = (float)(t->center2d[0] - mval[0]) * fac; } snapGrid(t, &time); @@ -5553,7 +5553,7 @@ int BakeTime(TransInfo *t, const int mval[2]) sprintf(str, "Time: %.3f %s", time, t->proptext); } - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -5612,7 +5612,7 @@ int Mirror(TransInfo *t, const int UNUSED(mval[2])) sprintf(str, "Mirror%s", t->con.text); - for (i = 0, td=t->data; i < t->total; i++, td++) { + for (i = 0, td = t->data; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -5631,7 +5631,7 @@ int Mirror(TransInfo *t, const int UNUSED(mval[2])) size_to_mat3(mat, size); - for (i = 0, td=t->data; i < t->total; i++, td++) { + for (i = 0, td = t->data; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -5672,7 +5672,7 @@ int Align(TransInfo *t, const int UNUSED(mval[2])) /* saving original center */ copy_v3_v3(center, t->center); - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { float mat[3][3], invmat[3][3]; if (td->flag & TD_NOACTION) @@ -5682,7 +5682,7 @@ int Align(TransInfo *t, const int UNUSED(mval[2])) continue; /* around local centers */ - if (t->flag & (T_OBJECT|T_POSE)) { + if (t->flag & (T_OBJECT | T_POSE)) { copy_v3_v3(t->center, td->center); } else { @@ -5746,7 +5746,7 @@ static void applySeqSlide(TransInfo *t, float val[2]) TransData *td = t->data; int i; - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { float tvec[2]; if (td->flag & TD_NOACTION) @@ -5803,38 +5803,38 @@ int SeqSlide(TransInfo *t, const int UNUSED(mval[2])) // XXX these modifier checks should be keymappable static short getAnimEdit_SnapMode(TransInfo *t) { - short autosnap= SACTSNAP_OFF; + short autosnap = SACTSNAP_OFF; if (t->spacetype == SPACE_ACTION) { - SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; + SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first; if (saction) - autosnap= saction->autosnap; + autosnap = saction->autosnap; } else if (t->spacetype == SPACE_IPO) { - SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first; + SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; if (sipo) - autosnap= sipo->autosnap; + autosnap = sipo->autosnap; } else if (t->spacetype == SPACE_NLA) { - SpaceNla *snla= (SpaceNla *)t->sa->spacedata.first; + SpaceNla *snla = (SpaceNla *)t->sa->spacedata.first; if (snla) - autosnap= snla->autosnap; + autosnap = snla->autosnap; } else { - autosnap= SACTSNAP_OFF; + autosnap = SACTSNAP_OFF; } /* toggle autosnap on/off - * - when toggling on, prefer nearest frame over 1.0 frame increments + * - when toggling on, prefer nearest frame over 1.0 frame increments */ if (t->modifiers & MOD_SNAP_INVERT) { if (autosnap) - autosnap= SACTSNAP_OFF; + autosnap = SACTSNAP_OFF; else - autosnap= SACTSNAP_FRAME; + autosnap = SACTSNAP_FRAME; } return autosnap; @@ -5849,19 +5849,19 @@ static short getAnimEdit_DrawTime(TransInfo *t) short drawtime; if (t->spacetype == SPACE_ACTION) { - SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; + SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first; - drawtime = (saction->flag & SACTION_DRAWTIME)? 1 : 0; + drawtime = (saction->flag & SACTION_DRAWTIME) ? 1 : 0; } else if (t->spacetype == SPACE_NLA) { - SpaceNla *snla= (SpaceNla *)t->sa->spacedata.first; + SpaceNla *snla = (SpaceNla *)t->sa->spacedata.first; - drawtime = (snla->flag & SNLA_DRAWTIME)? 1 : 0; + drawtime = (snla->flag & SNLA_DRAWTIME) ? 1 : 0; } else if (t->spacetype == SPACE_IPO) { - SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first; + SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; - drawtime = (sipo->flag & SIPO_DRAWTIME)? 1 : 0; + drawtime = (sipo->flag & SIPO_DRAWTIME) ? 1 : 0; } else { drawtime = 0; @@ -5881,23 +5881,23 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d, #if 0 /* 'do_time' disabled for now */ - const Scene *scene= t->scene; - const short do_time= 0; //getAnimEdit_DrawTime(t); // NOTE: this works, but may be confusing behavior given the option's label, hence disabled - const double secf= FPS; + const Scene *scene = t->scene; + const short do_time = 0; //getAnimEdit_DrawTime(t); // NOTE: this works, but may be confusing behavior given the option's label, hence disabled + const double secf = FPS; #endif double val; /* convert frame to nla-action time (if needed) */ if (adt) - val= BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP); + val = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP); else - val= *(td->val); + val = *(td->val); -#if 0 /* 'do_time' disabled for now */ +#if 0 /* 'do_time' disabled for now */ /* do the snapping to nearest frame/second */ if (do_time) { - val= (float)(floor((val/secf) + 0.5f) * secf); + val = (float)(floor((val / secf) + 0.5f) * secf); } else #endif @@ -5907,9 +5907,9 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d, /* convert frame out of nla-action time */ if (adt) - *(td->val)= BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP); + *(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP); else - *(td->val)= val; + *(td->val) = val; } /* snap key to nearest marker? */ else if (autosnap == SACTSNAP_MARKER) { @@ -5917,19 +5917,19 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d, /* convert frame to nla-action time (if needed) */ if (adt) - val= BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP); + val = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP); else - val= *(td->val); + val = *(td->val); /* snap to nearest marker */ // TODO: need some more careful checks for where data comes from - val= (float)ED_markers_find_nearest_marker_time(&t->scene->markers, val); + val = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, val); /* convert frame out of nla-action time */ if (adt) - *(td->val)= BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP); + *(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP); else - *(td->val)= val; + *(td->val) = val; } /* if the handles are to be moved too (as side-effect of keyframes moving, to keep the general effect) @@ -5980,21 +5980,21 @@ static void headerTimeTranslate(TransInfo *t, char *str) } else { const Scene *scene = t->scene; - const short autosnap= getAnimEdit_SnapMode(t); + const short autosnap = getAnimEdit_SnapMode(t); const short do_time = getAnimEdit_DrawTime(t); - const double secf= FPS; + const double secf = FPS; float val = t->values[0]; /* apply snapping + frame->seconds conversions */ if (autosnap == SACTSNAP_STEP) { if (do_time) - val= floorf((double)val / secf + 0.5); + val = floorf((double)val / secf + 0.5); else - val= floorf(val + 0.5f); + val = floorf(val + 0.5f); } else { if (do_time) - val= (float)((double)val / secf); + val = (float)((double)val / secf); } if (autosnap == SACTSNAP_FRAME) @@ -6013,20 +6013,20 @@ static void applyTimeTranslate(TransInfo *t, float UNUSED(sval)) Scene *scene = t->scene; int i; - const short do_time= getAnimEdit_DrawTime(t); - const double secf= FPS; + const short do_time = getAnimEdit_DrawTime(t); + const double secf = FPS; - const short autosnap= getAnimEdit_SnapMode(t); + const short autosnap = getAnimEdit_SnapMode(t); float deltax, val /* , valprev */; /* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */ - for (i = 0 ; i < t->total; i++, td++, td2d++) { + for (i = 0; i < t->total; i++, td++, td2d++) { /* it is assumed that td->extra is a pointer to the AnimData, * whose active action is where this keyframe comes from * (this is only valid when not in NLA) */ - AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL; + AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL; /* valprev = *td->val; */ /* UNUSED */ @@ -6097,7 +6097,7 @@ void initTimeSlide(TransInfo *t) { /* this tool is only really available in the Action Editor... */ if (t->spacetype == SPACE_ACTION) { - SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; + SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first; /* set flag for drawing stuff */ saction->flag |= SACTION_MOVING; @@ -6133,12 +6133,12 @@ static void headerTimeSlide(TransInfo *t, float sval, char *str) outputNumInput(&(t->num), tvec); } else { - float minx= *((float *)(t->customData)); - float maxx= *((float *)(t->customData) + 1); - float cval= t->values[0]; + float minx = *((float *)(t->customData)); + float maxx = *((float *)(t->customData) + 1); + float cval = t->values[0]; float val; - val= 2.0f*(cval-sval) / (maxx-minx); + val = 2.0f * (cval - sval) / (maxx - minx); CLAMP(val, -1.0f, 1.0f); sprintf(&tvec[0], "%.4f", val); @@ -6152,43 +6152,43 @@ static void applyTimeSlide(TransInfo *t, float sval) TransData *td = t->data; int i; - float minx= *((float *)(t->customData)); - float maxx= *((float *)(t->customData) + 1); + float minx = *((float *)(t->customData)); + float maxx = *((float *)(t->customData) + 1); /* set value for drawing black line */ if (t->spacetype == SPACE_ACTION) { - SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; + SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first; float cvalf = t->values[0]; - saction->timeslide= cvalf; + saction->timeslide = cvalf; } /* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */ - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { /* it is assumed that td->extra is a pointer to the AnimData, * whose active action is where this keyframe comes from * (this is only valid when not in NLA) */ - AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL; + AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL; float cval = t->values[0]; /* apply NLA-mapping to necessary values */ if (adt) - cval= BKE_nla_tweakedit_remap(adt, cval, NLATIME_CONVERT_UNMAP); + cval = BKE_nla_tweakedit_remap(adt, cval, NLATIME_CONVERT_UNMAP); /* only apply to data if in range */ if ((sval > minx) && (sval < maxx)) { - float cvalc= CLAMPIS(cval, minx, maxx); + float cvalc = CLAMPIS(cval, minx, maxx); float timefac; /* left half? */ if (td->ival < sval) { - timefac= (sval - td->ival) / (sval - minx); - *(td->val)= cvalc - timefac * (cvalc - minx); + timefac = (sval - td->ival) / (sval - minx); + *(td->val) = cvalc - timefac * (cvalc - minx); } else { - timefac= (td->ival - sval) / (maxx - sval); - *(td->val)= cvalc + timefac * (maxx - cvalc); + timefac = (td->ival - sval) / (maxx - sval); + *(td->val) = cvalc + timefac * (maxx - cvalc); } } } @@ -6198,8 +6198,8 @@ int TimeSlide(TransInfo *t, const int mval[2]) { View2D *v2d = (View2D *)t->view; float cval[2], sval[2]; - float minx= *((float *)(t->customData)); - float maxx= *((float *)(t->customData) + 1); + float minx = *((float *)(t->customData)); + float maxx = *((float *)(t->customData) + 1); char str[200]; /* calculate mouse co-ordinates */ @@ -6211,9 +6211,9 @@ int TimeSlide(TransInfo *t, const int mval[2]) t->values[0] = cval[0]; /* handle numeric-input stuff */ - t->vec[0] = 2.0f*(cval[0]-sval[0]) / (maxx-minx); + t->vec[0] = 2.0f * (cval[0] - sval[0]) / (maxx - minx); applyNumInput(&t->num, &t->vec[0]); - t->values[0] = (maxx-minx) * t->vec[0] / 2.0f + sval[0]; + t->values[0] = (maxx - minx) * t->vec[0] / 2.0f + sval[0]; headerTimeSlide(t, sval[0], str); applyTimeSlide(t, sval[0]); @@ -6286,19 +6286,19 @@ static void applyTimeScale(TransInfo *t) TransData2D *td2d = t->data2d; int i; - const short autosnap= getAnimEdit_SnapMode(t); - const short do_time= getAnimEdit_DrawTime(t); - const double secf= FPS; + const short autosnap = getAnimEdit_SnapMode(t); + const short do_time = getAnimEdit_DrawTime(t); + const double secf = FPS; - for (i = 0 ; i < t->total; i++, td++, td2d++) { + for (i = 0; i < t->total; i++, td++, td2d++) { /* it is assumed that td->extra is a pointer to the AnimData, * whose active action is where this keyframe comes from * (this is only valid when not in NLA) */ - AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL; - float startx= CFRA; - float fac= t->values[0]; + AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL; + float startx = CFRA; + float fac = t->values[0]; if (autosnap == SACTSNAP_STEP) { if (do_time) @@ -6309,7 +6309,7 @@ static void applyTimeScale(TransInfo *t) /* check if any need to apply nla-mapping */ if (adt) - startx= BKE_nla_tweakedit_remap(adt, startx, NLATIME_CONVERT_UNMAP); + startx = BKE_nla_tweakedit_remap(adt, startx, NLATIME_CONVERT_UNMAP); /* now, calculate the new value */ *(td->val) = ((td->ival - startx) * fac) + startx; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 007ec3c5250..95a9ab5900a 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -107,7 +107,7 @@ #include "ED_mask.h" #include "ED_util.h" /* for crazyspace correction */ -#include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */ +#include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */ #include "WM_types.h" #include "UI_view2d.h" @@ -162,10 +162,10 @@ static void qsort_trans_data(TransInfo *t, TransData *head, TransData *tail, Tra *head = *temp; if (ihead < head) { - qsort_trans_data(t, ihead, head-1, temp); + qsort_trans_data(t, ihead, head - 1, temp); } if (itail > head) { - qsort_trans_data(t, head+1, itail, temp); + qsort_trans_data(t, head + 1, itail, temp); } } @@ -217,18 +217,18 @@ static void set_prop_dist(TransInfo *t, short with_dist) TransData *tob; int a; - for (a=0, tob= t->data; atotal; a++, tob++) { + for (a = 0, tob = t->data; a < t->total; a++, tob++) { - tob->rdist= 0.0f; // init, it was mallocced + tob->rdist = 0.0f; // init, it was mallocced - if ((tob->flag & TD_SELECTED)==0) { + if ((tob->flag & TD_SELECTED) == 0) { TransData *td; int i; float dist, vec[3]; tob->rdist = -1.0f; // signal for next loop - for (i = 0, td= t->data; i < t->total; i++, td++) { + for (i = 0, td = t->data; i < t->total; i++, td++) { if (td->flag & TD_SELECTED) { sub_v3_v3v3(vec, tob->center, td->center); mul_m3_v3(tob->mtx, vec); @@ -240,7 +240,7 @@ static void set_prop_dist(TransInfo *t, short with_dist) tob->rdist = dist; } } - else break; // by definition transdata has selected items in beginning + else break; // by definition transdata has selected items in beginning } if (with_dist) { tob->dist = tob->rdist; @@ -269,16 +269,16 @@ static void createTransTexspace(TransInfo *t) } id = ob->data; - if (id == NULL || !ELEM3(GS(id->name), ID_ME, ID_CU, ID_MB )) { + if (id == NULL || !ELEM3(GS(id->name), ID_ME, ID_CU, ID_MB)) { t->total = 0; return; } t->total = 1; - td= t->data= MEM_callocN(sizeof(TransData), "TransTexspace"); - td->ext= t->ext= MEM_callocN(sizeof(TransDataExtension), "TransTexspace"); + td = t->data = MEM_callocN(sizeof(TransData), "TransTexspace"); + td->ext = t->ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace"); - td->flag= TD_SELECTED; + td->flag = TD_SELECTED; copy_v3_v3(td->center, ob->obmat[3]); td->ob = ob; @@ -306,7 +306,7 @@ static void createTransEdge(TransInfo *t) BMEdge *eed; BMIter iter; float mtx[3][3], smtx[3][3]; - int count=0, countsel=0; + int count = 0, countsel = 0; int propmode = t->flag & T_PROP_EDIT; BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { @@ -326,7 +326,7 @@ static void createTransEdge(TransInfo *t) t->total = countsel; } - td= t->data= MEM_callocN(t->total * sizeof(TransData), "TransCrease"); + td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransCrease"); copy_m3_m4(mtx, t->obedit->obmat); invert_m3_m3(smtx, mtx); @@ -340,11 +340,11 @@ static void createTransEdge(TransInfo *t) add_v3_v3v3(td->center, eed->v1->co, eed->v2->co); mul_v3_fl(td->center, 0.5f); - td->loc= NULL; + td->loc = NULL; if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) - td->flag= TD_SELECTED; + td->flag = TD_SELECTED; else - td->flag= 0; + td->flag = 0; copy_m3_m3(td->smtx, smtx); @@ -369,15 +369,15 @@ static void createTransEdge(TransInfo *t) static bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan) { - bConstraint *con= pchan->constraints.first; + bConstraint *con = pchan->constraints.first; - for (;con; con= con->next) { - if (con->type==CONSTRAINT_TYPE_KINEMATIC && (con->enforce!=0.0f)) { - bKinematicConstraint *data= con->data; + for (; con; con = con->next) { + if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) { + bKinematicConstraint *data = con->data; - if (data->tar==NULL) + if (data->tar == NULL) return data; - if (data->tar->type==OB_ARMATURE && data->subtarget[0]==0) + if (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0) return data; } } @@ -388,44 +388,44 @@ static short apply_targetless_ik(Object *ob) { bPoseChannel *pchan, *parchan, *chanlist[256]; bKinematicConstraint *data; - int segcount, apply= 0; + int segcount, apply = 0; /* now we got a difficult situation... we have to find the * target-less IK pchans, and apply transformation to the all * pchans that were in the chain */ - for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) { - data= has_targetless_ik(pchan); + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + data = has_targetless_ik(pchan); if (data && (data->flag & CONSTRAINT_IK_AUTO)) { /* fill the array with the bones of the chain (armature.c does same, keep it synced) */ - segcount= 0; + segcount = 0; /* exclude tip from chain? */ if (!(data->flag & CONSTRAINT_IK_TIP)) - parchan= pchan->parent; + parchan = pchan->parent; else - parchan= pchan; + parchan = pchan; /* Find the chain's root & count the segments needed */ - for (; parchan; parchan=parchan->parent) { - chanlist[segcount]= parchan; + for (; parchan; parchan = parchan->parent) { + chanlist[segcount] = parchan; segcount++; - if (segcount==data->rootbone || segcount>255) break; // 255 is weak + if (segcount == data->rootbone || segcount > 255) break; // 255 is weak } - for (;segcount;segcount--) { + for (; segcount; segcount--) { Bone *bone; - float rmat[4][4]/*, tmat[4][4], imat[4][4]*/; + float rmat[4][4] /*, tmat[4][4], imat[4][4]*/; /* pose_mat(b) = pose_mat(b-1) * offs_bone * channel * constraint * IK */ /* we put in channel the entire result of rmat= (channel * constraint * IK) */ /* pose_mat(b) = pose_mat(b-1) * offs_bone * rmat */ /* rmat = pose_mat(b) * inv(pose_mat(b-1) * offs_bone ) */ - parchan= chanlist[segcount-1]; - bone= parchan->bone; - bone->flag |= BONE_TRANSFORM; /* ensures it gets an auto key inserted */ + parchan = chanlist[segcount - 1]; + bone = parchan->bone; + bone->flag |= BONE_TRANSFORM; /* ensures it gets an auto key inserted */ BKE_armature_mat_pose_to_bone(parchan, parchan->pose_mat, rmat); @@ -436,11 +436,11 @@ static short apply_targetless_ik(Object *ob) copy_m3_m4(rmat3, rmat); /* rotation */ - /* [#22409] is partially caused by this, as slight numeric error introduced during - * the solving process leads to locked-axis values changing. However, we cannot modify - * the values here, or else there are huge discreptancies between IK-solver (interactive) - * and applied poses. - */ + /* [#22409] is partially caused by this, as slight numeric error introduced during + * the solving process leads to locked-axis values changing. However, we cannot modify + * the values here, or else there are huge discreptancies between IK-solver (interactive) + * and applied poses. + */ if (parchan->rotmode > 0) mat3_to_eulO(parchan->eul, parchan->rotmode, rmat3); else if (parchan->rotmode == ROT_MODE_AXISANGLE) @@ -470,7 +470,7 @@ static short apply_targetless_ik(Object *ob) } - apply= 1; + apply = 1; data->flag &= ~CONSTRAINT_IK_AUTO; } } @@ -480,7 +480,7 @@ static short apply_targetless_ik(Object *ob) static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td) { - Bone *bone= pchan->bone; + Bone *bone = pchan->bone; float pmat[3][3], omat[3][3]; float cmat[3][3], tmat[3][3]; float vec[3]; @@ -499,40 +499,40 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->flag |= TD_NO_LOC; } - td->protectflag= pchan->protectflag; + td->protectflag = pchan->protectflag; td->loc = pchan->loc; copy_v3_v3(td->iloc, pchan->loc); - td->ext->size= pchan->size; + td->ext->size = pchan->size; copy_v3_v3(td->ext->isize, pchan->size); if (pchan->rotmode > 0) { - td->ext->rot= pchan->eul; - td->ext->rotAxis= NULL; - td->ext->rotAngle= NULL; - td->ext->quat= NULL; + td->ext->rot = pchan->eul; + td->ext->rotAxis = NULL; + td->ext->rotAngle = NULL; + td->ext->quat = NULL; copy_v3_v3(td->ext->irot, pchan->eul); } else if (pchan->rotmode == ROT_MODE_AXISANGLE) { - td->ext->rot= NULL; - td->ext->rotAxis= pchan->rotAxis; - td->ext->rotAngle= &pchan->rotAngle; - td->ext->quat= NULL; + td->ext->rot = NULL; + td->ext->rotAxis = pchan->rotAxis; + td->ext->rotAngle = &pchan->rotAngle; + td->ext->quat = NULL; - td->ext->irotAngle= pchan->rotAngle; + td->ext->irotAngle = pchan->rotAngle; copy_v3_v3(td->ext->irotAxis, pchan->rotAxis); } else { - td->ext->rot= NULL; - td->ext->rotAxis= NULL; - td->ext->rotAngle= NULL; - td->ext->quat= pchan->quat; + td->ext->rot = NULL; + td->ext->rotAxis = NULL; + td->ext->rotAngle = NULL; + td->ext->quat = pchan->quat; copy_qt_qt(td->ext->iquat, pchan->quat); } - td->ext->rotOrder= pchan->rotmode; + td->ext->rotOrder = pchan->rotmode; /* proper way to get parent transform + own transform + constraints transform */ @@ -559,11 +559,11 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr copy_m3_m4(tmat, pchan->constinv); invert_m3_m3(cmat, tmat); mul_serie_m3(td->mtx, pmat, omat, cmat, NULL, NULL, NULL, NULL, NULL); - mul_serie_m3(td->ext->r_mtx, rpmat, omat, cmat, NULL,NULL,NULL,NULL,NULL); + mul_serie_m3(td->ext->r_mtx, rpmat, omat, cmat, NULL, NULL, NULL, NULL, NULL); } else { - mul_serie_m3(td->mtx, pmat, omat, NULL, NULL,NULL,NULL,NULL,NULL); - mul_serie_m3(td->ext->r_mtx, rpmat, omat, NULL, NULL,NULL,NULL,NULL,NULL); + mul_serie_m3(td->mtx, pmat, omat, NULL, NULL, NULL, NULL, NULL, NULL); + mul_serie_m3(td->ext->r_mtx, rpmat, omat, NULL, NULL, NULL, NULL, NULL, NULL); } invert_m3_m3(td->ext->r_smtx, td->ext->r_mtx); } @@ -588,25 +588,25 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr mul_m3_m3m3(td->axismtx, omat, pmat); normalize_m3(td->axismtx); - if (t->mode==TFM_BONESIZE) { - bArmature *arm= t->poseobj->data; + if (t->mode == TFM_BONESIZE) { + bArmature *arm = t->poseobj->data; - if (arm->drawtype==ARM_ENVELOPE) { - td->loc= NULL; - td->val= &bone->dist; - td->ival= bone->dist; + if (arm->drawtype == ARM_ENVELOPE) { + td->loc = NULL; + td->val = &bone->dist; + td->ival = bone->dist; } else { // abusive storage of scale in the loc pointer :) - td->loc= &bone->xwidth; + td->loc = &bone->xwidth; copy_v3_v3(td->iloc, td->loc); - td->val= NULL; + td->val = NULL; } } /* in this case we can do target-less IK grabbing */ - if (t->mode==TFM_TRANSLATION) { - bKinematicConstraint *data= has_targetless_ik(pchan); + if (t->mode == TFM_TRANSLATION) { + bKinematicConstraint *data = has_targetless_ik(pchan); if (data) { if (data->flag & CONSTRAINT_IK_TIP) { copy_v3_v3(data->grabtarget, pchan->pose_tail); @@ -625,14 +625,14 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr } /* store reference to first constraint */ - td->con= pchan->constraints.first; + td->con = pchan->constraints.first; } static void bone_children_clear_transflag(int mode, short around, ListBase *lb) { - Bone *bone= lb->first; + Bone *bone = lb->first; - for ( ; bone;bone= bone->next) { + for (; bone; bone = bone->next) { if ((bone->flag & BONE_HINGE) && (bone->flag & BONE_CONNECTED)) { bone->flag |= BONE_HINGE_CHILD_TRANSFORM; } @@ -654,7 +654,7 @@ static void bone_children_clear_transflag(int mode, short around, ListBase *lb) * returns total number of bones with BONE_TRANSFORM */ int count_set_pose_transflags(int *out_mode, short around, Object *ob) { - bArmature *arm= ob->data; + bArmature *arm = ob->data; bPoseChannel *pchan; Bone *bone; int mode = *out_mode; @@ -699,7 +699,7 @@ int count_set_pose_transflags(int *out_mode, short around, Object *ob) if (pchan->bone->flag & BONE_HINGE_CHILD_TRANSFORM) hastranslation = 1; } - else if ((pchan->protectflag & OB_LOCK_LOC)!=OB_LOCK_LOC) + else if ((pchan->protectflag & OB_LOCK_LOC) != OB_LOCK_LOC) hastranslation = 1; } else @@ -720,26 +720,26 @@ int count_set_pose_transflags(int *out_mode, short around, Object *ob) /* -------- Auto-IK ---------- */ /* adjust pose-channel's auto-ik chainlen */ -static void pchan_autoik_adjust (bPoseChannel *pchan, short chainlen) +static void pchan_autoik_adjust(bPoseChannel *pchan, short chainlen) { bConstraint *con; /* don't bother to search if no valid constraints */ - if ((pchan->constflag & (PCHAN_HAS_IK|PCHAN_HAS_TARGET))==0) + if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) return; /* check if pchan has ik-constraint */ - for (con= pchan->constraints.first; con; con= con->next) { - if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce!=0.0f)) { - bKinematicConstraint *data= con->data; + for (con = pchan->constraints.first; con; con = con->next) { + if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) { + bKinematicConstraint *data = con->data; /* only accept if a temporary one (for auto-ik) */ if (data->flag & CONSTRAINT_IK_TEMP) { /* chainlen is new chainlen, but is limited by maximum chainlen */ - if ((chainlen==0) || (chainlen > data->max_rootbone)) - data->rootbone= data->max_rootbone; + if ((chainlen == 0) || (chainlen > data->max_rootbone)) + data->rootbone = data->max_rootbone; else - data->rootbone= chainlen; + data->rootbone = chainlen; } } } @@ -748,7 +748,7 @@ static void pchan_autoik_adjust (bPoseChannel *pchan, short chainlen) /* change the chain-length of auto-ik */ void transform_autoik_update(TransInfo *t, short mode) { - short *chainlen= &t->settings->autoik_chainlen; + short *chainlen = &t->settings->autoik_chainlen; bPoseChannel *pchan; /* mode determines what change to apply to chainlen */ @@ -766,7 +766,7 @@ void transform_autoik_update(TransInfo *t, short mode) return; /* apply to all pose-channels */ - for (pchan=t->poseobj->pose->chanbase.first; pchan; pchan=pchan->next) { + for (pchan = t->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) { pchan_autoik_adjust(pchan, *chainlen); } } @@ -778,17 +778,17 @@ static void pose_grab_with_ik_clear(Object *ob) bPoseChannel *pchan; bConstraint *con, *next; - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { /* clear all temporary lock flags */ - pchan->ikflag &= ~(BONE_IK_NO_XDOF_TEMP|BONE_IK_NO_YDOF_TEMP|BONE_IK_NO_ZDOF_TEMP); + pchan->ikflag &= ~(BONE_IK_NO_XDOF_TEMP | BONE_IK_NO_YDOF_TEMP | BONE_IK_NO_ZDOF_TEMP); - pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET); + pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_TARGET); /* remove all temporary IK-constraints added */ - for (con= pchan->constraints.first; con; con= next) { - next= con->next; - if (con->type==CONSTRAINT_TYPE_KINEMATIC) { - data= con->data; + for (con = pchan->constraints.first; con; con = next) { + next = con->next; + if (con->type == CONSTRAINT_TYPE_KINEMATIC) { + data = con->data; if (data->flag & CONSTRAINT_IK_TEMP) { BLI_remlink(&pchan->constraints, con); MEM_freeN(con->data); @@ -796,7 +796,7 @@ static void pose_grab_with_ik_clear(Object *ob) continue; } pchan->constflag |= PCHAN_HAS_IK; - if (data->tar==NULL || (data->tar->type==OB_ARMATURE && data->subtarget[0]==0)) + if (data->tar == NULL || (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0)) pchan->constflag |= PCHAN_HAS_TARGET; } } @@ -815,21 +815,21 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) return 0; /* Rule: not if there's already an IK on this channel */ - for (con= pchan->constraints.first; con; con= con->next) { - if (con->type==CONSTRAINT_TYPE_KINEMATIC) { - data= con->data; + for (con = pchan->constraints.first; con; con = con->next) { + if (con->type == CONSTRAINT_TYPE_KINEMATIC) { + data = con->data; - if (data->tar==NULL || (data->tar->type==OB_ARMATURE && data->subtarget[0]=='\0')) { + if (data->tar == NULL || (data->tar->type == OB_ARMATURE && data->subtarget[0] == '\0')) { /* make reference to constraint to base things off later (if it's the last targetless constraint encountered) */ targetless = (bKinematicConstraint *)con->data; /* but, if this is a targetless IK, we make it auto anyway (for the children loop) */ - if (con->enforce!=0.0f) { + if (con->enforce != 0.0f) { data->flag |= CONSTRAINT_IK_AUTO; /* if no chain length has been specified, just make things obey standard rotation locks too */ if (data->rootbone == 0) { - for (; pchan; pchan=pchan->parent) { + for (; pchan; pchan = pchan->parent) { /* here, we set ik-settings for bone from pchan->protectflag */ // XXX: careful with quats/axis-angle rotations where we're locking 4d components if (pchan->protectflag & OB_LOCK_ROTX) pchan->ikflag |= BONE_IK_NO_XDOF_TEMP; @@ -842,23 +842,23 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) } } - if ((con->flag & CONSTRAINT_DISABLE)==0 && (con->enforce!=0.0f)) + if ((con->flag & CONSTRAINT_DISABLE) == 0 && (con->enforce != 0.0f)) return 0; } } con = add_pose_constraint(NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC); - pchan->constflag |= (PCHAN_HAS_IK|PCHAN_HAS_TARGET); /* for draw, but also for detecting while pose solving */ - data= con->data; + pchan->constflag |= (PCHAN_HAS_IK | PCHAN_HAS_TARGET); /* for draw, but also for detecting while pose solving */ + data = con->data; if (targetless) { /* if exists, use values from last targetless (but disabled) IK-constraint as base */ *data = *targetless; } else - data->flag= CONSTRAINT_IK_TIP; - data->flag |= CONSTRAINT_IK_TEMP|CONSTRAINT_IK_AUTO; + data->flag = CONSTRAINT_IK_TIP; + data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO; copy_v3_v3(data->grabtarget, pchan->pose_tail); - data->rootbone= 0; /* watch-it! has to be 0 here, since we're still on the same bone for the first time through the loop [#25885] */ + data->rootbone = 0; /* watch-it! has to be 0 here, since we're still on the same bone for the first time through the loop [#25885] */ /* we only include bones that are part of a continual connected chain */ while (pchan) { @@ -879,7 +879,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) } /* make a copy of maximum chain-length */ - data->max_rootbone= data->rootbone; + data->max_rootbone = data->rootbone; return 1; } @@ -888,19 +888,19 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) static short pose_grab_with_ik_children(bPose *pose, Bone *bone) { Bone *bonec; - short wentdeeper=0, added=0; + short wentdeeper = 0, added = 0; /* go deeper if children & children are connected */ - for (bonec= bone->childbase.first; bonec; bonec= bonec->next) { + for (bonec = bone->childbase.first; bonec; bonec = bonec->next) { if (bonec->flag & BONE_CONNECTED) { - wentdeeper= 1; - added+= pose_grab_with_ik_children(pose, bonec); + wentdeeper = 1; + added += pose_grab_with_ik_children(pose, bonec); } } - if (wentdeeper==0) { - bPoseChannel *pchan= BKE_pose_channel_find_name(pose, bone->name); + if (wentdeeper == 0) { + bPoseChannel *pchan = BKE_pose_channel_find_name(pose, bone->name); if (pchan) - added+= pose_grab_with_ik_add(pchan); + added += pose_grab_with_ik_add(pchan); } return added; @@ -912,30 +912,30 @@ static short pose_grab_with_ik(Object *ob) bArmature *arm; bPoseChannel *pchan, *parent; Bone *bonec; - short tot_ik= 0; + short tot_ik = 0; - if ((ob==NULL) || (ob->pose==NULL) || (ob->mode & OB_MODE_POSE)==0) + if ((ob == NULL) || (ob->pose == NULL) || (ob->mode & OB_MODE_POSE) == 0) return 0; arm = ob->data; /* Rule: allow multiple Bones (but they must be selected, and only one ik-solver per chain should get added) */ - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->bone->layer & arm->layer) { if (pchan->bone->flag & BONE_SELECTED) { /* Rule: no IK for solitatry (unconnected) bones */ - for (bonec=pchan->bone->childbase.first; bonec; bonec=bonec->next) { + for (bonec = pchan->bone->childbase.first; bonec; bonec = bonec->next) { if (bonec->flag & BONE_CONNECTED) { break; } } - if ((pchan->bone->flag & BONE_CONNECTED)==0 && (bonec == NULL)) + if ((pchan->bone->flag & BONE_CONNECTED) == 0 && (bonec == NULL)) continue; /* rule: if selected Bone is not a root bone, it gets a temporal IK */ if (pchan->parent) { /* only adds if there's no IK yet (and no parent bone was selected) */ - for (parent= pchan->parent; parent; parent= parent->parent) { + for (parent = pchan->parent; parent; parent = parent->parent) { if (parent->bone->flag & BONE_SELECTED) break; } @@ -961,17 +961,17 @@ static void createTransPose(TransInfo *t, Object *ob) bPoseChannel *pchan; TransData *td; TransDataExtension *tdx; - short ik_on= 0; + short ik_on = 0; int i; - t->total= 0; + t->total = 0; /* check validity of state */ - arm= BKE_armature_from_object(ob); - if ((arm==NULL) || (ob->pose==NULL)) return; + arm = BKE_armature_from_object(ob); + if ((arm == NULL) || (ob->pose == NULL)) return; if (arm->flag & ARM_RESTPOS) { - if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE)==0) { + if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE) == 0) { // XXX use transform operator reports // BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled"); return; @@ -979,8 +979,8 @@ static void createTransPose(TransInfo *t, Object *ob) } /* do we need to add temporal IK chains? */ - if ((arm->flag & ARM_AUTO_IK) && t->mode==TFM_TRANSLATION) { - ik_on= pose_grab_with_ik(ob); + if ((arm->flag & ARM_AUTO_IK) && t->mode == TFM_TRANSLATION) { + ik_on = pose_grab_with_ik(ob); if (ik_on) t->flag |= T_AUTOIK; } @@ -990,26 +990,26 @@ static void createTransPose(TransInfo *t, Object *ob) if (t->total == 0) return; t->flag |= T_POSE; - t->poseobj= ob; /* we also allow non-active objects to be transformed, in weightpaint */ + t->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */ /* init trans data */ - td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransPoseBone"); - tdx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransPoseBoneExt"); - for (i=0; itotal; i++, td++, tdx++) { - td->ext= tdx; + td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransPoseBone"); + tdx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "TransPoseBoneExt"); + for (i = 0; i < t->total; i++, td++, tdx++) { + td->ext = tdx; td->val = NULL; } /* use pose channels to fill trans data */ - td= t->data; - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + td = t->data; + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->bone->flag & BONE_TRANSFORM) { add_pose_transdata(t, pchan, ob, td); td++; } } - if (td != (t->data+t->total)) { + if (td != (t->data + t->total)) { // XXX use transform operator reports // BKE_report(op->reports, RPT_DEBUG, "Bone selection count error"); } @@ -1023,18 +1023,18 @@ static void createTransPose(TransInfo *t, Object *ob) static void createTransArmatureVerts(TransInfo *t) { EditBone *ebo; - bArmature *arm= t->obedit->data; + bArmature *arm = t->obedit->data; ListBase *edbo = arm->edbo; TransData *td; float mtx[3][3], smtx[3][3], delta[3], bonemat[3][3]; /* special hack for envelope drawmode and scaling: - * to allow scaling the size of the envelope around single points, + * to allow scaling the size of the envelope around single points, * mode should become TFM_BONE_ENVELOPE in this case */ // TODO: maybe we need a separate hotkey for it, but this is consistent with 2.4x for now - if ((t->mode == TFM_RESIZE) && (arm->drawtype==ARM_ENVELOPE)) - t->mode= TFM_BONE_ENVELOPE; + if ((t->mode == TFM_RESIZE) && (arm->drawtype == ARM_ENVELOPE)) + t->mode = TFM_BONE_ENVELOPE; t->total = 0; for (ebo = edbo->first; ebo; ebo = ebo->next) { @@ -1061,19 +1061,19 @@ static void createTransArmatureVerts(TransInfo *t) copy_m3_m4(mtx, t->obedit->obmat); invert_m3_m3(smtx, mtx); - td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransEditBone"); + td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransEditBone"); for (ebo = edbo->first; ebo; ebo = ebo->next) { - ebo->oldlength = ebo->length; // length==0.0 on extrude, used for scaling radius of bone points + ebo->oldlength = ebo->length; // length==0.0 on extrude, used for scaling radius of bone points if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) { - if (t->mode==TFM_BONE_ENVELOPE) { + if (t->mode == TFM_BONE_ENVELOPE) { if (ebo->flag & BONE_ROOTSEL) { - td->val= &ebo->rad_head; - td->ival= *td->val; + td->val = &ebo->rad_head; + td->ival = *td->val; copy_v3_v3(td->center, ebo->head); - td->flag= TD_SELECTED; + td->flag = TD_SELECTED; copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); @@ -1085,10 +1085,10 @@ static void createTransArmatureVerts(TransInfo *t) td++; } if (ebo->flag & BONE_TIPSEL) { - td->val= &ebo->rad_tail; - td->ival= *td->val; + td->val = &ebo->rad_tail; + td->ival = *td->val; copy_v3_v3(td->center, ebo->tail); - td->flag= TD_SELECTED; + td->flag = TD_SELECTED; copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); @@ -1101,21 +1101,21 @@ static void createTransArmatureVerts(TransInfo *t) } } - else if (t->mode==TFM_BONESIZE) { + else if (t->mode == TFM_BONESIZE) { if (ebo->flag & BONE_SELECTED) { - if (arm->drawtype==ARM_ENVELOPE) { - td->loc= NULL; - td->val= &ebo->dist; - td->ival= ebo->dist; + if (arm->drawtype == ARM_ENVELOPE) { + td->loc = NULL; + td->val = &ebo->dist; + td->ival = ebo->dist; } else { // abusive storage of scale in the loc pointer :) - td->loc= &ebo->xwidth; + td->loc = &ebo->xwidth; copy_v3_v3(td->iloc, td->loc); - td->val= NULL; + td->val = NULL; } copy_v3_v3(td->center, ebo->head); - td->flag= TD_SELECTED; + td->flag = TD_SELECTED; /* use local bone matrix */ sub_v3_v3v3(delta, ebo->tail, ebo->head); @@ -1132,14 +1132,14 @@ static void createTransArmatureVerts(TransInfo *t) td++; } } - else if (t->mode==TFM_BONE_ROLL) { + else if (t->mode == TFM_BONE_ROLL) { if (ebo->flag & BONE_SELECTED) { - td->loc= NULL; - td->val= &(ebo->roll); - td->ival= ebo->roll; + td->loc = NULL; + td->val = &(ebo->roll); + td->ival = ebo->roll; copy_v3_v3(td->center, ebo->head); - td->flag= TD_SELECTED; + td->flag = TD_SELECTED; td->ext = NULL; td->ob = t->obedit; @@ -1150,11 +1150,11 @@ static void createTransArmatureVerts(TransInfo *t) else { if (ebo->flag & BONE_TIPSEL) { copy_v3_v3(td->iloc, ebo->tail); - copy_v3_v3(td->center, (t->around==V3D_LOCAL) ? ebo->head : td->iloc); - td->loc= ebo->tail; - td->flag= TD_SELECTED; + copy_v3_v3(td->center, (t->around == V3D_LOCAL) ? ebo->head : td->iloc); + td->loc = ebo->tail; + td->flag = TD_SELECTED; if (ebo->flag & BONE_EDITMODE_LOCKED) - td->protectflag = OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE; + td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE; copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); @@ -1175,10 +1175,10 @@ static void createTransArmatureVerts(TransInfo *t) if (ebo->flag & BONE_ROOTSEL) { copy_v3_v3(td->iloc, ebo->head); copy_v3_v3(td->center, td->iloc); - td->loc= ebo->head; - td->flag= TD_SELECTED; + td->loc = ebo->head; + td->flag = TD_SELECTED; if (ebo->flag & BONE_EDITMODE_LOCKED) - td->protectflag = OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE; + td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE; copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); @@ -1203,40 +1203,40 @@ static void createTransArmatureVerts(TransInfo *t) static void createTransMBallVerts(TransInfo *t) { - MetaBall *mb = (MetaBall*)t->obedit->data; + MetaBall *mb = (MetaBall *)t->obedit->data; MetaElem *ml; TransData *td; TransDataExtension *tx; float mtx[3][3], smtx[3][3]; - int count=0, countsel=0; + int count = 0, countsel = 0; int propmode = t->flag & T_PROP_EDIT; /* count totals */ - for (ml= mb->editelems->first; ml; ml= ml->next) { + for (ml = mb->editelems->first; ml; ml = ml->next) { if (ml->flag & SELECT) countsel++; if (propmode) count++; } /* note: in prop mode we need at least 1 selected */ - if (countsel==0) return; + if (countsel == 0) return; if (propmode) t->total = count; else t->total = countsel; - td = t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(MBall EditMode)"); - tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "MetaElement_TransExtension"); + td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(MBall EditMode)"); + tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "MetaElement_TransExtension"); copy_m3_m4(mtx, t->obedit->obmat); invert_m3_m3(smtx, mtx); - for (ml= mb->editelems->first; ml; ml= ml->next) { + for (ml = mb->editelems->first; ml; ml = ml->next) { if (propmode || (ml->flag & SELECT)) { - td->loc= &ml->x; + td->loc = &ml->x; copy_v3_v3(td->iloc, td->loc); copy_v3_v3(td->center, td->loc); - if (ml->flag & SELECT) td->flag= TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE; - else td->flag= TD_USEQUAT; + if (ml->flag & SELECT) td->flag = TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE; + else td->flag = TD_USEQUAT; copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); @@ -1276,7 +1276,7 @@ static void createTransMBallVerts(TransInfo *t) static void calc_distanceCurveVerts(TransData *head, TransData *tail) { TransData *td, *td_near = NULL; - for (td = head; td<=tail; td++) { + for (td = head; td <= tail; td++) { if (td->flag & TD_SELECTED) { td_near = td; td->dist = 0.0f; @@ -1284,8 +1284,8 @@ static void calc_distanceCurveVerts(TransData *head, TransData *tail) else if (td_near) { float dist; dist = len_v3v3(td_near->center, td->center); - if (dist < (td-1)->dist) { - td->dist = (td-1)->dist; + if (dist < (td - 1)->dist) { + td->dist = (td - 1)->dist; } else { td->dist = dist; @@ -1297,7 +1297,7 @@ static void calc_distanceCurveVerts(TransData *head, TransData *tail) } } td_near = NULL; - for (td = tail; td>=head; td--) { + for (td = tail; td >= head; td--) { if (td->flag & TD_SELECTED) { td_near = td; td->dist = 0.0f; @@ -1305,10 +1305,10 @@ static void calc_distanceCurveVerts(TransData *head, TransData *tail) else if (td_near) { float dist; dist = len_v3v3(td_near->center, td->center); - if (td->flag & TD_NOTCONNECTED || dist < td->dist || (td+1)->dist < td->dist) { + if (td->flag & TD_NOTCONNECTED || dist < td->dist || (td + 1)->dist < td->dist) { td->flag &= ~TD_NOTCONNECTED; - if (dist < (td+1)->dist) { - td->dist = (td+1)->dist; + if (dist < (td + 1)->dist) { + td->dist = (td + 1)->dist; } else { td->dist = dist; @@ -1333,44 +1333,44 @@ static TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struc static void createTransCurveVerts(bContext *C, TransInfo *t) { - Object *obedit= CTX_data_edit_object(C); - Curve *cu= obedit->data; + Object *obedit = CTX_data_edit_object(C); + Curve *cu = obedit->data; TransData *td = NULL; Nurb *nu; BezTriple *bezt; BPoint *bp; float mtx[3][3], smtx[3][3]; int a; - int count=0, countsel=0; + int count = 0, countsel = 0; int propmode = t->flag & T_PROP_EDIT; short hide_handles = (cu->drawflag & CU_HIDE_HANDLES); ListBase *nurbs; /* to be sure */ - if (cu->editnurb==NULL) return; + if (cu->editnurb == NULL) return; /* count total of vertices, check identical as in 2nd loop for making transdata! */ - nurbs= BKE_curve_editNurbs_get(cu); - for (nu= nurbs->first; nu; nu= nu->next) { + nurbs = BKE_curve_editNurbs_get(cu); + for (nu = nurbs->first; nu; nu = nu->next) { if (nu->type == CU_BEZIER) { - for (a=0, bezt= nu->bezt; apntsu; a++, bezt++) { - if (bezt->hide==0) { + for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { + if (bezt->hide == 0) { if (hide_handles) { - if (bezt->f2 & SELECT) countsel+=3; - if (propmode) count+= 3; + if (bezt->f2 & SELECT) countsel += 3; + if (propmode) count += 3; } else { if (bezt->f1 & SELECT) countsel++; if (bezt->f2 & SELECT) countsel++; if (bezt->f3 & SELECT) countsel++; - if (propmode) count+= 3; + if (propmode) count += 3; } } } } else { - for (a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) { - if (bp->hide==0) { + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) { + if (bp->hide == 0) { if (propmode) count++; if (bp->f1 & SELECT) countsel++; } @@ -1378,22 +1378,22 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) } } /* note: in prop mode we need at least 1 selected */ - if (countsel==0) return; + if (countsel == 0) return; if (propmode) t->total = count; else t->total = countsel; - t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Curve EditMode)"); + t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Curve EditMode)"); copy_m3_m4(mtx, t->obedit->obmat); invert_m3_m3(smtx, mtx); td = t->data; - for (nu= nurbs->first; nu; nu= nu->next) { + for (nu = nurbs->first; nu; nu = nu->next) { if (nu->type == CU_BEZIER) { TransData *head, *tail; head = tail = td; - for (a=0, bezt= nu->bezt; apntsu; a++, bezt++) { - if (bezt->hide==0) { + for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { + if (bezt->hide == 0) { TransDataCurveHandleFlags *hdata = NULL; if (propmode || @@ -1401,15 +1401,15 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) ((bezt->f1 & SELECT) && hide_handles == 0)) { copy_v3_v3(td->iloc, bezt->vec[0]); - td->loc= bezt->vec[0]; - copy_v3_v3(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1:0]); + td->loc = bezt->vec[0]; + copy_v3_v3(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1 : 0]); if (hide_handles) { - if (bezt->f2 & SELECT) td->flag= TD_SELECTED; - else td->flag= 0; + if (bezt->f2 & SELECT) td->flag = TD_SELECTED; + else td->flag = 0; } else { - if (bezt->f1 & SELECT) td->flag= TD_SELECTED; - else td->flag= 0; + if (bezt->f1 & SELECT) td->flag = TD_SELECTED; + else td->flag = 0; } td->ext = NULL; td->val = NULL; @@ -1427,17 +1427,17 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) /* This is the Curve Point, the other two are handles */ if (propmode || (bezt->f2 & SELECT)) { copy_v3_v3(td->iloc, bezt->vec[1]); - td->loc= bezt->vec[1]; + td->loc = bezt->vec[1]; copy_v3_v3(td->center, td->loc); - if (bezt->f2 & SELECT) td->flag= TD_SELECTED; - else td->flag= 0; + if (bezt->f2 & SELECT) td->flag = TD_SELECTED; + else td->flag = 0; td->ext = NULL; - if (t->mode==TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */ + if (t->mode == TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */ td->val = &(bezt->radius); td->ival = bezt->radius; } - else if (t->mode==TFM_TILT) { + else if (t->mode == TFM_TILT) { td->val = &(bezt->alfa); td->ival = bezt->alfa; } @@ -1448,11 +1448,11 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); - if ((bezt->f1&SELECT)==0 && (bezt->f3&SELECT)==0) - /* If the middle is selected but the sides arnt, this is needed */ - if (hdata==NULL) { /* if the handle was not saved by the previous handle */ - hdata = initTransDataCurveHandles(td, bezt); - } + if ((bezt->f1 & SELECT) == 0 && (bezt->f3 & SELECT) == 0) + /* If the middle is selected but the sides arnt, this is needed */ + if (hdata == NULL) { /* if the handle was not saved by the previous handle */ + hdata = initTransDataCurveHandles(td, bezt); + } td++; count++; @@ -1463,20 +1463,20 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) ((bezt->f3 & SELECT) && hide_handles == 0)) { copy_v3_v3(td->iloc, bezt->vec[2]); - td->loc= bezt->vec[2]; - copy_v3_v3(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1:2]); + td->loc = bezt->vec[2]; + copy_v3_v3(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1 : 2]); if (hide_handles) { - if (bezt->f2 & SELECT) td->flag= TD_SELECTED; - else td->flag= 0; + if (bezt->f2 & SELECT) td->flag = TD_SELECTED; + else td->flag = 0; } else { - if (bezt->f3 & SELECT) td->flag= TD_SELECTED; - else td->flag= 0; + if (bezt->f3 & SELECT) td->flag = TD_SELECTED; + else td->flag = 0; } td->ext = NULL; td->val = NULL; - if (hdata==NULL) { /* if the handle was not saved by the previous handle */ + if (hdata == NULL) { /* if the handle was not saved by the previous handle */ hdata = initTransDataCurveHandles(td, bezt); } @@ -1489,12 +1489,12 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) } } else if (propmode && head != tail) { - calc_distanceCurveVerts(head, tail-1); + calc_distanceCurveVerts(head, tail - 1); head = tail; } } if (propmode && head != tail) - calc_distanceCurveVerts(head, tail-1); + calc_distanceCurveVerts(head, tail - 1); /* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandles * but for now just don't change handle types */ @@ -1506,17 +1506,17 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) else { TransData *head, *tail; head = tail = td; - for (a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) { - if (bp->hide==0) { + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) { + if (bp->hide == 0) { if (propmode || (bp->f1 & SELECT)) { copy_v3_v3(td->iloc, bp->vec); - td->loc= bp->vec; + td->loc = bp->vec; copy_v3_v3(td->center, td->loc); - if (bp->f1 & SELECT) td->flag= TD_SELECTED; - else td->flag= 0; + if (bp->f1 & SELECT) td->flag = TD_SELECTED; + else td->flag = 0; td->ext = NULL; - if (t->mode==TFM_CURVE_SHRINKFATTEN || t->mode==TFM_RESIZE) { + if (t->mode == TFM_CURVE_SHRINKFATTEN || t->mode == TFM_RESIZE) { td->val = &(bp->radius); td->ival = bp->radius; } @@ -1534,12 +1534,12 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) } } else if (propmode && head != tail) { - calc_distanceCurveVerts(head, tail-1); + calc_distanceCurveVerts(head, tail - 1); head = tail; } } if (propmode && head != tail) - calc_distanceCurveVerts(head, tail-1); + calc_distanceCurveVerts(head, tail - 1); } } } @@ -1548,30 +1548,30 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) static void createTransLatticeVerts(TransInfo *t) { - Lattice *latt = ((Lattice*)t->obedit->data)->editlatt->latt; + Lattice *latt = ((Lattice *)t->obedit->data)->editlatt->latt; TransData *td = NULL; BPoint *bp; float mtx[3][3], smtx[3][3]; int a; - int count=0, countsel=0; + int count = 0, countsel = 0; int propmode = t->flag & T_PROP_EDIT; bp = latt->def; a = latt->pntsu * latt->pntsv * latt->pntsw; while (a--) { - if (bp->hide==0) { + if (bp->hide == 0) { if (bp->f1 & SELECT) countsel++; if (propmode) count++; } bp++; } - /* note: in prop mode we need at least 1 selected */ - if (countsel==0) return; + /* note: in prop mode we need at least 1 selected */ + if (countsel == 0) return; if (propmode) t->total = count; else t->total = countsel; - t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Lattice EditMode)"); + t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Lattice EditMode)"); copy_m3_m4(mtx, t->obedit->obmat); invert_m3_m3(smtx, mtx); @@ -1581,12 +1581,12 @@ static void createTransLatticeVerts(TransInfo *t) a = latt->pntsu * latt->pntsv * latt->pntsw; while (a--) { if (propmode || (bp->f1 & SELECT)) { - if (bp->hide==0) { + if (bp->hide == 0) { copy_v3_v3(td->iloc, bp->vec); - td->loc= bp->vec; + td->loc = bp->vec; copy_v3_v3(td->center, td->loc); - if (bp->f1 & SELECT) td->flag= TD_SELECTED; - else td->flag= 0; + if (bp->f1 & SELECT) td->flag = TD_SELECTED; + else td->flag = 0; copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); @@ -1619,7 +1619,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) int count = 0, hasselected = 0; int propmode = t->flag & T_PROP_EDIT; - if (edit==NULL || t->settings->particle.selectmode==SCE_SELECT_PATH) return; + if (edit == NULL || t->settings->particle.selectmode == SCE_SELECT_PATH) return; psys = edit->psys; @@ -1628,19 +1628,19 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) base->flag |= BA_HAS_RECALC_DATA; - for (i=0, point=edit->points; itotpoint; i++, point++) { + for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) { point->flag &= ~PEP_TRANSFORM; - transformparticle= 0; + transformparticle = 0; - if ((point->flag & PEP_HIDE)==0) { - for (k=0, key=point->keys; ktotkey; k++, key++) { - if ((key->flag&PEK_HIDE)==0) { - if (key->flag&PEK_SELECT) { - hasselected= 1; - transformparticle= 1; + if ((point->flag & PEP_HIDE) == 0) { + for (k = 0, key = point->keys; k < point->totkey; k++, key++) { + if ((key->flag & PEK_HIDE) == 0) { + if (key->flag & PEK_SELECT) { + hasselected = 1; + transformparticle = 1; } else if (propmode) - transformparticle= 1; + transformparticle = 1; } } } @@ -1651,8 +1651,8 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) } } - /* note: in prop mode we need at least 1 selected */ - if (hasselected==0) return; + /* note: in prop mode we need at least 1 selected */ + if (hasselected == 0) return; t->total = count; td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Particle Mode)"); @@ -1666,7 +1666,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) invert_m4_m4(ob->imat, ob->obmat); - for (i=0, point=edit->points; itotpoint; i++, point++) { + for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) { TransData *head, *tail; head = tail = td; @@ -1675,7 +1675,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + i, mat); - for (k=0, key=point->keys; ktotkey; k++, key++) { + for (k = 0, key = point->keys; k < point->totkey; k++, key++) { if (key->flag & PEK_USE_WCO) { copy_v3_v3(key->world_co, key->co); mul_m4_v3(mat, key->world_co); @@ -1696,7 +1696,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) unit_m3(td->smtx); /* don't allow moving roots */ - if (k==0 && pset->flag & PE_LOCK_FIRST && (!psys || !(psys->flag & PSYS_GLOBAL_HAIR))) + if (k == 0 && pset->flag & PE_LOCK_FIRST && (!psys || !(psys->flag & PSYS_GLOBAL_HAIR))) td->protectflag |= OB_LOCK_LOC; td->ob = ob; @@ -1706,7 +1706,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) td->ival = *(key->time); /* abuse size and quat for min/max values */ td->flag |= TD_NO_EXT; - if (k==0) tx->size = NULL; + if (k == 0) tx->size = NULL; else tx->size = (key - 1)->time; if (k == point->totkey - 1) tx->quat = NULL; @@ -1741,15 +1741,15 @@ void flushTransParticles(TransInfo *t) /* we do transform in world space, so flush world space position * back to particle local space (only for hair particles) */ - td= t->data; - for (i=0, point=edit->points; itotpoint; i++, point++, td++) { + td = t->data; + for (i = 0, point = edit->points; i < edit->totpoint; i++, point++, td++) { if (!(point->flag & PEP_TRANSFORM)) continue; if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + i, mat); invert_m4_m4(imat, mat); - for (k=0, key=point->keys; ktotkey; k++, key++) { + for (k = 0, key = point->keys; k < point->totkey; k++, key++) { copy_v3_v3(co, key->world_co); mul_m4_v3(imat, co); @@ -1771,7 +1771,7 @@ void flushTransParticles(TransInfo *t) /* ********************* mesh ****************** */ /* proportional distance based on connectivity */ -#define THRESHOLDFACTOR (1.0f-0.0001f) +#define THRESHOLDFACTOR (1.0f - 0.0001f) /* I did this wrong, it should be a breadth-first search * but instead it's a depth-first search, fudged @@ -1781,10 +1781,10 @@ static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], f { BMVert **queue = NULL; float *dqueue = NULL; - int *tots = MEM_callocN(sizeof(int)*em->bm->totvert, "tots editmesh_set_connectivity_distance"); + int *tots = MEM_callocN(sizeof(int) * em->bm->totvert, "tots editmesh_set_connectivity_distance"); BLI_array_declare(queue); BLI_array_declare(dqueue); - SmallHash svisit, *visit=&svisit; + SmallHash svisit, *visit = &svisit; BMVert *v; BMIter viter; int i, start; @@ -1796,7 +1796,7 @@ static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], f BLI_smallhash_init(visit); BM_ITER_MESH (v, &viter, em->bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(v, BM_ELEM_SELECT)==0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN)) + if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN)) continue; @@ -1849,7 +1849,7 @@ static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], f BLI_smallhash_release(visit); - for (i=0; ibm->totvert; i++) { + for (i = 0; i < em->bm->totvert; i++) { if (tots[i]) dists[i] /= (float)tots[i]; } @@ -1860,7 +1860,7 @@ static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], f } /* loop-in-a-loop I know, but we need it! (ton) */ - static void get_face_center(float cent_r[3], BMVert *eve) +static void get_face_center(float cent_r[3], BMVert *eve) { BMFace *efa; @@ -1899,7 +1899,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx copy_v3_v3(td->center, td->loc); - if (t->around==V3D_LOCAL) { + if (t->around == V3D_LOCAL) { if (em->selectmode & SCE_SELECT_FACE) get_face_center(td->center, eve); else if (em->selectmode & SCE_SELECT_EDGE) @@ -1910,11 +1910,11 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx // Setting normals copy_v3_v3(td->axismtx[2], eve->no); td->axismtx[0][0] = - td->axismtx[0][1] = - td->axismtx[0][2] = - td->axismtx[1][0] = - td->axismtx[1][1] = - td->axismtx[1][2] = 0.0f; + td->axismtx[0][1] = + td->axismtx[0][2] = + td->axismtx[1][0] = + td->axismtx[1][1] = + td->axismtx[1][2] = 0.0f; td->ext = NULL; td->val = NULL; @@ -1945,10 +1945,10 @@ static void createTransEditVerts(bContext *C, TransInfo *t) BMVert *eve; BMIter iter; BMVert *eve_act = NULL; - float *mappedcos = NULL, *quats= NULL; + float *mappedcos = NULL, *quats = NULL; float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL; - float *dists=NULL; - int count=0, countsel=0, a, totleft; + float *dists = NULL; + int count = 0, countsel = 0, a, totleft; int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) : 0; int mirror = 0; char *selstate = NULL; @@ -1977,10 +1977,10 @@ static void createTransEditVerts(bContext *C, TransInfo *t) BMEdge *eed; eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for ( ; eve; eve=BM_iter_step(&iter)) BM_elem_flag_disable(eve, BM_ELEM_TAG); + for (; eve; eve = BM_iter_step(&iter)) BM_elem_flag_disable(eve, BM_ELEM_TAG); eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); - for ( ; eed; eed=BM_iter_step(&iter)) { + for (; eed; eed = BM_iter_step(&iter)) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { BM_elem_flag_enable(eed->v1, BM_ELEM_TAG); BM_elem_flag_enable(eed->v2, BM_ELEM_TAG); @@ -1990,16 +1990,16 @@ static void createTransEditVerts(bContext *C, TransInfo *t) else { BMFace *efa; eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for ( ; eve; eve=BM_iter_step(&iter)) BM_elem_flag_disable(eve, BM_ELEM_TAG); + for (; eve; eve = BM_iter_step(&iter)) BM_elem_flag_disable(eve, BM_ELEM_TAG); efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); - for ( ; efa; efa=BM_iter_step(&iter)) { + for (; efa; efa = BM_iter_step(&iter)) { if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BMIter liter; BMLoop *l; l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, efa); - for (; l; l=BM_iter_step(&liter)) { + for (; l; l = BM_iter_step(&liter)) { BM_elem_flag_enable(l->v, BM_ELEM_TAG); } } @@ -2011,7 +2011,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t) * verts*/ selstate = MEM_callocN(sizeof(*selstate) * bm->totvert, __func__); eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (a=0; eve; eve=BM_iter_step(&iter), a++) { + for (a = 0; eve; eve = BM_iter_step(&iter), a++) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { if (BM_elem_flag_test(eve, BM_ELEM_TAG)) { selstate[a] = 1; @@ -2044,10 +2044,10 @@ static void createTransEditVerts(bContext *C, TransInfo *t) } else t->total = countsel; - tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)"); + tob = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mesh EditMode)"); if (t->mode == TFM_SKIN_RESIZE) { tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), - "TransObData ext"); + "TransObData ext"); } copy_m3_m4(mtx, t->obedit->obmat); @@ -2058,19 +2058,19 @@ static void createTransEditVerts(bContext *C, TransInfo *t) } /* detect CrazySpace [tm] */ - if (modifiers_getCageIndex(t->scene, t->obedit, NULL, 1)>=0) { + if (modifiers_getCageIndex(t->scene, t->obedit, NULL, 1) >= 0) { if (modifiers_isCorrectableDeformed(t->obedit)) { /* check if we can use deform matrices for modifier from the * start up to stack, they are more accurate than quats */ - totleft= editbmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos); + totleft = editbmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos); /* if we still have more modifiers, also do crazyspace * correction with quats, relative to the coordinates after * the modifiers that support deform matrices (defcos) */ if (totleft > 0) { - mappedcos= crazyspace_get_mapped_editverts(t->scene, t->obedit); - quats= MEM_mallocN((t->total)*sizeof(float)*4, "crazy quats"); - crazyspace_set_quats_editmesh(em, (float*)defcos, mappedcos, quats); /* BMESH_TODO, abuses vertex index, should use an int array */ + mappedcos = crazyspace_get_mapped_editverts(t->scene, t->obedit); + quats = MEM_mallocN((t->total) * sizeof(float) * 4, "crazy quats"); + crazyspace_set_quats_editmesh(em, (float *)defcos, mappedcos, quats); /* BMESH_TODO, abuses vertex index, should use an int array */ if (mappedcos) MEM_freeN(mappedcos); } @@ -2083,8 +2083,8 @@ static void createTransEditVerts(bContext *C, TransInfo *t) /* find out which half we do */ if (mirror) { eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (a=0; eve; eve=BM_iter_step(&iter), a++) { - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && selstate[a] && eve->co[0]!=0.0f) { + for (a = 0; eve; eve = BM_iter_step(&iter), a++) { + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && selstate[a] && eve->co[0] != 0.0f) { if (eve->co[0] < 0.0f) { t->mirror = -1; mirror = -1; @@ -2095,7 +2095,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t) } eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (a=0; eve; eve=BM_iter_step(&iter), a++) { + for (a = 0; eve; eve = BM_iter_step(&iter), a++) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { if (propmode || selstate[a]) { float *bweight = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_BWEIGHT); @@ -2126,11 +2126,11 @@ static void createTransEditVerts(bContext *C, TransInfo *t) /* use both or either quat and defmat correction */ if (quats && BM_elem_index_get(eve) != -1) { - quat_to_mat3(qmat, quats + 4*BM_elem_index_get(eve)); + quat_to_mat3(qmat, quats + 4 * BM_elem_index_get(eve)); if (defmats) mul_serie_m3(mat, mtx, qmat, defmats[a], - NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); else mul_m3_m3m3(mat, mtx, qmat); } @@ -2148,8 +2148,8 @@ static void createTransEditVerts(bContext *C, TransInfo *t) } /* Mirror? */ - if ((mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) { - BMVert *vmir= EDBM_verts_mirror_get(em, eve); //t->obedit, em, eve, tob->iloc, a); + if ((mirror > 0 && tob->iloc[0] > 0.0f) || (mirror < 0 && tob->iloc[0] < 0.0f)) { + BMVert *vmir = EDBM_verts_mirror_get(em, eve); //t->obedit, em, eve, tob->iloc, a); if (vmir && vmir != eve) { tob->extra = vmir; } @@ -2161,7 +2161,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t) if (mirror != 0) { tob = t->data; - for (a = 0; a < t->total; a++, tob++ ) { + for (a = 0; a < t->total; a++, tob++) { if (ABS(tob->loc[0]) <= 0.00001f) { tob->flag |= TD_MIRROR_EDGE; } @@ -2192,13 +2192,13 @@ void flushTransNodes(TransInfo *t) TransData2D *td; /* flush to 2d vector from internally used 3d vector */ - for (a=0, td= t->data2d; atotal; a++, td++) { - td->loc2d[0]= td->loc[0]; - td->loc2d[1]= td->loc[1]; + for (a = 0, td = t->data2d; a < t->total; a++, td++) { + td->loc2d[0] = td->loc[0]; + td->loc2d[1] = td->loc[1]; } /* handle intersection with noodles */ - if (t->total==1) { + if (t->total == 1) { ED_node_link_intersect_test(t->sa, 1); } } @@ -2212,11 +2212,11 @@ void flushTransNodes(TransInfo *t) void flushTransSeq(TransInfo *t) { - ListBase *seqbasep= BKE_sequencer_editing_get(t->scene, FALSE)->seqbasep; /* Editing null check already done */ + ListBase *seqbasep = BKE_sequencer_editing_get(t->scene, FALSE)->seqbasep; /* Editing null check already done */ int a, new_frame, old_start; - TransData *td= NULL; - TransData2D *td2d= NULL; - TransDataSeq *tdsq= NULL; + TransData *td = NULL; + TransData2D *td2d = NULL; + TransDataSeq *tdsq = NULL; Sequence *seq; @@ -2224,43 +2224,43 @@ void flushTransSeq(TransInfo *t) /* prevent updating the same seq twice * if the transdata order is changed this will mess up * but so will TransDataSeq */ - Sequence *seq_prev= NULL; + Sequence *seq_prev = NULL; /* flush to 2d vector from internally used 3d vector */ - for (a=0, td= t->data, td2d= t->data2d; atotal; a++, td++, td2d++) { - tdsq= (TransDataSeq *)td->extra; - seq= tdsq->seq; + for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) { + tdsq = (TransDataSeq *)td->extra; + seq = tdsq->seq; old_start = seq->start; - new_frame= (int)floor(td2d->loc[0] + 0.5f); + new_frame = (int)floor(td2d->loc[0] + 0.5f); switch (tdsq->sel_flag) { - case SELECT: + case SELECT: #ifdef SEQ_TX_NESTED_METAS - if ((seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */ - seq->start= new_frame - tdsq->start_offset; + if ((seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */ + seq->start = new_frame - tdsq->start_offset; #else - if (seq->type != SEQ_TYPE_META && (seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */ - seq->start= new_frame - tdsq->start_offset; + if (seq->type != SEQ_TYPE_META && (seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */ + seq->start = new_frame - tdsq->start_offset; #endif - if (seq->depth==0) { - seq->machine= (int)floor(td2d->loc[1] + 0.5f); - CLAMP(seq->machine, 1, MAXSEQ); - } - break; - case SEQ_LEFTSEL: /* no vertical transform */ - seq_tx_set_final_left(seq, new_frame); - seq_tx_handle_xlimits(seq, tdsq->flag&SEQ_LEFTSEL, tdsq->flag&SEQ_RIGHTSEL); - seq_single_fix(seq); /* todo - move this into aftertrans update? - old seq tx needed it anyway */ - break; - case SEQ_RIGHTSEL: /* no vertical transform */ - seq_tx_set_final_right(seq, new_frame); - seq_tx_handle_xlimits(seq, tdsq->flag&SEQ_LEFTSEL, tdsq->flag&SEQ_RIGHTSEL); - seq_single_fix(seq); /* todo - move this into aftertrans update? - old seq tx needed it anyway */ - break; + if (seq->depth == 0) { + seq->machine = (int)floor(td2d->loc[1] + 0.5f); + CLAMP(seq->machine, 1, MAXSEQ); + } + break; + case SEQ_LEFTSEL: /* no vertical transform */ + seq_tx_set_final_left(seq, new_frame); + seq_tx_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); + seq_single_fix(seq); /* todo - move this into aftertrans update? - old seq tx needed it anyway */ + break; + case SEQ_RIGHTSEL: /* no vertical transform */ + seq_tx_set_final_right(seq, new_frame); + seq_tx_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); + seq_single_fix(seq); /* todo - move this into aftertrans update? - old seq tx needed it anyway */ + break; } if (seq != seq_prev) { - if (seq->depth==0) { + if (seq->depth == 0) { /* Calculate this strip and all nested strips * children are ALWAYS transformed first * so we don't need to do this in another loop. */ @@ -2273,7 +2273,7 @@ void flushTransSeq(TransInfo *t) if (tdsq->sel_flag == SELECT) seq_offset_animdata(t->scene, seq, seq->start - old_start); } - seq_prev= seq; + seq_prev = seq; } @@ -2295,14 +2295,14 @@ void flushTransSeq(TransInfo *t) /* need to do the overlap check in a new loop otherwise adjacent strips * will not be updated and we'll get false positives */ - seq_prev= NULL; - for (a=0, td= t->data, td2d= t->data2d; atotal; a++, td++, td2d++) { + seq_prev = NULL; + for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) { - tdsq= (TransDataSeq *)td->extra; - seq= tdsq->seq; + tdsq = (TransDataSeq *)td->extra; + seq = tdsq->seq; if (seq != seq_prev) { - if (seq->depth==0) { + if (seq->depth == 0) { /* test overlap, displayes red outline */ seq->flag &= ~SEQ_OVERLAP; if (seq_test_overlap(seqbasep, seq)) { @@ -2310,7 +2310,7 @@ void flushTransSeq(TransInfo *t) } } } - seq_prev= seq; + seq_prev = seq; } } @@ -2326,8 +2326,8 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f * proportional editing to be consistent with the stretched uv coords * that are displayed. this also means that for display and numinput, * and when the the uv coords are flushed, these are converted each time */ - td2d->loc[0] = uv[0]*aspx; - td2d->loc[1] = uv[1]*aspy; + td2d->loc[0] = uv[0] * aspx; + td2d->loc[1] = uv[1] * aspy; td2d->loc[2] = 0.0f; td2d->loc2d = uv; @@ -2339,14 +2339,14 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->val= NULL; + td->ext = NULL; td->val = NULL; if (selected) { td->flag |= TD_SELECTED; - td->dist= 0.0; + td->dist = 0.0; } else { - td->dist= MAXFLOAT; + td->dist = MAXFLOAT; } unit_m3(td->mtx); unit_m3(td->smtx); @@ -2365,14 +2365,14 @@ static void createTransUVs(bContext *C, TransInfo *t) BMFace *efa; BMLoop *l; BMIter iter, liter; - int count=0, countsel=0; + int count = 0, countsel = 0; int propmode = t->flag & T_PROP_EDIT; if (!ED_space_image_show_uvedit(sima, t->obedit)) return; /* count */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); if (!uvedit_face_visible_test(scene, ima, efa, tf)) { BM_elem_flag_disable(efa, BM_ELEM_TAG); @@ -2389,20 +2389,20 @@ static void createTransUVs(bContext *C, TransInfo *t) } } - /* note: in prop mode we need at least 1 selected */ - if (countsel==0) return; + /* note: in prop mode we need at least 1 selected */ + if (countsel == 0) return; - t->total= (propmode)? count: countsel; - t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(UV Editing)"); + t->total = (propmode) ? count : countsel; + t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(UV Editing)"); /* for each 2d uv coord a 3d vector is allocated, so that they can be * treated just as if they were 3d verts */ - t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)"); + t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransObData2D(UV Editing)"); if (sima->flag & SI_CLIP_UV) t->flag |= T_CLIP_UV; - td= t->data; - td2d= t->data2d; + td = t->data; + td2d = t->data2d; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) @@ -2430,17 +2430,17 @@ void flushTransUVs(TransInfo *t) ED_space_image_uv_aspect(sima, &aspx, &aspy); ED_space_image_size(sima, &width, &height); - invx= 1.0f/aspx; - invy= 1.0f/aspy; + invx = 1.0f / aspx; + invy = 1.0f / aspy; /* flush to 2d vector from internally used 3d vector */ - for (a=0, td= t->data2d; atotal; a++, td++) { - td->loc2d[0]= td->loc[0]*invx; - td->loc2d[1]= td->loc[1]*invy; + for (a = 0, td = t->data2d; a < t->total; a++, td++) { + td->loc2d[0] = td->loc[0] * invx; + td->loc2d[1] = td->loc[1] * invy; if ((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)) { - td->loc2d[0]= (float)floor(width*td->loc2d[0] + 0.5f)/width; - td->loc2d[1]= (float)floor(height*td->loc2d[1] + 0.5f)/height; + td->loc2d[0] = (float)floor(width * td->loc2d[0] + 0.5f) / width; + td->loc2d[1] = (float)floor(height * td->loc2d[1] + 0.5f) / height; } } } @@ -2448,46 +2448,46 @@ void flushTransUVs(TransInfo *t) int clipUVTransform(TransInfo *t, float *vec, int resize) { TransData *td; - int a, clipx=1, clipy=1; + int a, clipx = 1, clipy = 1; float aspx, aspy, min[2], max[2]; ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); - min[0]= min[1]= 0.0f; - max[0]= aspx; max[1]= aspy; + min[0] = min[1] = 0.0f; + max[0] = aspx; max[1] = aspy; - for (a=0, td= t->data; atotal; a++, td++) { + for (a = 0, td = t->data; a < t->total; a++, td++) { DO_MINMAX2(td->loc, min, max); } if (resize) { - if (min[0] < 0.0f && t->center[0] > 0.0f && t->center[0] < aspx*0.5f) - vec[0] *= t->center[0]/(t->center[0] - min[0]); + if (min[0] < 0.0f && t->center[0] > 0.0f && t->center[0] < aspx * 0.5f) + vec[0] *= t->center[0] / (t->center[0] - min[0]); else if (max[0] > aspx && t->center[0] < aspx) - vec[0] *= (t->center[0] - aspx)/(t->center[0] - max[0]); + vec[0] *= (t->center[0] - aspx) / (t->center[0] - max[0]); else - clipx= 0; + clipx = 0; - if (min[1] < 0.0f && t->center[1] > 0.0f && t->center[1] < aspy*0.5f) - vec[1] *= t->center[1]/(t->center[1] - min[1]); + if (min[1] < 0.0f && t->center[1] > 0.0f && t->center[1] < aspy * 0.5f) + vec[1] *= t->center[1] / (t->center[1] - min[1]); else if (max[1] > aspy && t->center[1] < aspy) - vec[1] *= (t->center[1] - aspy)/(t->center[1] - max[1]); + vec[1] *= (t->center[1] - aspy) / (t->center[1] - max[1]); else - clipy= 0; + clipy = 0; } else { if (min[0] < 0.0f) vec[0] -= min[0]; else if (max[0] > aspx) - vec[0] -= max[0]-aspx; + vec[0] -= max[0] - aspx; else - clipx= 0; + clipx = 0; if (min[1] < 0.0f) vec[1] -= min[1]; else if (max[1] > aspy) - vec[1] -= max[1]-aspy; + vec[1] -= max[1] - aspy; else - clipy= 0; + clipy = 0; } return (clipx || clipy); @@ -2512,7 +2512,7 @@ static short FrameOnMouseSide(char side, float frame, float cframe) static void createTransNlaData(bContext *C, TransInfo *t) { - Scene *scene= t->scene; + Scene *scene = t->scene; SpaceNla *snla = NULL; TransData *td = NULL; TransDataNla *tdn = NULL; @@ -2522,7 +2522,7 @@ static void createTransNlaData(bContext *C, TransInfo *t) bAnimListElem *ale; int filter; - int count=0; + int count = 0; /* determine what type of data we are operating on */ if (ANIM_animdata_get_context(C, &ac) == 0) @@ -2530,7 +2530,7 @@ static void createTransNlaData(bContext *C, TransInfo *t) snla = (SpaceNla *)ac.sl; /* filter data */ - filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* which side of the current frame should be allowed */ @@ -2539,7 +2539,7 @@ static void createTransNlaData(bContext *C, TransInfo *t) float xmouse, ymouse; UI_view2d_region_to_view(&ac.ar->v2d, t->imval[0], t->imval[1], &xmouse, &ymouse); - t->frame_side= (xmouse > CFRA) ? 'R' : 'L'; + t->frame_side = (xmouse > CFRA) ? 'R' : 'L'; } else { /* normal transform - both sides of current frame are considered */ @@ -2547,15 +2547,15 @@ static void createTransNlaData(bContext *C, TransInfo *t) } /* loop 1: count how many strips are selected (consider each strip as 2 points) */ - for (ale= anim_data.first; ale; ale= ale->next) { - NlaTrack *nlt= (NlaTrack *)ale->data; + for (ale = anim_data.first; ale; ale = ale->next) { + NlaTrack *nlt = (NlaTrack *)ale->data; NlaStrip *strip; /* make some meta-strips for chains of selected strips */ BKE_nlastrips_make_metas(&nlt->strips, 1); /* only consider selected strips */ - for (strip= nlt->strips.first; strip; strip= strip->next) { + for (strip = nlt->strips.first; strip; strip = strip->next) { // TODO: we can make strips have handles later on... /* transition strips can't get directly transformed */ if (strip->type != NLASTRIP_TYPE_TRANSITION) { @@ -2575,24 +2575,24 @@ static void createTransNlaData(bContext *C, TransInfo *t) } /* allocate memory for data */ - t->total= count; + t->total = count; - t->data= MEM_callocN(t->total*sizeof(TransData), "TransData(NLA Editor)"); - td= t->data; - t->customData= MEM_callocN(t->total*sizeof(TransDataNla), "TransDataNla (NLA Editor)"); - tdn= t->customData; + t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(NLA Editor)"); + td = t->data; + t->customData = MEM_callocN(t->total * sizeof(TransDataNla), "TransDataNla (NLA Editor)"); + tdn = t->customData; t->flag |= T_FREE_CUSTOMDATA; /* loop 2: build transdata array */ - for (ale= anim_data.first; ale; ale= ale->next) { + for (ale = anim_data.first; ale; ale = ale->next) { /* only if a real NLA-track */ if (ale->type == ANIMTYPE_NLATRACK) { AnimData *adt = ale->adt; - NlaTrack *nlt= (NlaTrack *)ale->data; + NlaTrack *nlt = (NlaTrack *)ale->data; NlaStrip *strip; /* only consider selected strips */ - for (strip= nlt->strips.first; strip; strip= strip->next) { + for (strip = nlt->strips.first; strip; strip = strip->next) { // TODO: we can make strips have handles later on... /* transition strips can't get directly transformed */ if (strip->type != NLASTRIP_TYPE_TRANSITION) { @@ -2602,37 +2602,37 @@ static void createTransNlaData(bContext *C, TransInfo *t) * - td structs are transform-elements operated on by the transform system * and represent a single handle. The storage/pointer used (val or loc) depends on * whether we're scaling or transforming. Ultimately though, the handles - * the td writes to will simply be a dummy in tdn + * the td writes to will simply be a dummy in tdn * - for each strip being transformed, a single tdn struct is used, so in some * cases, there will need to be 1 of these tdn elements in the array skipped... */ float center[3], yval; /* firstly, init tdn settings */ - tdn->id= ale->id; - tdn->oldTrack= tdn->nlt= nlt; - tdn->strip= strip; - tdn->trackIndex= BLI_findindex(&adt->nla_tracks, nlt); - - yval= (float)(tdn->trackIndex * NLACHANNEL_STEP(snla)); - - tdn->h1[0]= strip->start; - tdn->h1[1]= yval; - tdn->h2[0]= strip->end; - tdn->h2[1]= yval; - - center[0]= (float)CFRA; - center[1]= yval; - center[2]= 0.0f; + tdn->id = ale->id; + tdn->oldTrack = tdn->nlt = nlt; + tdn->strip = strip; + tdn->trackIndex = BLI_findindex(&adt->nla_tracks, nlt); + + yval = (float)(tdn->trackIndex * NLACHANNEL_STEP(snla)); + + tdn->h1[0] = strip->start; + tdn->h1[1] = yval; + tdn->h2[0] = strip->end; + tdn->h2[1] = yval; + + center[0] = (float)CFRA; + center[1] = yval; + center[2] = 0.0f; /* set td's based on which handles are applicable */ if (FrameOnMouseSide(t->frame_side, strip->start, (float)CFRA)) { /* just set tdn to assume that it only has one handle for now */ - tdn->handle= -1; + tdn->handle = -1; /* now, link the transform data up to this data */ if (ELEM(t->mode, TFM_TRANSLATION, TFM_TIME_EXTEND)) { - td->loc= tdn->h1; + td->loc = tdn->h1; copy_v3_v3(td->iloc, tdn->h1); /* store all the other gunk that is required by transform */ @@ -2640,30 +2640,30 @@ static void createTransNlaData(bContext *C, TransInfo *t) memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->val= NULL; + td->ext = NULL; td->val = NULL; td->flag |= TD_SELECTED; - td->dist= 0.0f; + td->dist = 0.0f; unit_m3(td->mtx); unit_m3(td->smtx); } else { /* time scaling only needs single value */ - td->val= &tdn->h1[0]; - td->ival= tdn->h1[0]; + td->val = &tdn->h1[0]; + td->ival = tdn->h1[0]; } - td->extra= tdn; + td->extra = tdn; td++; } if (FrameOnMouseSide(t->frame_side, strip->end, (float)CFRA)) { /* if tdn is already holding the start handle, then we're doing both, otherwise, only end */ - tdn->handle= (tdn->handle) ? 2 : 1; + tdn->handle = (tdn->handle) ? 2 : 1; /* now, link the transform data up to this data */ if (ELEM(t->mode, TFM_TRANSLATION, TFM_TIME_EXTEND)) { - td->loc= tdn->h2; + td->loc = tdn->h2; copy_v3_v3(td->iloc, tdn->h2); /* store all the other gunk that is required by transform */ @@ -2671,21 +2671,21 @@ static void createTransNlaData(bContext *C, TransInfo *t) memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->val= NULL; + td->ext = NULL; td->val = NULL; td->flag |= TD_SELECTED; - td->dist= 0.0f; + td->dist = 0.0f; unit_m3(td->mtx); unit_m3(td->smtx); } else { /* time scaling only needs single value */ - td->val= &tdn->h2[0]; - td->ival= tdn->h2[0]; + td->val = &tdn->h2[0]; + td->ival = tdn->h2[0]; } - td->extra= tdn; + td->extra = tdn; td++; } @@ -2713,11 +2713,11 @@ static void createTransNlaData(bContext *C, TransInfo *t) * It also makes sure gp-frames are still stored in chronological order after * transform. */ -static void posttrans_gpd_clean (bGPdata *gpd) +static void posttrans_gpd_clean(bGPdata *gpd) { bGPDlayer *gpl; - for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { ListBase sel_buffer = {NULL, NULL}; bGPDframe *gpf, *gpfn; bGPDframe *gfs, *gfsn; @@ -2725,9 +2725,9 @@ static void posttrans_gpd_clean (bGPdata *gpd) /* loop 1: loop through and isolate selected gp-frames to buffer * (these need to be sorted as they are isolated) */ - for (gpf= gpl->frames.first; gpf; gpf= gpfn) { - short added= 0; - gpfn= gpf->next; + for (gpf = gpl->frames.first; gpf; gpf = gpfn) { + short added = 0; + gpfn = gpf->next; if (gpf->flag & GP_FRAME_SELECT) { BLI_remlink(&gpl->frames, gpf); @@ -2736,11 +2736,11 @@ static void posttrans_gpd_clean (bGPdata *gpd) * - go backwards as most frames will still be in order, * so doing it this way will be faster */ - for (gfs= sel_buffer.last; gfs; gfs= gfs->prev) { + for (gfs = sel_buffer.last; gfs; gfs = gfs->prev) { /* if current (gpf) occurs after this one in buffer, add! */ if (gfs->framenum < gpf->framenum) { BLI_insertlinkafter(&sel_buffer, gfs, gpf); - added= 1; + added = 1; break; } } @@ -2755,19 +2755,19 @@ static void posttrans_gpd_clean (bGPdata *gpd) /* if all were selected (i.e. gpl->frames is empty), then just transfer sel-buf over */ if (gpl->frames.first == NULL) { - gpl->frames.first= sel_buffer.first; - gpl->frames.last= sel_buffer.last; + gpl->frames.first = sel_buffer.first; + gpl->frames.last = sel_buffer.last; continue; } /* loop 2: remove duplicates of frames in buffers */ - for (gpf= gpl->frames.first; gpf && sel_buffer.first; gpf= gpfn) { - gpfn= gpf->next; + for (gpf = gpl->frames.first; gpf && sel_buffer.first; gpf = gpfn) { + gpfn = gpf->next; /* loop through sel_buffer, emptying stuff from front of buffer if ok */ - for (gfs= sel_buffer.first; gfs && gpf; gfs= gfsn) { - gfsn= gfs->next; + for (gfs = sel_buffer.first; gfs && gpf; gfs = gfsn) { + gfsn = gfs->next; /* if this buffer frame needs to go before current, add it! */ if (gfs->framenum < gpf->framenum) { @@ -2788,8 +2788,8 @@ static void posttrans_gpd_clean (bGPdata *gpd) } /* if anything is still in buffer, append to end */ - for (gfs= sel_buffer.first; gfs; gfs= gfsn) { - gfsn= gfs->next; + for (gfs = sel_buffer.first; gfs; gfs = gfsn) { + gfsn = gfs->next; BLI_remlink(&sel_buffer, gfs); BLI_addtail(&gpl->frames, gfs); @@ -2807,7 +2807,7 @@ static void posttrans_mask_clean(Mask *mask) { MaskLayer *masklay; - for (masklay = mask->masklayers.first; masklay; masklay= masklay->next) { + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { ListBase sel_buffer = {NULL, NULL}; MaskLayerShape *masklay_shape, *masklay_shape_new; MaskLayerShape *masklay_shape_sort, *masklay_shape_sort_new; @@ -2815,9 +2815,9 @@ static void posttrans_mask_clean(Mask *mask) /* loop 1: loop through and isolate selected gp-frames to buffer * (these need to be sorted as they are isolated) */ - for (masklay_shape= masklay->splines_shapes.first; masklay_shape; masklay_shape= masklay_shape_new) { - short added= 0; - masklay_shape_new= masklay_shape->next; + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_new) { + short added = 0; + masklay_shape_new = masklay_shape->next; if (masklay_shape->flag & GP_FRAME_SELECT) { BLI_remlink(&masklay->splines_shapes, masklay_shape); @@ -2826,11 +2826,11 @@ static void posttrans_mask_clean(Mask *mask) * - go backwards as most frames will still be in order, * so doing it this way will be faster */ - for (masklay_shape_sort= sel_buffer.last; masklay_shape_sort; masklay_shape_sort= masklay_shape_sort->prev) { + for (masklay_shape_sort = sel_buffer.last; masklay_shape_sort; masklay_shape_sort = masklay_shape_sort->prev) { /* if current (masklay_shape) occurs after this one in buffer, add! */ if (masklay_shape_sort->frame < masklay_shape->frame) { BLI_insertlinkafter(&sel_buffer, masklay_shape_sort, masklay_shape); - added= 1; + added = 1; break; } } @@ -2845,19 +2845,19 @@ static void posttrans_mask_clean(Mask *mask) /* if all were selected (i.e. masklay->splines_shapes is empty), then just transfer sel-buf over */ if (masklay->splines_shapes.first == NULL) { - masklay->splines_shapes.first= sel_buffer.first; - masklay->splines_shapes.last= sel_buffer.last; + masklay->splines_shapes.first = sel_buffer.first; + masklay->splines_shapes.last = sel_buffer.last; continue; } /* loop 2: remove duplicates of splines_shapes in buffers */ - for (masklay_shape= masklay->splines_shapes.first; masklay_shape && sel_buffer.first; masklay_shape= masklay_shape_new) { - masklay_shape_new= masklay_shape->next; + for (masklay_shape = masklay->splines_shapes.first; masklay_shape && sel_buffer.first; masklay_shape = masklay_shape_new) { + masklay_shape_new = masklay_shape->next; /* loop through sel_buffer, emptying stuff from front of buffer if ok */ - for (masklay_shape_sort= sel_buffer.first; masklay_shape_sort && masklay_shape; masklay_shape_sort= masklay_shape_sort_new) { - masklay_shape_sort_new= masklay_shape_sort->next; + for (masklay_shape_sort = sel_buffer.first; masklay_shape_sort && masklay_shape; masklay_shape_sort = masklay_shape_sort_new) { + masklay_shape_sort_new = masklay_shape_sort->next; /* if this buffer frame needs to go before current, add it! */ if (masklay_shape_sort->frame < masklay_shape->frame) { @@ -2878,8 +2878,8 @@ static void posttrans_mask_clean(Mask *mask) } /* if anything is still in buffer, append to end */ - for (masklay_shape_sort= sel_buffer.first; masklay_shape_sort; masklay_shape_sort= masklay_shape_sort_new) { - masklay_shape_sort_new= masklay_shape_sort->next; + for (masklay_shape_sort = sel_buffer.first; masklay_shape_sort; masklay_shape_sort = masklay_shape_sort_new) { + masklay_shape_sort_new = masklay_shape_sort->next; BLI_remlink(&sel_buffer, masklay_shape_sort); BLI_addtail(&masklay->splines_shapes, masklay_shape_sort); @@ -2893,18 +2893,18 @@ static void posttrans_mask_clean(Mask *mask) /* Called during special_aftertrans_update to make sure selected keyframes replace * any other keyframes which may reside on that frame (that is not selected). */ -static void posttrans_fcurve_clean (FCurve *fcu, const short use_handle) +static void posttrans_fcurve_clean(FCurve *fcu, const short use_handle) { - float *selcache; /* cache for frame numbers of selected frames (fcu->totvert*sizeof(float)) */ - int len, index, i; /* number of frames in cache, item index */ + float *selcache; /* cache for frame numbers of selected frames (fcu->totvert*sizeof(float)) */ + int len, index, i; /* number of frames in cache, item index */ /* allocate memory for the cache */ // TODO: investigate using BezTriple columns instead? - if (fcu->totvert == 0 || fcu->bezt==NULL) + if (fcu->totvert == 0 || fcu->bezt == NULL) return; - selcache= MEM_callocN(sizeof(float)*fcu->totvert, "FCurveSelFrameNums"); - len= 0; - index= 0; + selcache = MEM_callocN(sizeof(float) * fcu->totvert, "FCurveSelFrameNums"); + len = 0; + index = 0; /* We do 2 loops, 1 for marking keyframes for deletion, one for deleting * as there is no guarantee what order the keyframes are exactly, even though @@ -2913,10 +2913,10 @@ static void posttrans_fcurve_clean (FCurve *fcu, const short use_handle) /* Loop 1: find selected keyframes */ for (i = 0; i < fcu->totvert; i++) { - BezTriple *bezt= &fcu->bezt[i]; + BezTriple *bezt = &fcu->bezt[i]; if (BEZSELECTED(bezt)) { - selcache[index]= bezt->vec[1][0]; + selcache[index] = bezt->vec[1][0]; index++; len++; } @@ -2926,12 +2926,12 @@ static void posttrans_fcurve_clean (FCurve *fcu, const short use_handle) * (if any keyframes were found, or the whole curve wasn't affected) */ if ((len) && (len != fcu->totvert)) { - for (i= fcu->totvert-1; i >= 0; i--) { - BezTriple *bezt= &fcu->bezt[i]; + for (i = fcu->totvert - 1; i >= 0; i--) { + BezTriple *bezt = &fcu->bezt[i]; if (BEZSELECTED(bezt) == 0) { /* check beztriple should be removed according to cache */ - for (index= 0; index < len; index++) { + for (index = 0; index < len; index++) { if (IS_EQF(bezt->vec[1][0], selcache[index])) { delete_fcurve_key(fcu, i, 0); break; @@ -2955,21 +2955,21 @@ static void posttrans_fcurve_clean (FCurve *fcu, const short use_handle) * any other keyframes which may reside on that frame (that is not selected). * remake_action_ipos should have already been called */ -static void posttrans_action_clean (bAnimContext *ac, bAction *act) +static void posttrans_action_clean(bAnimContext *ac, bAction *act) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; /* filter data */ - filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/); ANIM_animdata_filter(ac, &anim_data, filter, act, ANIMCONT_ACTION); /* loop through relevant data, removing keyframes as appropriate - * - all keyframes are converted in/out of global time + * - all keyframes are converted in/out of global time */ - for (ale= anim_data.first; ale; ale= ale->next) { - AnimData *adt= ANIM_nla_mapping_get(ac, ale); + for (ale = anim_data.first; ale; ale = ale->next) { + AnimData *adt = ANIM_nla_mapping_get(ac, ale); if (adt) { ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); @@ -2977,7 +2977,7 @@ static void posttrans_action_clean (bAnimContext *ac, bAction *act) ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); } else - posttrans_fcurve_clean(ale->key_data, FALSE); /* only use handles in graph editor */ + posttrans_fcurve_clean(ale->key_data, FALSE); /* only use handles in graph editor */ } /* free temp data */ @@ -2996,7 +2996,7 @@ static int count_fcurve_keys(FCurve *fcu, char side, float cfra) return count; /* only include points that occur on the right side of cfra */ - for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) { + for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { if (bezt->f2 & SELECT) { /* no need to adjust the handle selection since they are assumed * selected (like graph editor with SIPO_NOHANDLES) */ @@ -3019,7 +3019,7 @@ static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra) return count; /* only include points that occur on the right side of cfra */ - for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { + for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { if (gpf->flag & GP_FRAME_SELECT) { if (FrameOnMouseSide(side, (float)gpf->framenum, cfra)) count++; @@ -3039,7 +3039,7 @@ static int count_masklayer_frames(MaskLayer *masklay, char side, float cfra) return count; /* only include points that occur on the right side of cfra */ - for (masklayer_shape= masklay->splines_shapes.first; masklayer_shape; masklayer_shape= masklayer_shape->next) { + for (masklayer_shape = masklay->splines_shapes.first; masklayer_shape; masklayer_shape = masklayer_shape->next) { if (masklayer_shape->flag & MASK_SHAPE_SELECT) { if (FrameOnMouseSide(side, (float)masklayer_shape->frame, cfra)) count++; @@ -3060,7 +3060,7 @@ static void TimeToTransData(TransData *td, float *time, AnimData *adt) /* store the AnimData where this keyframe exists as a keyframe of the * active action as td->extra. */ - td->extra= adt; + td->extra = adt; } /* This function advances the address to which td points to, so it must return @@ -3079,7 +3079,7 @@ static TransData *ActionFCurveToTransData(TransData *td, TransData2D **td2dv, FC if (ELEM(NULL, fcu, fcu->bezt)) return td; - for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) { + for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { /* only add selected keyframes (for now, proportional edit is not enabled) */ if (bezt->f2 & SELECT) { /* note this MUST match count_fcurve_keys(), so can't use BEZSELECTED() macro */ /* only add if on the right 'side' of the current frame */ @@ -3087,7 +3087,7 @@ static TransData *ActionFCurveToTransData(TransData *td, TransData2D **td2dv, FC TimeToTransData(td, bezt->vec[1], adt); /*set flags to move handles as necessary*/ - td->flag |= TD_MOVEHANDLE1|TD_MOVEHANDLE2; + td->flag |= TD_MOVEHANDLE1 | TD_MOVEHANDLE2; td2d->h1 = bezt->vec[0]; td2d->h2 = bezt->vec[2]; @@ -3107,8 +3107,8 @@ static TransData *ActionFCurveToTransData(TransData *td, TransData2D **td2dv, FC /* helper struct for gp-frame transforms (only used here) */ typedef struct tGPFtransdata { - float val; /* where transdata writes transform */ - int *sdata; /* pointer to gpf->framenum */ + float val; /* where transdata writes transform */ + int *sdata; /* pointer to gpf->framenum */ } tGPFtransdata; /* This function helps flush transdata written to tempdata into the gp-frames */ @@ -3119,13 +3119,13 @@ void flushTransIntFrameActionData(TransInfo *t) /* find the first one to start from */ if (t->mode == TFM_TIME_SLIDE) - tfd= (tGPFtransdata *)((float *)(t->customData) + 2); + tfd = (tGPFtransdata *)((float *)(t->customData) + 2); else - tfd= (tGPFtransdata *)(t->customData); + tfd = (tGPFtransdata *)(t->customData); /* flush data! */ for (i = 0; i < t->total; i++, tfd++) { - *(tfd->sdata)= (int)floor(tfd->val + 0.5f); + *(tfd->sdata) = (int)floor(tfd->val + 0.5f); } } @@ -3136,21 +3136,21 @@ void flushTransIntFrameActionData(TransInfo *t) * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data * on the named side are used. */ -static int GPLayerToTransData (TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl, char side, float cfra) +static int GPLayerToTransData(TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl, char side, float cfra) { bGPDframe *gpf; - int count= 0; + int count = 0; /* check for select frames on right side of current frame */ - for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { + for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { if (gpf->flag & GP_FRAME_SELECT) { if (FrameOnMouseSide(side, (float)gpf->framenum, cfra)) { /* memory is calloc'ed, so that should zero everything nicely for us */ - td->val= &tfd->val; - td->ival= (float)gpf->framenum; + td->val = &tfd->val; + td->ival = (float)gpf->framenum; - tfd->val= (float)gpf->framenum; - tfd->sdata= &gpf->framenum; + tfd->val = (float)gpf->framenum; + tfd->sdata = &gpf->framenum; /* advance td now */ td++; @@ -3167,18 +3167,18 @@ static int GPLayerToTransData (TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl static int MaskLayerToTransData(TransData *td, tGPFtransdata *tfd, MaskLayer *masklay, char side, float cfra) { MaskLayerShape *masklay_shape; - int count= 0; + int count = 0; /* check for select frames on right side of current frame */ - for (masklay_shape= masklay->splines_shapes.first; masklay_shape; masklay_shape= masklay_shape->next) { + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { if (masklay_shape->flag & MASK_SHAPE_SELECT) { if (FrameOnMouseSide(side, (float)masklay_shape->frame, cfra)) { /* memory is calloc'ed, so that should zero everything nicely for us */ - td->val= &tfd->val; - td->ival= (float)masklay_shape->frame; + td->val = &tfd->val; + td->ival = (float)masklay_shape->frame; - tfd->val= (float)masklay_shape->frame; - tfd->sdata= &masklay_shape->frame; + tfd->val = (float)masklay_shape->frame; + tfd->sdata = &masklay_shape->frame; /* advance td now */ td++; @@ -3194,7 +3194,7 @@ static int MaskLayerToTransData(TransData *td, tGPFtransdata *tfd, MaskLayer *ma static void createTransActionData(bContext *C, TransInfo *t) { - Scene *scene= t->scene; + Scene *scene = t->scene; TransData *td = NULL; TransData2D *td2d = NULL; tGPFtransdata *tfd = NULL; @@ -3204,7 +3204,7 @@ static void createTransActionData(bContext *C, TransInfo *t) bAnimListElem *ale; int filter; - int count=0; + int count = 0; float cfra; /* determine what type of data we are operating on */ @@ -3213,9 +3213,9 @@ static void createTransActionData(bContext *C, TransInfo *t) /* filter data */ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) - filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT); else - filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* which side of the current frame should be allowed */ @@ -3232,8 +3232,8 @@ static void createTransActionData(bContext *C, TransInfo *t) } /* loop 1: fully select ipo-keys and count how many BezTriples are selected */ - for (ale= anim_data.first; ale; ale= ale->next) { - AnimData *adt= ANIM_nla_mapping_get(&ac, ale); + for (ale = anim_data.first; ale; ale = ale->next) { + AnimData *adt = ANIM_nla_mapping_get(&ac, ale); /* convert current-frame to action-time (slightly less accurate, especially under * higher scaling ratios, but is faster than converting all points) @@ -3261,30 +3261,30 @@ static void createTransActionData(bContext *C, TransInfo *t) } /* allocate memory for data */ - t->total= count; + t->total = count; - t->data= MEM_callocN(t->total*sizeof(TransData), "TransData(Action Editor)"); - t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "transdata2d"); - td= t->data; + t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(Action Editor)"); + t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "transdata2d"); + td = t->data; td2d = t->data2d; if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { if (t->mode == TFM_TIME_SLIDE) { - t->customData= MEM_callocN((sizeof(float)*2)+(sizeof(tGPFtransdata)*count), "TimeSlide + tGPFtransdata"); - tfd= (tGPFtransdata *)((float *)(t->customData) + 2); + t->customData = MEM_callocN((sizeof(float) * 2) + (sizeof(tGPFtransdata) * count), "TimeSlide + tGPFtransdata"); + tfd = (tGPFtransdata *)((float *)(t->customData) + 2); } else { - t->customData= MEM_callocN(sizeof(tGPFtransdata)*count, "tGPFtransdata"); - tfd= (tGPFtransdata *)(t->customData); + t->customData = MEM_callocN(sizeof(tGPFtransdata) * count, "tGPFtransdata"); + tfd = (tGPFtransdata *)(t->customData); } } else if (t->mode == TFM_TIME_SLIDE) - t->customData= MEM_callocN(sizeof(float)*2, "TimeSlide Min/Max"); + t->customData = MEM_callocN(sizeof(float) * 2, "TimeSlide Min/Max"); /* loop 2: build transdata array */ - for (ale= anim_data.first; ale; ale= ale->next) { + for (ale = anim_data.first; ale; ale = ale->next) { if (ale->type == ANIMTYPE_GPLAYER) { - bGPDlayer *gpl= (bGPDlayer *)ale->data; + bGPDlayer *gpl = (bGPDlayer *)ale->data; int i; i = GPLayerToTransData(td, tfd, gpl, t->frame_side, cfra); @@ -3300,8 +3300,8 @@ static void createTransActionData(bContext *C, TransInfo *t) tfd += i; } else { - AnimData *adt= ANIM_nla_mapping_get(&ac, ale); - FCurve *fcu= (FCurve *)ale->key_data; + AnimData *adt = ANIM_nla_mapping_get(&ac, ale); + FCurve *fcu = (FCurve *)ale->key_data; /* convert current-frame to action-time (slightly less accurate, especially under * higher scaling ratios, but is faster than converting all points) @@ -3311,19 +3311,19 @@ static void createTransActionData(bContext *C, TransInfo *t) else cfra = (float)CFRA; - td= ActionFCurveToTransData(td, &td2d, fcu, adt, t->frame_side, cfra); + td = ActionFCurveToTransData(td, &td2d, fcu, adt, t->frame_side, cfra); } } /* check if we're supposed to be setting minx/maxx for TimeSlide */ if (t->mode == TFM_TIME_SLIDE) { - float min=999999999.0f, max=-999999999.0f; + float min = 999999999.0f, max = -999999999.0f; int i; - td= t->data; - for (i=0; i < count; i++, td++) { - if (min > *(td->val)) min= *(td->val); - if (max < *(td->val)) max= *(td->val); + td = t->data; + for (i = 0; i < count; i++, td++) { + if (min > *(td->val)) min = *(td->val); + if (max < *(td->val)) max = *(td->val); } if (min == max) { @@ -3349,9 +3349,9 @@ static void createTransActionData(bContext *C, TransInfo *t) /* Helper function for createTransGraphEditData, which is responsible for associating * source data with transform data */ -static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, BezTriple *bezt, - int bi, short selected, short ishandle, short intvals, - float mtx[3][3], float smtx[3][3]) +static void bezt_to_transdata(TransData *td, TransData2D *td2d, AnimData *adt, BezTriple *bezt, + int bi, short selected, short ishandle, short intvals, + float mtx[3][3], float smtx[3][3]) { float *loc = bezt->vec[bi]; float *cent = bezt->vec[1]; @@ -3404,17 +3404,17 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->val= NULL; + td->ext = NULL; td->val = NULL; /* store AnimData info in td->extra, for applying mapping when flushing */ - td->extra= adt; + td->extra = adt; if (selected) { td->flag |= TD_SELECTED; - td->dist= 0.0f; + td->dist = 0.0f; } else - td->dist= MAXFLOAT; + td->dist = MAXFLOAT; if (ishandle) td->flag |= TD_NOTIMESNAP; @@ -3429,9 +3429,9 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, static void createTransGraphEditData(bContext *C, TransInfo *t) { SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; - Scene *scene= t->scene; - ARegion *ar= t->ar; - View2D *v2d= &ar->v2d; + Scene *scene = t->scene; + ARegion *ar = t->ar; + View2D *v2d = &ar->v2d; TransData *td = NULL; TransData2D *td2d = NULL; @@ -3442,7 +3442,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) int filter; BezTriple *bezt; - int count=0, i; + int count = 0, i; float cfra; float mtx[3][3], smtx[3][3]; const short use_handle = !(sipo->flag & SIPO_NOHANDLES); @@ -3452,11 +3452,11 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) return; /* filter data */ - filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* which side of the current frame should be allowed */ - // XXX we still want this mode, but how to get this using standard transform too? + // XXX we still want this mode, but how to get this using standard transform too? if (t->mode == TFM_TIME_EXTEND) { /* only side on which mouse is gets transformed */ float xmouse, ymouse; @@ -3470,9 +3470,9 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) } /* loop 1: count how many BezTriples (specifically their verts) are selected (or should be edited) */ - for (ale= anim_data.first; ale; ale= ale->next) { - AnimData *adt= ANIM_nla_mapping_get(&ac, ale); - FCurve *fcu= (FCurve *)ale->key_data; + for (ale = anim_data.first; ale; ale = ale->next) { + AnimData *adt = ANIM_nla_mapping_get(&ac, ale); + FCurve *fcu = (FCurve *)ale->key_data; /* convert current-frame to action-time (slightly less accurate, especially under * higher scaling ratios, but is faster than converting all points) @@ -3487,11 +3487,11 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) continue; /* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse */ - for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) { + for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) { - const char sel2= bezt->f2 & SELECT; - const char sel1= use_handle ? bezt->f1 & SELECT : sel2; - const char sel3= use_handle ? bezt->f3 & SELECT : sel2; + const char sel2 = bezt->f2 & SELECT; + const char sel1 = use_handle ? bezt->f1 & SELECT : sel2; + const char sel3 = use_handle ? bezt->f3 & SELECT : sel2; if (ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE)) { /* for 'normal' pivots - just include anything that is selected. @@ -3531,14 +3531,14 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) } /* allocate memory for data */ - t->total= count; + t->total = count; - t->data= MEM_callocN(t->total*sizeof(TransData), "TransData (Graph Editor)"); - /* for each 2d vert a 3d vector is allocated, so that they can be treated just as if they were 3d verts */ - t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransData2D (Graph Editor)"); + t->data = MEM_callocN(t->total * sizeof(TransData), "TransData (Graph Editor)"); + /* for each 2d vert a 3d vector is allocated, so that they can be treated just as if they were 3d verts */ + t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransData2D (Graph Editor)"); - td= t->data; - td2d= t->data2d; + td = t->data; + td2d = t->data2d; /* precompute space-conversion matrices for dealing with non-uniform scaling of Graph Editor */ unit_m3(mtx); @@ -3555,15 +3555,15 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) mul_v3_fl(mtx[1], yscale); /* smtx is global (i.e. view) to data conversion */ - if (IS_EQF(xscale, 0.0f) == 0) mul_v3_fl(smtx[0], 1.0f/xscale); - if (IS_EQF(yscale, 0.0f) == 0) mul_v3_fl(smtx[1], 1.0f/yscale); + if (IS_EQF(xscale, 0.0f) == 0) mul_v3_fl(smtx[0], 1.0f / xscale); + if (IS_EQF(yscale, 0.0f) == 0) mul_v3_fl(smtx[1], 1.0f / yscale); } /* loop 2: build transdata arrays */ - for (ale= anim_data.first; ale; ale= ale->next) { - AnimData *adt= ANIM_nla_mapping_get(&ac, ale); - FCurve *fcu= (FCurve *)ale->key_data; - short intvals= (fcu->flag & FCURVE_INT_VALUES); + for (ale = anim_data.first; ale; ale = ale->next) { + AnimData *adt = ANIM_nla_mapping_get(&ac, ale); + FCurve *fcu = (FCurve *)ale->key_data; + short intvals = (fcu->flag & FCURVE_INT_VALUES); /* convert current-frame to action-time (slightly less accurate, especially under * higher scaling ratios, but is faster than converting all points) @@ -3577,14 +3577,14 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) if (fcu->bezt == NULL) continue; - ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYSEL|ANIM_UNITCONV_SELVERTS); + ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYSEL | ANIM_UNITCONV_SELVERTS); /* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse (if applicable) */ - for (i=0, bezt= fcu->bezt; i < fcu->totvert; i++, bezt++) { + for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) { - const char sel2= bezt->f2 & SELECT; - const char sel1= use_handle ? bezt->f1 & SELECT : sel2; - const char sel3= use_handle ? bezt->f3 & SELECT : sel2; + const char sel2 = bezt->f2 & SELECT; + const char sel1 = use_handle ? bezt->f1 & SELECT : sel2; + const char sel3 = use_handle ? bezt->f3 & SELECT : sel2; TransDataCurveHandleFlags *hdata = NULL; /* short h1=1, h2=1; */ /* UNUSED */ @@ -3602,7 +3602,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) } if (sel3) { - if (hdata==NULL) + if (hdata == NULL) hdata = initTransDataCurveHandles(td, bezt); bezt_to_transdata(td++, td2d++, adt, bezt, 2, 1, 1, intvals, mtx, smtx); } @@ -3639,8 +3639,8 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) { if (hdata && (sel1) && (sel3)) { - bezt->h1= HD_ALIGN; - bezt->h2= HD_ALIGN; + bezt->h1 = HD_ALIGN; + bezt->h2 = HD_ALIGN; } } } @@ -3660,64 +3660,64 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) /* struct for use in re-sorting BezTriples during Graph Editor transform */ typedef struct BeztMap { BezTriple *bezt; - unsigned int oldIndex; /* index of bezt in fcu->bezt array before sorting */ - unsigned int newIndex; /* index of bezt in fcu->bezt array after sorting */ - short swapHs; /* swap order of handles (-1=clear; 0=not checked, 1=swap) */ - char pipo, cipo; /* interpolation of current and next segments */ + unsigned int oldIndex; /* index of bezt in fcu->bezt array before sorting */ + unsigned int newIndex; /* index of bezt in fcu->bezt array after sorting */ + short swapHs; /* swap order of handles (-1=clear; 0=not checked, 1=swap) */ + char pipo, cipo; /* interpolation of current and next segments */ } BeztMap; /* This function converts an FCurve's BezTriple array to a BeztMap array * NOTE: this allocates memory that will need to get freed later */ -static BeztMap *bezt_to_beztmaps (BezTriple *bezts, int totvert, const short UNUSED(use_handle)) +static BeztMap *bezt_to_beztmaps(BezTriple *bezts, int totvert, const short UNUSED(use_handle)) { - BezTriple *bezt= bezts; - BezTriple *prevbezt= NULL; + BezTriple *bezt = bezts; + BezTriple *prevbezt = NULL; BeztMap *bezm, *bezms; int i; /* allocate memory for this array */ - if (totvert==0 || bezts==NULL) + if (totvert == 0 || bezts == NULL) return NULL; - bezm= bezms= MEM_callocN(sizeof(BeztMap)*totvert, "BeztMaps"); + bezm = bezms = MEM_callocN(sizeof(BeztMap) * totvert, "BeztMaps"); /* assign beztriples to beztmaps */ - for (i=0; i < totvert; i++, bezm++, prevbezt=bezt, bezt++) { - bezm->bezt= bezt; + for (i = 0; i < totvert; i++, bezm++, prevbezt = bezt, bezt++) { + bezm->bezt = bezt; - bezm->oldIndex= i; - bezm->newIndex= i; + bezm->oldIndex = i; + bezm->newIndex = i; - bezm->pipo= (prevbezt) ? prevbezt->ipo : bezt->ipo; - bezm->cipo= bezt->ipo; + bezm->pipo = (prevbezt) ? prevbezt->ipo : bezt->ipo; + bezm->cipo = bezt->ipo; } return bezms; } /* This function copies the code of sort_time_ipocurve, but acts on BeztMap structs instead */ -static void sort_time_beztmaps (BeztMap *bezms, int totvert, const short UNUSED(use_handle)) +static void sort_time_beztmaps(BeztMap *bezms, int totvert, const short UNUSED(use_handle)) { BeztMap *bezm; - int i, ok= 1; + int i, ok = 1; /* keep repeating the process until nothing is out of place anymore */ while (ok) { - ok= 0; + ok = 0; - bezm= bezms; - i= totvert; + bezm = bezms; + i = totvert; while (i--) { /* is current bezm out of order (i.e. occurs later than next)? */ if (i > 0) { - if (bezm->bezt->vec[1][0] > (bezm+1)->bezt->vec[1][0]) { + if (bezm->bezt->vec[1][0] > (bezm + 1)->bezt->vec[1][0]) { bezm->newIndex++; - (bezm+1)->newIndex--; + (bezm + 1)->newIndex--; - SWAP(BeztMap, *bezm, *(bezm+1)); + SWAP(BeztMap, *bezm, *(bezm + 1)); - ok= 1; + ok = 1; } } @@ -3743,7 +3743,7 @@ static void sort_time_beztmaps (BeztMap *bezms, int totvert, const short UNUSED( } /* This function firstly adjusts the pointers that the transdata has to each BezTriple */ -static void beztmap_to_data (TransInfo *t, FCurve *fcu, BeztMap *bezms, int totvert, const short UNUSED(use_handle)) +static void beztmap_to_data(TransInfo *t, FCurve *fcu, BeztMap *bezms, int totvert, const short UNUSED(use_handle)) { BezTriple *bezts = fcu->bezt; BeztMap *bezm; @@ -3756,17 +3756,17 @@ static void beztmap_to_data (TransInfo *t, FCurve *fcu, BeztMap *bezms, int totv * pointers have been fixed already, so that we don't override ones that are * already done */ - adjusted= MEM_callocN(t->total, "beztmap_adjusted_map"); + adjusted = MEM_callocN(t->total, "beztmap_adjusted_map"); /* for each beztmap item, find if it is used anywhere */ - bezm= bezms; - for (i= 0; i < totvert; i++, bezm++) { + bezm = bezms; + for (i = 0; i < totvert; i++, bezm++) { /* loop through transdata, testing if we have a hit * for the handles (vec[0]/vec[2]), we must also check if they need to be swapped... */ - td2d= t->data2d; - td= t->data; - for (j= 0; j < t->total; j++, td2d++, td++) { + td2d = t->data2d; + td = t->data; + for (j = 0; j < t->total; j++, td2d++, td++) { /* skip item if already marked */ if (adjusted[j] != 0) continue; @@ -3775,26 +3775,26 @@ static void beztmap_to_data (TransInfo *t, FCurve *fcu, BeztMap *bezms, int totv */ if (td2d->loc2d == bezm->bezt->vec[0]) { if (bezm->swapHs == 1) - td2d->loc2d= (bezts + bezm->newIndex)->vec[2]; + td2d->loc2d = (bezts + bezm->newIndex)->vec[2]; else - td2d->loc2d= (bezts + bezm->newIndex)->vec[0]; + td2d->loc2d = (bezts + bezm->newIndex)->vec[0]; adjusted[j] = 1; } else if (td2d->loc2d == bezm->bezt->vec[2]) { if (bezm->swapHs == 1) - td2d->loc2d= (bezts + bezm->newIndex)->vec[0]; + td2d->loc2d = (bezts + bezm->newIndex)->vec[0]; else - td2d->loc2d= (bezts + bezm->newIndex)->vec[2]; + td2d->loc2d = (bezts + bezm->newIndex)->vec[2]; adjusted[j] = 1; } else if (td2d->loc2d == bezm->bezt->vec[1]) { - td2d->loc2d= (bezts + bezm->newIndex)->vec[1]; + td2d->loc2d = (bezts + bezm->newIndex)->vec[1]; /* if only control point is selected, the handle pointers need to be updated as well */ if (td2d->h1) - td2d->h1= (bezts + bezm->newIndex)->vec[0]; + td2d->h1 = (bezts + bezm->newIndex)->vec[0]; if (td2d->h2) - td2d->h2= (bezts + bezm->newIndex)->vec[2]; + td2d->h2 = (bezts + bezm->newIndex)->vec[2]; adjusted[j] = 1; } @@ -3832,15 +3832,15 @@ void remake_graph_transdata(TransInfo *t, ListBase *anim_data) const short use_handle = !(sipo->flag & SIPO_NOHANDLES); /* sort and reassign verts */ - for (ale= anim_data->first; ale; ale= ale->next) { - FCurve *fcu= (FCurve *)ale->key_data; + for (ale = anim_data->first; ale; ale = ale->next) { + FCurve *fcu = (FCurve *)ale->key_data; if (fcu->bezt) { BeztMap *bezm; /* adjust transform-data pointers */ /* note, none of these functions use 'use_handle', it could be removed */ - bezm= bezt_to_beztmaps(fcu->bezt, fcu->totvert, use_handle); + bezm = bezt_to_beztmaps(fcu->bezt, fcu->totvert, use_handle); sort_time_beztmaps(bezm, fcu->totvert, use_handle); beztmap_to_data(t, fcu, bezm, fcu->totvert, use_handle); @@ -3864,19 +3864,19 @@ void flushTransGraphData(TransInfo *t) SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; TransData *td; TransData2D *td2d; - Scene *scene= t->scene; - double secf= FPS; + Scene *scene = t->scene; + double secf = FPS; int a; /* flush to 2d vector from internally used 3d vector */ - for (a=0, td= t->data, td2d=t->data2d; atotal; a++, td++, td2d++) { - AnimData *adt= (AnimData *)td->extra; /* pointers to relevant AnimData blocks are stored in the td->extra pointers */ + for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) { + AnimData *adt = (AnimData *)td->extra; /* pointers to relevant AnimData blocks are stored in the td->extra pointers */ /* handle snapping for time values * - we should still be in NLA-mapping timespace * - only apply to keyframes (but never to handles) */ - if ((td->flag & TD_NOTIMESNAP)==0) { + if ((td->flag & TD_NOTIMESNAP) == 0) { switch (sipo->autosnap) { case SACTSNAP_FRAME: /* snap to nearest frame (or second if drawing seconds) */ if (sipo->flag & SIPO_DRAWTIME) @@ -3886,22 +3886,22 @@ void flushTransGraphData(TransInfo *t) break; case SACTSNAP_MARKER: /* snap to nearest marker */ - td2d->loc[0]= (float)ED_markers_find_nearest_marker_time(&t->scene->markers, td2d->loc[0]); + td2d->loc[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, td2d->loc[0]); break; } } /* we need to unapply the nla-mapping from the time in some situations */ if (adt) - td2d->loc2d[0]= BKE_nla_tweakedit_remap(adt, td2d->loc[0], NLATIME_CONVERT_UNMAP); + td2d->loc2d[0] = BKE_nla_tweakedit_remap(adt, td2d->loc[0], NLATIME_CONVERT_UNMAP); else - td2d->loc2d[0]= td2d->loc[0]; + td2d->loc2d[0] = td2d->loc[0]; /* if int-values only, truncate to integers */ if (td->flag & TD_INTVALUES) - td2d->loc2d[1]= floorf(td2d->loc[1] + 0.5f); + td2d->loc2d[1] = floorf(td2d->loc[1] + 0.5f); else - td2d->loc2d[1]= td2d->loc[1]; + td2d->loc2d[1] = td2d->loc[1]; if ((td->flag & TD_MOVEHANDLE1) && td2d->h1) { td2d->h1[0] = td2d->ih1[0] + td->loc[0] - td->iloc[0]; @@ -3933,9 +3933,9 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count /* *** Extend Transform *** */ Scene *scene = t->scene; - int cfra= CFRA; - int left= seq_tx_get_final_left(seq, 1); - int right= seq_tx_get_final_right(seq, 1); + int cfra = CFRA; + int left = seq_tx_get_final_left(seq, 1); + int right = seq_tx_get_final_right(seq, 1); if (seq->depth == 0 && ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) { *recursive = FALSE; @@ -3946,34 +3946,34 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count /* for meta's we only ever need to extend their children, no matter what depth * just check the meta's are in the bounds */ - if (t->frame_side=='R' && right <= cfra) *recursive = FALSE; - else if (t->frame_side=='L' && left >= cfra) *recursive = FALSE; - else *recursive = TRUE; + if (t->frame_side == 'R' && right <= cfra) *recursive = FALSE; + else if (t->frame_side == 'L' && left >= cfra) *recursive = FALSE; + else *recursive = TRUE; - *count= 1; - *flag= (seq->flag | SELECT) & ~(SEQ_LEFTSEL|SEQ_RIGHTSEL); + *count = 1; + *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL); } else { *recursive = FALSE; /* not a meta, so no thinking here */ *count = 1; /* unless its set to 0, extend will never set 2 handles at once */ - *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL|SEQ_RIGHTSEL); + *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL); - if (t->frame_side=='R') { - if (right <= cfra) *count = *flag= 0; /* ignore */ + if (t->frame_side == 'R') { + if (right <= cfra) *count = *flag = 0; /* ignore */ else if (left > cfra) ; /* keep the selection */ - else *flag |= SEQ_RIGHTSEL; + else *flag |= SEQ_RIGHTSEL; } else { - if (left >= cfra) *count = *flag= 0; /* ignore */ - else if (right < cfra) ; /* keep the selection */ - else *flag |= SEQ_LEFTSEL; + if (left >= cfra) *count = *flag = 0; /* ignore */ + else if (right < cfra) ; /* keep the selection */ + else *flag |= SEQ_LEFTSEL; } } } else { - t->frame_side= 'B'; + t->frame_side = 'B'; /* *** Normal Transform *** */ @@ -3988,18 +3988,18 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count *flag = 0; } else { - if ((seq->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) == (SEQ_LEFTSEL|SEQ_RIGHTSEL)) { - *flag= seq->flag; - *count= 2; /* we need 2 transdata's */ + if ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == (SEQ_LEFTSEL | SEQ_RIGHTSEL)) { + *flag = seq->flag; + *count = 2; /* we need 2 transdata's */ } else { - *flag= seq->flag; - *count= 1; /* selected or with a handle selected */ + *flag = seq->flag; + *count = 1; /* selected or with a handle selected */ } /* Recursive */ - if ((seq->type == SEQ_TYPE_META) && ((seq->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) == 0)) { + if ((seq->type == SEQ_TYPE_META) && ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == 0)) { /* if any handles are selected, don't recurse */ *recursive = TRUE; } @@ -4012,7 +4012,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count /* Nested, different rules apply */ #ifdef SEQ_TX_NESTED_METAS - *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL|SEQ_RIGHTSEL); + *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL); *count = 1; /* ignore the selection for nested */ *recursive = (seq->type == SEQ_TYPE_META); #else @@ -4021,13 +4021,13 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count * don't have their start and length set directly (children affect that) * since this Meta is nested we don't need any of its data in fact. * calc_sequence() will update its settings when run on the toplevel meta */ - *flag= 0; - *count= 0; + *flag = 0; + *count = 0; *recursive = TRUE; } else { - *flag= (seq->flag | SELECT) & ~(SEQ_LEFTSEL|SEQ_RIGHTSEL); - *count= 1; /* ignore the selection for nested */ + *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL); + *count = 1; /* ignore the selection for nested */ *recursive = FALSE; } #endif @@ -4040,10 +4040,10 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count static int SeqTransCount(TransInfo *t, Sequence *parent, ListBase *seqbase, int depth) { Sequence *seq; - int tot= 0, recursive, count, flag; + int tot = 0, recursive, count, flag; - for (seq= seqbase->first; seq; seq= seq->next) { - seq->depth= depth; + for (seq = seqbase->first; seq; seq = seq->next) { + seq->depth = depth; /* seq->tmp is used by seq_tx_get_final_{left, right} to check sequence's range and clamp to it if needed. * it's first place where digging into sequences tree, so store link to parent here */ @@ -4053,7 +4053,7 @@ static int SeqTransCount(TransInfo *t, Sequence *parent, ListBase *seqbase, int tot += count; if (recursive) { - tot += SeqTransCount(t, seq, &seq->seqbase, depth+1); + tot += SeqTransCount(t, seq, &seq->seqbase, depth + 1); } } @@ -4066,21 +4066,21 @@ static TransData *SeqToTransData(TransData *td, TransData2D *td2d, TransDataSeq int start_left; switch (sel_flag) { - case SELECT: - /* Use seq_tx_get_final_left() and an offset here - * so transform has the left hand location of the strip. - * tdsq->start_offset is used when flushing the tx data back */ - start_left= seq_tx_get_final_left(seq, 0); - td2d->loc[0]= start_left; - tdsq->start_offset= start_left - seq->start; /* use to apply the original location */ - break; - case SEQ_LEFTSEL: - start_left= seq_tx_get_final_left(seq, 0); - td2d->loc[0] = start_left; - break; - case SEQ_RIGHTSEL: - td2d->loc[0] = seq_tx_get_final_right(seq, 0); - break; + case SELECT: + /* Use seq_tx_get_final_left() and an offset here + * so transform has the left hand location of the strip. + * tdsq->start_offset is used when flushing the tx data back */ + start_left = seq_tx_get_final_left(seq, 0); + td2d->loc[0] = start_left; + tdsq->start_offset = start_left - seq->start; /* use to apply the original location */ + break; + case SEQ_LEFTSEL: + start_left = seq_tx_get_final_left(seq, 0); + td2d->loc[0] = start_left; + break; + case SEQ_RIGHTSEL: + td2d->loc[0] = seq_tx_get_final_right(seq, 0); + break; } td2d->loc[1] = seq->machine; /* channel - Y location */ @@ -4088,15 +4088,15 @@ static TransData *SeqToTransData(TransData *td, TransData2D *td2d, TransDataSeq td2d->loc2d = NULL; - tdsq->seq= seq; + tdsq->seq = seq; /* Use instead of seq->flag for nested strips and other * cases where the selection may need to be modified */ - tdsq->flag= flag; - tdsq->sel_flag= sel_flag; + tdsq->flag = flag; + tdsq->sel_flag = sel_flag; - td->extra= (void *)tdsq; /* allow us to update the strip from here */ + td->extra = (void *)tdsq; /* allow us to update the strip from here */ td->flag = 0; td->loc = td2d->loc; @@ -4106,17 +4106,17 @@ static TransData *SeqToTransData(TransData *td, TransData2D *td2d, TransDataSeq memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->val= NULL; + td->ext = NULL; td->val = NULL; td->flag |= TD_SELECTED; - td->dist= 0.0; + td->dist = 0.0; unit_m3(td->mtx); unit_m3(td->smtx); /* Time Transform (extend) */ - td->val= td2d->loc; - td->ival= td2d->loc[0]; + td->val = td2d->loc; + td->ival = td2d->loc[0]; return td; } @@ -4125,26 +4125,26 @@ static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData * { Sequence *seq; int recursive, count, flag; - int tot= 0; + int tot = 0; - for (seq= seqbase->first; seq; seq= seq->next) { + for (seq = seqbase->first; seq; seq = seq->next) { SeqTransInfo(t, seq, &recursive, &count, &flag); /* add children first so recalculating metastrips does nested strips first */ if (recursive) { - int tot_children= SeqToTransData_Recursive(t, &seq->seqbase, td, td2d, tdsq); + int tot_children = SeqToTransData_Recursive(t, &seq->seqbase, td, td2d, tdsq); - td= td + tot_children; - td2d= td2d + tot_children; - tdsq= tdsq + tot_children; + td = td + tot_children; + td2d = td2d + tot_children; + tdsq = tdsq + tot_children; tot += tot_children; } /* use 'flag' which is derived from seq->flag but modified for special cases */ if (flag & SELECT) { - if (flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) { + if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) { if (flag & SEQ_LEFTSEL) { SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_LEFTSEL); tot++; @@ -4166,83 +4166,83 @@ static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData * static void freeSeqData(TransInfo *t) { - Editing *ed= BKE_sequencer_editing_get(t->scene, FALSE); + Editing *ed = BKE_sequencer_editing_get(t->scene, FALSE); if (ed != NULL) { - ListBase *seqbasep= ed->seqbasep; - TransData *td= t->data; + ListBase *seqbasep = ed->seqbasep; + TransData *td = t->data; int a; /* prevent updating the same seq twice * if the transdata order is changed this will mess up * but so will TransDataSeq */ - Sequence *seq_prev= NULL; + Sequence *seq_prev = NULL; Sequence *seq; if (!(t->state == TRANS_CANCEL)) { -#if 0 // default 2.4 behavior +#if 0 // default 2.4 behavior /* flush to 2d vector from internally used 3d vector */ - for (a=0; atotal; a++, td++) { - if ((seq != seq_prev) && (seq->depth==0) && (seq->flag & SEQ_OVERLAP)) { - seq= ((TransDataSeq *)td->extra)->seq; + for (a = 0; a < t->total; a++, td++) { + if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) { + seq = ((TransDataSeq *)td->extra)->seq; shuffle_seq(seqbasep, seq); } - seq_prev= seq; + seq_prev = seq; } -#else // durian hack +#else // durian hack { - int overlap= 0; + int overlap = 0; - for (a=0; atotal; a++, td++) { - seq_prev= NULL; - seq= ((TransDataSeq *)td->extra)->seq; - if ((seq != seq_prev) && (seq->depth==0) && (seq->flag & SEQ_OVERLAP)) { - overlap= 1; + for (a = 0; a < t->total; a++, td++) { + seq_prev = NULL; + seq = ((TransDataSeq *)td->extra)->seq; + if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) { + overlap = 1; break; } - seq_prev= seq; + seq_prev = seq; } if (overlap) { - int has_effect= 0; - for (seq= seqbasep->first; seq; seq= seq->next) - seq->tmp= NULL; + int has_effect = 0; + for (seq = seqbasep->first; seq; seq = seq->next) + seq->tmp = NULL; - td= t->data; - seq_prev= NULL; - for (a=0; atotal; a++, td++) { - seq= ((TransDataSeq *)td->extra)->seq; + td = t->data; + seq_prev = NULL; + for (a = 0; a < t->total; a++, td++) { + seq = ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { /* check effects strips, we cant change their time */ if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { - has_effect= TRUE; + has_effect = TRUE; } else { /* Tag seq with a non zero value, used by shuffle_seq_time to identify the ones to shuffle */ - seq->tmp= (void*)1; + seq->tmp = (void *)1; } } } -#if 1 /* (mango hack! - for Ian) this is truely bad - should _never_ be in a release :| */ +#if 1 /* (mango hack! - for Ian) this is truely bad - should _never_ be in a release :| */ if (CTX_wm_window(t->context)->eventstate->alt) { int minframe = MAXFRAME; - td= t->data; - seq_prev= NULL; - for (a=0; atotal; a++, td++) { - seq= ((TransDataSeq *)td->extra)->seq; + td = t->data; + seq_prev = NULL; + for (a = 0; a < t->total; a++, td++) { + seq = ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { minframe = MIN2(minframe, seq->startdisp); } } - for (seq= seqbasep->first; seq; seq= seq->next) { + for (seq = seqbasep->first; seq; seq = seq->next) { if (!(seq->flag & SELECT)) { if (seq->startdisp >= minframe) { seq->machine += MAXSEQ * 2; @@ -4252,13 +4252,13 @@ static void freeSeqData(TransInfo *t) shuffle_seq_time(seqbasep, t->scene); - for (seq= seqbasep->first; seq; seq= seq->next) { + for (seq = seqbasep->first; seq; seq = seq->next) { if (seq->machine >= MAXSEQ * 2) { seq->machine -= MAXSEQ * 2; - seq->tmp= (void*)1; + seq->tmp = (void *)1; } else { - seq->tmp= NULL; + seq->tmp = NULL; } } @@ -4273,10 +4273,10 @@ static void freeSeqData(TransInfo *t) if (has_effect) { /* update effects strips based on strips just moved in time */ - td= t->data; - seq_prev= NULL; - for (a=0; atotal; a++, td++) { - seq= ((TransDataSeq *)td->extra)->seq; + td = t->data; + seq_prev = NULL; + for (a = 0; a < t->total; a++, td++) { + seq = ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { calc_sequence(t->scene, seq); @@ -4285,10 +4285,10 @@ static void freeSeqData(TransInfo *t) } /* now if any effects _still_ overlap, we need to move them up */ - td= t->data; - seq_prev= NULL; - for (a=0; atotal; a++, td++) { - seq= ((TransDataSeq *)td->extra)->seq; + td = t->data; + seq_prev = NULL; + for (a = 0; a < t->total; a++, td++) { + seq = ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { if (seq_test_overlap(seqbasep, seq)) { @@ -4303,7 +4303,7 @@ static void freeSeqData(TransInfo *t) } #endif - for (seq= seqbasep->first; seq; seq= seq->next) { + for (seq = seqbasep->first; seq; seq = seq->next) { /* We might want to build a list of effects that need to be updated during transform */ if (seq->type & SEQ_TYPE_EFFECT) { if (seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(t->scene, seq); @@ -4316,12 +4316,12 @@ static void freeSeqData(TransInfo *t) } else { /* Cancelled, need to update the strips display */ - for (a=0; atotal; a++, td++) { - seq= ((TransDataSeq *)td->extra)->seq; - if ((seq != seq_prev) && (seq->depth==0)) { + for (a = 0; a < t->total; a++, td++) { + seq = ((TransDataSeq *)td->extra)->seq; + if ((seq != seq_prev) && (seq->depth == 0)) { calc_sequence_disp(t->scene, seq); } - seq_prev= seq; + seq_prev = seq; } } } @@ -4332,7 +4332,7 @@ static void freeSeqData(TransInfo *t) } if (t->data) { MEM_freeN(t->data); // XXX postTrans usually does this - t->data= NULL; + t->data = NULL; } } @@ -4340,21 +4340,21 @@ static void createTransSeqData(bContext *C, TransInfo *t) { #define XXX_DURIAN_ANIM_TX_HACK - View2D *v2d= UI_view2d_fromcontext(C); - Scene *scene= t->scene; - Editing *ed= BKE_sequencer_editing_get(t->scene, FALSE); + View2D *v2d = UI_view2d_fromcontext(C); + Scene *scene = t->scene; + Editing *ed = BKE_sequencer_editing_get(t->scene, FALSE); TransData *td = NULL; - TransData2D *td2d= NULL; - TransDataSeq *tdsq= NULL; + TransData2D *td2d = NULL; + TransDataSeq *tdsq = NULL; - int count=0; + int count = 0; - if (ed==NULL) { - t->total= 0; + if (ed == NULL) { + t->total = 0; return; } - t->customFree= freeSeqData; + t->customFree = freeSeqData; /* which side of the current frame should be allowed */ if (t->mode == TFM_TIME_EXTEND) { @@ -4372,16 +4372,16 @@ static void createTransSeqData(bContext *C, TransInfo *t) #ifdef XXX_DURIAN_ANIM_TX_HACK { Sequence *seq; - for (seq= ed->seqbasep->first; seq; seq= seq->next) { + for (seq = ed->seqbasep->first; seq; seq = seq->next) { /* hack */ - if ((seq->flag & SELECT)==0 && seq->type & SEQ_TYPE_EFFECT) { + if ((seq->flag & SELECT) == 0 && seq->type & SEQ_TYPE_EFFECT) { Sequence *seq_user; int i; - for (i=0; i<3; i++) { - seq_user= *((&seq->seq1) + i); + for (i = 0; i < 3; i++) { + seq_user = *((&seq->seq1) + i); if (seq_user && (seq_user->flag & SELECT) && !(seq_user->flag & SEQ_LOCK) && - !(seq_user->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL))) + !(seq_user->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL))) { seq->flag |= SELECT; } @@ -4394,16 +4394,16 @@ static void createTransSeqData(bContext *C, TransInfo *t) count = SeqTransCount(t, NULL, ed->seqbasep, 0); /* allocate memory for data */ - t->total= count; + t->total = count; /* stop if trying to build list if nothing selected */ if (count == 0) { return; } - td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransSeq TransData"); - td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransSeq TransData2D"); - tdsq = t->customData = MEM_callocN(t->total*sizeof(TransDataSeq), "TransSeq TransDataSeq"); + td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransSeq TransData"); + td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransSeq TransData2D"); + tdsq = t->customData = MEM_callocN(t->total * sizeof(TransDataSeq), "TransSeq TransDataSeq"); t->flag |= T_FREE_CUSTOMDATA; @@ -4431,17 +4431,17 @@ static short constraints_list_needinv(TransInfo *t, ListBase *list) * constraints needing special crazyspace corrections */ if (list) { - for (con= list->first; con; con=con->next) { + for (con = list->first; con; con = con->next) { /* only consider constraint if it is enabled, and has influence on result */ - if ((con->flag & CONSTRAINT_DISABLE)==0 && (con->enforce!=0.0f)) { + if ((con->flag & CONSTRAINT_DISABLE) == 0 && (con->enforce != 0.0f)) { /* (affirmative) returns for specific constraints here... */ - /* constraints that require this regardless */ + /* constraints that require this regardless */ if (con->type == CONSTRAINT_TYPE_CHILDOF) return 1; if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) return 1; if (con->type == CONSTRAINT_TYPE_CLAMPTO) return 1; if (con->type == CONSTRAINT_TYPE_OBJECTSOLVER) return 1; - /* constraints that require this only under special conditions */ + /* constraints that require this only under special conditions */ if (con->type == CONSTRAINT_TYPE_ROTLIKE) { /* CopyRot constraint only does this when rotating, and offset is on */ bRotateLikeConstraint *data = (bRotateLikeConstraint *)con->data; @@ -4469,11 +4469,11 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) copy_m3_m4(td->axismtx, ob->obmat); normalize_m3(td->axismtx); - td->con= ob->constraints.first; + td->con = ob->constraints.first; /* hack: temporarily disable tracking and/or constraints when getting * object matrix, if tracking is on, or if constraints don't need - * inverse correction to stop it from screwing up space conversion + * inverse correction to stop it from screwing up space conversion * matrix later */ constinv = constraints_list_needinv(t, &ob->constraints); @@ -4484,7 +4484,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) if (skip_invert == 0 && constinv == 0) { if (constinv == 0) - ob->transflag |= OB_NO_CONSTRAINTS; /* BKE_object_where_is_calc_time checks this */ + ob->transflag |= OB_NO_CONSTRAINTS; /* BKE_object_where_is_calc_time checks this */ BKE_object_where_is_calc(t->scene, ob); @@ -4500,35 +4500,35 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) copy_v3_v3(td->iloc, td->loc); if (ob->rotmode > 0) { - td->ext->rot= ob->rot; - td->ext->rotAxis= NULL; - td->ext->rotAngle= NULL; - td->ext->quat= NULL; + td->ext->rot = ob->rot; + td->ext->rotAxis = NULL; + td->ext->rotAngle = NULL; + td->ext->quat = NULL; copy_v3_v3(td->ext->irot, ob->rot); copy_v3_v3(td->ext->drot, ob->drot); } else if (ob->rotmode == ROT_MODE_AXISANGLE) { - td->ext->rot= NULL; - td->ext->rotAxis= ob->rotAxis; - td->ext->rotAngle= &ob->rotAngle; - td->ext->quat= NULL; + td->ext->rot = NULL; + td->ext->rotAxis = ob->rotAxis; + td->ext->rotAngle = &ob->rotAngle; + td->ext->quat = NULL; - td->ext->irotAngle= ob->rotAngle; + td->ext->irotAngle = ob->rotAngle; copy_v3_v3(td->ext->irotAxis, ob->rotAxis); // td->ext->drotAngle= ob->drotAngle; // XXX, not implemented // copy_v3_v3(td->ext->drotAxis, ob->drotAxis); // XXX, not implemented } else { - td->ext->rot= NULL; - td->ext->rotAxis= NULL; - td->ext->rotAngle= NULL; - td->ext->quat= ob->quat; + td->ext->rot = NULL; + td->ext->rotAxis = NULL; + td->ext->rotAngle = NULL; + td->ext->quat = ob->quat; copy_qt_qt(td->ext->iquat, ob->quat); copy_qt_qt(td->ext->dquat, ob->dquat); } - td->ext->rotOrder=ob->rotmode; + td->ext->rotOrder = ob->rotmode; td->ext->size = ob->size; copy_v3_v3(td->ext->isize, ob->size); @@ -4586,17 +4586,17 @@ static void set_trans_object_base_flags(TransInfo *t) BKE_scene_base_flag_to_objects(t->scene); /* handle pending update events, otherwise they got copied below */ - for (base= scene->base.first; base; base= base->next) { + for (base = scene->base.first; base; base = base->next) { if (base->object->recalc) BKE_object_handle_update(t->scene, base->object); } - for (base= scene->base.first; base; base= base->next) { + for (base = scene->base.first; base; base = base->next) { base->flag &= ~BA_WAS_SEL; if (TESTBASELIB_BGMODE(v3d, scene, base)) { - Object *ob= base->object; - Object *parsel= ob->parent; + Object *ob = base->object; + Object *parsel = ob->parent; /* if parent selected, deselect */ while (parsel) { @@ -4608,7 +4608,7 @@ static void set_trans_object_base_flags(TransInfo *t) } } } - parsel= parsel->parent; + parsel = parsel->parent; } if (parsel) { @@ -4631,7 +4631,7 @@ static void set_trans_object_base_flags(TransInfo *t) /* and we store them temporal in base (only used for transform code) */ /* this because after doing updates, the object->recalc is cleared */ - for (base= scene->base.first; base; base= base->next) { + for (base = scene->base.first; base; base = base->next) { if (base->object->recalc & OB_RECALC_OB) base->flag |= BA_HAS_RECALC_OB; if (base->object->recalc & OB_RECALC_DATA) @@ -4641,7 +4641,7 @@ static void set_trans_object_base_flags(TransInfo *t) static int mark_children(Object *ob) { - if (ob->flag & (SELECT|BA_TRANSFORM_CHILD)) + if (ob->flag & (SELECT | BA_TRANSFORM_CHILD)) return 1; if (ob->parent) { @@ -4664,7 +4664,7 @@ static int count_proportional_objects(TransInfo *t) /* rotations around local centers are allowed to propagate, so we take all objects */ if (!((t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL) && t->around == V3D_LOCAL)) { /* mark all parents */ - for (base= scene->base.first; base; base= base->next) { + for (base = scene->base.first; base; base = base->next) { if (TESTBASELIB_BGMODE(v3d, scene, base)) { Object *parent = base->object->parent; @@ -4677,9 +4677,9 @@ static int count_proportional_objects(TransInfo *t) } /* mark all children */ - for (base= scene->base.first; base; base= base->next) { + for (base = scene->base.first; base; base = base->next) { /* all base not already selected or marked that is editable */ - if ((base->object->flag & (SELECT|BA_TRANSFORM_CHILD|BA_TRANSFORM_PARENT)) == 0 && + if ((base->object->flag & (SELECT | BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 && (BASE_EDITABLE_BGMODE(v3d, scene, base))) { mark_children(base->object); @@ -4687,11 +4687,11 @@ static int count_proportional_objects(TransInfo *t) } } - for (base= scene->base.first; base; base= base->next) { - Object *ob= base->object; + for (base = scene->base.first; base; base = base->next) { + Object *ob = base->object; /* if base is not selected, not a parent of selection or not a child of selection and it is editable */ - if ((ob->flag & (SELECT|BA_TRANSFORM_CHILD|BA_TRANSFORM_PARENT)) == 0 && + if ((ob->flag & (SELECT | BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 && (BASE_EDITABLE_BGMODE(v3d, scene, base))) { @@ -4708,7 +4708,7 @@ static int count_proportional_objects(TransInfo *t) /* and we store them temporal in base (only used for transform code) */ /* this because after doing updates, the object->recalc is cleared */ - for (base= scene->base.first; base; base= base->next) { + for (base = scene->base.first; base; base = base->next) { if (base->object->recalc & OB_RECALC_OB) base->flag |= BA_HAS_RECALC_OB; if (base->object->recalc & OB_RECALC_DATA) @@ -4723,21 +4723,21 @@ static void clear_trans_object_base_flags(TransInfo *t) Scene *sce = t->scene; Base *base; - for (base= sce->base.first; base; base = base->next) { + for (base = sce->base.first; base; base = base->next) { if (base->flag & BA_WAS_SEL) base->flag |= SELECT; - base->flag &= ~(BA_WAS_SEL|BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA|BA_TEMP_TAG|BA_TRANSFORM_CHILD|BA_TRANSFORM_PARENT); + base->flag &= ~(BA_WAS_SEL | BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA | BA_TEMP_TAG | BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT); } } /* auto-keyframing feature - for objects - * tmode: should be a transform mode + * tmode: should be a transform mode */ // NOTE: context may not always be available, so must check before using it as it's a luxury for a few cases void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob, int tmode) { - ID *id= &ob->id; + ID *id = &ob->id; FCurve *fcu; // TODO: this should probably be done per channel instead... @@ -4745,7 +4745,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob, ReportList *reports = CTX_wm_reports(C); KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene); ListBase dsources = {NULL, NULL}; - float cfra= (float)CFRA; // xxx this will do for now + float cfra = (float)CFRA; // xxx this will do for now short flag = 0; /* get flags used for inserting keyframes */ @@ -4761,11 +4761,11 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob, ANIM_apply_keyingset(C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra); } else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) { - AnimData *adt= ob->adt; + AnimData *adt = ob->adt; /* only key on available channels */ if (adt && adt->action) { - for (fcu= adt->action->curves.first; fcu; fcu= fcu->next) { + for (fcu = adt->action->curves.first; fcu; fcu = fcu->next) { fcu->flag &= ~FCURVE_SELECTED; insert_keyframe(reports, id, adt->action, (fcu->grp ? fcu->grp->name : NULL), @@ -4788,7 +4788,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob, else if (v3d->around == V3D_CURSOR) do_loc = TRUE; - if ((v3d->flag & V3D_ALIGN)==0) + if ((v3d->flag & V3D_ALIGN) == 0) do_rot = TRUE; } else if (tmode == TFM_RESIZE) { @@ -4799,27 +4799,27 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob, else if (v3d->around == V3D_CURSOR) do_loc = TRUE; - if ((v3d->flag & V3D_ALIGN)==0) + if ((v3d->flag & V3D_ALIGN) == 0) do_scale = TRUE; } /* insert keyframes for the affected sets of channels using the builtin KeyingSets found */ if (do_loc) { - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID); + KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID); ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (do_rot) { - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID); + KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID); ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (do_scale) { - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID); + KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID); ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } } /* insert keyframe in all (transform) channels */ else { - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID); + KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID); ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } @@ -4829,16 +4829,16 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob, } /* auto-keyframing feature - for poses/pose-channels - * tmode: should be a transform mode + * tmode: should be a transform mode * targetless_ik: has targetless ik been done on any channels? */ // NOTE: context may not always be available, so must check before using it as it's a luxury for a few cases void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob, int tmode, short targetless_ik) { - ID *id= &ob->id; - AnimData *adt= ob->adt; - bAction *act= (adt) ? adt->action : NULL; - bPose *pose= ob->pose; + ID *id = &ob->id; + AnimData *adt = ob->adt; + bAction *act = (adt) ? adt->action : NULL; + bPose *pose = ob->pose; bPoseChannel *pchan; FCurve *fcu; @@ -4846,12 +4846,12 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o if (autokeyframe_cfra_can_key(scene, id)) { ReportList *reports = CTX_wm_reports(C); KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene); - float cfra= (float)CFRA; - short flag= 0; + float cfra = (float)CFRA; + short flag = 0; /* flag is initialized from UserPref keyframing settings * - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get - * visual keyframes even if flag not set, as it's not that useful otherwise + * visual keyframes even if flag not set, as it's not that useful otherwise * (for quick animation recording) */ flag = ANIM_get_keyframing_flags(scene, 1); @@ -4859,7 +4859,7 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o if (targetless_ik) flag |= INSERTKEY_MATRIX; - for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) { + for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->bone->flag & BONE_TRANSFORM) { ListBase dsources = {NULL, NULL}; @@ -4877,16 +4877,16 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o /* only insert into available channels? */ else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) { if (act) { - for (fcu= act->curves.first; fcu; fcu= fcu->next) { + for (fcu = act->curves.first; fcu; fcu = fcu->next) { /* only insert keyframes for this F-Curve if it affects the current bone */ if (strstr(fcu->rna_path, "bones")) { - char *pchanName= BLI_getQuotedStr(fcu->rna_path, "bones["); + char *pchanName = BLI_getQuotedStr(fcu->rna_path, "bones["); /* only if bone name matches too... * NOTE: this will do constraints too, but those are ok to do here too? */ if (pchanName && strcmp(pchanName, pchan->name) == 0) - insert_keyframe(reports, id, act, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag); + insert_keyframe(reports, id, act, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag); if (pchanName) MEM_freeN(pchanName); } @@ -4908,33 +4908,33 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE)) do_loc = TRUE; - if ((v3d->flag & V3D_ALIGN)==0) + if ((v3d->flag & V3D_ALIGN) == 0) do_rot = TRUE; } else if (tmode == TFM_RESIZE) { if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE)) do_loc = TRUE; - if ((v3d->flag & V3D_ALIGN)==0) + if ((v3d->flag & V3D_ALIGN) == 0) do_scale = TRUE; } if (do_loc) { - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID); + KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID); ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (do_rot) { - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID); + KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID); ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (do_scale) { - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID); + KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID); ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } } /* insert keyframe in all (transform) channels */ else { - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID); + KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID); ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } @@ -4944,7 +4944,7 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o } /* do the bone paths - * - only do this when there is context info, since we need that to resolve + * - only do this when there is context info, since we need that to resolve * how to do the updates and so on... * - do not calculate unless there are paths already to update... */ @@ -4955,7 +4955,7 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o } else { /* tag channels that should have unkeyed data */ - for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) { + for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->bone->flag & BONE_TRANSFORM) { /* tag this channel */ pchan->bone->flag |= BONE_UNKEYED; @@ -4968,22 +4968,22 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o /* inserting keys, pointcache, redraw events... */ /* * note: sequencer freeing has its own function now because of a conflict with transform's order of freeing (campbell) - * Order changed, the sequencer stuff should go back in here + * Order changed, the sequencer stuff should go back in here * */ void special_aftertrans_update(bContext *C, TransInfo *t) { Object *ob; // short redrawipo=0, resetslowpar=1; - int canceled= (t->state == TRANS_CANCEL); - short duplicate= (t->mode == TFM_TIME_DUPLICATE); + int canceled = (t->state == TRANS_CANCEL); + short duplicate = (t->mode == TFM_TIME_DUPLICATE); /* early out when nothing happened */ if (t->total == 0 || t->mode == TFM_DUMMY) return; - if (t->spacetype==SPACE_VIEW3D) { + if (t->spacetype == SPACE_VIEW3D) { if (t->obedit) { - if (canceled==0) { + if (canceled == 0) { /* we need to delete the temporary faces before automerging */ if (t->mode == TFM_EDGE_SLIDE) { SlideData *sld = t->customData; @@ -5014,7 +5014,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) /* freeSeqData in transform_conversions.c does this * keep here so the else at the end wont run... */ - SpaceSeq *sseq= (SpaceSeq *)t->sa->spacedata.first; + SpaceSeq *sseq = (SpaceSeq *)t->sa->spacedata.first; /* marker transform, not especially nice but we may want to move markers * at the same time as keyframes in the dope sheet. */ @@ -5033,7 +5033,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } else if (t->spacetype == SPACE_NODE) { - SpaceNode *snode= (SpaceNode *)t->sa->spacedata.first; + SpaceNode *snode = (SpaceNode *)t->sa->spacedata.first; if (canceled == 0) { ED_node_post_apply_transform(C, snode->edittree); @@ -5052,7 +5052,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) /* tracks can be used for stabilization nodes, * flush update for such nodes */ nodeUpdateID(t->scene->nodetree, &clip->id); - WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL); } } else if (t->options & CTX_MASK) { @@ -5063,7 +5063,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) /* tracks can be used for stabilization nodes, * flush update for such nodes */ nodeUpdateID(t->scene->nodetree, &mask->id); - WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL); } /* TODO - dont key all masks... */ @@ -5075,7 +5075,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } } else if (t->spacetype == SPACE_ACTION) { - SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; + SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first; bAnimContext ac; /* initialize relevant anim-context 'context' data */ @@ -5087,22 +5087,22 @@ void special_aftertrans_update(bContext *C, TransInfo *t) if (ELEM(ac.datatype, ANIMCONT_DOPESHEET, ANIMCONT_SHAPEKEY)) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; - short filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/); + short filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/); /* get channels to work on */ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* these should all be F-Curves */ - for (ale= anim_data.first; ale; ale= ale->next) { - AnimData *adt= ANIM_nla_mapping_get(&ac, ale); - FCurve *fcu= (FCurve *)ale->key_data; + for (ale = anim_data.first; ale; ale = ale->next) { + AnimData *adt = ANIM_nla_mapping_get(&ac, ale); + FCurve *fcu = (FCurve *)ale->key_data; /* 3 cases here for curve cleanups: * 1) NOTRANSKEYCULL on -> cleanup of duplicates shouldn't be done * 2) canceled == 0 -> user confirmed the transform, so duplicates should be removed * 3) canceled + duplicate -> user canceled the transform, but we made duplicates, so get rid of these */ - if ((saction->flag & SACTION_NOTRANSKEYCULL)==0 && + if ((saction->flag & SACTION_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate)) ) { if (adt) { @@ -5111,7 +5111,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1); } else - posttrans_fcurve_clean(fcu, FALSE); /* only use handles in graph editor */ + posttrans_fcurve_clean(fcu, FALSE); /* only use handles in graph editor */ } } @@ -5123,7 +5123,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) // fixme... some of this stuff is not good if (ob) { if (ob->pose || ob_get_key(ob)) - DAG_id_tag_update(&ob->id, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME); + DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); else DAG_id_tag_update(&ob->id, OB_RECALC_OB); } @@ -5133,7 +5133,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) * 2) canceled == 0 -> user confirmed the transform, so duplicates should be removed * 3) canceled + duplicate -> user canceled the transform, but we made duplicates, so get rid of these */ - if ((saction->flag & SACTION_NOTRANSKEYCULL)==0 && + if ((saction->flag & SACTION_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) { posttrans_action_clean(&ac, (bAction *)ac.data); @@ -5141,13 +5141,13 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } else if (ac.datatype == ANIMCONT_GPENCIL) { /* remove duplicate frames and also make sure points are in order! */ - /* 3 cases here for curve cleanups: - * 1) NOTRANSKEYCULL on -> cleanup of duplicates shouldn't be done - * 2) canceled == 0 -> user confirmed the transform, so duplicates should be removed - * 3) canceled + duplicate -> user canceled the transform, but we made duplicates, so get rid of these - */ - if ((saction->flag & SACTION_NOTRANSKEYCULL)==0 && - ((canceled == 0) || (duplicate))) + /* 3 cases here for curve cleanups: + * 1) NOTRANSKEYCULL on -> cleanup of duplicates shouldn't be done + * 2) canceled == 0 -> user confirmed the transform, so duplicates should be removed + * 3) canceled + duplicate -> user canceled the transform, but we made duplicates, so get rid of these + */ + if ((saction->flag & SACTION_NOTRANSKEYCULL) == 0 && + ((canceled == 0) || (duplicate))) { bGPdata *gpd; @@ -5161,13 +5161,13 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } else if (ac.datatype == ANIMCONT_MASK) { /* remove duplicate frames and also make sure points are in order! */ - /* 3 cases here for curve cleanups: - * 1) NOTRANSKEYCULL on -> cleanup of duplicates shouldn't be done - * 2) canceled == 0 -> user confirmed the transform, so duplicates should be removed - * 3) canceled + duplicate -> user canceled the transform, but we made duplicates, so get rid of these - */ - if ((saction->flag & SACTION_NOTRANSKEYCULL)==0 && - ((canceled == 0) || (duplicate))) + /* 3 cases here for curve cleanups: + * 1) NOTRANSKEYCULL on -> cleanup of duplicates shouldn't be done + * 2) canceled == 0 -> user confirmed the transform, so duplicates should be removed + * 3) canceled + duplicate -> user canceled the transform, but we made duplicates, so get rid of these + */ + if ((saction->flag & SACTION_NOTRANSKEYCULL) == 0 && + ((canceled == 0) || (duplicate))) { Mask *mask; @@ -5209,7 +5209,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) saction->flag &= ~SACTION_MOVING; } else if (t->spacetype == SPACE_IPO) { - SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first; + SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; bAnimContext ac; const short use_handle = !(sipo->flag & SIPO_NOHANDLES); @@ -5220,21 +5220,21 @@ void special_aftertrans_update(bContext *C, TransInfo *t) if (ac.datatype) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; - short filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE); + short filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE); /* get channels to work on */ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - for (ale= anim_data.first; ale; ale= ale->next) { - AnimData *adt= ANIM_nla_mapping_get(&ac, ale); - FCurve *fcu= (FCurve *)ale->key_data; + for (ale = anim_data.first; ale; ale = ale->next) { + AnimData *adt = ANIM_nla_mapping_get(&ac, ale); + FCurve *fcu = (FCurve *)ale->key_data; /* 3 cases here for curve cleanups: * 1) NOTRANSKEYCULL on -> cleanup of duplicates shouldn't be done * 2) canceled == 0 -> user confirmed the transform, so duplicates should be removed * 3) canceled + duplicate -> user canceled the transform, but we made duplicates, so get rid of these */ - if ((sipo->flag & SIPO_NOTRANSKEYCULL)==0 && + if ((sipo->flag & SIPO_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) { if (adt) { @@ -5269,13 +5269,13 @@ void special_aftertrans_update(bContext *C, TransInfo *t) if (ac.datatype) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; - short filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT); + short filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT); /* get channels to work on */ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - for (ale= anim_data.first; ale; ale= ale->next) { - NlaTrack *nlt= (NlaTrack *)ale->data; + for (ale = anim_data.first; ale; ale = ale->next) { + NlaTrack *nlt = (NlaTrack *)ale->data; /* make sure strips are in order again */ BKE_nlatrack_sort_strips(nlt); @@ -5301,16 +5301,16 @@ void special_aftertrans_update(bContext *C, TransInfo *t) else if ((t->flag & T_POSE) && (t->poseobj)) { bArmature *arm; bPoseChannel *pchan; - short targetless_ik= 0; + short targetless_ik = 0; - ob= t->poseobj; - arm= ob->data; + ob = t->poseobj; + arm = ob->data; if ((t->flag & T_AUTOIK) && (t->options & CTX_AUTOCONFIRM)) { /* when running transform non-interactively (operator exec), * we need to update the pose otherwise no updates get called during * transform and the auto-ik is not applied. see [#26164] */ - struct Object *pose_ob=t->poseobj; + struct Object *pose_ob = t->poseobj; BKE_pose_where_is(t->scene, pose_ob); } @@ -5319,17 +5319,17 @@ void special_aftertrans_update(bContext *C, TransInfo *t) count_set_pose_transflags(&t->mode, t->around, ob); /* if target-less IK grabbing, we calculate the pchan transforms and clear flag */ - if (!canceled && t->mode==TFM_TRANSLATION) - targetless_ik= apply_targetless_ik(ob); + if (!canceled && t->mode == TFM_TRANSLATION) + targetless_ik = apply_targetless_ik(ob); else { /* not forget to clear the auto flag */ - for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) { - bKinematicConstraint *data= has_targetless_ik(pchan); + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + bKinematicConstraint *data = has_targetless_ik(pchan); if (data) data->flag &= ~CONSTRAINT_IK_AUTO; } } - if (t->mode==TFM_TRANSLATION) + if (t->mode == TFM_TRANSLATION) pose_grab_with_ik_clear(ob); /* automatic inserting of keys and unkeyed tagging - only if transform wasn't canceled (or TFM_DUMMY) */ @@ -5340,7 +5340,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) else if (arm->flag & ARM_DELAYDEFORM) { /* old optimize trick... this enforces to bypass the depgraph */ DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - ob->recalc= 0; // is set on OK position already by recalcData() + ob->recalc = 0; // is set on OK position already by recalcData() } else DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -5354,7 +5354,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) /* do nothing */ } else { /* Objects */ - int i, recalcObPaths=0; + int i, recalcObPaths = 0; for (i = 0; i < t->total; i++) { TransData *td = t->data + i; @@ -5370,7 +5370,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) /* flag object caches as outdated */ BKE_ptcache_ids_from_object(&pidlist, ob, t->scene, MAX_DUPLI_RECUR); - for (pid=pidlist.first; pid; pid=pid->next) { + for (pid = pidlist.first; pid; pid = pid->next) { if (pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */ pid->cache->flag |= PTCACHE_OUTDATED; } @@ -5392,7 +5392,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) /* only calculate paths if there are paths to be recalculated */ if (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) - recalcObPaths= 1; + recalcObPaths = 1; } } @@ -5434,7 +5434,7 @@ static void createTransObject(bContext *C, TransInfo *t) set_trans_object_base_flags(t); /* count */ - t->total= CTX_DATA_COUNT(C, selected_objects); + t->total = CTX_DATA_COUNT(C, selected_objects); if (!t->total) { /* clear here, main transform function escapes too */ @@ -5446,17 +5446,17 @@ static void createTransObject(bContext *C, TransInfo *t) t->total += count_proportional_objects(t); } - td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransOb"); - tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransObExtension"); + td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransOb"); + tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "TransObExtension"); - CTX_DATA_BEGIN (C, Base*, base, selected_bases) + CTX_DATA_BEGIN(C, Base *, base, selected_bases) { - Object *ob= base->object; + Object *ob = base->object; td->flag = TD_SELECTED; - td->protectflag= ob->protectflag; + td->protectflag = ob->protectflag; td->ext = tx; - td->ext->rotOrder= ob->rotmode; + td->ext->rotOrder = ob->rotmode; if (base->flag & BA_TRANSFORM_CHILD) { td->flag |= TD_NOCENTER; @@ -5480,16 +5480,16 @@ static void createTransObject(bContext *C, TransInfo *t) View3D *v3d = t->view; Base *base; - for (base= scene->base.first; base; base= base->next) { - Object *ob= base->object; + for (base = scene->base.first; base; base = base->next) { + Object *ob = base->object; /* if base is not selected, not a parent of selection or not a child of selection and it is editable */ if ((ob->flag & (SELECT | BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 && BASE_EDITABLE_BGMODE(v3d, scene, base)) { - td->protectflag= ob->protectflag; + td->protectflag = ob->protectflag; td->ext = tx; - td->ext->rotOrder= ob->rotmode; + td->ext->rotOrder = ob->rotmode; ObjectToTransData(t, td, ob); td->val = NULL; @@ -5522,10 +5522,10 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->val= NULL; + td->ext = NULL; td->val = NULL; td->flag |= TD_SELECTED; - td->dist= 0.0; + td->dist = 0.0; unit_m3(td->mtx); unit_m3(td->smtx); @@ -5535,29 +5535,29 @@ static void createTransNodeData(bContext *C, TransInfo *t) { TransData *td; TransData2D *td2d; - SpaceNode *snode= t->sa->spacedata.first; + SpaceNode *snode = t->sa->spacedata.first; bNode *node; if (!snode->edittree) { - t->total= 0; + t->total = 0; return; } /* set transform flags on nodes */ - for (node=snode->edittree->nodes.first; node; node=node->next) { + for (node = snode->edittree->nodes.first; node; node = node->next) { if ((node->flag & NODE_SELECT) || (node->parent && (node->parent->flag & NODE_TRANSFORM))) node->flag |= NODE_TRANSFORM; else node->flag &= ~NODE_TRANSFORM; } - t->total= CTX_DATA_COUNT(C, selected_nodes); + t->total = CTX_DATA_COUNT(C, selected_nodes); - td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransNode TransData"); - td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransNode TransData2D"); + td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransNode TransData"); + td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransNode TransData2D"); - CTX_DATA_BEGIN (C, bNode *, selnode, selected_nodes) - NodeToTransData(td++, td2d++, selnode); + CTX_DATA_BEGIN(C, bNode *, selnode, selected_nodes) + NodeToTransData(td++, td2d++, selnode); CTX_DATA_END } @@ -5600,7 +5600,7 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra td2d->loc[0] = rel[0] * aspx; /* hold original location */ td2d->loc[1] = rel[1] * aspy; - tdt->loc= loc; + tdt->loc = loc; td2d->loc2d = loc; /* current location */ } else { @@ -5640,8 +5640,8 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; - td->val= NULL; + td->ext = NULL; + td->val = NULL; td->flag |= TD_SELECTED; td->dist = 0.0; @@ -5715,19 +5715,19 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) track = tracksbase->first; while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { marker = BKE_tracking_get_marker(track, framenr); - t->total++; /* offset */ + t->total++; /* offset */ if (track->flag & SELECT) t->total++; if (track->pat_flag & SELECT) - t->total+= 4; + t->total += 4; if (track->search_flag & SELECT) - t->total+= 2; + t->total += 2; } track = track->next; @@ -5738,9 +5738,9 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); - td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransTracking TransData"); - td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransTracking TransData2D"); - tdt = t->customData = MEM_callocN(t->total*sizeof(TransDataTracking), "TransTracking TransDataTracking"); + td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransTracking TransData"); + td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransTracking TransData2D"); + tdt = t->customData = MEM_callocN(t->total * sizeof(TransDataTracking), "TransTracking TransDataTracking"); t->customFree = transDataTrackingFree; @@ -5815,8 +5815,8 @@ static void markerToTransCurveDataInit(TransData *td, TransData2D *td2d, TransDa memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; - td->val= NULL; + td->ext = NULL; + td->val = NULL; td->flag |= TD_SELECTED; td->dist = 0.0; @@ -5831,7 +5831,7 @@ static void createTransTrackingCurvesData(bContext *C, TransInfo *t) TransData2D *td2d; SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); - ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; MovieTrackingMarker *marker, *prev_marker; TransDataTracking *tdt; @@ -5844,10 +5844,10 @@ static void createTransTrackingCurvesData(bContext *C, TransInfo *t) track = tracksbase->first; while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { for (i = 1; i < track->markersnr; i++) { marker = &track->markers[i]; - prev_marker = &track->markers[i-1]; + prev_marker = &track->markers[i - 1]; if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) continue; @@ -5866,32 +5866,32 @@ static void createTransTrackingCurvesData(bContext *C, TransInfo *t) if (t->total == 0) return; - td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransTracking TransData"); - td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransTracking TransData2D"); - tdt = t->customData = MEM_callocN(t->total*sizeof(TransDataTracking), "TransTracking TransDataTracking"); + td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransTracking TransData"); + td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransTracking TransData2D"); + tdt = t->customData = MEM_callocN(t->total * sizeof(TransDataTracking), "TransTracking TransDataTracking"); t->customFree = transDataTrackingFree; /* create actual data */ track = tracksbase->first; while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { for (i = 1; i < track->markersnr; i++) { marker = &track->markers[i]; - prev_marker = &track->markers[i-1]; + prev_marker = &track->markers[i - 1]; if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) continue; if (marker->flag & MARKER_GRAPH_SEL_X) { - markerToTransCurveDataInit(td, td2d, tdt, marker, &track->markers[i-1], 0, width); + markerToTransCurveDataInit(td, td2d, tdt, marker, &track->markers[i - 1], 0, width); td += 1; td2d += 1; tdt += 1; } if (marker->flag & MARKER_GRAPH_SEL_Y) { - markerToTransCurveDataInit(td, td2d, tdt, marker, &track->markers[i-1], 1, height); + markerToTransCurveDataInit(td, td2d, tdt, marker, &track->markers[i - 1], 1, height); td += 1; td2d += 1; @@ -5940,7 +5940,7 @@ static void cancelTransTracking(TransInfo *t) if (tdt->mode == transDataTracking_ModeTracks) { track = tracksbase->first; while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { marker = BKE_tracking_get_marker(track, framenr); marker->flag = tdt->flag; @@ -5964,15 +5964,15 @@ static void cancelTransTracking(TransInfo *t) track = tracksbase->first; while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { for (a = 1; a < track->markersnr; a++) { marker = &track->markers[a]; - prev_marker = &track->markers[a-1]; + prev_marker = &track->markers[a - 1]; if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) continue; - if (marker->flag & (MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y)) { + if (marker->flag & (MARKER_GRAPH_SEL_X | MARKER_GRAPH_SEL_Y)) { marker->flag = tdt->flag; } } @@ -5998,7 +5998,7 @@ void flushTransTracking(TransInfo *t) cancelTransTracking(t); /* flush to 2d vector from internally used 3d vector */ - for (a=0, td= t->data, td2d= t->data2d, tdt= t->customData; atotal; a++, td2d++, td++, tdt++) { + for (a = 0, td = t->data, td2d = t->data2d, tdt = t->customData; a < t->total; a++, td2d++, td++, tdt++) { if (tdt->mode == transDataTracking_ModeTracks) { float loc2d[2]; @@ -6019,7 +6019,7 @@ void flushTransTracking(TransInfo *t) float d[2], d2[2]; if (!tdt->smarkers) { - tdt->smarkers = MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers"); + tdt->smarkers = MEM_callocN(sizeof(*tdt->smarkers) * tdt->markersnr, "flushTransTracking markers"); for (a = 0; a < tdt->markersnr; a++) copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos); } @@ -6029,7 +6029,7 @@ void flushTransTracking(TransInfo *t) sub_v2_v2v2(d2, loc2d, tdt->srelative); - for (a= 0; amarkersnr; a++) + for (a = 0; a < tdt->markersnr; a++) add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2); negate_v2_v2(td2d->loc2d, d); @@ -6037,7 +6037,7 @@ void flushTransTracking(TransInfo *t) } } - if (tdt->area!=TRACK_AREA_POINT || tdt->relative==0) { + if (tdt->area != TRACK_AREA_POINT || tdt->relative == 0) { td2d->loc2d[0] = loc2d[0]; td2d->loc2d[1] = loc2d[1]; @@ -6054,7 +6054,7 @@ void flushTransTracking(TransInfo *t) /* * masking * */ typedef struct TransDataMasking { - int is_handle; + int is_handle; float handle[2], orig_handle[2]; float vec[3][3]; @@ -6081,8 +6081,8 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, * proportional editing to be consistent with the stretched CV coords * that are displayed. this also means that for display and numinput, * and when the the CV coords are flushed, these are converted each time */ - td2d->loc[0] = bezt->vec[i][0]*aspx; - td2d->loc[1] = bezt->vec[i][1]*aspy; + td2d->loc[0] = bezt->vec[i][0] * aspx; + td2d->loc[1] = bezt->vec[i][1] * aspy; td2d->loc[2] = 0.0f; td2d->loc2d = bezt->vec[i]; @@ -6108,7 +6108,7 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, if (is_sel_any) { td->flag |= TD_SELECTED; } - td->dist= 0.0; + td->dist = 0.0; unit_m3(td->mtx); unit_m3(td->smtx); @@ -6124,8 +6124,8 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, copy_v2_v2(tdm->orig_handle, tdm->handle); - td2d->loc[0] = tdm->handle[0]*aspx; - td2d->loc[1] = tdm->handle[1]*aspy; + td2d->loc[0] = tdm->handle[0] * aspx; + td2d->loc[1] = tdm->handle[1] * aspy; td2d->loc[2] = 0.0f; td2d->loc2d = tdm->handle; @@ -6137,14 +6137,14 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; - td->val= NULL; + td->ext = NULL; + td->val = NULL; if (is_sel_any) { td->flag |= TD_SELECTED; } - td->dist= 0.0; + td->dist = 0.0; unit_m3(td->mtx); unit_m3(td->smtx); @@ -6200,12 +6200,12 @@ static void createTransMaskingData(bContext *C, TransInfo *t) /* note: in prop mode we need at least 1 selected */ if (countsel == 0) return; - t->total = (propmode) ? count: countsel; - td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransObData(Mask Editing)"); + t->total = (propmode) ? count : countsel; + td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mask Editing)"); /* for each 2d uv coord a 3d vector is allocated, so that they can be * treated just as if they were 3d verts */ - td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(Mask Editing)"); - tdm = t->customData = MEM_callocN(t->total*sizeof(TransDataMasking), "TransDataMasking(Mask Editing)"); + td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransObData2D(Mask Editing)"); + tdm = t->customData = MEM_callocN(t->total * sizeof(TransDataMasking), "TransDataMasking(Mask Editing)"); t->flag |= T_FREE_CUSTOMDATA; @@ -6251,13 +6251,13 @@ void flushTransMasking(TransInfo *t) float aspx, aspy, invx, invy; ED_space_clip_mask_aspect(sc, &aspx, &aspy); - invx = 1.0f/aspx; - invy = 1.0f/aspy; + invx = 1.0f / aspx; + invy = 1.0f / aspy; /* flush to 2d vector from internally used 3d vector */ - for (a=0, td = t->data2d, tdm = t->customData; atotal; a++, td++, tdm++) { - td->loc2d[0]= td->loc[0]*invx; - td->loc2d[1]= td->loc[1]*invy; + for (a = 0, td = t->data2d, tdm = t->customData; a < t->total; a++, td++, tdm++) { + td->loc2d[0] = td->loc[0] * invx; + td->loc2d[1] = td->loc[1] * invy; if (tdm->is_handle) BKE_mask_point_set_handle(tdm->point, td->loc2d, t->flag & T_ALT_TRANSFORM, tdm->orig_handle, tdm->vec); @@ -6278,7 +6278,7 @@ void createTransData(bContext *C, TransInfo *t) t->flag |= T_EDIT; createTransEdge(t); if (t->data && t->flag & T_PROP_EDIT) { - sort_trans_data(t); // makes selected become first in array + sort_trans_data(t); // makes selected become first in array set_prop_dist(t, 1); sort_trans_data_dist(t); } @@ -6288,56 +6288,56 @@ void createTransData(bContext *C, TransInfo *t) //createTransBMeshVerts(t, G.editBMesh->bm, G.editBMesh->td); } else if (t->spacetype == SPACE_IMAGE) { - t->flag |= T_POINTS|T_2D_EDIT; + t->flag |= T_POINTS | T_2D_EDIT; createTransUVs(C, t); if (t->data && (t->flag & T_PROP_EDIT)) { - sort_trans_data(t); // makes selected become first in array + sort_trans_data(t); // makes selected become first in array set_prop_dist(t, 1); sort_trans_data_dist(t); } } else if (t->spacetype == SPACE_ACTION) { - t->flag |= T_POINTS|T_2D_EDIT; + t->flag |= T_POINTS | T_2D_EDIT; createTransActionData(C, t); } else if (t->spacetype == SPACE_NLA) { - t->flag |= T_POINTS|T_2D_EDIT; + t->flag |= T_POINTS | T_2D_EDIT; createTransNlaData(C, t); } else if (t->spacetype == SPACE_SEQ) { - t->flag |= T_POINTS|T_2D_EDIT; + t->flag |= T_POINTS | T_2D_EDIT; t->num.flag |= NUM_NO_FRACTION; /* sequencer has no use for floating point transformations */ createTransSeqData(C, t); } else if (t->spacetype == SPACE_IPO) { - t->flag |= T_POINTS|T_2D_EDIT; + t->flag |= T_POINTS | T_2D_EDIT; createTransGraphEditData(C, t); #if 0 if (t->data && (t->flag & T_PROP_EDIT)) { - sort_trans_data(t); // makes selected become first in array + sort_trans_data(t); // makes selected become first in array set_prop_dist(t, 1); sort_trans_data_dist(t); } #endif } else if (t->spacetype == SPACE_NODE) { - t->flag |= T_2D_EDIT|T_POINTS; + t->flag |= T_2D_EDIT | T_POINTS; createTransNodeData(C, t); if (t->data && (t->flag & T_PROP_EDIT)) { - sort_trans_data(t); // makes selected become first in array + sort_trans_data(t); // makes selected become first in array set_prop_dist(t, 1); sort_trans_data_dist(t); } } else if (t->spacetype == SPACE_CLIP) { - t->flag |= T_POINTS|T_2D_EDIT; + t->flag |= T_POINTS | T_2D_EDIT; if (t->options & CTX_MOVIECLIP) createTransTrackingData(C, t); else if (t->options & CTX_MASK) { createTransMaskingData(C, t); if (t->data && (t->flag & T_PROP_EDIT)) { - sort_trans_data(t); // makes selected become first in array + sort_trans_data(t); // makes selected become first in array set_prop_dist(t, TRUE); sort_trans_data_dist(t); } @@ -6351,13 +6351,13 @@ void createTransData(bContext *C, TransInfo *t) else if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) { createTransCurveVerts(C, t); } - else if (t->obedit->type==OB_LATTICE) { + else if (t->obedit->type == OB_LATTICE) { createTransLatticeVerts(t); } - else if (t->obedit->type==OB_MBALL) { + else if (t->obedit->type == OB_MBALL) { createTransMBallVerts(t); } - else if (t->obedit->type==OB_ARMATURE) { + else if (t->obedit->type == OB_ARMATURE) { t->flag &= ~T_PROP_EDIT; createTransArmatureVerts(t); } @@ -6365,26 +6365,26 @@ void createTransData(bContext *C, TransInfo *t) printf("edit type not implemented!\n"); } - t->flag |= T_EDIT|T_POINTS; + t->flag |= T_EDIT | T_POINTS; if (t->data && t->flag & T_PROP_EDIT) { if (ELEM(t->obedit->type, OB_CURVE, OB_MESH)) { - sort_trans_data(t); // makes selected become first in array + sort_trans_data(t); // makes selected become first in array set_prop_dist(t, 0); sort_trans_data_dist(t); } else { - sort_trans_data(t); // makes selected become first in array + sort_trans_data(t); // makes selected become first in array set_prop_dist(t, 1); sort_trans_data_dist(t); } } /* exception... hackish, we want bonesize to use bone orientation matrix (ton) */ - if (t->mode==TFM_BONESIZE) { - t->flag &= ~(T_EDIT|T_POINTS); + if (t->mode == TFM_BONESIZE) { + t->flag &= ~(T_EDIT | T_POINTS); t->flag |= T_POSE; - t->poseobj = ob; /* <- tsk tsk, this is going to give issues one day */ + t->poseobj = ob; /* <- tsk tsk, this is going to give issues one day */ } } else if (ob && (ob->mode & OB_MODE_POSE)) { @@ -6395,9 +6395,9 @@ void createTransData(bContext *C, TransInfo *t) else if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT)) { /* important that ob_armature can be set even when its not selected [#23412] * lines below just check is also visible */ - Object *ob_armature= modifiers_isDeformedByArmature(ob); + Object *ob_armature = modifiers_isDeformedByArmature(ob); if (ob_armature && ob_armature->mode & OB_MODE_POSE) { - Base *base_arm= BKE_scene_base_find(t->scene, ob_armature); + Base *base_arm = BKE_scene_base_find(t->scene, ob_armature); if (base_arm) { View3D *v3d = t->view; if (BASE_VISIBLE(v3d, base_arm)) { @@ -6412,12 +6412,12 @@ void createTransData(bContext *C, TransInfo *t) t->flag |= T_POINTS; if (t->data && t->flag & T_PROP_EDIT) { - sort_trans_data(t); // makes selected become first in array + sort_trans_data(t); // makes selected become first in array set_prop_dist(t, 1); sort_trans_data_dist(t); } } - else if (ob && (ob->mode & (OB_MODE_SCULPT|OB_MODE_TEXTURE_PAINT))) { + else if (ob && (ob->mode & (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT))) { /* sculpt mode and project paint have own undo stack * transform ops redo clears sculpt/project undo stack. * @@ -6437,7 +6437,7 @@ void createTransData(bContext *C, TransInfo *t) if ((t->spacetype == SPACE_VIEW3D) && (t->ar->regiontype == RGN_TYPE_WINDOW)) { View3D *v3d = t->view; RegionView3D *rv3d = CTX_wm_region_view3d(C); - if (rv3d && (t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==RV3D_CAMOB) { + if (rv3d && (t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp == RV3D_CAMOB) { t->flag |= T_CAMERA; } } @@ -6447,7 +6447,3 @@ void createTransData(bContext *C, TransInfo *t) // /* temporal...? */ // t->scene->recalc |= SCE_PRV_CHANGED; /* test for 3d preview */ } - - - - diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 1b8cc14ecac..f21e0a0515d 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -140,13 +140,13 @@ void getViewVector(TransInfo *t, float coord[3], float vec[3]) static void clipMirrorModifier(TransInfo *t, Object *ob) { - ModifierData *md= ob->modifiers.first; + ModifierData *md = ob->modifiers.first; float tolerance[3] = {0.0f, 0.0f, 0.0f}; int axis = 0; - for (; md; md=md->next) { - if ((md->type==eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { - MirrorModifierData *mmd = (MirrorModifierData*) md; + for (; md; md = md->next) { + if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { + MirrorModifierData *mmd = (MirrorModifierData *) md; if (mmd->flag & MOD_MIR_CLIPPING) { axis = 0; @@ -175,13 +175,13 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) invert_m4_m4(imtx, mtx); } - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { int clip; float loc[3], iloc[3]; if (td->flag & TD_NOACTION) break; - if (td->loc==NULL) + if (td->loc == NULL) break; if (td->flag & TD_SKIP) @@ -197,27 +197,27 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) clip = 0; if (axis & 1) { - if (fabsf(iloc[0])<=tolerance[0] || - loc[0]*iloc[0]<0.0f) + if (fabsf(iloc[0]) <= tolerance[0] || + loc[0] * iloc[0] < 0.0f) { - loc[0]= 0.0f; + loc[0] = 0.0f; clip = 1; } } if (axis & 2) { if (fabsf(iloc[1]) <= tolerance[1] || - loc[1] * iloc[1]<0.0f) + loc[1] * iloc[1] < 0.0f) { - loc[1]= 0.0f; + loc[1] = 0.0f; clip = 1; } } if (axis & 4) { if (fabsf(iloc[2]) <= tolerance[2] || - loc[2] * iloc[2] < 0.0f) + loc[2] * iloc[2] < 0.0f) { - loc[2]= 0.0f; + loc[2] = 0.0f; clip = 1; } } @@ -242,19 +242,19 @@ static void editbmesh_apply_to_mirror(TransInfo *t) BMVert *eve; int i; - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; - if (td->loc==NULL) + if (td->loc == NULL) break; if (td->flag & TD_SKIP) continue; eve = td->extra; if (eve) { - eve->co[0]= -td->loc[0]; - eve->co[1]= td->loc[1]; - eve->co[2]= td->loc[2]; + eve->co[0] = -td->loc[0]; + eve->co[1] = td->loc[1]; + eve->co[2] = td->loc[2]; } if (td->flag & TD_MIRROR_EDGE) { @@ -264,23 +264,23 @@ static void editbmesh_apply_to_mirror(TransInfo *t) } /* for the realtime animation recording feature, handle overlapping data */ -static void animrecord_check_state (Scene *scene, ID *id, wmTimer *animtimer) +static void animrecord_check_state(Scene *scene, ID *id, wmTimer *animtimer) { - ScreenAnimData *sad= (animtimer) ? animtimer->customdata : NULL; + ScreenAnimData *sad = (animtimer) ? animtimer->customdata : NULL; /* sanity checks */ if (ELEM3(NULL, scene, id, sad)) return; /* check if we need a new strip if: - * - if animtimer is running + * - if animtimer is running * - we're not only keying for available channels * - the option to add new actions for each round is not enabled */ - if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)==0 && (scene->toolsettings->autokey_flag & ANIMRECORD_FLAG_WITHNLA)) { + if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL) == 0 && (scene->toolsettings->autokey_flag & ANIMRECORD_FLAG_WITHNLA)) { /* if playback has just looped around, we need to add a new NLA track+strip to allow a clean pass to occur */ if ((sad) && (sad->flag & ANIMPLAY_FLAG_JUMPED)) { - AnimData *adt= BKE_animdata_from_id(id); + AnimData *adt = BKE_animdata_from_id(id); /* perform push-down manually with some differences * NOTE: BKE_nla_action_pushdown() sync warning... @@ -290,21 +290,21 @@ static void animrecord_check_state (Scene *scene, ID *id, wmTimer *animtimer) /* only push down if action is more than 1-2 frames long */ calc_action_range(adt->action, &astart, &aend, 1); - if (aend > astart+2.0f) { - NlaStrip *strip= add_nlastrip_to_stack(adt, adt->action); + if (aend > astart + 2.0f) { + NlaStrip *strip = add_nlastrip_to_stack(adt, adt->action); /* clear reference to action now that we've pushed it onto the stack */ adt->action->id.us--; - adt->action= NULL; + adt->action = NULL; /* adjust blending + extend so that they will behave correctly */ - strip->extendmode= NLASTRIP_EXTEND_NOTHING; - strip->flag &= ~(NLASTRIP_FLAG_AUTO_BLENDS|NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_ACTIVE); + strip->extendmode = NLASTRIP_EXTEND_NOTHING; + strip->flag &= ~(NLASTRIP_FLAG_AUTO_BLENDS | NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_ACTIVE); /* also, adjust the AnimData's action extend mode to be on * 'nothing' so that previous result still play */ - adt->act_extendmode= NLASTRIP_EXTEND_NOTHING; + adt->act_extendmode = NLASTRIP_EXTEND_NOTHING; } } } @@ -313,13 +313,13 @@ static void animrecord_check_state (Scene *scene, ID *id, wmTimer *animtimer) static int fcu_test_selected(FCurve *fcu) { - BezTriple *bezt= fcu->bezt; + BezTriple *bezt = fcu->bezt; unsigned int i; - if (bezt==NULL) /* ignore baked */ + if (bezt == NULL) /* ignore baked */ return 0; - for (i=0; i < fcu->totvert; i++, bezt++) { + for (i = 0; i < fcu->totvert; i++, bezt++) { if (BEZSELECTED(bezt)) return 1; } @@ -329,23 +329,23 @@ static int fcu_test_selected(FCurve *fcu) /* helper for recalcData() - for Action Editor transforms */ static void recalcData_actedit(TransInfo *t) { - Scene *scene= t->scene; - SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; + Scene *scene = t->scene; + SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first; - bAnimContext ac= {NULL}; + bAnimContext ac = {NULL}; ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; /* initialize relevant anim-context 'context' data from TransInfo data */ - /* NOTE: sync this with the code in ANIM_animdata_get_context() */ - ac.scene= t->scene; - ac.obact= OBACT; - ac.sa= t->sa; - ac.ar= t->ar; - ac.sl= (t->sa)? t->sa->spacedata.first : NULL; - ac.spacetype= (t->sa)? t->sa->spacetype : 0; - ac.regiontype= (t->ar)? t->ar->regiontype : 0; + /* NOTE: sync this with the code in ANIM_animdata_get_context() */ + ac.scene = t->scene; + ac.obact = OBACT; + ac.sa = t->sa; + ac.ar = t->ar; + ac.sl = (t->sa) ? t->sa->spacedata.first : NULL; + ac.spacetype = (t->sa) ? t->sa->spacetype : 0; + ac.regiontype = (t->ar) ? t->ar->regiontype : 0; ANIM_animdata_context_getdata(&ac); @@ -356,14 +356,14 @@ static void recalcData_actedit(TransInfo *t) } else { /* get animdata blocks visible in editor, assuming that these will be the ones where things changed */ - filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* just tag these animdata-blocks to recalc, assuming that some data there changed * BUT only do this if realtime updates are enabled */ if ((saction->flag & SACTION_NOREALTIMEUPDATES) == 0) { - for (ale= anim_data.first; ale; ale= ale->next) { + for (ale = anim_data.first; ale; ale = ale->next) { /* set refresh tags for objects using this animation */ ANIM_list_elem_update(t->scene, ale); } @@ -376,11 +376,11 @@ static void recalcData_actedit(TransInfo *t) /* helper for recalcData() - for Graph Editor transforms */ static void recalcData_graphedit(TransInfo *t) { - SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first; + SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; Scene *scene; ListBase anim_data = {NULL, NULL}; - bAnimContext ac= {NULL}; + bAnimContext ac = {NULL}; int filter; bAnimListElem *ale; @@ -388,14 +388,14 @@ static void recalcData_graphedit(TransInfo *t) /* initialize relevant anim-context 'context' data from TransInfo data */ - /* NOTE: sync this with the code in ANIM_animdata_get_context() */ - scene= ac.scene= t->scene; - ac.obact= OBACT; - ac.sa= t->sa; - ac.ar= t->ar; - ac.sl= (t->sa)? t->sa->spacedata.first : NULL; - ac.spacetype= (t->sa)? t->sa->spacetype : 0; - ac.regiontype= (t->ar)? t->ar->regiontype : 0; + /* NOTE: sync this with the code in ANIM_animdata_get_context() */ + scene = ac.scene = t->scene; + ac.obact = OBACT; + ac.sa = t->sa; + ac.ar = t->ar; + ac.sl = (t->sa) ? t->sa->spacedata.first : NULL; + ac.spacetype = (t->sa) ? t->sa->spacetype : 0; + ac.regiontype = (t->ar) ? t->ar->regiontype : 0; ANIM_animdata_context_getdata(&ac); @@ -403,19 +403,19 @@ static void recalcData_graphedit(TransInfo *t) flushTransGraphData(t); /* get curves to check if a re-sort is needed */ - filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* now test if there is a need to re-sort */ - for (ale= anim_data.first; ale; ale= ale->next) { - FCurve *fcu= (FCurve *)ale->key_data; + for (ale = anim_data.first; ale; ale = ale->next) { + FCurve *fcu = (FCurve *)ale->key_data; /* ignore unselected fcurves */ if (!fcu_test_selected(fcu)) continue; // fixme: only do this for selected verts... - ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYSEL|ANIM_UNITCONV_SELVERTS|ANIM_UNITCONV_RESTORE); + ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYSEL | ANIM_UNITCONV_SELVERTS | ANIM_UNITCONV_RESTORE); /* watch it: if the time is wrong: do not correct handles yet */ @@ -441,10 +441,10 @@ static void recalcData_graphedit(TransInfo *t) /* helper for recalcData() - for NLA Editor transforms */ static void recalcData_nla(TransInfo *t) { - TransDataNla *tdn= (TransDataNla *)t->customData; - SpaceNla *snla= (SpaceNla *)t->sa->spacedata.first; - Scene *scene= t->scene; - double secf= FPS; + TransDataNla *tdn = (TransDataNla *)t->customData; + SpaceNla *snla = (SpaceNla *)t->sa->spacedata.first; + Scene *scene = t->scene; + double secf = FPS; int i; /* for each strip we've got, perform some additional validation of the values that got set before @@ -452,7 +452,7 @@ static void recalcData_nla(TransInfo *t) * sure that everything works ok) */ for (i = 0; i < t->total; i++, tdn++) { - NlaStrip *strip= tdn->strip; + NlaStrip *strip = tdn->strip; PointerRNA strip_ptr; short pExceeded, nExceeded, iter; int delta_y1, delta_y2; @@ -474,16 +474,16 @@ static void recalcData_nla(TransInfo *t) */ /* start */ - strip->start= tdn->h1[0]; + strip->start = tdn->h1[0]; if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION)) - strip->prev->end= tdn->h1[0]; + strip->prev->end = tdn->h1[0]; /* end */ - strip->end= tdn->h2[0]; + strip->end = tdn->h2[0]; if ((strip->next) && (strip->next->type == NLASTRIP_TYPE_TRANSITION)) - strip->next->start= tdn->h2[0]; + strip->next->start = tdn->h2[0]; /* flush transforms to child strips (since this should be a meta) */ BKE_nlameta_flush_transforms(strip); @@ -503,9 +503,9 @@ static void recalcData_nla(TransInfo *t) * * this is done as a iterative procedure (done 5 times max for now) */ - for (iter=0; iter < 5; iter++) { - pExceeded= ((strip->prev) && (strip->prev->type != NLASTRIP_TYPE_TRANSITION) && (tdn->h1[0] < strip->prev->end)); - nExceeded= ((strip->next) && (strip->next->type != NLASTRIP_TYPE_TRANSITION) && (tdn->h2[0] > strip->next->start)); + for (iter = 0; iter < 5; iter++) { + pExceeded = ((strip->prev) && (strip->prev->type != NLASTRIP_TYPE_TRANSITION) && (tdn->h1[0] < strip->prev->end)); + nExceeded = ((strip->next) && (strip->next->type != NLASTRIP_TYPE_TRANSITION) && (tdn->h2[0] > strip->next->start)); if ((pExceeded && nExceeded) || (iter == 4) ) { /* both endpoints exceeded (or iteration ping-pong'd meaning that we need a compromise) @@ -513,24 +513,24 @@ static void recalcData_nla(TransInfo *t) * - if there were no neighbors, clear the transforms (make it default to the strip's current values) */ if (strip->prev && strip->next) { - tdn->h1[0]= strip->prev->end; - tdn->h2[0]= strip->next->start; + tdn->h1[0] = strip->prev->end; + tdn->h2[0] = strip->next->start; } else { - tdn->h1[0]= strip->start; - tdn->h2[0]= strip->end; + tdn->h1[0] = strip->start; + tdn->h2[0] = strip->end; } } else if (nExceeded) { /* move backwards */ - float offset= tdn->h2[0] - strip->next->start; + float offset = tdn->h2[0] - strip->next->start; tdn->h1[0] -= offset; tdn->h2[0] -= offset; } else if (pExceeded) { /* more forwards */ - float offset= strip->prev->end - tdn->h1[0]; + float offset = strip->prev->end - tdn->h1[0]; tdn->h1[0] += offset; tdn->h2[0] += offset; @@ -553,8 +553,8 @@ static void recalcData_nla(TransInfo *t) break; case SACTSNAP_MARKER: /* snap to nearest marker */ - tdn->h1[0]= (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h1[0]); - tdn->h2[0]= (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h2[0]); + tdn->h1[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h1[0]); + tdn->h2[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h2[0]); break; } @@ -572,8 +572,8 @@ static void recalcData_nla(TransInfo *t) /* now, check if we need to try and move track * - we need to calculate both, as only one may have been altered by transform if only 1 handle moved */ - delta_y1= ((int)tdn->h1[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex); - delta_y2= ((int)tdn->h2[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex); + delta_y1 = ((int)tdn->h1[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex); + delta_y2 = ((int)tdn->h2[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex); if (delta_y1 || delta_y2) { NlaTrack *track; @@ -584,14 +584,14 @@ static void recalcData_nla(TransInfo *t) * stopping on the last track available or that we're able to fit in */ if (delta > 0) { - for (track=tdn->nlt->next, n=0; (track) && (n < delta); track=track->next, n++) { + for (track = tdn->nlt->next, n = 0; (track) && (n < delta); track = track->next, n++) { /* check if space in this track for the strip */ if (BKE_nlatrack_has_space(track, strip->start, strip->end)) { /* move strip to this track */ BLI_remlink(&tdn->nlt->strips, strip); BKE_nlatrack_add_strip(track, strip); - tdn->nlt= track; + tdn->nlt = track; tdn->trackIndex++; } else /* can't move any further */ @@ -600,16 +600,16 @@ static void recalcData_nla(TransInfo *t) } else { /* make delta 'positive' before using it, since we now know to go backwards */ - delta= -delta; + delta = -delta; - for (track=tdn->nlt->prev, n=0; (track) && (n < delta); track=track->prev, n++) { + for (track = tdn->nlt->prev, n = 0; (track) && (n < delta); track = track->prev, n++) { /* check if space in this track for the strip */ if (BKE_nlatrack_has_space(track, strip->start, strip->end)) { /* move strip to this track */ BLI_remlink(&tdn->nlt->strips, strip); BKE_nlatrack_add_strip(track, strip); - tdn->nlt= track; + tdn->nlt = track; tdn->trackIndex--; } else /* can't move any further */ @@ -624,7 +624,7 @@ static void recalcData_nla(TransInfo *t) static void recalcData_image(TransInfo *t) { if (t->obedit && t->obedit->type == OB_MESH) { - SpaceImage *sima= t->sa->spacedata.first; + SpaceImage *sima = t->sa->spacedata.first; flushTransUVs(t); if (sima->flag & SI_LIVE_UNWRAP) @@ -649,7 +649,7 @@ static void recalcData_spaceclip(TransInfo *t) track = tracksbase->first; while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if (t->mode == TFM_TRANSLATION) { @@ -691,9 +691,9 @@ static void recalcData_view3d(TransInfo *t) if (t->obedit) { if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) { - Curve *cu= t->obedit->data; - ListBase *nurbs= BKE_curve_editNurbs_get(cu); - Nurb *nu= nurbs->first; + Curve *cu = t->obedit->data; + ListBase *nurbs = BKE_curve_editNurbs_get(cu); + Nurb *nu = nurbs->first; if (t->state != TRANS_CANCEL) { clipMirrorModifier(t, t->obedit); @@ -705,7 +705,7 @@ static void recalcData_view3d(TransInfo *t) if (t->state == TRANS_CANCEL) { while (nu) { BKE_nurb_handles_calc(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */ - nu= nu->next; + nu = nu->next; } } else { @@ -713,12 +713,12 @@ static void recalcData_view3d(TransInfo *t) while (nu) { BKE_nurb_test2D(nu); BKE_nurb_handles_calc(nu); - nu= nu->next; + nu = nu->next; } } } - else if (t->obedit->type==OB_LATTICE) { - Lattice *la= t->obedit->data; + else if (t->obedit->type == OB_LATTICE) { + Lattice *la = t->obedit->data; if (t->state != TRANS_CANCEL) { applyProject(t); @@ -744,8 +744,8 @@ static void recalcData_view3d(TransInfo *t) EDBM_mesh_normals_update(em); BMEdit_RecalcTessellation(em); } - else if (t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */ - bArmature *arm= t->obedit->data; + else if (t->obedit->type == OB_ARMATURE) { /* no recalc flag, does pose */ + bArmature *arm = t->obedit->data; ListBase *edbo = arm->edbo; EditBone *ebo; TransData *td = t->data; @@ -761,33 +761,33 @@ static void recalcData_view3d(TransInfo *t) if ((ebo->flag & BONE_CONNECTED) && ebo->parent) { /* If this bone has a parent tip that has been moved */ if (ebo->parent->flag & BONE_TIPSEL) { - copy_v3_v3 (ebo->head, ebo->parent->tail); - if (t->mode==TFM_BONE_ENVELOPE) ebo->rad_head= ebo->parent->rad_tail; + copy_v3_v3(ebo->head, ebo->parent->tail); + if (t->mode == TFM_BONE_ENVELOPE) ebo->rad_head = ebo->parent->rad_tail; } /* If this bone has a parent tip that has NOT been moved */ else { - copy_v3_v3 (ebo->parent->tail, ebo->head); - if (t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head; + copy_v3_v3(ebo->parent->tail, ebo->head); + if (t->mode == TFM_BONE_ENVELOPE) ebo->parent->rad_tail = ebo->rad_head; } } /* on extrude bones, oldlength==0.0f, so we scale radius of points */ - ebo->length= len_v3v3(ebo->head, ebo->tail); - if (ebo->oldlength==0.0f) { - ebo->rad_head= 0.25f*ebo->length; - ebo->rad_tail= 0.10f*ebo->length; - ebo->dist= 0.25f*ebo->length; + ebo->length = len_v3v3(ebo->head, ebo->tail); + if (ebo->oldlength == 0.0f) { + ebo->rad_head = 0.25f * ebo->length; + ebo->rad_tail = 0.10f * ebo->length; + ebo->dist = 0.25f * ebo->length; if (ebo->parent) { if (ebo->rad_head > ebo->parent->rad_tail) - ebo->rad_head= ebo->parent->rad_tail; + ebo->rad_head = ebo->parent->rad_tail; } } - else if (t->mode!=TFM_BONE_ENVELOPE) { + else if (t->mode != TFM_BONE_ENVELOPE) { /* if bones change length, lets do that for the deform distance as well */ - ebo->dist*= ebo->length/ebo->oldlength; - ebo->rad_head*= ebo->length/ebo->oldlength; - ebo->rad_tail*= ebo->length/ebo->oldlength; - ebo->oldlength= ebo->length; + ebo->dist *= ebo->length / ebo->oldlength; + ebo->rad_head *= ebo->length / ebo->oldlength; + ebo->rad_tail *= ebo->length / ebo->oldlength; + ebo->oldlength = ebo->length; } } @@ -829,8 +829,8 @@ static void recalcData_view3d(TransInfo *t) } } else if ( (t->flag & T_POSE) && t->poseobj) { - Object *ob= t->poseobj; - bArmature *arm= ob->data; + Object *ob = t->poseobj; + bArmature *arm = ob->data; /* if animtimer is running, and the object already has animation data, * check if the auto-record feature means that we should record 'samples' @@ -840,7 +840,7 @@ static void recalcData_view3d(TransInfo *t) */ // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? if ((t->animtimer) && (t->context) && IS_AUTOKEY_ON(t->scene)) { - int targetless_ik= (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet! + int targetless_ik = (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet! animrecord_check_state(t->scene, &ob->id, t->animtimer); autokeyframe_pose_cb_func(t->context, t->scene, (View3D *)t->view, ob, t->mode, targetless_ik); @@ -897,10 +897,10 @@ static void recalcData_view3d(TransInfo *t) /* called for updating while transform acts, once per redraw */ void recalcData(TransInfo *t) { - if (t->spacetype==SPACE_NODE) { + if (t->spacetype == SPACE_NODE) { flushTransNodes(t); } - else if (t->spacetype==SPACE_SEQ) { + else if (t->spacetype == SPACE_SEQ) { flushTransSeq(t); } else if (t->spacetype == SPACE_ACTION) { @@ -953,8 +953,8 @@ void drawLine(TransInfo *t, float *center, float *dir, char axis, short options) setlinestyle(0); glBegin(GL_LINE_STRIP); - glVertex3fv(v1); - glVertex3fv(v2); + glVertex3fv(v1); + glVertex3fv(v2); glEnd(); glPopMatrix(); @@ -1011,20 +1011,20 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->mval[0] = t->imval[0]; t->mval[1] = t->imval[1]; - t->transform = NULL; - t->handleEvent = NULL; + t->transform = NULL; + t->handleEvent = NULL; - t->total = 0; + t->total = 0; t->val = 0.0f; - t->vec[0] = - t->vec[1] = - t->vec[2] = 0.0f; - - t->center[0] = - t->center[1] = - t->center[2] = 0.0f; + t->vec[0] = + t->vec[1] = + t->vec[2] = 0.0f; + + t->center[0] = + t->center[1] = + t->center[2] = 0.0f; unit_m3(t->mat); @@ -1042,15 +1042,15 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) /* Assign the space type, some exceptions for running in different mode */ if (sa == NULL) { /* background mode */ - t->spacetype= SPACE_EMPTY; + t->spacetype = SPACE_EMPTY; } else if ((ar == NULL) && (sa->spacetype == SPACE_VIEW3D)) { /* running in the text editor */ - t->spacetype= SPACE_EMPTY; + t->spacetype = SPACE_EMPTY; } else { /* normal operation */ - t->spacetype= sa->spacetype; + t->spacetype = sa->spacetype; } @@ -1059,7 +1059,7 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) bScreen *animscreen = ED_screen_animation_playing(CTX_wm_manager(C)); t->view = v3d; - t->animtimer= (animscreen)? animscreen->animtimer: NULL; + t->animtimer = (animscreen) ? animscreen->animtimer : NULL; /* turn manipulator off during transform */ // FIXME: but don't do this when USING the manipulator... @@ -1085,7 +1085,7 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) } /* exceptional case */ - if (t->around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) { + if (t->around == V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) { if (ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL)) { t->options |= CTX_NO_PET; } @@ -1107,23 +1107,23 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) } } - else if (t->spacetype==SPACE_IMAGE) { + else if (t->spacetype == SPACE_IMAGE) { SpaceImage *sima = sa->spacedata.first; // XXX for now, get View2D from the active region t->view = &ar->v2d; t->around = sima->around; } - else if (t->spacetype==SPACE_NODE) { + else if (t->spacetype == SPACE_NODE) { // XXX for now, get View2D from the active region t->view = &ar->v2d; t->around = V3D_CENTER; } - else if (t->spacetype==SPACE_IPO) { - SpaceIpo *sipo= sa->spacedata.first; + else if (t->spacetype == SPACE_IPO) { + SpaceIpo *sipo = sa->spacedata.first; t->view = &ar->v2d; t->around = sipo->around; } - else if (t->spacetype==SPACE_CLIP) { + else if (t->spacetype == SPACE_CLIP) { SpaceClip *sclip = sa->spacedata.first; t->view = &ar->v2d; t->around = sclip->around; @@ -1140,7 +1140,7 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) // XXX for now, the center point is the midpoint of the data } else { - t->view= NULL; + t->view = NULL; } t->around = V3D_CENTER; } @@ -1277,7 +1277,7 @@ void postTrans(bContext *C, TransInfo *t) int a; /* free data malloced per trans-data */ - for (a=0, td= t->data; atotal; a++, td++) { + for (a = 0, td = t->data; a < t->total; a++, td++) { if (td->flag & TD_BEZTRIPLE) MEM_freeN(td->hdata); } @@ -1289,15 +1289,15 @@ void postTrans(bContext *C, TransInfo *t) if (t->ext) MEM_freeN(t->ext); if (t->data2d) { MEM_freeN(t->data2d); - t->data2d= NULL; + t->data2d = NULL; } - if (t->spacetype==SPACE_IMAGE) { - SpaceImage *sima= t->sa->spacedata.first; + if (t->spacetype == SPACE_IMAGE) { + SpaceImage *sima = t->sa->spacedata.first; if (sima->flag & SI_LIVE_UNWRAP) ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL); } - else if (t->spacetype==SPACE_VIEW3D) { + else if (t->spacetype == SPACE_VIEW3D) { View3D *v3d = t->sa->spacedata.first; /* restore manipulator */ if (t->flag & T_MODAL) { @@ -1336,12 +1336,12 @@ static void restoreElement(TransData *td) *td->val = td->ival; } - if (td->ext && (td->flag&TD_NO_EXT)==0) { + if (td->ext && (td->flag & TD_NO_EXT) == 0) { if (td->ext->rot) { copy_v3_v3(td->ext->rot, td->ext->irot); } if (td->ext->rotAngle) { - *td->ext->rotAngle= td->ext->irotAngle; + *td->ext->rotAngle = td->ext->irotAngle; } if (td->ext->rotAxis) { copy_v3_v3(td->ext->rotAxis, td->ext->irotAxis); @@ -1370,7 +1370,7 @@ void restoreTransObjects(TransInfo *t) restoreElement(td); } - for (td2d=t->data2d; t->data2d && td2d < t->data2d + t->total; td2d++) { + for (td2d = t->data2d; t->data2d && td2d < t->data2d + t->total; td2d++) { if (td2d->h1) { td2d->h1[0] = td2d->ih1[0]; td2d->h1[1] = td2d->ih1[1]; @@ -1388,8 +1388,8 @@ void restoreTransObjects(TransInfo *t) void calculateCenter2D(TransInfo *t) { - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob= t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; float vec[3]; copy_v3_v3(vec, t->center); @@ -1409,8 +1409,8 @@ void calculateCenterCursor(TransInfo *t) copy_v3_v3(t->center, cursor); /* If edit or pose mode, move cursor in local space */ - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob = t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; float mat[3][3], imat[3][3]; sub_v3_v3v3(t->center, t->center, ob->obmat[3]); @@ -1424,11 +1424,11 @@ void calculateCenterCursor(TransInfo *t) void calculateCenterCursor2D(TransInfo *t) { - float aspx=1.0, aspy=1.0; - float *cursor= NULL; + float aspx = 1.0, aspy = 1.0; + float *cursor = NULL; - if (t->spacetype==SPACE_IMAGE) { - SpaceImage *sima= (SpaceImage *)t->sa->spacedata.first; + if (t->spacetype == SPACE_IMAGE) { + SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first; /* only space supported right now but may change */ ED_space_image_uv_aspect(sima, &aspx, &aspy); cursor = sima->cursor; @@ -1444,12 +1444,12 @@ void calculateCenterCursor2D(TransInfo *t) static void calculateCenterCursorGraph2D(TransInfo *t) { - SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first; - Scene *scene= t->scene; + SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; + Scene *scene = t->scene; /* cursor is combination of current frame, and graph-editor cursor value */ - t->center[0]= (float)(scene->r.cfra); - t->center[1]= sipo->cursorVal; + t->center[0] = (float)(scene->r.cfra); + t->center[1] = sipo->cursorVal; calculateCenter2D(t); } @@ -1515,95 +1515,95 @@ void calculateCenterBound(TransInfo *t) void calculateCenter(TransInfo *t) { switch (t->around) { - case V3D_CENTER: - calculateCenterBound(t); - break; - case V3D_CENTROID: - calculateCenterMedian(t); - break; - case V3D_CURSOR: - if (t->spacetype==SPACE_IMAGE) - calculateCenterCursor2D(t); - else if (t->spacetype==SPACE_IPO) - calculateCenterCursorGraph2D(t); - else - calculateCenterCursor(t); - break; - case V3D_LOCAL: - /* Individual element center uses median center for helpline and such */ - calculateCenterMedian(t); - break; - case V3D_ACTIVE: + case V3D_CENTER: + calculateCenterBound(t); + break; + case V3D_CENTROID: + calculateCenterMedian(t); + break; + case V3D_CURSOR: + if (t->spacetype == SPACE_IMAGE) + calculateCenterCursor2D(t); + else if (t->spacetype == SPACE_IPO) + calculateCenterCursorGraph2D(t); + else + calculateCenterCursor(t); + break; + case V3D_LOCAL: + /* Individual element center uses median center for helpline and such */ + calculateCenterMedian(t); + break; + case V3D_ACTIVE: { - /* set median, and if if if... do object center */ + /* set median, and if if if... do object center */ - /* EDIT MODE ACTIVE EDITMODE ELEMENT */ + /* EDIT MODE ACTIVE EDITMODE ELEMENT */ - if (t->obedit) { - if (t->obedit && t->obedit->type == OB_MESH) { - BMEditSelection ese; - BMEditMesh *em = BMEdit_FromObject(t->obedit); + if (t->obedit) { + if (t->obedit && t->obedit->type == OB_MESH) { + BMEditSelection ese; + BMEditMesh *em = BMEdit_FromObject(t->obedit); - if (BM_select_history_active_get(em->bm, &ese)) { - BM_editselection_center(&ese, t->center); - calculateCenter2D(t); - break; + if (BM_select_history_active_get(em->bm, &ese)) { + BM_editselection_center(&ese, t->center); + calculateCenter2D(t); + break; + } + } + else if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) { + float center[3]; + Curve *cu = (Curve *)t->obedit->data; + + if (ED_curve_actSelection(cu, center)) { + copy_v3_v3(t->center, center); + calculateCenter2D(t); + break; + } + } + } /* END EDIT MODE ACTIVE ELEMENT */ + + calculateCenterMedian(t); + if ((t->flag & (T_EDIT | T_POSE)) == 0) { + Scene *scene = t->scene; + Object *ob = OBACT; + if (ob) { + copy_v3_v3(t->center, ob->obmat[3]); + projectIntView(t, t->center, t->center2d); } } - else if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) { - float center[3]; - Curve *cu= (Curve *)t->obedit->data; - - if (ED_curve_actSelection(cu, center)) { - copy_v3_v3(t->center, center); - calculateCenter2D(t); - break; - } - } - } /* END EDIT MODE ACTIVE ELEMENT */ - - calculateCenterMedian(t); - if ((t->flag & (T_EDIT|T_POSE))==0) { - Scene *scene = t->scene; - Object *ob= OBACT; - if (ob) { - copy_v3_v3(t->center, ob->obmat[3]); - projectIntView(t, t->center, t->center2d); - } - } } } /* setting constraint center */ copy_v3_v3(t->con.center, t->center); - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob= t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; mul_m4_v3(ob->obmat, t->con.center); } /* for panning from cameraview */ if (t->flag & T_OBJECT) { - if (t->spacetype==SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) { + if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) { View3D *v3d = t->view; Scene *scene = t->scene; RegionView3D *rv3d = t->ar->regiondata; - if (v3d->camera == OBACT && rv3d->persp==RV3D_CAMOB) { + if (v3d->camera == OBACT && rv3d->persp == RV3D_CAMOB) { float axis[3]; /* persinv is nasty, use viewinv instead, always right */ copy_v3_v3(axis, t->viewinv[2]); normalize_v3(axis); /* 6.0 = 6 grid units */ - axis[0]= t->center[0]- 6.0f*axis[0]; - axis[1]= t->center[1]- 6.0f*axis[1]; - axis[2]= t->center[2]- 6.0f*axis[2]; + axis[0] = t->center[0] - 6.0f * axis[0]; + axis[1] = t->center[1] - 6.0f * axis[1]; + axis[2] = t->center[2] - 6.0f * axis[2]; projectIntView(t, axis, t->center2d); /* rotate only needs correct 2d center, grab needs initgrabz() value */ - if (t->mode==TFM_TRANSLATION) { + if (t->mode == TFM_TRANSLATION) { copy_v3_v3(t->center, axis); copy_v3_v3(t->con.center, t->center); } @@ -1611,10 +1611,10 @@ void calculateCenter(TransInfo *t) } } - if (t->spacetype==SPACE_VIEW3D) { + if (t->spacetype == SPACE_VIEW3D) { /* initgrabz() defines a factor for perspective depth correction, used in window_to_3d_delta() */ - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob= t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; float vec[3]; copy_v3_v3(vec, t->center); @@ -1635,7 +1635,7 @@ void calculatePropRatio(TransInfo *t) short connected = t->flag & T_PROP_CONNECTED; if (t->flag & T_PROP_EDIT) { - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_SELECTED) { td->factor = 1.0f; } @@ -1660,9 +1660,9 @@ void calculatePropRatio(TransInfo *t) td->flag &= ~TD_NOACTION; if (connected) - dist= (t->prop_size-td->dist)/t->prop_size; + dist = (t->prop_size - td->dist) / t->prop_size; else - dist= (t->prop_size-td->rdist)/t->prop_size; + dist = (t->prop_size - td->rdist) / t->prop_size; /* * Clamp to positive numbers. @@ -1673,63 +1673,63 @@ void calculatePropRatio(TransInfo *t) dist = 0.0f; switch (t->prop_mode) { - case PROP_SHARP: - td->factor= dist*dist; - break; - case PROP_SMOOTH: - td->factor= 3.0f*dist*dist - 2.0f*dist*dist*dist; - break; - case PROP_ROOT: - td->factor = (float)sqrt(dist); - break; - case PROP_LIN: - td->factor = dist; - break; - case PROP_CONST: - td->factor = 1.0f; - break; - case PROP_SPHERE: - td->factor = (float)sqrt(2*dist - dist * dist); - break; - case PROP_RANDOM: - BLI_srand(BLI_rand()); /* random seed */ - td->factor = BLI_frand()*dist; - break; - default: - td->factor = 1; + case PROP_SHARP: + td->factor = dist * dist; + break; + case PROP_SMOOTH: + td->factor = 3.0f * dist * dist - 2.0f * dist * dist * dist; + break; + case PROP_ROOT: + td->factor = (float)sqrt(dist); + break; + case PROP_LIN: + td->factor = dist; + break; + case PROP_CONST: + td->factor = 1.0f; + break; + case PROP_SPHERE: + td->factor = (float)sqrt(2 * dist - dist * dist); + break; + case PROP_RANDOM: + BLI_srand(BLI_rand()); /* random seed */ + td->factor = BLI_frand() * dist; + break; + default: + td->factor = 1; } } } switch (t->prop_mode) { - case PROP_SHARP: - strcpy(t->proptext, "(Sharp)"); - break; - case PROP_SMOOTH: - strcpy(t->proptext, "(Smooth)"); - break; - case PROP_ROOT: - strcpy(t->proptext, "(Root)"); - break; - case PROP_LIN: - strcpy(t->proptext, "(Linear)"); - break; - case PROP_CONST: - strcpy(t->proptext, "(Constant)"); - break; - case PROP_SPHERE: - strcpy(t->proptext, "(Sphere)"); - break; - case PROP_RANDOM: - strcpy(t->proptext, "(Random)"); - break; - default: - t->proptext[0]= '\0'; + case PROP_SHARP: + strcpy(t->proptext, "(Sharp)"); + break; + case PROP_SMOOTH: + strcpy(t->proptext, "(Smooth)"); + break; + case PROP_ROOT: + strcpy(t->proptext, "(Root)"); + break; + case PROP_LIN: + strcpy(t->proptext, "(Linear)"); + break; + case PROP_CONST: + strcpy(t->proptext, "(Constant)"); + break; + case PROP_SPHERE: + strcpy(t->proptext, "(Sphere)"); + break; + case PROP_RANDOM: + strcpy(t->proptext, "(Random)"); + break; + default: + t->proptext[0] = '\0'; } } else { - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { td->factor = 1.0; } - t->proptext[0]= '\0'; + t->proptext[0] = '\0'; } } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 52b32ae66fc..f00e2418ad9 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -53,8 +53,8 @@ typedef struct TransformModeItem { char *idname; - int mode; - void (*opfunc)(wmOperatorType*); + int mode; + void (*opfunc)(wmOperatorType *); } TransformModeItem; static float VecOne[3] = {1, 1, 1}; @@ -151,11 +151,11 @@ EnumPropertyItem transform_mode_types[] = static int snap_type_exec(bContext *C, wmOperator *op) { - ToolSettings *ts= CTX_data_tool_settings(C); + ToolSettings *ts = CTX_data_tool_settings(C); ts->snap_mode = RNA_enum_get(op->ptr, "type"); - WM_event_add_notifier(C, NC_SCENE|ND_TOOLSETTINGS, NULL); /* header redraw */ + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ return OPERATOR_FINISHED; } @@ -187,7 +187,7 @@ static int select_orientation_exec(bContext *C, wmOperator *op) BIF_selectTransformOrientationValue(C, orientation); - WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); return OPERATOR_FINISHED; } @@ -197,8 +197,8 @@ static int select_orientation_invoke(bContext *C, wmOperator *UNUSED(op), wmEven uiPopupMenu *pup; uiLayout *layout; - pup= uiPupMenuBegin(C, "Orientation", ICON_NONE); - layout= uiPupMenuLayout(pup); + pup = uiPupMenuBegin(C, "Orientation", ICON_NONE); + layout = uiPupMenuLayout(pup); uiItemsEnumO(layout, "TRANSFORM_OT_select_orientation", "orientation"); uiPupMenuEnd(C, pup); @@ -220,7 +220,7 @@ static void TRANSFORM_OT_select_orientation(struct wmOperatorType *ot) ot->exec = select_orientation_exec; ot->poll = ED_operator_view3d_active; - prop= RNA_def_property(ot->srna, "orientation", PROP_ENUM, PROP_NONE); + prop = RNA_def_property(ot->srna, "orientation", PROP_ENUM, PROP_NONE); RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation"); RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf); } @@ -233,8 +233,8 @@ static int delete_orientation_exec(bContext *C, wmOperator *UNUSED(op)) BIF_removeTransformOrientationIndex(C, selected_index); - WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); - WM_event_add_notifier(C, NC_SCENE|NA_EDITED, CTX_data_scene(C)); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + WM_event_add_notifier(C, NC_SCENE | NA_EDITED, CTX_data_scene(C)); return OPERATOR_FINISHED; } @@ -284,8 +284,8 @@ static int create_orientation_exec(bContext *C, wmOperator *op) BIF_createTransformOrientation(C, op->reports, name, use, overwrite); - WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); - WM_event_add_notifier(C, NC_SCENE|NA_EDITED, CTX_data_scene(C)); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + WM_event_add_notifier(C, NC_SCENE | NA_EDITED, CTX_data_scene(C)); return OPERATOR_FINISHED; } @@ -301,13 +301,13 @@ static void TRANSFORM_OT_create_orientation(struct wmOperatorType *ot) ot->name = "Create Orientation"; ot->description = "Create transformation orientation from selection"; ot->idname = "TRANSFORM_OT_create_orientation"; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* api callbacks */ ot->invoke = create_orientation_invoke; ot->exec = create_orientation_exec; ot->poll = ED_operator_areaactive; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Text to insert at the cursor position"); RNA_def_boolean(ot->srna, "use", 0, "Use after creation", "Select orientation after its creation"); @@ -372,9 +372,9 @@ static int transform_modal(bContext *C, wmOperator *op, wmEvent *event) #endif /* XXX insert keys are called here, and require context */ - t->context= C; + t->context = C; exit_code = transformEvent(t, event); - t->context= NULL; + t->context = NULL; transformApply(C, t); @@ -418,7 +418,7 @@ static int transform_exec(bContext *C, wmOperator *op) transformops_exit(C, op); - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return OPERATOR_FINISHED; } @@ -447,7 +447,7 @@ void Transform_Properties(struct wmOperatorType *ot, int flags) PropertyRNA *prop; if (flags & P_AXIS) { - prop= RNA_def_property(ot->srna, "axis", PROP_FLOAT, PROP_DIRECTION); + prop = RNA_def_property(ot->srna, "axis", PROP_FLOAT, PROP_DIRECTION); RNA_def_property_array(prop, 3); /* Make this not hidden when there's a nice axis selection widget */ RNA_def_property_flag(prop, PROP_HIDDEN); @@ -457,7 +457,7 @@ void Transform_Properties(struct wmOperatorType *ot, int flags) if (flags & P_CONSTRAINT) { RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", ""); - prop= RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE); + prop = RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE); RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation"); RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf); @@ -476,19 +476,19 @@ void Transform_Properties(struct wmOperatorType *ot, int flags) } if (flags & P_SNAP) { - prop= RNA_def_boolean(ot->srna, "snap", 0, "Use Snapping Options", ""); + prop = RNA_def_boolean(ot->srna, "snap", 0, "Use Snapping Options", ""); RNA_def_property_flag(prop, PROP_HIDDEN); if (flags & P_GEO_SNAP) { - prop= RNA_def_enum(ot->srna, "snap_target", snap_target_items, 0, "Target", ""); + prop = RNA_def_enum(ot->srna, "snap_target", snap_target_items, 0, "Target", ""); RNA_def_property_flag(prop, PROP_HIDDEN); - prop= RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX); + prop = RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX); RNA_def_property_flag(prop, PROP_HIDDEN); if (flags & P_ALIGN_SNAP) { - prop= RNA_def_boolean(ot->srna, "snap_align", 0, "Align with Point Normal", ""); + prop = RNA_def_boolean(ot->srna, "snap_align", 0, "Align with Point Normal", ""); RNA_def_property_flag(prop, PROP_HIDDEN); - prop= RNA_def_float_vector(ot->srna, "snap_normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "", -FLT_MAX, FLT_MAX); + prop = RNA_def_float_vector(ot->srna, "snap_normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "", -FLT_MAX, FLT_MAX); RNA_def_property_flag(prop, PROP_HIDDEN); } } @@ -513,7 +513,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot) ot->name = "Translate"; ot->description = "Translate (move) selected items"; ot->idname = OP_TRANSLATION; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -524,7 +524,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot) RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_ALIGN_SNAP|P_OPTIONS); + Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_OPTIONS); } static void TRANSFORM_OT_resize(struct wmOperatorType *ot) @@ -533,7 +533,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot) ot->name = "Resize"; ot->description = "Scale (resize) selected items"; ot->idname = OP_RESIZE; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -544,7 +544,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot) RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_GEO_SNAP|P_OPTIONS); + Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS); } static int skin_resize_poll(bContext *C) @@ -563,7 +563,7 @@ static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot) ot->name = "Skin Resize"; ot->description = "Scale selected vertices' skin radii"; ot->idname = OP_SKIN_RESIZE; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -574,7 +574,7 @@ static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot) RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_GEO_SNAP|P_OPTIONS); + Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS); } static void TRANSFORM_OT_trackball(struct wmOperatorType *ot) @@ -583,7 +583,7 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot) ot->name = "Trackball"; ot->description = "Trackball style rotation of selected items"; ot->idname = OP_TRACKBALL; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -594,7 +594,7 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot) RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); } static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) @@ -603,7 +603,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) ot->name = "Rotate"; ot->description = "Rotate selected items"; ot->idname = OP_ROTATION; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -612,9 +612,9 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; - RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2); + RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); - Transform_Properties(ot, P_AXIS|P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_GEO_SNAP); + Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP); } static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) @@ -626,7 +626,7 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) * "Specify an extra axis rotation for selected vertices of 3d curve" */ ot->description = "Tilt selected control vertices of 3d curve"; ot->idname = OP_TILT; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -635,9 +635,9 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_editcurve_3d; - RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2); + RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); - Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_SNAP); + Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_SNAP); } static void TRANSFORM_OT_warp(struct wmOperatorType *ot) @@ -646,7 +646,7 @@ static void TRANSFORM_OT_warp(struct wmOperatorType *ot) ot->name = "Warp"; ot->description = "Warp selected items around the cursor"; ot->idname = OP_WARP; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -655,9 +655,9 @@ static void TRANSFORM_OT_warp(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; - RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2); + RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); - Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); // XXX Warp axis? } @@ -667,7 +667,7 @@ static void TRANSFORM_OT_shear(struct wmOperatorType *ot) ot->name = "Shear"; ot->description = "Shear selected items along the horizontal screen axis"; ot->idname = OP_SHEAR; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -678,7 +678,7 @@ static void TRANSFORM_OT_shear(struct wmOperatorType *ot) RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); // XXX Shear axis? } @@ -688,7 +688,7 @@ static void TRANSFORM_OT_push_pull(struct wmOperatorType *ot) ot->name = "Push/Pull"; ot->description = "Push/Pull selected items"; ot->idname = OP_PUSH_PULL; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -699,7 +699,7 @@ static void TRANSFORM_OT_push_pull(struct wmOperatorType *ot) RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Distance", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); } static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot) @@ -708,7 +708,7 @@ static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot) ot->name = "Shrink/Fatten"; ot->description = "Shrink/fatten selected vertices along normals"; ot->idname = OP_SHRINK_FATTEN; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -719,7 +719,7 @@ static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot) RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); } static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot) @@ -729,7 +729,7 @@ static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot) //added "around mesh center" to differentiate between "MESH_OT_vertices_to_sphere()" ot->description = "Move selected vertices outward in a spherical shape around mesh center"; ot->idname = OP_TOSPHERE; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -740,7 +740,7 @@ static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot) RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1); - Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); } static void TRANSFORM_OT_mirror(struct wmOperatorType *ot) @@ -749,7 +749,7 @@ static void TRANSFORM_OT_mirror(struct wmOperatorType *ot) ot->name = "Mirror"; ot->description = "Mirror selected vertices around one or more axes"; ot->idname = OP_MIRROR; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -758,7 +758,7 @@ static void TRANSFORM_OT_mirror(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; - Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL); + Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL); } static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot) @@ -767,7 +767,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot) ot->name = "Edge Slide"; ot->description = "Slide an edge loop along a mesh"; ot->idname = OP_EDGE_SLIDE; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -778,7 +778,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot) RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f); - Transform_Properties(ot, P_MIRROR|P_SNAP|P_CORRECT_UV); + Transform_Properties(ot, P_MIRROR | P_SNAP | P_CORRECT_UV); } static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot) @@ -787,7 +787,7 @@ static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot) ot->name = "Edge Crease"; ot->description = "Change the crease of edges"; ot->idname = OP_EDGE_CREASE; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -807,7 +807,7 @@ static void TRANSFORM_OT_edge_bevelweight(struct wmOperatorType *ot) ot->name = "Edge Bevel Weight"; ot->description = "Change the bevel weight of edges"; ot->idname = OP_EDGE_BWEIGHT; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -827,7 +827,7 @@ static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot) ot->name = "Sequence Slide"; ot->description = "Slide a sequence strip in time"; ot->idname = OP_SEQ_SLIDE; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -849,7 +849,7 @@ static void TRANSFORM_OT_transform(struct wmOperatorType *ot) ot->name = "Transform"; ot->description = "Transform selected items by mode type"; ot->idname = "TRANSFORM_OT_transform"; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -858,12 +858,12 @@ static void TRANSFORM_OT_transform(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; - prop= RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", ""); + prop = RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", ""); RNA_def_property_flag(prop, PROP_HIDDEN); RNA_def_float_vector(ot->srna, "value", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_AXIS|P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_ALIGN_SNAP); + Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP); } void transform_operatortypes(void) @@ -913,13 +913,13 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac WM_keymap_add_item(keymap, OP_WARP, WKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, OP_TOSPHERE, SKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0); + WM_keymap_add_item(keymap, OP_TOSPHERE, SKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0); - WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0); + WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT | KM_CTRL | KM_SHIFT, 0); WM_keymap_add_item(keymap, "TRANSFORM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0); - kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); + kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); RNA_boolean_set(kmi->ptr, "use", TRUE); WM_keymap_add_item(keymap, OP_MIRROR, MKEY, KM_PRESS, KM_CTRL, 0); @@ -927,12 +927,12 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap"); - WM_keymap_add_item(keymap, "TRANSFORM_OT_snap_type", TABKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); + WM_keymap_add_item(keymap, "TRANSFORM_OT_snap_type", TABKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0); kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, TKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "texture_space", TRUE); - kmi = WM_keymap_add_item(keymap, OP_RESIZE, TKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); + kmi = WM_keymap_add_item(keymap, OP_RESIZE, TKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0); RNA_boolean_set(kmi->ptr, "texture_space", TRUE); WM_keymap_add_item(keymap, OP_SKIN_RESIZE, AKEY, KM_PRESS, KM_CTRL, 0); @@ -1014,7 +1014,7 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0); + WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT | KM_CTRL | KM_SHIFT, 0); WM_keymap_add_item(keymap, "TRANSFORM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h index b9d63167700..b5ab7898bd9 100644 --- a/source/blender/makesdna/DNA_movieclip_types.h +++ b/source/blender/makesdna/DNA_movieclip_types.h @@ -47,97 +47,97 @@ struct MovieTrackingTrack; struct MovieTrackingMarker; typedef struct MovieClipUser { - int framenr; /* current frame number */ - short render_size, render_flag; /* proxy render size */ + int framenr; /* current frame number */ + short render_size, render_flag; /* proxy render size */ } MovieClipUser; typedef struct MovieClipProxy { - char dir[768]; /* 768=FILE_MAXDIR custom directory for index and proxy files (defaults to BL_proxy) */ + char dir[768]; /* 768=FILE_MAXDIR custom directory for index and proxy files (defaults to BL_proxy) */ - short tc; /* time code in use */ - short quality; /* proxy build quality */ - short build_size_flag; /* size flags (see below) of all proxies to build */ - short build_tc_flag; /* time code flags (see below) of all tc indices to build */ + short tc; /* time code in use */ + short quality; /* proxy build quality */ + short build_size_flag; /* size flags (see below) of all proxies to build */ + short build_tc_flag; /* time code flags (see below) of all tc indices to build */ } MovieClipProxy; typedef struct MovieClip { ID id; - struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ + struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ - char name[1024]; /* file path, 1024 = FILE_MAX */ + char name[1024]; /* file path, 1024 = FILE_MAX */ - int source; /* sequence or movie */ - int lastframe; /* last accessed frame number */ - int lastsize[2]; /* size of last accessed frame */ + int source; /* sequence or movie */ + int lastframe; /* last accessed frame number */ + int lastsize[2]; /* size of last accessed frame */ - float aspx, aspy; /* display aspect */ + float aspx, aspy; /* display aspect */ - struct anim *anim; /* movie source data */ - struct MovieClipCache *cache; /* cache for different stuff, not in file */ - struct bGPdata *gpd; /* grease pencil data */ + struct anim *anim; /* movie source data */ + struct MovieClipCache *cache; /* cache for different stuff, not in file */ + struct bGPdata *gpd; /* grease pencil data */ - struct MovieTracking tracking; /* data for SfM tracking */ - void *tracking_context; /* context of tracking job - * used to synchronize data like framenumber - * in SpaceClip clip user */ + struct MovieTracking tracking; /* data for SfM tracking */ + void *tracking_context; /* context of tracking job + * used to synchronize data like framenumber + * in SpaceClip clip user */ - struct MovieClipProxy proxy; /* proxy to clip data */ + struct MovieClipProxy proxy; /* proxy to clip data */ int flag; - int len; /* length of movie */ + int len; /* length of movie */ int start_frame, pad; } MovieClip; typedef struct MovieClipScopes { - int ok; /* 1 means scopes are ok and recalculation is unneeded */ - int track_preview_height; /* height of track preview widget */ - int frame_width, frame_height; /* width and height of frame for which scopes are calculated */ - struct MovieTrackingMarker undist_marker; /* undistorted position of marker used for pattern sampling */ - struct ImBuf *track_search; /* search area of a track */ - struct ImBuf *track_preview; /* ImBuf displayed in track preview */ - float track_pos[2]; /* sub-pizel position of marker in track ImBuf */ - short track_disabled; /* active track is disabled, special notifier should be drawn */ + int ok; /* 1 means scopes are ok and recalculation is unneeded */ + int track_preview_height; /* height of track preview widget */ + int frame_width, frame_height; /* width and height of frame for which scopes are calculated */ + struct MovieTrackingMarker undist_marker; /* undistorted position of marker used for pattern sampling */ + struct ImBuf *track_search; /* search area of a track */ + struct ImBuf *track_preview; /* ImBuf displayed in track preview */ + float track_pos[2]; /* sub-pizel position of marker in track ImBuf */ + short track_disabled; /* active track is disabled, special notifier should be drawn */ char pad[2]; - int framenr; /* frame number scopes are created for */ - struct MovieTrackingTrack *track; /* track scopes are created for */ - struct MovieTrackingMarker *marker; /* marker scopes are created for */ - float slide_scale[2]; /* scale used for sliding from previewe area */ + int framenr; /* frame number scopes are created for */ + struct MovieTrackingTrack *track; /* track scopes are created for */ + struct MovieTrackingMarker *marker; /* marker scopes are created for */ + float slide_scale[2]; /* scale used for sliding from previewe area */ } MovieClipScopes; /* MovieClipProxy->build_size_flag */ -#define MCLIP_PROXY_SIZE_25 (1<<0) -#define MCLIP_PROXY_SIZE_50 (1<<1) -#define MCLIP_PROXY_SIZE_75 (1<<2) -#define MCLIP_PROXY_SIZE_100 (1<<3) -#define MCLIP_PROXY_UNDISTORTED_SIZE_25 (1<<4) -#define MCLIP_PROXY_UNDISTORTED_SIZE_50 (1<<5) -#define MCLIP_PROXY_UNDISTORTED_SIZE_75 (1<<6) -#define MCLIP_PROXY_UNDISTORTED_SIZE_100 (1<<7) +#define MCLIP_PROXY_SIZE_25 (1 << 0) +#define MCLIP_PROXY_SIZE_50 (1 << 1) +#define MCLIP_PROXY_SIZE_75 (1 << 2) +#define MCLIP_PROXY_SIZE_100 (1 << 3) +#define MCLIP_PROXY_UNDISTORTED_SIZE_25 (1 << 4) +#define MCLIP_PROXY_UNDISTORTED_SIZE_50 (1 << 5) +#define MCLIP_PROXY_UNDISTORTED_SIZE_75 (1 << 6) +#define MCLIP_PROXY_UNDISTORTED_SIZE_100 (1 << 7) /* MovieClip->source */ -#define MCLIP_SRC_SEQUENCE 1 -#define MCLIP_SRC_MOVIE 2 +#define MCLIP_SRC_SEQUENCE 1 +#define MCLIP_SRC_MOVIE 2 /* MovieClip->selection types */ -#define MCLIP_SEL_NONE 0 -#define MCLIP_SEL_TRACK 1 +#define MCLIP_SEL_NONE 0 +#define MCLIP_SEL_TRACK 1 /* MovieClip->flag */ -#define MCLIP_USE_PROXY (1<<0) -#define MCLIP_USE_PROXY_CUSTOM_DIR (1<<1) +#define MCLIP_USE_PROXY (1 << 0) +#define MCLIP_USE_PROXY_CUSTOM_DIR (1 << 1) /*#define MCLIP_CUSTOM_START_FRAME (1<<2)*/ /* UNUSED */ -#define MCLIP_TIMECODE_FLAGS (MCLIP_USE_PROXY|MCLIP_USE_PROXY_CUSTOM_DIR) +#define MCLIP_TIMECODE_FLAGS (MCLIP_USE_PROXY | MCLIP_USE_PROXY_CUSTOM_DIR) /* MovieClip->render_size */ -#define MCLIP_PROXY_RENDER_SIZE_FULL 0 -#define MCLIP_PROXY_RENDER_SIZE_25 1 -#define MCLIP_PROXY_RENDER_SIZE_50 2 -#define MCLIP_PROXY_RENDER_SIZE_75 3 -#define MCLIP_PROXY_RENDER_SIZE_100 4 +#define MCLIP_PROXY_RENDER_SIZE_FULL 0 +#define MCLIP_PROXY_RENDER_SIZE_25 1 +#define MCLIP_PROXY_RENDER_SIZE_50 2 +#define MCLIP_PROXY_RENDER_SIZE_75 3 +#define MCLIP_PROXY_RENDER_SIZE_100 4 /* MovieClip->render_flag */ -#define MCLIP_PROXY_RENDER_UNDISTORT 1 +#define MCLIP_PROXY_RENDER_UNDISTORT 1 #endif diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index a315feed6c5..0b5b2177342 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -35,11 +35,11 @@ #include "DNA_defs.h" #include "DNA_listBase.h" -#include "DNA_color_types.h" /* for Histogram */ +#include "DNA_color_types.h" /* for Histogram */ #include "DNA_vec_types.h" -#include "DNA_outliner_types.h" /* for TreeStoreElem */ -#include "DNA_image_types.h" /* ImageUser */ -#include "DNA_movieclip_types.h" /* MovieClipUser */ +#include "DNA_outliner_types.h" /* for TreeStoreElem */ +#include "DNA_image_types.h" /* ImageUser */ +#include "DNA_movieclip_types.h" /* MovieClipUser */ /* Hum ... Not really nice... but needed for spacebuts. */ #include "DNA_view2d_types.h" @@ -79,9 +79,9 @@ struct Mask; */ typedef struct SpaceLink { struct SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; /* XXX make deprecated */ + float blockscale DNA_DEPRECATED; /* XXX make deprecated */ short blockhandler[8] DNA_DEPRECATED; /* XXX make deprecated */ } SpaceLink; @@ -91,10 +91,10 @@ typedef struct SpaceLink { /* Info Header */ typedef struct SpaceInfo { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; - short blockhandler[8] DNA_DEPRECATED; /* XXX make deprecated */ + float blockscale DNA_DEPRECATED; + short blockhandler[8] DNA_DEPRECATED; /* XXX make deprecated */ char rpt_mask; char pad[7]; @@ -102,11 +102,11 @@ typedef struct SpaceInfo { /* SpaceInfo.rpt_mask */ typedef enum eSpaceInfo_RptMask { - INFO_RPT_DEBUG = (1 << 0), - INFO_RPT_INFO = (1 << 1), - INFO_RPT_OP = (1 << 2), - INFO_RPT_WARN = (1 << 3), - INFO_RPT_ERR = (1 << 4), + INFO_RPT_DEBUG = (1 << 0), + INFO_RPT_INFO = (1 << 1), + INFO_RPT_OP = (1 << 2), + INFO_RPT_WARN = (1 << 3), + INFO_RPT_ERR = (1 << 4), } eSpaceInfo_RptMask; @@ -115,22 +115,22 @@ typedef enum eSpaceInfo_RptMask { /* Properties Editor */ typedef struct SpaceButs { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; + float blockscale DNA_DEPRECATED; short blockhandler[8] DNA_DEPRECATED; - View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ + View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ - short mainb, mainbo, mainbuser; /* context tabs */ - short re_align, align; /* align for panels */ - short preview; /* preview is signal to refresh */ - short texture_context; /* texture context selector (material, world, brush)*/ + short mainb, mainbo, mainbuser; /* context tabs */ + short re_align, align; /* align for panels */ + short preview; /* preview is signal to refresh */ + short texture_context; /* texture context selector (material, world, brush)*/ char flag, pad; - void *path; /* runtime */ - int pathflag, dataicon; /* runtime */ + void *path; /* runtime */ + int pathflag, dataicon; /* runtime */ ID *pinid; void *texuser; @@ -139,30 +139,30 @@ typedef struct SpaceButs { /* button defines (deprecated) */ /* warning: the values of these defines are used in sbuts->tabs[8] */ /* sbuts->mainb new */ -#define CONTEXT_SCENE 0 -#define CONTEXT_OBJECT 1 -#define CONTEXT_TYPES 2 -#define CONTEXT_SHADING 3 -#define CONTEXT_EDITING 4 -#define CONTEXT_SCRIPT 5 -#define CONTEXT_LOGIC 6 +#define CONTEXT_SCENE 0 +#define CONTEXT_OBJECT 1 +#define CONTEXT_TYPES 2 +#define CONTEXT_SHADING 3 +#define CONTEXT_EDITING 4 +#define CONTEXT_SCRIPT 5 +#define CONTEXT_LOGIC 6 /* sbuts->mainb old (deprecated) */ -#define BUTS_VIEW 0 -#define BUTS_LAMP 1 -#define BUTS_MAT 2 -#define BUTS_TEX 3 -#define BUTS_ANIM 4 -#define BUTS_WORLD 5 -#define BUTS_RENDER 6 -#define BUTS_EDIT 7 -#define BUTS_GAME 8 -#define BUTS_FPAINT 9 -#define BUTS_RADIO 10 -#define BUTS_SCRIPT 11 -#define BUTS_SOUND 12 -#define BUTS_CONSTRAINT 13 -#define BUTS_EFFECTS 14 +#define BUTS_VIEW 0 +#define BUTS_LAMP 1 +#define BUTS_MAT 2 +#define BUTS_TEX 3 +#define BUTS_ANIM 4 +#define BUTS_WORLD 5 +#define BUTS_RENDER 6 +#define BUTS_EDIT 7 +#define BUTS_GAME 8 +#define BUTS_FPAINT 9 +#define BUTS_RADIO 10 +#define BUTS_SCRIPT 11 +#define BUTS_SOUND 12 +#define BUTS_CONSTRAINT 13 +#define BUTS_EFFECTS 14 /* buts->mainb new */ typedef enum eSpaceButtons_Context { @@ -185,11 +185,11 @@ typedef enum eSpaceButtons_Context { } eSpaceButtons_Context; /* sbuts->flag */ -#define SB_PRV_OSA 1 -#define SB_PIN_CONTEXT 2 +#define SB_PRV_OSA 1 +#define SB_PIN_CONTEXT 2 //#define SB_WORLD_TEX 4 //not used anymore //#define SB_BRUSH_TEX 8 //not used anymore -#define SB_SHADING_CONTEXT 16 +#define SB_SHADING_CONTEXT 16 /* sbuts->texture_context */ typedef enum eSpaceButtons_Texture_Context { @@ -208,18 +208,18 @@ typedef enum eSpaceButtons_Align { } eSpaceButtons_Align; /* sbuts->scaflag */ -#define BUTS_SENS_SEL 1 -#define BUTS_SENS_ACT 2 -#define BUTS_SENS_LINK 4 -#define BUTS_CONT_SEL 8 -#define BUTS_CONT_ACT 16 -#define BUTS_CONT_LINK 32 -#define BUTS_ACT_SEL 64 -#define BUTS_ACT_ACT 128 -#define BUTS_ACT_LINK 256 -#define BUTS_SENS_STATE 512 -#define BUTS_ACT_STATE 1024 -#define BUTS_CONT_INIT_STATE 2048 +#define BUTS_SENS_SEL 1 +#define BUTS_SENS_ACT 2 +#define BUTS_SENS_LINK 4 +#define BUTS_CONT_SEL 8 +#define BUTS_CONT_ACT 16 +#define BUTS_CONT_LINK 32 +#define BUTS_ACT_SEL 64 +#define BUTS_ACT_ACT 128 +#define BUTS_ACT_LINK 256 +#define BUTS_SENS_STATE 512 +#define BUTS_ACT_STATE 1024 +#define BUTS_CONT_INIT_STATE 2048 /* Outliner =============================================== */ @@ -227,12 +227,12 @@ typedef enum eSpaceButtons_Align { /* Outliner */ typedef struct SpaceOops { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; + float blockscale DNA_DEPRECATED; short blockhandler[8] DNA_DEPRECATED; - View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ + View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ ListBase tree; struct TreeStore *treestore; @@ -273,9 +273,9 @@ typedef enum eSpaceOutliner_Mode { /* SpaceOops->storeflag */ typedef enum eSpaceOutliner_StoreFlag { - /* rebuild tree */ + /* rebuild tree */ SO_TREESTORE_CLEANUP = (1 << 0), - /* if set, it allows redraws. gets set for some allqueue events */ + /* if set, it allows redraws. gets set for some allqueue events */ SO_TREESTORE_REDRAW = (1 << 1), } eSpaceOutliner_StoreFlag; @@ -292,23 +292,23 @@ typedef enum eSpaceOutliner_Search_Flags { /* 'Graph' Editor (formerly known as the IPO Editor) */ typedef struct SpaceIpo { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; + float blockscale DNA_DEPRECATED; short blockhandler[8] DNA_DEPRECATED; - View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ + View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ - struct bDopeSheet *ads; /* settings for filtering animation data (NOTE: we use a pointer due to code-linking issues) */ + struct bDopeSheet *ads; /* settings for filtering animation data (NOTE: we use a pointer due to code-linking issues) */ - ListBase ghostCurves; /* sampled snapshots of F-Curves used as in-session guides */ + ListBase ghostCurves; /* sampled snapshots of F-Curves used as in-session guides */ - short mode; /* mode for the Graph editor (eGraphEdit_Mode) */ - short autosnap; /* time-transform autosnapping settings for Graph editor (eAnimEdit_AutoSnap in DNA_action_types.h) */ - int flag; /* settings for Graph editor (eGraphEdit_Flag) */ + short mode; /* mode for the Graph editor (eGraphEdit_Mode) */ + short autosnap; /* time-transform autosnapping settings for Graph editor (eAnimEdit_AutoSnap in DNA_action_types.h) */ + int flag; /* settings for Graph editor (eGraphEdit_Flag) */ - float cursorVal; /* cursor value (y-value, x-value is current frame) */ - int around; /* pivot point for transforms */ + float cursorVal; /* cursor value (y-value, x-value is current frame) */ + int around; /* pivot point for transforms */ } SpaceIpo; @@ -348,9 +348,9 @@ typedef enum eGraphEdit_Flag { /* SpaceIpo->mode (Graph Editor Mode) */ typedef enum eGraphEdit_Mode { - /* all animation curves (from all over Blender) */ - SIPO_MODE_ANIMATION = 0, - /* drivers only */ + /* all animation curves (from all over Blender) */ + SIPO_MODE_ANIMATION = 0, + /* drivers only */ SIPO_MODE_DRIVERS, } eGraphEdit_Mode; @@ -360,17 +360,17 @@ typedef enum eGraphEdit_Mode { /* NLA Editor */ typedef struct SpaceNla { struct SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; + float blockscale DNA_DEPRECATED; short blockhandler[8] DNA_DEPRECATED; - short autosnap; /* this uses the same settings as autosnap for Action Editor */ + short autosnap; /* this uses the same settings as autosnap for Action Editor */ short flag; int pad; struct bDopeSheet *ads; - View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ + View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ } SpaceNla; /* nla->flag */ @@ -401,11 +401,11 @@ typedef struct SpaceTimeCache { /* Timeline View */ typedef struct SpaceTime { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; + float blockscale DNA_DEPRECATED; - View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ + View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ ListBase caches; @@ -454,25 +454,25 @@ typedef enum eTimeline_Cache_Flag { /* Sequencer */ typedef struct SpaceSeq { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; + float blockscale DNA_DEPRECATED; short blockhandler[8] DNA_DEPRECATED; - View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ + View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ - float xof DNA_DEPRECATED, yof DNA_DEPRECATED; /* deprecated: offset for drawing the image preview */ - short mainb; /* weird name for the sequencer subtype (seq, image, luma... etc) */ + float xof DNA_DEPRECATED, yof DNA_DEPRECATED; /* deprecated: offset for drawing the image preview */ + short mainb; /* weird name for the sequencer subtype (seq, image, luma... etc) */ short render_size; short chanshown; short zebra; int flag; - float zoom DNA_DEPRECATED; /* deprecated, handled by View2D now */ + float zoom DNA_DEPRECATED; /* deprecated, handled by View2D now */ int view; /* see SEQ_VIEW_* below */ int pad; - struct bGPdata *gpd; /* grease-pencil data */ + struct bGPdata *gpd; /* grease-pencil data */ } SpaceSeq; @@ -491,7 +491,7 @@ typedef enum eSpaceSeq_Flag { SEQ_MARKER_TRANS = (1 << 1), SEQ_DRAW_COLOR_SEPARATED = (1 << 2), SEQ_DRAW_SAFE_MARGINS = (1 << 3), - SEQ_DRAW_GPENCIL = (1 << 4), /* DEPRECATED */ + SEQ_DRAW_GPENCIL = (1 << 4), /* DEPRECATED */ SEQ_NO_DRAW_CFRANUM = (1 << 5), } eSpaceSeq_Flag; @@ -527,7 +527,7 @@ typedef struct FileSelectParams { char filter_glob[64]; /* list of filetypes to filter */ - int active_file; + int active_file; int sel_first; int sel_last; @@ -548,7 +548,7 @@ typedef struct FileSelectParams { /* File Browser */ typedef struct SpaceFile { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; int scroll_offset; @@ -595,20 +595,20 @@ enum FileSortTypeE { /* these values need to be hardcoded in structs, dna does not recognize defines */ /* also defined in BKE */ -#define FILE_MAXDIR 768 -#define FILE_MAXFILE 256 -#define FILE_MAX 1024 +#define FILE_MAXDIR 768 +#define FILE_MAXFILE 256 +#define FILE_MAX 1024 #define FILE_MAX_LIBEXTRA (FILE_MAX + 32) /* filesel types */ -#define FILE_UNIX 8 -#define FILE_BLENDER 8 /* don't display relative paths */ -#define FILE_SPECIAL 9 +#define FILE_UNIX 8 +#define FILE_BLENDER 8 /* don't display relative paths */ +#define FILE_SPECIAL 9 -#define FILE_LOADLIB 1 -#define FILE_MAIN 2 -#define FILE_LOADFONT 3 +#define FILE_LOADLIB 1 +#define FILE_MAIN 2 +#define FILE_LOADFONT 3 /* filesel op property -> action */ typedef enum eFileSel_Action { @@ -624,7 +624,7 @@ typedef enum eFileSel_Params_Flag { FILE_HIDE_DOT = (1 << 3), FILE_AUTOSELECT = (1 << 4), FILE_ACTIVELAY = (1 << 5), -/* FILE_ATCURSOR = (1 << 6), */ /* deprecated */ +/* FILE_ATCURSOR = (1 << 6), */ /* deprecated */ FILE_DIRSEL_ONLY = (1 << 7), FILE_FILTER = (1 << 8), FILE_BOOKMARKS = (1 << 9), @@ -651,7 +651,7 @@ typedef enum eFileSel_File_Types { /* Selection Flags in filesel: struct direntry, unsigned char selflag */ typedef enum eDirEntry_SelectFlag { -/* ACTIVE_FILE = (1 << 1), */ /* UNUSED */ +/* ACTIVE_FILE = (1 << 1), */ /* UNUSED */ HILITED_FILE = (1 << 2), SELECTED_FILE = (1 << 3), EDITING_FILE = (1 << 4), @@ -662,7 +662,7 @@ typedef enum eDirEntry_SelectFlag { /* Image/UV Editor */ typedef struct SpaceImage { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; int flag; @@ -671,15 +671,15 @@ typedef struct SpaceImage { struct ImageUser iuser; struct CurveMapping *cumap; - struct Scopes scopes; /* histogram waveform and vectorscope */ - struct Histogram sample_line_hist; /* sample line histogram */ + struct Scopes scopes; /* histogram waveform and vectorscope */ + struct Histogram sample_line_hist; /* sample line histogram */ - struct bGPdata *gpd; /* grease pencil data */ + struct bGPdata *gpd; /* grease pencil data */ - float cursor[2]; /* UV editor 2d cursor */ - float xof, yof; /* user defined offset, image is centered */ - float zoom; /* user defined zoom level */ - float centx, centy; /* storage for offset while render drawing */ + float cursor[2]; /* UV editor 2d cursor */ + float xof, yof; /* user defined offset, image is centered */ + float zoom; /* user defined zoom level */ + float centx, centy; /* storage for offset while render drawing */ short curtile; /* the currently active tile of the image when tile is enabled, is kept in sync with the active faces tile */ short pad; @@ -717,15 +717,15 @@ typedef enum eSpaceImage_Sticky { /* SpaceImage->flag */ typedef enum eSpaceImage_Flag { - SI_BE_SQUARE = (1 << 0), - SI_EDITTILE = (1 << 1), - SI_CLIP_UV = (1 << 2), - SI_DRAWTOOL = (1 << 3), - SI_NO_DRAWFACES = (1 << 4), + SI_BE_SQUARE = (1 << 0), + SI_EDITTILE = (1 << 1), + SI_CLIP_UV = (1 << 2), + SI_DRAWTOOL = (1 << 3), + SI_NO_DRAWFACES = (1 << 4), SI_DRAWSHADOW = (1 << 5), -/* SI_SELACTFACE = (1 << 6), */ /* deprecated */ +/* SI_SELACTFACE = (1 << 6), */ /* deprecated */ SI_DEPRECATED2 = (1 << 7), - SI_DEPRECATED3 = (1 << 8), /* stick UV selection to mesh vertex (UVs wont always be touching) */ + SI_DEPRECATED3 = (1 << 8), /* stick UV selection to mesh vertex (UVs wont always be touching) */ SI_COORDFLOATS = (1 << 9), SI_PIXELSNAP = (1 << 10), SI_LIVE_UNWRAP = (1 << 11), @@ -733,16 +733,16 @@ typedef enum eSpaceImage_Flag { SI_SHOW_ALPHA = (1 << 13), SI_SHOW_ZBUF = (1 << 14), - /* next two for render window display */ + /* next two for render window display */ SI_PREVSPACE = (1 << 15), SI_FULLWINDOW = (1 << 16), SI_DEPRECATED4 = (1 << 17), SI_DEPRECATED5 = (1 << 18), - /* this means that the image is drawn until it reaches the view edge, - * in the image view, its unrelated to the 'tile' mode for texface - */ + /* this means that the image is drawn until it reaches the view edge, + * in the image view, its unrelated to the 'tile' mode for texface + */ SI_DRAW_TILE = (1 << 19), SI_SMOOTH_UV = (1 << 20), SI_DRAW_STRETCH = (1 << 21), @@ -757,9 +757,9 @@ typedef enum eSpaceImage_Flag { /* Text Editor */ typedef struct SpaceText { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; + float blockscale DNA_DEPRECATED; short blockhandler[8] DNA_DEPRECATED; struct Text *text; @@ -767,8 +767,8 @@ typedef struct SpaceText { int top, viewlines; short flags, menunr; - short lheight; /* user preference */ - char cwidth, linenrs_tot; /* runtime computed, character width and the number of chars to use when showing line numbers */ + short lheight; /* user preference */ + char cwidth, linenrs_tot; /* runtime computed, character width and the number of chars to use when showing line numbers */ int left; int showlinenrs; int tabnumber; @@ -783,8 +783,8 @@ typedef struct SpaceText { int wordwrap, doplugins; - char findstr[256]; /* ST_MAX_FIND_STR */ - char replacestr[256]; /* ST_MAX_FIND_STR */ + char findstr[256]; /* ST_MAX_FIND_STR */ + char replacestr[256]; /* ST_MAX_FIND_STR */ short margin_column; /* column number to show right margin at */ char pad[6]; @@ -807,7 +807,7 @@ typedef enum eSpaceText_Flags { } eSpaceText_Flags; /* stext->findstr/replacestr */ -#define ST_MAX_FIND_STR 256 +#define ST_MAX_FIND_STR 256 /* Script View (Obsolete) ================================== */ @@ -831,9 +831,9 @@ typedef struct Script { /* Script View - Obsolete (pre 2.5) */ typedef struct SpaceScript { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; + float blockscale DNA_DEPRECATED; struct Script *script; short flags, menunr; @@ -847,30 +847,30 @@ typedef struct SpaceScript { /* Node Editor */ typedef struct SpaceNode { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; + float blockscale DNA_DEPRECATED; short blockhandler[8] DNA_DEPRECATED; - View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ + View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ - struct ID *id, *from; /* context, no need to save in file? well... pinning... */ - short flag, pad1; /* menunr: browse id block in header */ + struct ID *id, *from; /* context, no need to save in file? well... pinning... */ + short flag, pad1; /* menunr: browse id block in header */ float aspect; - float xof, yof; /* offset for drawing the backdrop */ - float zoom, padf; /* zoom for backdrop */ - float mx, my; /* mousepos for drawing socketless link */ + float xof, yof; /* offset for drawing the backdrop */ + float zoom, padf; /* zoom for backdrop */ + float mx, my; /* mousepos for drawing socketless link */ struct bNodeTree *nodetree, *edittree; - int treetype; /* treetype: as same nodetree->type */ - short texfrom; /* texfrom object, world or brush */ - short shaderfrom; /* shader from object or world */ - short recalc; /* currently on 0/1, for auto compo */ + int treetype; /* treetype: as same nodetree->type */ + short texfrom; /* texfrom object, world or brush */ + short shaderfrom; /* shader from object or world */ + short recalc; /* currently on 0/1, for auto compo */ short pad[3]; - ListBase linkdrag; /* temporary data for modal linking operator */ + ListBase linkdrag; /* temporary data for modal linking operator */ - struct bGPdata *gpd; /* grease-pencil data */ + struct bGPdata *gpd; /* grease-pencil data */ } SpaceNode; /* snode->flag */ @@ -891,7 +891,7 @@ typedef enum eSpaceNode_TexFrom { /* snode->shaderfrom */ typedef enum eSpaceNode_ShaderFrom { - SNODE_SHADER_OBJECT = 0, + SNODE_SHADER_OBJECT = 0, SNODE_SHADER_WORLD, } eSpaceNode_ShaderFrom; @@ -900,16 +900,16 @@ typedef enum eSpaceNode_ShaderFrom { /* Logic Editor */ typedef struct SpaceLogic { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; + float blockscale DNA_DEPRECATED; short blockhandler[8] DNA_DEPRECATED; short flag, scaflag; int pad; - struct bGPdata *gpd; /* grease-pencil data */ + struct bGPdata *gpd; /* grease-pencil data */ } SpaceLogic; /* Console ================================================ */ @@ -919,8 +919,8 @@ typedef struct ConsoleLine { struct ConsoleLine *next, *prev; /* keep these 3 vars so as to share free, realloc funcs */ - int len_alloc; /* allocated length */ - int len; /* real len - strlen() */ + int len_alloc; /* allocated length */ + int len; /* real len - strlen() */ char *line; int cursor; @@ -939,10 +939,10 @@ typedef enum eConsoleLine_Type { /* Console View */ typedef struct SpaceConsole { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float blockscale DNA_DEPRECATED; // XXX are these needed? - short blockhandler[8] DNA_DEPRECATED; // XXX are these needed? + float blockscale DNA_DEPRECATED; // XXX are these needed? + short blockhandler[8] DNA_DEPRECATED; // XXX are these needed? /* space vars */ int lheight, pad; @@ -962,12 +962,12 @@ typedef struct SpaceConsole { /* User Preferences View */ typedef struct SpaceUserPref { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; int pad; - char filter[64]; /* search term for filtering in the UI */ + char filter[64]; /* search term for filtering in the UI */ } SpaceUserPref; /* Motion Tracking ======================================== */ @@ -975,25 +975,25 @@ typedef struct SpaceUserPref { /* Clip Editor */ typedef struct SpaceClip { SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; - float xof, yof; /* user defined offset, image is centered */ - float xlockof, ylockof; /* user defined offset from locked position */ - float zoom; /* user defined zoom level */ + float xof, yof; /* user defined offset, image is centered */ + float xlockof, ylockof; /* user defined offset from locked position */ + float zoom; /* user defined zoom level */ - struct MovieClipUser user; /* user of clip */ - struct MovieClip *clip; /* clip data */ - struct MovieClipScopes scopes; /* different scoped displayed in space panels */ + struct MovieClipUser user; /* user of clip */ + struct MovieClip *clip; /* clip data */ + struct MovieClipScopes scopes; /* different scoped displayed in space panels */ - int flag; /* flags */ - short mode; /* editor mode (editing context being displayed) */ - short view; /* type of the clip editor view */ + int flag; /* flags */ + short mode; /* editor mode (editing context being displayed) */ + short view; /* type of the clip editor view */ - int path_length; /* length of displaying path, in frames */ + int path_length; /* length of displaying path, in frames */ /* current stabilization data */ - float loc[2], scale, angle; /* pre-composed stabilization data */ + float loc[2], scale, angle; /* pre-composed stabilization data */ int pad; float stabmat[4][4], unistabmat[4][4]; /* current stabilization matrix and the same matrix in unified space, * defined when drawing and used for mouse position calculation */ @@ -1007,10 +1007,10 @@ typedef struct SpaceClip { void *draw_context; /* dopesheet */ - short dope_sort; /* sort order in dopesheet view */ - short dope_flag; /* dopsheet view flags */ + short dope_sort; /* sort order in dopesheet view */ + short dope_flag; /* dopsheet view flags */ - int around; /* pivot point for transforms */ + int around; /* pivot point for transforms */ /* **** mask editing **** */ struct Mask *mask; @@ -1080,8 +1080,8 @@ typedef enum eSpaceClip_GPencil_Source { /* **************** SPACE DEFINES ********************* */ /* headerbuttons: 450-499 */ -#define B_IMASELHOME 451 -#define B_IMASELREMOVEBIP 452 +#define B_IMASELHOME 451 +#define B_IMASELREMOVEBIP 452 /* space types, moved from DNA_screen_types.h */ diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index c5b0174a3c9..6ca63f2c1c9 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -56,20 +56,20 @@ typedef struct MovieReconstructedCamera { } MovieReconstructedCamera; typedef struct MovieTrackingCamera { - void *intrinsics; /* intrinsics handle */ + void *intrinsics; /* intrinsics handle */ - float sensor_width; /* width of CCD sensor */ - float pixel_aspect; /* pixel aspect ratio */ + float sensor_width; /* width of CCD sensor */ + float pixel_aspect; /* pixel aspect ratio */ float pad; - float focal; /* focal length */ - short units; /* units of focal length user is working with */ + float focal; /* focal length */ + short units; /* units of focal length user is working with */ short pad1; - float principal[2]; /* principal point */ - float k1, k2, k3; /* radial distortion */ + float principal[2]; /* principal point */ + float k1, k2, k3; /* radial distortion */ } MovieTrackingCamera; typedef struct MovieTrackingMarker { - float pos[2]; /* 2d position of marker on frame (in unified 0..1 space) */ + float pos[2]; /* 2d position of marker on frame (in unified 0..1 space) */ /* corners of pattern in the following order: * @@ -91,14 +91,14 @@ typedef struct MovieTrackingMarker { */ float search_min[2], search_max[2]; - int framenr; /* number of frame marker is associated with */ - int flag; /* Marker's flag (alive, ...) */ + int framenr; /* number of frame marker is associated with */ + int flag; /* Marker's flag (alive, ...) */ } MovieTrackingMarker; typedef struct MovieTrackingTrack { struct MovieTrackingTrack *next, *prev; - char name[64]; /* MAX_NAME */ + char name[64]; /* MAX_NAME */ /* ** setings ** */ @@ -114,32 +114,32 @@ typedef struct MovieTrackingTrack { */ float search_min[2] DNA_DEPRECATED, search_max[2] DNA_DEPRECATED; - float offset[2]; /* offset to "parenting" point */ + float offset[2]; /* offset to "parenting" point */ /* ** track ** */ - int markersnr; /* count of markers in track */ - int last_marker; /* most recently used marker */ - MovieTrackingMarker *markers; /* markers in track */ + int markersnr; /* count of markers in track */ + int last_marker; /* most recently used marker */ + MovieTrackingMarker *markers; /* markers in track */ /* ** reconstruction data ** */ - float bundle_pos[3]; /* reconstructed position */ - float error; /* average track reprojection error */ + float bundle_pos[3]; /* reconstructed position */ + float error; /* average track reprojection error */ /* ** UI editing ** */ - int flag, pat_flag, search_flag; /* flags (selection, ...) */ - float color[3]; /* custom color for track */ + int flag, pat_flag, search_flag; /* flags (selection, ...) */ + float color[3]; /* custom color for track */ /* ** control how tracking happens */ - short frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */ - short margin; /* margin from frame boundaries */ - short pattern_match; /* re-adjust every N frames */ + short frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */ + short margin; /* margin from frame boundaries */ + short pattern_match; /* re-adjust every N frames */ /* tracking parameters */ short motion_model; /* model of the motion for this track */ int algorithm_flag; /* flags for the tracking algorithm (use brute, use esm, use pyramid, etc */ - float minimum_correlation; /* minimal correlation which is still treated as successful tracking */ + float minimum_correlation; /* minimal correlation which is still treated as successful tracking */ - struct bGPdata *gpd; /* grease-pencil data */ + struct bGPdata *gpd; /* grease-pencil data */ } MovieTrackingTrack; typedef struct MovieTrackingSettings { @@ -156,13 +156,13 @@ typedef struct MovieTrackingSettings { short default_pattern_match; /* re-adjust every N frames */ short default_flag; /* default flags like color channels used by default */ - short motion_flag; /* flags describes motion type */ + short motion_flag; /* flags describes motion type */ /* ** common tracker settings ** */ - short speed; /* speed of tracking */ + short speed; /* speed of tracking */ /* ** reconstruction settings ** */ - int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */ + int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */ /* which camera intrinsics to refine. uses on the REFINE_* flags */ short refine_camera_intrinsics, pad2; @@ -170,56 +170,56 @@ typedef struct MovieTrackingSettings { /* ** tool settings ** */ /* set scale */ - float dist; /* distance between two bundles used for scene scaling */ + float dist; /* distance between two bundles used for scene scaling */ /* cleanup */ int clean_frames, clean_action; float clean_error; /* set object scale */ - float object_distance; /* distance between two bundles used for object scaling */ + float object_distance; /* distance between two bundles used for object scaling */ int pad3; } MovieTrackingSettings; typedef struct MovieTrackingStabilization { int flag; - int tot_track, act_track; /* total number and index of active track in list */ + int tot_track, act_track; /* total number and index of active track in list */ /* 2d stabilization */ - float maxscale; /* max auto-scale factor */ - MovieTrackingTrack *rot_track; /* track used to stabilize rotation */ + float maxscale; /* max auto-scale factor */ + MovieTrackingTrack *rot_track; /* track used to stabilize rotation */ - float locinf, scaleinf, rotinf; /* influence on location, scale and rotation */ + float locinf, scaleinf, rotinf; /* influence on location, scale and rotation */ - int filter; /* filter used for pixel interpolation */ + int filter; /* filter used for pixel interpolation */ /* some pre-computing run-time variables */ - int ok; /* are precomputed values and scaled buf relevant? */ - float scale; /* autoscale factor */ + int ok; /* are precomputed values and scaled buf relevant? */ + float scale; /* autoscale factor */ - struct ImBuf *scaleibuf; /* currently scaled ibuf */ + struct ImBuf *scaleibuf; /* currently scaled ibuf */ } MovieTrackingStabilization; typedef struct MovieTrackingReconstruction { int flag; - float error; /* average error of reconstruction */ + float error; /* average error of reconstruction */ - int last_camera; /* most recently used camera */ - int camnr; /* number of reconstructed cameras */ - struct MovieReconstructedCamera *cameras; /* reconstructed cameras */ + int last_camera; /* most recently used camera */ + int camnr; /* number of reconstructed cameras */ + struct MovieReconstructedCamera *cameras; /* reconstructed cameras */ } MovieTrackingReconstruction; typedef struct MovieTrackingObject { struct MovieTrackingObject *next, *prev; - char name[64]; /* Name of tracking object, MAX_NAME */ + char name[64]; /* Name of tracking object, MAX_NAME */ int flag; - float scale; /* scale of object solution in amera space */ + float scale; /* scale of object solution in amera space */ - ListBase tracks; /* list of tracks use to tracking this object */ - MovieTrackingReconstruction reconstruction; /* reconstruction data for this object */ + ListBase tracks; /* list of tracks use to tracking this object */ + MovieTrackingReconstruction reconstruction; /* reconstruction data for this object */ } MovieTrackingObject; typedef struct MovieTrackingStats { @@ -229,38 +229,38 @@ typedef struct MovieTrackingStats { typedef struct MovieTrackingDopesheetChannel { struct MovieTrackingDopesheetChannel *next, *prev; - MovieTrackingTrack *track; /* motion track for which channel is created */ + MovieTrackingTrack *track; /* motion track for which channel is created */ int pad; - int tot_segment; /* total number of segments */ - int *segments; /* tracked segments */ - int max_segment, total_frames; /* longest segment length and total number of tracked frames */ + int tot_segment; /* total number of segments */ + int *segments; /* tracked segments */ + int max_segment, total_frames; /* longest segment length and total number of tracked frames */ } MovieTrackingDopesheetChannel; typedef struct MovieTrackingDopesheet { - int ok, pad; /* flag if dopesheet information is still relevant */ + int ok, pad; /* flag if dopesheet information is still relevant */ ListBase channels; int tot_channel; - short sort_method; /* method to be used to sort tracks */ - short sort_inverse; /* order of tracks is inverted */ + short sort_method; /* method to be used to sort tracks */ + short sort_inverse; /* order of tracks is inverted */ } MovieTrackingDopesheet; typedef struct MovieTracking { - MovieTrackingSettings settings; /* different tracking-related settings */ - MovieTrackingCamera camera; /* camera intrinsics */ - ListBase tracks; /* list of tracks used for camera object */ - MovieTrackingReconstruction reconstruction; /* reconstruction data for camera object */ - MovieTrackingStabilization stabilization; /* stabilization data */ - MovieTrackingTrack *act_track; /* active track */ + MovieTrackingSettings settings; /* different tracking-related settings */ + MovieTrackingCamera camera; /* camera intrinsics */ + ListBase tracks; /* list of tracks used for camera object */ + MovieTrackingReconstruction reconstruction; /* reconstruction data for camera object */ + MovieTrackingStabilization stabilization; /* stabilization data */ + MovieTrackingTrack *act_track; /* active track */ ListBase objects; - int objectnr, tot_object; /* index of active object and total number of objects */ + int objectnr, tot_object; /* index of active object and total number of objects */ - MovieTrackingStats *stats; /* statistics displaying in clip editor */ + MovieTrackingStats *stats; /* statistics displaying in clip editor */ - MovieTrackingDopesheet dopesheet; /* dopesheet data */ + MovieTrackingDopesheet dopesheet; /* dopesheet data */ } MovieTracking; /* MovieTrackingCamera->units */ @@ -270,23 +270,23 @@ enum { }; /* MovieTrackingMarker->flag */ -#define MARKER_DISABLED (1<<0) -#define MARKER_TRACKED (1<<1) -#define MARKER_GRAPH_SEL_X (1<<2) -#define MARKER_GRAPH_SEL_Y (1<<3) -#define MARKER_GRAPH_SEL (MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y) +#define MARKER_DISABLED (1 << 0) +#define MARKER_TRACKED (1 << 1) +#define MARKER_GRAPH_SEL_X (1 << 2) +#define MARKER_GRAPH_SEL_Y (1 << 3) +#define MARKER_GRAPH_SEL (MARKER_GRAPH_SEL_X | MARKER_GRAPH_SEL_Y) /* MovieTrackingTrack->flag */ -#define TRACK_HAS_BUNDLE (1<<1) -#define TRACK_DISABLE_RED (1<<2) -#define TRACK_DISABLE_GREEN (1<<3) -#define TRACK_DISABLE_BLUE (1<<4) -#define TRACK_HIDDEN (1<<5) -#define TRACK_LOCKED (1<<6) -#define TRACK_CUSTOMCOLOR (1<<7) -#define TRACK_USE_2D_STAB (1<<8) -#define TRACK_PREVIEW_GRAYSCALE (1<<9) -#define TRACK_DOPE_SEL (1<<10) +#define TRACK_HAS_BUNDLE (1 << 1) +#define TRACK_DISABLE_RED (1 << 2) +#define TRACK_DISABLE_GREEN (1 << 3) +#define TRACK_DISABLE_BLUE (1 << 4) +#define TRACK_HIDDEN (1 << 5) +#define TRACK_LOCKED (1 << 6) +#define TRACK_CUSTOMCOLOR (1 << 7) +#define TRACK_USE_2D_STAB (1 << 8) +#define TRACK_PREVIEW_GRAYSCALE (1 << 9) +#define TRACK_DOPE_SEL (1 << 10) /* MovieTrackingTrack->motion_model */ #define TRACK_MOTION_MODEL_TRANSLATION 0 @@ -301,48 +301,48 @@ enum { #define TRACK_ALGORITHM_FLAG_USE_NORMALIZATION 2 /* MovieTrackingTrack->adjframes */ -#define TRACK_MATCH_KEYFRAME 0 -#define TRACK_MATCH_PREVFRAME 1 +#define TRACK_MATCH_KEYFRAME 0 +#define TRACK_MATCH_PREVFRAME 1 /* MovieTrackingSettings->flag */ -#define TRACKING_SETTINGS_SHOW_DEFAULT_EXPANDED (1<<0) +#define TRACKING_SETTINGS_SHOW_DEFAULT_EXPANDED (1 << 0) /* MovieTrackingSettings->motion_flag */ -#define TRACKING_MOTION_TRIPOD (1<<0) +#define TRACKING_MOTION_TRIPOD (1 << 0) -#define TRACKING_MOTION_MODAL (TRACKING_MOTION_TRIPOD) +#define TRACKING_MOTION_MODAL (TRACKING_MOTION_TRIPOD) /* MovieTrackingSettings->speed */ -#define TRACKING_SPEED_FASTEST 0 -#define TRACKING_SPEED_REALTIME 1 -#define TRACKING_SPEED_HALF 2 -#define TRACKING_SPEED_QUARTER 4 -#define TRACKING_SPEED_DOUBLE 5 +#define TRACKING_SPEED_FASTEST 0 +#define TRACKING_SPEED_REALTIME 1 +#define TRACKING_SPEED_HALF 2 +#define TRACKING_SPEED_QUARTER 4 +#define TRACKING_SPEED_DOUBLE 5 /* MovieTrackingSettings->refine_camera_intrinsics */ -#define REFINE_FOCAL_LENGTH (1<<0) -#define REFINE_PRINCIPAL_POINT (1<<1) -#define REFINE_RADIAL_DISTORTION_K1 (1<<2) -#define REFINE_RADIAL_DISTORTION_K2 (1<<4) +#define REFINE_FOCAL_LENGTH (1 << 0) +#define REFINE_PRINCIPAL_POINT (1 << 1) +#define REFINE_RADIAL_DISTORTION_K1 (1 << 2) +#define REFINE_RADIAL_DISTORTION_K2 (1 << 4) /* MovieTrackingStrabilization->flag */ -#define TRACKING_2D_STABILIZATION (1<<0) -#define TRACKING_AUTOSCALE (1<<1) -#define TRACKING_STABILIZE_ROTATION (1<<2) +#define TRACKING_2D_STABILIZATION (1 << 0) +#define TRACKING_AUTOSCALE (1 << 1) +#define TRACKING_STABILIZE_ROTATION (1 << 2) /* MovieTrackingStrabilization->filter */ -#define TRACKING_FILTER_NEAREAST 0 -#define TRACKING_FILTER_BILINEAR 1 -#define TRACKING_FILTER_BICUBIC 2 +#define TRACKING_FILTER_NEAREAST 0 +#define TRACKING_FILTER_BILINEAR 1 +#define TRACKING_FILTER_BICUBIC 2 /* MovieTrackingReconstruction->flag */ -#define TRACKING_RECONSTRUCTED (1<<0) +#define TRACKING_RECONSTRUCTED (1 << 0) /* MovieTrackingObject->flag */ -#define TRACKING_OBJECT_CAMERA (1<<0) +#define TRACKING_OBJECT_CAMERA (1 << 0) -#define TRACKING_CLEAN_SELECT 0 -#define TRACKING_CLEAN_DELETE_TRACK 1 -#define TRACKING_CLEAN_DELETE_SEGMENT 2 +#define TRACKING_CLEAN_SELECT 0 +#define TRACKING_CLEAN_DELETE_TRACK 1 +#define TRACKING_CLEAN_DELETE_SEGMENT 2 #endif diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index bf02ae50a94..5395f9c8b34 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -843,14 +843,14 @@ int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index); * UI code or Actions, though efficiency is a concern. */ char *RNA_path_append(const char *path, PointerRNA *ptr, PropertyRNA *prop, - int intkey, const char *strkey); + int intkey, const char *strkey); char *RNA_path_back(const char *path); int RNA_path_resolve(PointerRNA *ptr, const char *path, - PointerRNA *r_ptr, PropertyRNA **r_prop); + PointerRNA *r_ptr, PropertyRNA **r_prop); int RNA_path_resolve_full(PointerRNA *ptr, const char *path, - PointerRNA *r_ptr, PropertyRNA **r_prop, int *index); + PointerRNA *r_ptr, PropertyRNA **r_prop, int *index); char *RNA_path_from_ID_to_struct(PointerRNA *ptr); char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop); @@ -967,7 +967,7 @@ char *RNA_pointer_as_string_keywords_ex(struct bContext *C, PointerRNA *ptr, Poi char *RNA_pointer_as_string_keywords(struct bContext *C, PointerRNA *ptr, PointerRNA *ptr_default, const short skip_optional_value, const short all_args); char *RNA_function_as_string_keywords(struct bContext *C, FunctionRNA *func, PointerRNA *ptr_default, - const short as_function, const short all_args); + const short as_function, const short all_args); /* Function */ @@ -1006,12 +1006,12 @@ int RNA_function_call_lookup(struct bContext *C, struct ReportList *reports, Poi int RNA_function_call_direct(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, ...) #ifdef __GNUC__ -__attribute__ ((format (printf, 5, 6))) +__attribute__ ((format(printf, 5, 6))) #endif ; int RNA_function_call_direct_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, const char *identifier, const char *format, ...) #ifdef __GNUC__ -__attribute__ ((format (printf, 5, 6))) +__attribute__ ((format(printf, 5, 6))) #endif ; int RNA_function_call_direct_va(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, va_list args); @@ -1025,14 +1025,14 @@ StructRNA *ID_code_to_RNA_type(short idcode); /* macro which inserts the function name */ #if defined __GNUC__ || defined __sun -# define RNA_warning(format, args...) _RNA_warning("%s: " format "\n", __func__, ##args) +# define RNA_warning(format, args ...) _RNA_warning("%s: " format "\n", __func__, ##args) #else # define RNA_warning(format, ...) _RNA_warning("%s: " format "\n", __FUNCTION__, __VA_ARGS__) #endif void _RNA_warning(const char *format, ...) #ifdef __GNUC__ -__attribute__ ((format (printf, 1, 2))) +__attribute__ ((format(printf, 1, 2))) #endif ; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index eb31d83fce8..e54654e2b32 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -2651,7 +2651,7 @@ static void rna_def_modifier_screw(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Modifier_update"); #if 0 - prop= RNA_def_property(srna, "use_angle_object", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "use_angle_object", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SCREW_OBJECT_ANGLE); RNA_def_property_ui_text(prop, "Object Angle", "Use the angle between the objects rather than the fixed angle"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); @@ -3219,7 +3219,7 @@ static void rna_def_modifier_skin(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - srna= RNA_def_struct(brna, "SkinModifier", "Modifier"); + srna = RNA_def_struct(brna, "SkinModifier", "Modifier"); RNA_def_struct_ui_text(srna, "Skin Modifier", "Generate Skin"); RNA_def_struct_sdna(srna, "SkinModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_SKIN); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index cafe8ebefad..3d01f5ba082 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1041,9 +1041,9 @@ static void rna_SpaceClipEditor_clip_set(PointerRNA *ptr, PointerRNA value) static void rna_SpaceClipEditor_mask_set(PointerRNA *ptr, PointerRNA value) { - SpaceClip *sc= (SpaceClip*)(ptr->data); + SpaceClip *sc = (SpaceClip *)(ptr->data); - ED_space_clip_set_mask(NULL, sc, (Mask*)value.data); + ED_space_clip_set_mask(NULL, sc, (Mask *)value.data); } static void rna_SpaceClipEditor_clip_mode_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) @@ -3040,23 +3040,23 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); /* mask */ - prop= RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); + prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Mask", "Mask displayed and edited in this space"); RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceClipEditor_mask_set", NULL, NULL); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); /* mask drawing */ prop = RNA_def_property(srna, "mask_draw_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "mask_draw_type"); RNA_def_property_enum_items(prop, dt_uv_items); RNA_def_property_ui_text(prop, "Edge Draw Type", "Draw type for mask splines"); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); prop = RNA_def_property(srna, "show_mask_smooth", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mask_draw_flag", MASK_DRAWFLAG_SMOOTH); RNA_def_property_ui_text(prop, "Draw Smooth Splines", ""); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); /* mode */ diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index aaa96fc4d95..9fae4c496df 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -40,7 +40,7 @@ #include "rna_internal.h" #include "DNA_movieclip_types.h" -#include "DNA_object_types.h" /* SELECT */ +#include "DNA_object_types.h" /* SELECT */ #include "DNA_scene_types.h" #include "WM_types.h" @@ -61,21 +61,21 @@ static char *rna_tracking_path(PointerRNA *UNUSED(ptr)) static void rna_tracking_defaultSettings_patternUpdate(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; MovieTracking *tracking = &clip->tracking; MovieTrackingSettings *settings = &tracking->settings; - if (settings->default_search_sizedefault_pattern_size) + if (settings->default_search_size < settings->default_pattern_size) settings->default_search_size = settings->default_pattern_size; } static void rna_tracking_defaultSettings_searchUpdate(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; MovieTracking *tracking = &clip->tracking; MovieTrackingSettings *settings = &tracking->settings; - if (settings->default_pattern_size>settings->default_search_size) + if (settings->default_pattern_size > settings->default_search_size) settings->default_pattern_size = settings->default_search_size; } @@ -88,44 +88,44 @@ static char *rna_trackingTrack_path(PointerRNA *ptr) static void rna_trackingTracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; rna_iterator_listbase_begin(iter, &clip->tracking.tracks, NULL); } static void rna_trackingObjects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; rna_iterator_listbase_begin(iter, &clip->tracking.objects, NULL); } static int rna_tracking_active_object_index_get(PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; return clip->tracking.objectnr; } static void rna_tracking_active_object_index_set(PointerRNA *ptr, int value) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; clip->tracking.objectnr = value; } static void rna_tracking_active_object_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; *min = 0; - *max = clip->tracking.tot_object-1; + *max = clip->tracking.tot_object - 1; *max = MAX2(0, *max); } static PointerRNA rna_tracking_active_track_get(PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking); return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingTrack, act_track); @@ -133,7 +133,7 @@ static PointerRNA rna_tracking_active_track_get(PointerRNA *ptr) static void rna_tracking_active_track_set(PointerRNA *ptr, PointerRNA value) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; MovieTrackingTrack *track = (MovieTrackingTrack *)value.data; ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); int index = BLI_findindex(tracksbase, track); @@ -202,23 +202,23 @@ static char *rna_trackingCamera_path(PointerRNA *UNUSED(ptr)) static float rna_trackingCamera_focal_mm_get(PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; MovieTrackingCamera *camera = &clip->tracking.camera; float val = camera->focal; if (clip->lastsize[0]) - val = val*camera->sensor_width/(float)clip->lastsize[0]; + val = val * camera->sensor_width / (float)clip->lastsize[0]; return val; } static void rna_trackingCamera_focal_mm_set(PointerRNA *ptr, float value) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; MovieTrackingCamera *camera = &clip->tracking.camera; if (clip->lastsize[0]) - value = clip->lastsize[0]*value/camera->sensor_width; + value = clip->lastsize[0] * value / camera->sensor_width; if (value >= 0.0001f) camera->focal = value; @@ -231,9 +231,9 @@ static char *rna_trackingStabilization_path(PointerRNA *UNUSED(ptr)) static int rna_track_2d_stabilization(CollectionPropertyIterator *UNUSED(iter), void *data) { - MovieTrackingTrack *track = (MovieTrackingTrack*)data; + MovieTrackingTrack *track = (MovieTrackingTrack *)data; - if ((track->flag&TRACK_USE_2D_STAB) == 0) + if ((track->flag & TRACK_USE_2D_STAB) == 0) return 1; return 0; @@ -241,50 +241,50 @@ static int rna_track_2d_stabilization(CollectionPropertyIterator *UNUSED(iter), static void rna_tracking_stabTracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; rna_iterator_listbase_begin(iter, &clip->tracking.tracks, rna_track_2d_stabilization); } static int rna_tracking_stabTracks_active_index_get(PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; return clip->tracking.stabilization.act_track; } static void rna_tracking_stabTracks_active_index_set(PointerRNA *ptr, int value) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; clip->tracking.stabilization.act_track = value; } static void rna_tracking_stabTracks_active_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; *min = 0; - *max = clip->tracking.stabilization.tot_track-1; + *max = clip->tracking.stabilization.tot_track - 1; *max = MAX2(0, *max); } static void rna_tracking_flushUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; MovieTrackingStabilization *stab = &clip->tracking.stabilization; stab->ok = 0; nodeUpdateID(scene->nodetree, &clip->id); - WM_main_add_notifier(NC_SCENE|ND_NODES, NULL); + WM_main_add_notifier(NC_SCENE | ND_NODES, NULL); DAG_id_tag_update(&clip->id, 0); } static void rna_trackingObject_tracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { - MovieTrackingObject *object = (MovieTrackingObject* )ptr->data; + MovieTrackingObject *object = (MovieTrackingObject * )ptr->data; - if (object->flag&TRACKING_OBJECT_CAMERA) { - MovieClip *clip = (MovieClip*)ptr->id.data; + if (object->flag & TRACKING_OBJECT_CAMERA) { + MovieClip *clip = (MovieClip *)ptr->id.data; rna_iterator_listbase_begin(iter, &clip->tracking.tracks, NULL); } @@ -295,10 +295,10 @@ static void rna_trackingObject_tracks_begin(CollectionPropertyIterator *iter, Po static PointerRNA rna_trackingObject_reconstruction_get(PointerRNA *ptr) { - MovieTrackingObject *object = (MovieTrackingObject* )ptr->data; + MovieTrackingObject *object = (MovieTrackingObject * )ptr->data; if (object->flag & TRACKING_OBJECT_CAMERA) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingReconstruction, &clip->tracking.reconstruction); } @@ -309,7 +309,7 @@ static PointerRNA rna_trackingObject_reconstruction_get(PointerRNA *ptr) static PointerRNA rna_tracking_active_object_get(PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; MovieTrackingObject *object = BLI_findlink(&clip->tracking.objects, clip->tracking.objectnr); return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingObject, object); @@ -317,7 +317,7 @@ static PointerRNA rna_tracking_active_object_get(PointerRNA *ptr) static void rna_tracking_active_object_set(PointerRNA *ptr, PointerRNA value) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; MovieTrackingObject *object = (MovieTrackingObject *)value.data; int index = BLI_findindex(&clip->tracking.objects, object); @@ -337,9 +337,9 @@ void rna_trackingObject_name_set(PointerRNA *ptr, const char *value) static void rna_trackingObject_flushUpdate(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { - MovieClip *clip = (MovieClip*)ptr->id.data; + MovieClip *clip = (MovieClip *)ptr->id.data; - WM_main_add_notifier(NC_OBJECT|ND_TRANSFORM, NULL); + WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, NULL); DAG_id_tag_update(&clip->id, 0); } @@ -352,7 +352,7 @@ static void rna_trackingMarker_frame_set(PointerRNA *ptr, int value) track = tracking->tracks.first; while (track) { - if (marker >= track->markers && marker < track->markers+track->markersnr) { + if (marker >= track->markers && marker < track->markers + track->markersnr) { break; } @@ -393,7 +393,7 @@ static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBas BKE_movieclip_get_size(clip, &user, &width, &height); - for (a = 0; atracks, frame, number); - WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, clip); + WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, clip); } static void rna_trackingObject_tracks_add(ID *id, MovieTrackingObject *object, int frame, int number) @@ -411,19 +411,19 @@ static void rna_trackingObject_tracks_add(ID *id, MovieTrackingObject *object, i MovieClip *clip = (MovieClip *) id; ListBase *tracksbase = &object->tracks; - if (object->flag&TRACKING_OBJECT_CAMERA) + if (object->flag & TRACKING_OBJECT_CAMERA) tracksbase = &clip->tracking.tracks; add_tracks_to_base(clip, &clip->tracking, tracksbase, frame, number); - WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL); + WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); } static MovieTrackingObject *rna_trackingObject_new(MovieTracking *tracking, const char *name) { MovieTrackingObject *object = BKE_tracking_new_object(tracking, name); - WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL); + WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); return object; } @@ -432,7 +432,7 @@ void rna_trackingObject_remove(MovieTracking *tracking, MovieTrackingObject *obj { BKE_tracking_remove_object(tracking, object); - WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL); + WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); } static MovieTrackingMarker *rna_trackingMarkers_find_frame(MovieTrackingTrack *track, int framenr) @@ -440,7 +440,7 @@ static MovieTrackingMarker *rna_trackingMarkers_find_frame(MovieTrackingTrack *t return BKE_tracking_exact_marker(track, framenr); } -static MovieTrackingMarker* rna_trackingMarkers_insert_frame(MovieTrackingTrack *track, int framenr, float *co) +static MovieTrackingMarker *rna_trackingMarkers_insert_frame(MovieTrackingTrack *track, int framenr, float *co) { MovieTrackingMarker marker, *new_marker; @@ -450,7 +450,7 @@ static MovieTrackingMarker* rna_trackingMarkers_insert_frame(MovieTrackingTrack new_marker = BKE_tracking_insert_marker(track, &marker); - WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL); + WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); return new_marker; } @@ -462,7 +462,7 @@ void rna_trackingMarkers_delete_frame(MovieTrackingTrack *track, int framenr) BKE_tracking_delete_marker(track, framenr); - WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL); + WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); } #else @@ -480,12 +480,14 @@ static EnumPropertyItem tracker_motion_model[] = { "Search for markers that are translated and rotated between frames."}, {TRACK_MOTION_MODEL_TRANSLATION, "Loc", 0, "Loc", "Search for markers that are translated between frames."}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} +}; static EnumPropertyItem pattern_match_items[] = { {TRACK_MATCH_KEYFRAME, "KEYFRAME", 0, "Keyframe", "Track pattern from keyframe to next frame"}, {TRACK_MATCH_PREVFRAME, "PREV_FRAME", 0, "Previous frame", "Track pattern from current frame to next frame"}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} +}; static int rna_matrix_dimsize_4x4[] = {4, 4}; static int rna_matrix_dimsize_4x2[] = {4, 2}; @@ -497,11 +499,12 @@ static void rna_def_trackingSettings(BlenderRNA *brna) static EnumPropertyItem speed_items[] = { {0, "FASTEST", 0, "Fastest", "Track as fast as it's possible"}, - {TRACKING_SPEED_DOUBLE, "DOUBLE", 0, "Double", "Track with double speed"}, + {TRACKING_SPEED_DOUBLE, "DOUBLE", 0, "Double", "Track with double speed"}, {TRACKING_SPEED_REALTIME, "REALTIME", 0, "Realtime", "Track with realtime speed"}, {TRACKING_SPEED_HALF, "HALF", 0, "Half", "Track with half of realtime speed"}, {TRACKING_SPEED_QUARTER, "QUARTER", 0, "Quarter", "Track with quarter of realtime speed"}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; static EnumPropertyItem cleanup_items[] = { {TRACKING_CLEAN_SELECT, "SELECT", 0, "Select", "Select unclean tracks"}, @@ -513,21 +516,21 @@ static void rna_def_trackingSettings(BlenderRNA *brna) static EnumPropertyItem refine_items[] = { {0, "NONE", 0, "Nothing", "Do not refine camera intrinsics"}, {REFINE_FOCAL_LENGTH, "FOCAL_LENGTH", 0, "Focal Length", "Refine focal length"}, - {REFINE_FOCAL_LENGTH|REFINE_RADIAL_DISTORTION_K1, "FOCAL_LENGTH_RADIAL_K1", 0, "Focal length, K1", - "Refine focal length and radial distortion K1"}, - {REFINE_FOCAL_LENGTH| - REFINE_RADIAL_DISTORTION_K1| + {REFINE_FOCAL_LENGTH | REFINE_RADIAL_DISTORTION_K1, "FOCAL_LENGTH_RADIAL_K1", 0, "Focal length, K1", + "Refine focal length and radial distortion K1"}, + {REFINE_FOCAL_LENGTH | + REFINE_RADIAL_DISTORTION_K1 | REFINE_RADIAL_DISTORTION_K2, "FOCAL_LENGTH_RADIAL_K1_K2", 0, "Focal length, K1, K2", - "Refine focal length and radial distortion K1 and K2"}, - {REFINE_FOCAL_LENGTH| - REFINE_PRINCIPAL_POINT| - REFINE_RADIAL_DISTORTION_K1| + "Refine focal length and radial distortion K1 and K2"}, + {REFINE_FOCAL_LENGTH | + REFINE_PRINCIPAL_POINT | + REFINE_RADIAL_DISTORTION_K1 | REFINE_RADIAL_DISTORTION_K2, "FOCAL_LENGTH_PRINCIPAL_POINT_RADIAL_K1_K2", 0, - "Focal Length, Optical Center, K1, K2", - "Refine focal length, optical center and radial distortion K1 and K2"}, - {REFINE_FOCAL_LENGTH| + "Focal Length, Optical Center, K1, K2", + "Refine focal length, optical center and radial distortion K1 and K2"}, + {REFINE_FOCAL_LENGTH | REFINE_PRINCIPAL_POINT, "FOCAL_LENGTH_PRINCIPAL_POINT", 0, "Focal Length, Optical Center", - "Refine focal length and optical center"}, + "Refine focal length and optical center"}, {0, NULL, 0, NULL, NULL} }; @@ -638,13 +641,13 @@ static void rna_def_trackingSettings(BlenderRNA *brna) prop = RNA_def_property(srna, "default_use_brute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation-only initialization when tracking"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* default use_normalization */ prop = RNA_def_property(srna, "default_use_normalization", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking. Slower"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* default minmal correlation */ prop = RNA_def_property(srna, "default_correlation_min", PROP_FLOAT, PROP_NONE); @@ -677,19 +680,19 @@ static void rna_def_trackingSettings(BlenderRNA *brna) prop = RNA_def_property(srna, "use_default_red_channel", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_RED); RNA_def_property_ui_text(prop, "Use Red Channel", "Use red channel from footage for tracking"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* default_use_green_channel */ prop = RNA_def_property(srna, "use_default_green_channel", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_GREEN); RNA_def_property_ui_text(prop, "Use Green Channel", "Use green channel from footage for tracking"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* default_use_blue_channel */ prop = RNA_def_property(srna, "use_default_blue_channel", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_BLUE); RNA_def_property_ui_text(prop, "Use Blue Channel", "Use blue channel from footage for tracking"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* ** object tracking ** */ @@ -711,7 +714,8 @@ static void rna_def_trackingCamera(BlenderRNA *brna) static EnumPropertyItem camera_units_items[] = { {CAMERA_UNITS_PX, "PIXELS", 0, "px", "Use pixels for units of focal length"}, {CAMERA_UNITS_MM, "MILLIMETERS", 0, "mm", "Use millimeters for units of focal length"}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; srna = RNA_def_struct(brna, "MovieTrackingCamera", NULL); RNA_def_struct_path_func(srna, "rna_trackingCamera_path"); @@ -723,7 +727,7 @@ static void rna_def_trackingCamera(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 0.0f, 500.0f); RNA_def_property_ui_text(prop, "Sensor", "Width of CCD sensor in millimeters"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, NULL); /* Focal Length */ prop = RNA_def_property(srna, "focal_length", PROP_FLOAT, PROP_NONE); @@ -732,7 +736,7 @@ static void rna_def_trackingCamera(BlenderRNA *brna) RNA_def_property_range(prop, 0.0001f, 5000.0f); RNA_def_property_float_funcs(prop, "rna_trackingCamera_focal_mm_get", "rna_trackingCamera_focal_mm_set", NULL); RNA_def_property_ui_text(prop, "Focal Length", "Camera's focal length"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, NULL); /* Focal Length in pixels */ prop = RNA_def_property(srna, "focal_length_pixels", PROP_FLOAT, PROP_NONE); @@ -740,7 +744,7 @@ static void rna_def_trackingCamera(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 0.0f, 5000.0f); RNA_def_property_ui_text(prop, "Focal Length", "Camera's focal length"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, NULL); /* Units */ prop = RNA_def_property(srna, "units", PROP_ENUM, PROP_NONE); @@ -756,7 +760,7 @@ static void rna_def_trackingCamera(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "principal"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Principal Point", "Optical center of lens"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, NULL); /* Radial distortion parameters */ prop = RNA_def_property(srna, "k1", PROP_FLOAT, PROP_NONE); @@ -764,21 +768,21 @@ static void rna_def_trackingCamera(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_range(prop, -10, 10, .1, 3); RNA_def_property_ui_text(prop, "K1", "First coefficient of third order polynomial radial distortion"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_flushUpdate"); prop = RNA_def_property(srna, "k2", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "k2"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_range(prop, -10, 10, .1, 3); RNA_def_property_ui_text(prop, "K2", "Second coefficient of third order polynomial radial distortion"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_flushUpdate"); prop = RNA_def_property(srna, "k3", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "k3"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_range(prop, -10, 10, .1, 3); RNA_def_property_ui_text(prop, "K3", "Third coefficient of third order polynomial radial distortion"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_flushUpdate"); /* pixel aspect */ prop = RNA_def_property(srna, "pixel_aspect", PROP_FLOAT, PROP_XYZ); @@ -788,7 +792,7 @@ static void rna_def_trackingCamera(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.1f, 5000.0f, 1, 2); RNA_def_property_float_default(prop, 1.0f); RNA_def_property_ui_text(prop, "Pixel Aspect Ratio", "Pixel aspect ratio"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_tracking_flushUpdate"); } static void rna_def_trackingMarker(BlenderRNA *brna) @@ -805,20 +809,20 @@ static void rna_def_trackingMarker(BlenderRNA *brna) RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_float_sdna(prop, NULL, "pos"); RNA_def_property_ui_text(prop, "Position", "Marker position at frame in normalized coordinates"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, NULL); /* frame */ prop = RNA_def_property(srna, "frame", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "framenr"); RNA_def_property_ui_text(prop, "Frame", "Frame number marker is keyframed on"); RNA_def_property_int_funcs(prop, NULL, "rna_trackingMarker_frame_set", NULL); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, 0); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, 0); /* enable */ prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MARKER_DISABLED); RNA_def_property_ui_text(prop, "Mode", "Is marker muted for current frame"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, NULL); /* pattern */ prop = RNA_def_property(srna, "pattern_corners", PROP_FLOAT, PROP_MATRIX); @@ -827,9 +831,9 @@ static void rna_def_trackingMarker(BlenderRNA *brna) RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x2); RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_ui_text(prop, "Pattern Corners", - "Array of coordinates which represents patter's corners in " - " normalized coordinates relative to marker position"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_markerPattern_update"); + "Array of coordinates which represents patter's corners in " + " normalized coordinates relative to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_markerPattern_update"); /* search */ prop = RNA_def_property(srna, "search_min", PROP_FLOAT, PROP_TRANSLATION); @@ -838,9 +842,9 @@ static void rna_def_trackingMarker(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "search_min"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Search Min", - "Left-bottom corner of search area in normalized coordinates relative " - "to marker position"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_markerSearch_update"); + "Left-bottom corner of search area in normalized coordinates relative " + "to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_markerSearch_update"); prop = RNA_def_property(srna, "search_max", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_array(prop, 2); @@ -848,9 +852,9 @@ static void rna_def_trackingMarker(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "search_max"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Search Max", - "Right-bottom corner of search area in normalized coordinates relative " - "to marker position"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_markerSearch_update"); + "Right-bottom corner of search area in normalized coordinates relative " + "to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_markerSearch_update"); } static void rna_def_trackingMarkers(BlenderRNA *brna, PropertyRNA *cprop) @@ -907,8 +911,8 @@ static void rna_def_trackingTrack(BlenderRNA *brna) prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", "Unique name of track"); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_trackingTrack_name_set"); - RNA_def_property_string_maxlength(prop, MAX_ID_NAME-2); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, NULL); RNA_def_struct_name_property(srna, prop); /* limit frames */ @@ -958,14 +962,14 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation only pre-track before refinement"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* use_brute */ prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking. Slower"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* markers */ prop = RNA_def_property(srna, "markers", PROP_COLLECTION, PROP_NONE); @@ -981,28 +985,28 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", TRACK_DISABLE_RED); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Use Red Channel", "Use red channel from footage for tracking"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* use_green_channel */ prop = RNA_def_property(srna, "use_green_channel", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", TRACK_DISABLE_GREEN); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Use Green Channel", "Use green channel from footage for tracking"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* use_blue_channel */ prop = RNA_def_property(srna, "use_blue_channel", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", TRACK_DISABLE_BLUE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Use Blue Channel", "Use blue channel from footage for tracking"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* preview_grayscale */ prop = RNA_def_property(srna, "use_grayscale_preview", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_PREVIEW_GRAYSCALE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Grayscale", "Display what the tracking algorithm sees in the preview"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* has bundle */ prop = RNA_def_property(srna, "has_bundle", PROP_BOOLEAN, PROP_NONE); @@ -1023,45 +1027,45 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_HIDDEN); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Hide", "Track is hidden"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* select */ prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_trackingTrack_select_get", "rna_trackingTrack_select_set"); RNA_def_property_ui_text(prop, "Select", "Track is selected"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* select_anchor */ prop = RNA_def_property(srna, "select_anchor", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT); RNA_def_property_ui_text(prop, "Select Anchor", "Track's anchor point is selected"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* select_pattern */ prop = RNA_def_property(srna, "select_pattern", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "pat_flag", SELECT); RNA_def_property_ui_text(prop, "Select Pattern", "Track's pattern area is selected"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* select_search */ prop = RNA_def_property(srna, "select_search", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "search_flag", SELECT); RNA_def_property_ui_text(prop, "Select Search", "Track's search area is selected"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* locked */ prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_LOCKED); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Lock", "Track is locked and all changes to it are disabled"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* custom color */ prop = RNA_def_property(srna, "use_custom_color", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_CUSTOMCOLOR); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Custom Color", "Use custom color instead of theme-defined"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* color */ prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); @@ -1069,7 +1073,7 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Color", "Color of the track in the Movie Clip Editor and the 3D viewport after a solve"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* average error */ prop = RNA_def_property(srna, "average_error", PROP_FLOAT, PROP_NONE); @@ -1095,7 +1099,8 @@ static void rna_def_trackingStabilization(BlenderRNA *brna) {TRACKING_FILTER_NEAREAST, "NEAREST", 0, "Nearest", ""}, {TRACKING_FILTER_BILINEAR, "BILINEAR", 0, "Bilinear", ""}, {TRACKING_FILTER_BICUBIC, "BICUBIC", 0, "Bicubic", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; srna = RNA_def_struct(brna, "MovieTrackingStabilization", NULL); RNA_def_struct_path_func(srna, "rna_trackingStabilization_path"); @@ -1106,7 +1111,7 @@ static void rna_def_trackingStabilization(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_2D_STABILIZATION); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Use 2D stabilization", "Use 2D stabilization for footage"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_tracking_flushUpdate"); /* tracks */ prop = RNA_def_property(srna, "tracks", PROP_COLLECTION, PROP_NONE); @@ -1115,14 +1120,14 @@ static void rna_def_trackingStabilization(BlenderRNA *brna) NULL, NULL, NULL, NULL); RNA_def_property_struct_type(prop, "MovieTrackingTrack"); RNA_def_property_ui_text(prop, "Tracks", "Collection of tracks used for stabilization"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_tracking_flushUpdate"); /* rotation track */ prop = RNA_def_property(srna, "rotation_track", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "rot_track"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Rotation Track", "Track used to compensate rotation"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_flushUpdate"); /* active track index */ prop = RNA_def_property(srna, "active_track_index", PROP_INT, PROP_NONE); @@ -1139,49 +1144,49 @@ static void rna_def_trackingStabilization(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Autoscale", "Automatically scale footage to cover unfilled areas when stabilizating"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_tracking_flushUpdate"); /* max scale */ prop = RNA_def_property(srna, "scale_max", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "maxscale"); RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_text(prop, "Maximal Scale", "Limit the amount of automatic scaling"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_tracking_flushUpdate"); /* influence_location */ prop = RNA_def_property(srna, "influence_location", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "locinf"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Location Influence", "Influence of stabilization algorithm on footage location"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_tracking_flushUpdate"); /* influence_scale */ prop = RNA_def_property(srna, "influence_scale", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "scaleinf"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Scale Influence", "Influence of stabilization algorithm on footage scale"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_tracking_flushUpdate"); /* use_stabilize_rotation */ prop = RNA_def_property(srna, "use_stabilize_rotation", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_STABILIZE_ROTATION); RNA_def_property_ui_text(prop, "Stabilize Rotation", "Stabilize horizon line on the shot"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_tracking_flushUpdate"); /* influence_rotation */ prop = RNA_def_property(srna, "influence_rotation", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "rotinf"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Rotation Influence", "Influence of stabilization algorithm on footage rotation"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_tracking_flushUpdate"); /* filter */ prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "filter"); RNA_def_property_enum_items(prop, filter_items); RNA_def_property_ui_text(prop, "Filter", "Method to use to filter stabilization"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_tracking_flushUpdate"); } static void rna_def_reconstructedCamera(BlenderRNA *brna) @@ -1263,7 +1268,7 @@ static void rna_def_trackingTracks(BlenderRNA *brna) prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MovieTrackingTrack"); RNA_def_property_pointer_funcs(prop, "rna_tracking_active_track_get", "rna_tracking_active_track_set", NULL, NULL); - RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK); RNA_def_property_ui_text(prop, "Active Track", "Active track in this tracking data object"); } @@ -1287,7 +1292,7 @@ static void rna_def_trackingObjectTracks(BlenderRNA *brna) prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MovieTrackingTrack"); RNA_def_property_pointer_funcs(prop, "rna_tracking_active_track_get", "rna_tracking_active_track_set", NULL, NULL); - RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK); RNA_def_property_ui_text(prop, "Active Track", "Active track in this tracking data object"); } @@ -1303,8 +1308,8 @@ static void rna_def_trackingObject(BlenderRNA *brna) prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", "Unique name of object"); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_trackingObject_name_set"); - RNA_def_property_string_maxlength(prop, MAX_ID_NAME-2); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, NULL); RNA_def_struct_name_property(srna, prop); /* is_camera */ @@ -1312,7 +1317,7 @@ static void rna_def_trackingObject(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_OBJECT_CAMERA); RNA_def_property_ui_text(prop, "Camera", "Object is used for camera tracking"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* tracks */ prop = RNA_def_property(srna, "tracks", PROP_COLLECTION, PROP_NONE); @@ -1336,7 +1341,7 @@ static void rna_def_trackingObject(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.0001f, 10000.0, 1, 4); RNA_def_property_float_default(prop, 1.0f); RNA_def_property_ui_text(prop, "Scale", "Scale of object solution in camera space"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_trackingObject_flushUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_trackingObject_flushUpdate"); } static void rna_def_trackingObjects(BlenderRNA *brna, PropertyRNA *cprop) @@ -1368,7 +1373,7 @@ static void rna_def_trackingObjects(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_struct_type(prop, "MovieTrackingObject"); RNA_def_property_pointer_funcs(prop, "rna_tracking_active_object_get", "rna_tracking_active_object_set", NULL, NULL); - RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK); RNA_def_property_ui_text(prop, "Active Object", "Active object in this tracking data object"); } @@ -1431,7 +1436,7 @@ static void rna_def_tracking(BlenderRNA *brna) RNA_def_property_int_funcs(prop, "rna_tracking_active_object_index_get", "rna_tracking_active_object_index_set", "rna_tracking_active_object_index_range"); RNA_def_property_ui_text(prop, "Active Object Index", "Index of active object"); - RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); } void RNA_def_tracking(BlenderRNA *brna) From 9c504f6db28febabc685517d1d0c329903470963 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 Jun 2012 20:14:15 +0000 Subject: [PATCH 184/360] correct freeing C++ arrays. --- intern/smoke/intern/WTURBULENCE.cpp | 2 +- .../compositor/operations/COM_ConvolutionFilterOperation.cpp | 2 +- .../compositor/operations/COM_DoubleEdgeMaskOperation.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/intern/smoke/intern/WTURBULENCE.cpp b/intern/smoke/intern/WTURBULENCE.cpp index 83bec466c9f..671198065e8 100644 --- a/intern/smoke/intern/WTURBULENCE.cpp +++ b/intern/smoke/intern/WTURBULENCE.cpp @@ -511,7 +511,7 @@ void WTURBULENCE::computeEnergy(float *_energy, float* xvel, float* yvel, float* if (obstacles[index]) obstacles[index] = 1; // DG TODO ? animated obstacle flag? - free(obstacles); + delete [] obstacles; } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp index 9fec75abafe..2720a0a4146 100644 --- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp @@ -61,7 +61,7 @@ void ConvolutionFilterOperation::deinitExecution() this->inputOperation = NULL; this->inputValueOperation = NULL; if (this->filter) { - delete this->filter; + delete [] this->filter; this->filter = NULL; } } diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp index 9e911e7ba40..40f492b0f10 100644 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp @@ -1220,7 +1220,7 @@ void DoubleEdgeMaskOperation::doDoubleEdgeMask(float *imask, float *omask, float do_createEdgeLocationBuffer(t,rw,lres,res,gbuf,&innerEdgeOffset,&outerEdgeOffset,isz,gsz); do_fillGradientBuffer(rw,res,gbuf,isz,osz,gsz,innerEdgeOffset,outerEdgeOffset); - delete gbuf; // free the gradient index buffer + delete [] gbuf; // free the gradient index buffer } } From 113968aa15fccf8e6086c2103662323856102567 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 Jun 2012 20:20:37 +0000 Subject: [PATCH 185/360] quiet warning --- source/blender/bmesh/intern/bmesh_queries.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index c1c5dd73bb7..3ec4c51bcb1 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -754,6 +754,7 @@ void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2, BMLoop *edge_loop) { BLI_assert(edge_loop->e == edge); + (void)edge; /* quiet warning in release build */ *r_v1 = edge_loop->v; *r_v2 = edge_loop->next->v; } From 51e456a455f29d045d48cdbadbe7f876c929aa1f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 Jun 2012 20:31:01 +0000 Subject: [PATCH 186/360] correct float vector sizes --- source/blender/editors/uvedit/uvedit_parametrizer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 4c0e96426e7..16cd95a2f70 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -3596,7 +3596,7 @@ typedef struct SmoothNode { int axis, ntri; } SmoothNode; -static void p_barycentric_2d(const float v1[2], const float v2[2], const float v3[2], float p[2], float b[2]) +static void p_barycentric_2d(const float v1[2], const float v2[2], const float v3[2], const float p[2], float b[3]) { float a[2], c[2], h[2], div; @@ -3624,7 +3624,7 @@ static void p_barycentric_2d(const float v1[2], const float v2[2], const float v } } -static PBool p_triangle_inside(SmoothTriangle *t, float *co) +static PBool p_triangle_inside(SmoothTriangle *t, float co[2]) { float b[3]; @@ -3706,7 +3706,7 @@ static void p_node_delete(SmoothNode *node) MEM_freeN(node->tri); } -static PBool p_node_intersect(SmoothNode *node, float *co) +static PBool p_node_intersect(SmoothNode *node, float co[2]) { int i; @@ -3726,7 +3726,7 @@ static PBool p_node_intersect(SmoothNode *node, float *co) } -/* smooothing */ +/* smoothing */ static int p_compare_float(const void *a, const void *b) { From 3d8817626954b7161227950b8bf34f3817d4e1b0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 Jun 2012 21:38:24 +0000 Subject: [PATCH 187/360] fix [#31712] User prefs Input: Filter searches for names starting with entered phrase only --- release/scripts/startup/bl_ui/space_userpref_keymap.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py index 58697225811..6646da4a91a 100644 --- a/release/scripts/startup/bl_ui/space_userpref_keymap.py +++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py @@ -217,7 +217,9 @@ class InputKeyMapPanel: km = km.active() layout.context_pointer_set("keymap", km) - filtered_items = [kmi for kmi in km.keymap_items if filter_text in kmi.name.lower()] + filtered_items = [kmi for kmi in km.keymap_items + if filter_text in kmi.idname.lower() or + filter_text in kmi.name.lower()] if filtered_items: col = layout.column() From 869efe927cdaa041cd51e28dacef16f090f3ba2b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 Jun 2012 22:13:17 +0000 Subject: [PATCH 188/360] style cleanup --- source/blender/editors/transform/transform.c | 10 +- .../editors/transform/transform_constraints.c | 208 ++--- .../editors/transform/transform_conversions.c | 2 +- .../editors/transform/transform_generics.c | 2 +- .../editors/transform/transform_input.c | 170 ++-- .../editors/transform/transform_manipulator.c | 763 +++++++++--------- .../transform/transform_orientations.c | 164 ++-- .../editors/transform/transform_snap.c | 218 ++--- 8 files changed, 770 insertions(+), 767 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 3710ef1d30d..9e7facf1b6f 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1607,7 +1607,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int t->state = TRANS_STARTING; - if ( (prop = RNA_struct_find_property(op->ptr, "texture_space")) && RNA_property_is_set(op->ptr, prop)) { + if ((prop = RNA_struct_find_property(op->ptr, "texture_space")) && RNA_property_is_set(op->ptr, prop)) { if (RNA_property_boolean_get(op->ptr, prop)) { options |= CTX_TEXTURE; } @@ -2071,7 +2071,9 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu mul_qt_fl(quat, qlen); /* quaternions flip w sign to accumulate rotations correctly */ - if ( (nquat[0] < 0.0f && quat[0] > 0.0f) || (nquat[0] > 0.0f && quat[0] < 0.0f) ) { + if ((nquat[0] < 0.0f && quat[0] > 0.0f) || + (nquat[0] > 0.0f && quat[0] < 0.0f)) + { mul_qt_fl(quat, -1.0f); } } @@ -2818,9 +2820,9 @@ int Resize(TransInfo *t, const int mval[2]) float ratio; int i; char str[200]; - + /* for manipulator, center handle, the scaling can't be done relative to center */ - if ( (t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) { + if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) { ratio = 1.0f - ((t->imval[0] - mval[0]) + (t->imval[1] - mval[1])) / 100.0f; } else { diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index b18d132f8df..d2910c5b602 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -77,7 +77,7 @@ static void constraintAutoValues(TransInfo *t, float vec[3]) { int mode = t->con.mode; if (mode & CON_APPLY) { - float nval = (t->flag & T_NULL_ONE)?1.0f:0.0f; + float nval = (t->flag & T_NULL_ONE) ? 1.0f : 0.0f; if ((mode & CON_AXIS0) == 0) { vec[0] = nval; @@ -95,21 +95,21 @@ void constraintNumInput(TransInfo *t, float vec[3]) { int mode = t->con.mode; if (mode & CON_APPLY) { - float nval = (t->flag & T_NULL_ONE)?1.0f:0.0f; + float nval = (t->flag & T_NULL_ONE) ? 1.0f : 0.0f; if (getConstraintSpaceDimension(t) == 2) { - int axis = mode & (CON_AXIS0|CON_AXIS1|CON_AXIS2); - if (axis == (CON_AXIS0|CON_AXIS1)) { + int axis = mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2); + if (axis == (CON_AXIS0 | CON_AXIS1)) { /* vec[0] = vec[0]; */ /* same */ /* vec[1] = vec[1]; */ /* same */ vec[2] = nval; } - else if (axis == (CON_AXIS1|CON_AXIS2)) { + else if (axis == (CON_AXIS1 | CON_AXIS2)) { vec[2] = vec[1]; vec[1] = vec[0]; vec[0] = nval; } - else if (axis == (CON_AXIS0|CON_AXIS2)) { + else if (axis == (CON_AXIS0 | CON_AXIS2)) { /* vec[0] = vec[0]; */ /* same */ vec[2] = vec[1]; vec[1] = nval; @@ -184,7 +184,7 @@ static void viewAxisCorrectCenter(TransInfo *t, float t_con_center[3]) { if (t->spacetype == SPACE_VIEW3D) { // View3D *v3d = t->sa->spacedata.first; - const float min_dist= 1.0f; // v3d->near; + const float min_dist = 1.0f; /* v3d->near; */ float dir[3]; float l; @@ -194,7 +194,7 @@ static void viewAxisCorrectCenter(TransInfo *t, float t_con_center[3]) } project_v3_v3v3(dir, dir, t->viewinv[2]); - l= len_v3(dir); + l = len_v3(dir); if (l < min_dist) { float diff[3]; @@ -211,7 +211,7 @@ static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3 float norm[3], vec[3], factor, angle; float t_con_center[3]; - if (in[0]==0.0f && in[1]==0.0f && in[2]==0.0f) + if (in[0] == 0.0f && in[1] == 0.0f && in[2] == 0.0f) return; copy_v3_v3(t_con_center, t->con.center); @@ -232,12 +232,12 @@ static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3 project_v3_v3v3(vec, in, t->viewinv[1]); factor = dot_v3v3(t->viewinv[1], vec) * 2.0f; /* since camera distance is quite relative, use quadratic relationship. holding shift can compensate */ - if (factor<0.0f) factor*= -factor; - else factor*= factor; + if (factor < 0.0f) factor *= -factor; + else factor *= factor; copy_v3_v3(out, axis); normalize_v3(out); - mul_v3_fl(out, -factor); /* -factor makes move down going backwards */ + mul_v3_fl(out, -factor); /* -factor makes move down going backwards */ } else { float v[3], i1[3], i2[3]; @@ -276,10 +276,10 @@ static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3 sub_v3_v3v3(out, i1, t_con_center); /* possible some values become nan when - * viewpoint and object are both zero */ - if (!finite(out[0])) out[0]= 0.0f; - if (!finite(out[1])) out[1]= 0.0f; - if (!finite(out[2])) out[2]= 0.0f; + * viewpoint and object are both zero */ + if (!finite(out[0])) out[0] = 0.0f; + if (!finite(out[1])) out[1] = 0.0f; + if (!finite(out[2])) out[2] = 0.0f; } } } @@ -386,7 +386,7 @@ static void applyObjectConstraintVec(TransInfo *t, TransData *td, float in[3], f copy_v3_v3(out, pvec); } else { - int i=0; + int i = 0; out[0] = out[1] = out[2] = 0.0f; if (t->con.mode & CON_AXIS0) { @@ -475,21 +475,21 @@ static void applyObjectConstraintSize(TransInfo *t, TransData *td, float smat[3] static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3], float *angle) { if (!td && t->con.mode & CON_APPLY) { - int mode = t->con.mode & (CON_AXIS0|CON_AXIS1|CON_AXIS2); + int mode = t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2); switch (mode) { - case CON_AXIS0: - case (CON_AXIS1|CON_AXIS2): - copy_v3_v3(vec, t->con.mtx[0]); - break; - case CON_AXIS1: - case (CON_AXIS0|CON_AXIS2): - copy_v3_v3(vec, t->con.mtx[1]); - break; - case CON_AXIS2: - case (CON_AXIS0|CON_AXIS1): - copy_v3_v3(vec, t->con.mtx[2]); - break; + case CON_AXIS0: + case (CON_AXIS1 | CON_AXIS2): + copy_v3_v3(vec, t->con.mtx[0]); + break; + case CON_AXIS1: + case (CON_AXIS0 | CON_AXIS2): + copy_v3_v3(vec, t->con.mtx[1]); + break; + case CON_AXIS2: + case (CON_AXIS0 | CON_AXIS1): + copy_v3_v3(vec, t->con.mtx[2]); + break; } /* don't flip axis if asked to or if num input */ if (angle && (mode & CON_NOFLIP) == 0 && hasNumInput(&t->num) == 0) { @@ -517,26 +517,26 @@ static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3], fl static void applyObjectConstraintRot(TransInfo *t, TransData *td, float vec[3], float *angle) { if (t->con.mode & CON_APPLY) { - int mode = t->con.mode & (CON_AXIS0|CON_AXIS1|CON_AXIS2); + int mode = t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2); /* on setup call, use first object */ if (td == NULL) { - td= t->data; + td = t->data; } switch (mode) { - case CON_AXIS0: - case (CON_AXIS1|CON_AXIS2): - copy_v3_v3(vec, td->axismtx[0]); - break; - case CON_AXIS1: - case (CON_AXIS0|CON_AXIS2): - copy_v3_v3(vec, td->axismtx[1]); - break; - case CON_AXIS2: - case (CON_AXIS0|CON_AXIS1): - copy_v3_v3(vec, td->axismtx[2]); - break; + case CON_AXIS0: + case (CON_AXIS1 | CON_AXIS2): + copy_v3_v3(vec, td->axismtx[0]); + break; + case CON_AXIS1: + case (CON_AXIS0 | CON_AXIS2): + copy_v3_v3(vec, td->axismtx[1]); + break; + case CON_AXIS2: + case (CON_AXIS0 | CON_AXIS1): + copy_v3_v3(vec, td->axismtx[2]); + break; } if (angle && (mode & CON_NOFLIP) == 0 && hasNumInput(&t->num) == 0) { if (dot_v3v3(vec, t->viewinv[2]) > 0.0f) { @@ -604,33 +604,33 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte char text[40]; switch (orientation) { - case V3D_MANIP_GLOBAL: + case V3D_MANIP_GLOBAL: { - float mtx[3][3]= MAT3_UNITY; + float mtx[3][3] = MAT3_UNITY; BLI_snprintf(text, sizeof(text), ftext, "global"); setConstraint(t, mtx, mode, text); } break; - case V3D_MANIP_LOCAL: - BLI_snprintf(text, sizeof(text), ftext, "local"); - setLocalConstraint(t, mode, text); - break; - case V3D_MANIP_NORMAL: - BLI_snprintf(text, sizeof(text), ftext, "normal"); - setConstraint(t, t->spacemtx, mode, text); - break; - case V3D_MANIP_VIEW: - BLI_snprintf(text, sizeof(text), ftext, "view"); - setConstraint(t, t->spacemtx, mode, text); - break; - case V3D_MANIP_GIMBAL: - BLI_snprintf(text, sizeof(text), ftext, "gimbal"); - setConstraint(t, t->spacemtx, mode, text); - break; - default: /* V3D_MANIP_CUSTOM */ - BLI_snprintf(text, sizeof(text), ftext, t->spacename); - setConstraint(t, t->spacemtx, mode, text); - break; + case V3D_MANIP_LOCAL: + BLI_snprintf(text, sizeof(text), ftext, "local"); + setLocalConstraint(t, mode, text); + break; + case V3D_MANIP_NORMAL: + BLI_snprintf(text, sizeof(text), ftext, "normal"); + setConstraint(t, t->spacemtx, mode, text); + break; + case V3D_MANIP_VIEW: + BLI_snprintf(text, sizeof(text), ftext, "view"); + setConstraint(t, t->spacemtx, mode, text); + break; + case V3D_MANIP_GIMBAL: + BLI_snprintf(text, sizeof(text), ftext, "gimbal"); + setConstraint(t, t->spacemtx, mode, text); + break; + default: /* V3D_MANIP_CUSTOM */ + BLI_snprintf(text, sizeof(text), ftext, t->spacename); + setConstraint(t, t->spacemtx, mode, text); + break; } t->con.orientation = orientation; @@ -682,8 +682,8 @@ void drawConstraint(TransInfo *t) setlinestyle(1); glBegin(GL_LINE_STRIP); - glVertex3fv(tc->center); - glVertex3fv(vec); + glVertex3fv(tc->center); + glVertex3fv(vec); glEnd(); setlinestyle(0); @@ -733,7 +733,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) float aspx, aspy; ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); - glScalef(1.0f/aspx, 1.0f/aspy, 1.0); + glScalef(1.0f / aspx, 1.0f / aspy, 1.0); } set_inverted_drawing(1); @@ -747,7 +747,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) static void drawObjectConstraint(TransInfo *t) { int i; - TransData * td = t->data; + TransData *td = t->data; /* Draw the first one lighter because that's the one who controls the others. * Meaning the transformation is projected on that one and just copied on the others @@ -767,7 +767,7 @@ static void drawObjectConstraint(TransInfo *t) td++; - for (i=1; i < t->total; i++, td++) { + for (i = 1; i < t->total; i++, td++) { if (t->con.mode & CON_AXIS0) { drawLine(t, td->ob->obmat[3], td->axismtx[0], 'X', 0); } @@ -791,7 +791,7 @@ void startConstraint(TransInfo *t) void stopConstraint(TransInfo *t) { - t->con.mode &= ~(CON_APPLY|CON_SELECT); + t->con.mode &= ~(CON_APPLY | CON_SELECT); *t->con.text = '\0'; t->num.idx_max = t->idx_max; } @@ -803,21 +803,21 @@ void getConstraintMatrix(TransInfo *t) unit_m3(t->con.pmtx); if (!(t->con.mode & CON_AXIS0)) { - t->con.pmtx[0][0] = - t->con.pmtx[0][1] = - t->con.pmtx[0][2] = 0.0f; + t->con.pmtx[0][0] = + t->con.pmtx[0][1] = + t->con.pmtx[0][2] = 0.0f; } if (!(t->con.mode & CON_AXIS1)) { - t->con.pmtx[1][0] = - t->con.pmtx[1][1] = - t->con.pmtx[1][2] = 0.0f; + t->con.pmtx[1][0] = + t->con.pmtx[1][1] = + t->con.pmtx[1][2] = 0.0f; } if (!(t->con.mode & CON_AXIS2)) { - t->con.pmtx[2][0] = - t->con.pmtx[2][1] = - t->con.pmtx[2][2] = 0.0f; + t->con.pmtx[2][0] = + t->con.pmtx[2][1] = + t->con.pmtx[2][2] = 0.0f; } mul_m3_m3m3(mat, t->con.pmtx, t->con.imtx); @@ -866,7 +866,7 @@ void postSelectConstraint(TransInfo *t) static void setNearestAxis2d(TransInfo *t) { /* no correction needed... just use whichever one is lower */ - if ( abs(t->mval[0]-t->con.imval[0]) < abs(t->mval[1]-t->con.imval[1]) ) { + if (abs(t->mval[0] - t->con.imval[0]) < abs(t->mval[1] - t->con.imval[1]) ) { t->con.mode |= CON_AXIS1; BLI_snprintf(t->con.text, sizeof(t->con.text), " along Y axis"); } @@ -895,10 +895,10 @@ static void setNearestAxis3d(TransInfo *t) * of two 2D points 30 pixels apart (that's the last factor in the formula) after * projecting them with window_to_3d_delta and then get the length of that vector. */ - zfac= t->persmat[0][3]*t->center[0]+ t->persmat[1][3]*t->center[1]+ t->persmat[2][3]*t->center[2]+ t->persmat[3][3]; - zfac = len_v3(t->persinv[0]) * 2.0f/t->ar->winx * zfac * 30.0f; + zfac = t->persmat[0][3] * t->center[0] + t->persmat[1][3] * t->center[1] + t->persmat[2][3] * t->center[2] + t->persmat[3][3]; + zfac = len_v3(t->persinv[0]) * 2.0f / t->ar->winx * zfac * 30.0f; - for (i = 0; i<3; i++) { + for (i = 0; i < 3; i++) { copy_v3_v3(axis, t->con.mtx[i]); mul_v3_fl(axis, zfac); @@ -922,7 +922,7 @@ static void setNearestAxis3d(TransInfo *t) if (len[0] <= len[1] && len[0] <= len[2]) { if (t->modifiers & MOD_CONSTRAINT_PLANE) { - t->con.mode |= (CON_AXIS1|CON_AXIS2); + t->con.mode |= (CON_AXIS1 | CON_AXIS2); BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s X axis", t->spacename); } else { @@ -932,7 +932,7 @@ static void setNearestAxis3d(TransInfo *t) } else if (len[1] <= len[0] && len[1] <= len[2]) { if (t->modifiers & MOD_CONSTRAINT_PLANE) { - t->con.mode |= (CON_AXIS0|CON_AXIS2); + t->con.mode |= (CON_AXIS0 | CON_AXIS2); BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s Y axis", t->spacename); } else { @@ -942,7 +942,7 @@ static void setNearestAxis3d(TransInfo *t) } else if (len[2] <= len[1] && len[2] <= len[0]) { if (t->modifiers & MOD_CONSTRAINT_PLANE) { - t->con.mode |= (CON_AXIS0|CON_AXIS1); + t->con.mode |= (CON_AXIS0 | CON_AXIS1); BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s Z axis", t->spacename); } else { @@ -976,21 +976,21 @@ void setNearestAxis(TransInfo *t) char constraintModeToChar(TransInfo *t) { - if ((t->con.mode & CON_APPLY)==0) { + if ((t->con.mode & CON_APPLY) == 0) { return '\0'; } - switch (t->con.mode & (CON_AXIS0|CON_AXIS1|CON_AXIS2)) { - case (CON_AXIS0): - case (CON_AXIS1|CON_AXIS2): - return 'X'; - case (CON_AXIS1): - case (CON_AXIS0|CON_AXIS2): - return 'Y'; - case (CON_AXIS2): - case (CON_AXIS0|CON_AXIS1): - return 'Z'; - default: - return '\0'; + switch (t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2)) { + case (CON_AXIS0): + case (CON_AXIS1 | CON_AXIS2): + return 'X'; + case (CON_AXIS1): + case (CON_AXIS0 | CON_AXIS2): + return 'Y'; + case (CON_AXIS2): + case (CON_AXIS0 | CON_AXIS1): + return 'Z'; + default: + return '\0'; } } @@ -999,13 +999,13 @@ int isLockConstraint(TransInfo *t) { int mode = t->con.mode; - if ( (mode & (CON_AXIS0|CON_AXIS1)) == (CON_AXIS0|CON_AXIS1)) + if ((mode & (CON_AXIS0 | CON_AXIS1)) == (CON_AXIS0 | CON_AXIS1)) return 1; - if ( (mode & (CON_AXIS1|CON_AXIS2)) == (CON_AXIS1|CON_AXIS2)) + if ((mode & (CON_AXIS1 | CON_AXIS2)) == (CON_AXIS1 | CON_AXIS2)) return 1; - if ( (mode & (CON_AXIS0|CON_AXIS2)) == (CON_AXIS0|CON_AXIS2)) + if ((mode & (CON_AXIS0 | CON_AXIS2)) == (CON_AXIS0 | CON_AXIS2)) return 1; return 0; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 95a9ab5900a..5a38bf607d9 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1909,7 +1909,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx // Setting normals copy_v3_v3(td->axismtx[2], eve->no); - td->axismtx[0][0] = + td->axismtx[0][0] = td->axismtx[0][1] = td->axismtx[0][2] = td->axismtx[1][0] = diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index f21e0a0515d..8682b866742 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -828,7 +828,7 @@ static void recalcData_view3d(TransInfo *t) DAG_id_tag_update(t->obedit->data, 0); /* sets recalc flags */ } } - else if ( (t->flag & T_POSE) && t->poseobj) { + else if ((t->flag & T_POSE) && t->poseobj) { Object *ob = t->poseobj; bArmature *arm = ob->data; diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index 9c485e17dc7..7e05fdae364 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -64,18 +64,18 @@ static void InputSpring(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], /* calculate ratio for shiftkey pos, and for total, and blend these for precision */ dx = (float)(mi->center[0] - mi->precision_mval[0]); dy = (float)(mi->center[1] - mi->precision_mval[1]); - ratio = (float)sqrt( dx*dx + dy*dy); + ratio = sqrtf(dx * dx + dy * dy); - dx= (float)(mi->center[0] - mval[0]); - dy= (float)(mi->center[1] - mval[1]); - precise_ratio = (float)sqrt( dx*dx + dy*dy); + dx = (float)(mi->center[0] - mval[0]); + dy = (float)(mi->center[1] - mval[1]); + precise_ratio = (float)sqrt(dx * dx + dy * dy); ratio = (ratio + (precise_ratio - ratio) / 10.0f) / mi->factor; } else { dx = (float)(mi->center[0] - mval[0]); dy = (float)(mi->center[1] - mval[1]); - ratio = (float)sqrt( dx*dx + dy*dy) / mi->factor; + ratio = sqrtf(dx * dx + dy * dy) / mi->factor; } output[0] = ratio; @@ -98,12 +98,12 @@ static void InputTrackBall(TransInfo *UNUSED(t), MouseInput *mi, const int mval[ { if (mi->precision) { - output[0] = ( mi->imval[1] - mi->precision_mval[1] ) + ( mi->precision_mval[1] - mval[1] ) * 0.1f; - output[1] = ( mi->precision_mval[0] - mi->imval[0] ) + ( mval[0] - mi->precision_mval[0] ) * 0.1f; + output[0] = (mi->imval[1] - mi->precision_mval[1]) + (mi->precision_mval[1] - mval[1]) * 0.1f; + output[1] = (mi->precision_mval[0] - mi->imval[0]) + (mval[0] - mi->precision_mval[0]) * 0.1f; } else { - output[0] = (float)( mi->imval[1] - mval[1] ); - output[1] = (float)( mval[0] - mi->imval[0] ); + output[0] = (float)(mi->imval[1] - mval[1]); + output[1] = (float)(mval[0] - mi->imval[0]); } output[0] *= mi->factor; @@ -191,7 +191,7 @@ static void InputCustomRatio(TransInfo *UNUSED(t), MouseInput *mi, const int mva dx = data[2] - data[0]; dy = data[3] - data[1]; - length = sqrt(dx*dx + dy*dy); + length = sqrt(dx * dx + dy * dy); if (mi->precision) { /* deal with Shift key by adding motion / 10 to motion before shift press */ @@ -199,7 +199,7 @@ static void InputCustomRatio(TransInfo *UNUSED(t), MouseInput *mi, const int mva mdx = (mi->precision_mval[0] + (float)(mval[0] - mi->precision_mval[0]) / 10.0f) - data[2]; mdy = (mi->precision_mval[1] + (float)(mval[1] - mi->precision_mval[1]) / 10.0f) - data[3]; - distance = (length != 0.0) ? (mdx * dx + mdy * dy) / length: 0.0; + distance = (length != 0.0) ? (mdx * dx + mdy * dy) / length : 0.0; } else { int mdx, mdy; @@ -217,11 +217,11 @@ static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], { double dx2 = mval[0] - mi->center[0]; double dy2 = mval[1] - mi->center[1]; - double B = sqrt(dx2*dx2+dy2*dy2); + double B = sqrt(dx2 * dx2 + dy2 * dy2); double dx1 = mi->imval[0] - mi->center[0]; double dy1 = mi->imval[1] - mi->center[1]; - double A = sqrt(dx1*dx1+dy1*dy1); + double A = sqrt(dx1 * dx1 + dy1 * dy1); double dx3 = mval[0] - mi->imval[0]; double dy3 = mval[1] - mi->imval[1]; @@ -237,7 +237,7 @@ static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], float dphi; dphi = saacos((float)deler); - if ( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi; + if ((dx1 * dy2 - dx2 * dy1) > 0.0) dphi = -dphi; /* If the angle is zero, because of lack of precision close to the 1.0 value in acos * approximate the angle with the opposite side of the normalized triangle @@ -256,12 +256,12 @@ static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], dx = dx1 - dx2; dy = dy1 - dy2; - dphi = sqrt(dx*dx + dy*dy); - if ( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi; + dphi = sqrt(dx * dx + dy * dy); + if ((dx1 * dy2 - dx2 * dy1) > 0.0) dphi = -dphi; } if (mi->precision) { - dphi = dphi/30.0f; + dphi = dphi / 30.0f; } /* if no delta angle, don't update initial position */ @@ -295,7 +295,7 @@ static void calcSpringFactor(MouseInput *mi) ((float)(mi->center[0] - mi->imval[0])) * ((float)(mi->center[0] - mi->imval[0]))); if (mi->factor == 0.0f) { - mi->factor= 1.0f; /* prevent Inf */ + mi->factor = 1.0f; /* prevent Inf */ } } @@ -307,68 +307,68 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode) #if 0 if (mi->data) { MEM_freeN(mi->data); - mi->data= NULL; + mi->data = NULL; } #endif switch (mode) { - case INPUT_VECTOR: - mi->apply = InputVector; - t->helpline = HLP_NONE; - break; - case INPUT_SPRING: - calcSpringFactor(mi); - mi->apply = InputSpring; - t->helpline = HLP_SPRING; - break; - case INPUT_SPRING_FLIP: - calcSpringFactor(mi); - mi->apply = InputSpringFlip; - t->helpline = HLP_SPRING; - break; - case INPUT_ANGLE: - mi->data = MEM_callocN(sizeof(double), "angle accumulator"); - mi->apply = InputAngle; - t->helpline = HLP_ANGLE; - break; - case INPUT_TRACKBALL: - /* factor has to become setting or so */ - mi->factor = 0.01f; - mi->apply = InputTrackBall; - t->helpline = HLP_TRACKBALL; - break; - case INPUT_HORIZONTAL_RATIO: - mi->factor = (float)(mi->center[0] - mi->imval[0]); - mi->apply = InputHorizontalRatio; - t->helpline = HLP_HARROW; - break; - case INPUT_HORIZONTAL_ABSOLUTE: - mi->apply = InputHorizontalAbsolute; - t->helpline = HLP_HARROW; - break; - case INPUT_VERTICAL_RATIO: - mi->apply = InputVerticalRatio; - t->helpline = HLP_VARROW; - break; - case INPUT_VERTICAL_ABSOLUTE: - mi->apply = InputVerticalAbsolute; - t->helpline = HLP_VARROW; - break; - case INPUT_CUSTOM_RATIO: - mi->apply = InputCustomRatio; - t->helpline = HLP_NONE; - break; - case INPUT_NONE: - default: - mi->apply = NULL; - break; + case INPUT_VECTOR: + mi->apply = InputVector; + t->helpline = HLP_NONE; + break; + case INPUT_SPRING: + calcSpringFactor(mi); + mi->apply = InputSpring; + t->helpline = HLP_SPRING; + break; + case INPUT_SPRING_FLIP: + calcSpringFactor(mi); + mi->apply = InputSpringFlip; + t->helpline = HLP_SPRING; + break; + case INPUT_ANGLE: + mi->data = MEM_callocN(sizeof(double), "angle accumulator"); + mi->apply = InputAngle; + t->helpline = HLP_ANGLE; + break; + case INPUT_TRACKBALL: + /* factor has to become setting or so */ + mi->factor = 0.01f; + mi->apply = InputTrackBall; + t->helpline = HLP_TRACKBALL; + break; + case INPUT_HORIZONTAL_RATIO: + mi->factor = (float)(mi->center[0] - mi->imval[0]); + mi->apply = InputHorizontalRatio; + t->helpline = HLP_HARROW; + break; + case INPUT_HORIZONTAL_ABSOLUTE: + mi->apply = InputHorizontalAbsolute; + t->helpline = HLP_HARROW; + break; + case INPUT_VERTICAL_RATIO: + mi->apply = InputVerticalRatio; + t->helpline = HLP_VARROW; + break; + case INPUT_VERTICAL_ABSOLUTE: + mi->apply = InputVerticalAbsolute; + t->helpline = HLP_VARROW; + break; + case INPUT_CUSTOM_RATIO: + mi->apply = InputCustomRatio; + t->helpline = HLP_NONE; + break; + case INPUT_NONE: + default: + mi->apply = NULL; + break; } /* bootstrap mouse input with initial values */ applyMouseInput(t, mi, mi->imval, t->values); } -void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *, float [3])) +void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *, float[3])) { mi->post = post; } @@ -389,21 +389,21 @@ int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event) int redraw = TREDRAW_NOTHING; switch (event->type) { - case LEFTSHIFTKEY: - case RIGHTSHIFTKEY: - if (event->val == KM_PRESS) { - t->modifiers |= MOD_PRECISION; - /* shift is modifier for higher precision transform - * store the mouse position where the normal movement ended */ - copy_v2_v2_int(mi->precision_mval, event->mval); - mi->precision = 1; - } - else { - t->modifiers &= ~MOD_PRECISION; - mi->precision = 0; - } - redraw = TREDRAW_HARD; - break; + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + if (event->val == KM_PRESS) { + t->modifiers |= MOD_PRECISION; + /* shift is modifier for higher precision transform + * store the mouse position where the normal movement ended */ + copy_v2_v2_int(mi->precision_mval, event->mval); + mi->precision = 1; + } + else { + t->modifiers &= ~MOD_PRECISION; + mi->precision = 0; + } + redraw = TREDRAW_HARD; + break; } return redraw; diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 7d0e9dd6005..e02ad00ac7f 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -84,35 +84,35 @@ /* return codes for select, and drawing flags */ -#define MAN_TRANS_X 1 -#define MAN_TRANS_Y 2 -#define MAN_TRANS_Z 4 -#define MAN_TRANS_C 7 +#define MAN_TRANS_X 1 +#define MAN_TRANS_Y 2 +#define MAN_TRANS_Z 4 +#define MAN_TRANS_C 7 -#define MAN_ROT_X 8 -#define MAN_ROT_Y 16 -#define MAN_ROT_Z 32 -#define MAN_ROT_V 64 -#define MAN_ROT_T 128 -#define MAN_ROT_C 248 +#define MAN_ROT_X 8 +#define MAN_ROT_Y 16 +#define MAN_ROT_Z 32 +#define MAN_ROT_V 64 +#define MAN_ROT_T 128 +#define MAN_ROT_C 248 -#define MAN_SCALE_X 256 -#define MAN_SCALE_Y 512 -#define MAN_SCALE_Z 1024 -#define MAN_SCALE_C 1792 +#define MAN_SCALE_X 256 +#define MAN_SCALE_Y 512 +#define MAN_SCALE_Z 1024 +#define MAN_SCALE_C 1792 /* color codes */ -#define MAN_RGB 0 -#define MAN_GHOST 1 -#define MAN_MOVECOL 2 +#define MAN_RGB 0 +#define MAN_GHOST 1 +#define MAN_MOVECOL 2 /* transform widget center calc helper for below */ static void calc_tw_center(Scene *scene, float *co) { - float *twcent= scene->twcent; - float *min= scene->twmin; - float *max= scene->twmax; + float *twcent = scene->twcent; + float *min = scene->twmin; + float *max = scene->twmax; minmax_v3v3_v3(min, max, co); add_v3_v3(twcent, co); @@ -145,7 +145,7 @@ static void protectflag_to_drawflags(short protectflag, short *drawflags) /* for pose mode */ static void stats_pose(Scene *scene, RegionView3D *rv3d, bPoseChannel *pchan) { - Bone *bone= pchan->bone; + Bone *bone = pchan->bone; if (bone) { if (bone->flag & BONE_TRANSFORM) { @@ -159,7 +159,7 @@ static void stats_pose(Scene *scene, RegionView3D *rv3d, bPoseChannel *pchan) static void stats_editbone(RegionView3D *rv3d, EditBone *ebo) { if (ebo->flag & BONE_EDITMODE_LOCKED) - protectflag_to_drawflags(OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE, &rv3d->twdrawflag); + protectflag_to_drawflags(OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE, &rv3d->twdrawflag); } /* could move into BLI_math however this is only useful for display/editing purposes */ @@ -172,9 +172,9 @@ static void axis_angle_to_gimbal_axis(float gmat[3][3], float axis[3], float ang /* this is an un-scientific method to get a vector to cross with * XYZ intentionally YZX */ - cross_vec[0]= axis[1]; - cross_vec[1]= axis[2]; - cross_vec[2]= axis[0]; + cross_vec[0] = axis[1]; + cross_vec[1] = axis[2]; + cross_vec[2] = axis[0]; /* X-axis */ cross_v3_v3v3(gmat[0], cross_vec, axis); @@ -183,7 +183,7 @@ static void axis_angle_to_gimbal_axis(float gmat[3][3], float axis[3], float ang mul_qt_v3(quat, gmat[0]); /* Y-axis */ - axis_angle_to_quat(quat, axis, M_PI/2.0); + axis_angle_to_quat(quat, axis, M_PI / 2.0); copy_v3_v3(gmat[1], gmat[0]); mul_qt_v3(quat, gmat[1]); @@ -196,14 +196,14 @@ static void axis_angle_to_gimbal_axis(float gmat[3][3], float axis[3], float ang static int test_rotmode_euler(short rotmode) { - return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0:1; + return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1; } int gimbal_axis(Object *ob, float gmat[][3]) { if (ob) { if (ob->mode & OB_MODE_POSE) { - bPoseChannel *pchan= BKE_pose_channel_active(ob); + bPoseChannel *pchan = BKE_pose_channel_active(ob); if (pchan) { float mat[3][3], tmat[3][3], obmat[3][3]; @@ -270,40 +270,40 @@ int gimbal_axis(Object *ob, float gmat[][3]) /* returns total items selected */ int calc_manipulator_stats(const bContext *C) { - ScrArea *sa= CTX_wm_area(C); - ARegion *ar= CTX_wm_region(C); - Scene *scene= CTX_data_scene(C); - Object *obedit= CTX_data_edit_object(C); + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); ToolSettings *ts = CTX_data_tool_settings(C); - View3D *v3d= sa->spacedata.first; - RegionView3D *rv3d= ar->regiondata; + View3D *v3d = sa->spacedata.first; + RegionView3D *rv3d = ar->regiondata; Base *base; - Object *ob= OBACT; - int a, totsel= 0; + Object *ob = OBACT; + int a, totsel = 0; /* transform widget matrix */ unit_m4(rv3d->twmat); - rv3d->twdrawflag= 0xFFFF; + rv3d->twdrawflag = 0xFFFF; /* transform widget centroid/center */ INIT_MINMAX(scene->twmin, scene->twmax); zero_v3(scene->twcent); if (obedit) { - ob= obedit; - if ((ob->lay & v3d->lay)==0) return 0; + ob = obedit; + if ((ob->lay & v3d->lay) == 0) return 0; - if (obedit->type==OB_MESH) { + if (obedit->type == OB_MESH) { BMEditMesh *em = BMEdit_FromObject(obedit); BMEditSelection ese; - float vec[3]= {0, 0, 0}; + float vec[3] = {0, 0, 0}; /* USE LAST SELECTE WITH ACTIVE */ if ((v3d->around == V3D_ACTIVE) && BM_select_history_active_get(em->bm, &ese)) { BM_editselection_center(&ese, vec); calc_tw_center(scene, vec); - totsel= 1; + totsel = 1; } else { BMesh *bm = em->bm; @@ -358,10 +358,10 @@ int calc_manipulator_stats(const bContext *C) } } } /* end editmesh */ - else if (obedit->type==OB_ARMATURE) { - bArmature *arm= obedit->data; + else if (obedit->type == OB_ARMATURE) { + bArmature *arm = obedit->data; EditBone *ebo; - for (ebo= arm->edbo->first; ebo; ebo=ebo->next) { + for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { if (EBONE_VISIBLE(arm, ebo)) { if (ebo->flag & BONE_TIPSEL) { calc_tw_center(scene, ebo->tail); @@ -378,24 +378,24 @@ int calc_manipulator_stats(const bContext *C) } } else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { - Curve *cu= obedit->data; + Curve *cu = obedit->data; float center[3]; - if (v3d->around==V3D_ACTIVE && ED_curve_actSelection(cu, center)) { - calc_tw_center(scene, center); + if (v3d->around == V3D_ACTIVE && ED_curve_actSelection(cu, center)) { + calc_tw_center(scene, center); totsel++; } else { Nurb *nu; BezTriple *bezt; BPoint *bp; - ListBase *nurbs= BKE_curve_editNurbs_get(cu); + ListBase *nurbs = BKE_curve_editNurbs_get(cu); - nu= nurbs->first; + nu = nurbs->first; while (nu) { if (nu->type == CU_BEZIER) { - bezt= nu->bezt; - a= nu->pntsu; + bezt = nu->bezt; + a = nu->pntsu; while (a--) { /* exceptions * if handles are hidden then only check the center points. @@ -425,8 +425,8 @@ int calc_manipulator_stats(const bContext *C) } } else { - bp= nu->bp; - a= nu->pntsu*nu->pntsv; + bp = nu->bp; + a = nu->pntsu * nu->pntsv; while (a--) { if (bp->f1 & SELECT) { calc_tw_center(scene, bp->vec); @@ -435,31 +435,31 @@ int calc_manipulator_stats(const bContext *C) bp++; } } - nu= nu->next; + nu = nu->next; } } } - else if (obedit->type==OB_MBALL) { - MetaBall *mb = (MetaBall*)obedit->data; + else if (obedit->type == OB_MBALL) { + MetaBall *mb = (MetaBall *)obedit->data; MetaElem *ml /* , *ml_sel=NULL */ /* UNUSED */; - ml= mb->editelems->first; + ml = mb->editelems->first; while (ml) { if (ml->flag & SELECT) { calc_tw_center(scene, &ml->x); /* ml_sel = ml; */ /* UNUSED */ totsel++; } - ml= ml->next; + ml = ml->next; } } - else if (obedit->type==OB_LATTICE) { + else if (obedit->type == OB_LATTICE) { BPoint *bp; - Lattice *lt= obedit->data; + Lattice *lt = obedit->data; - bp= lt->editlatt->latt->def; + bp = lt->editlatt->latt->def; - a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw; + a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; while (a--) { if (bp->f1 & SELECT) { calc_tw_center(scene, bp->vec); @@ -471,7 +471,7 @@ int calc_manipulator_stats(const bContext *C) /* selection center */ if (totsel) { - mul_v3_fl(scene->twcent, 1.0f/(float)totsel); // centroid! + mul_v3_fl(scene->twcent, 1.0f / (float)totsel); // centroid! mul_m4_v3(obedit->obmat, scene->twcent); mul_m4_v3(obedit->obmat, scene->twmin); mul_m4_v3(obedit->obmat, scene->twmax); @@ -481,17 +481,17 @@ int calc_manipulator_stats(const bContext *C) bPoseChannel *pchan; int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed - if ((ob->lay & v3d->lay)==0) return 0; + if ((ob->lay & v3d->lay) == 0) return 0; totsel = count_set_pose_transflags(&mode, 0, ob); if (totsel) { /* use channels to get stats */ - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { stats_pose(scene, rv3d, pchan); } - mul_v3_fl(scene->twcent, 1.0f/(float)totsel); // centroid! + mul_v3_fl(scene->twcent, 1.0f / (float)totsel); // centroid! mul_m4_v3(ob->obmat, scene->twcent); mul_m4_v3(ob->obmat, scene->twmin); mul_m4_v3(ob->obmat, scene->twmax); @@ -501,17 +501,17 @@ int calc_manipulator_stats(const bContext *C) ; } else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) { - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit = PE_get_current(scene, ob); PTCacheEditPoint *point; PTCacheEditKey *ek; int k; if (edit) { point = edit->points; - for (a=0; atotpoint; a++, point++) { + for (a = 0; a < edit->totpoint; a++, point++) { if (point->flag & PEP_HIDE) continue; - for (k=0, ek=point->keys; ktotkey; k++, ek++) { + for (k = 0, ek = point->keys; k < point->totkey; k++, ek++) { if (ek->flag & PEK_SELECT) { calc_tw_center(scene, ek->flag & PEK_USE_WCO ? ek->world_co : ek->co); totsel++; @@ -521,19 +521,19 @@ int calc_manipulator_stats(const bContext *C) /* selection center */ if (totsel) - mul_v3_fl(scene->twcent, 1.0f/(float)totsel); // centroid! + mul_v3_fl(scene->twcent, 1.0f / (float)totsel); // centroid! } } else { /* we need the one selected object, if its not active */ - ob= OBACT; - if (ob && !(ob->flag & SELECT)) ob= NULL; + ob = OBACT; + if (ob && !(ob->flag & SELECT)) ob = NULL; - for (base= scene->base.first; base; base= base->next) { + for (base = scene->base.first; base; base = base->next) { if (TESTBASELIB(v3d, base)) { - if (ob==NULL) - ob= base->object; + if (ob == NULL) + ob = base->object; calc_tw_center(scene, base->object->obmat[3]); protectflag_to_drawflags(base->object->protectflag, &rv3d->twdrawflag); totsel++; @@ -542,7 +542,7 @@ int calc_manipulator_stats(const bContext *C) /* selection center */ if (totsel) { - mul_v3_fl(scene->twcent, 1.0f/(float)totsel); // centroid! + mul_v3_fl(scene->twcent, 1.0f / (float)totsel); // centroid! } } @@ -551,32 +551,32 @@ int calc_manipulator_stats(const bContext *C) switch (v3d->twmode) { - case V3D_MANIP_GLOBAL: - break; /* nothing to do */ + case V3D_MANIP_GLOBAL: + break; /* nothing to do */ - case V3D_MANIP_GIMBAL: - { - float mat[3][3]; - if (gimbal_axis(ob, mat)) { - copy_m4_m3(rv3d->twmat, mat); - break; - } - /* if not gimbal, fall through to normal */ - } - case V3D_MANIP_NORMAL: - if (obedit || ob->mode & OB_MODE_POSE) { + case V3D_MANIP_GIMBAL: + { float mat[3][3]; - ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE)); - copy_m4_m3(rv3d->twmat, mat); - break; + if (gimbal_axis(ob, mat)) { + copy_m4_m3(rv3d->twmat, mat); + break; + } + /* if not gimbal, fall through to normal */ } + case V3D_MANIP_NORMAL: + if (obedit || ob->mode & OB_MODE_POSE) { + float mat[3][3]; + ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE)); + copy_m4_m3(rv3d->twmat, mat); + break; + } /* no break we define 'normal' as 'local' in Object mode */ - case V3D_MANIP_LOCAL: - copy_m4_m4(rv3d->twmat, ob->obmat); - normalize_m4(rv3d->twmat); - break; + case V3D_MANIP_LOCAL: + copy_m4_m4(rv3d->twmat, ob->obmat); + normalize_m4(rv3d->twmat); + break; - case V3D_MANIP_VIEW: + case V3D_MANIP_VIEW: { float mat[3][3]; copy_m3_m4(mat, rv3d->viewinv); @@ -584,7 +584,7 @@ int calc_manipulator_stats(const bContext *C) copy_m4_m3(rv3d->twmat, mat); } break; - default: /* V3D_MANIP_CUSTOM */ + default: /* V3D_MANIP_CUSTOM */ { float mat[3][3]; applyTransformOrientation(C, mat, NULL); @@ -601,7 +601,7 @@ int calc_manipulator_stats(const bContext *C) /* don't draw axis perpendicular to the view */ static void test_manipulator_axis(const bContext *C) { - RegionView3D *rv3d= CTX_wm_region_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); float angle; float vec[3]; @@ -613,7 +613,7 @@ static void test_manipulator_axis(const bContext *C) } angle = rv3d->twangle[0] = RAD2DEGF(angle); if (angle < 5.0f) { - rv3d->twdrawflag &= ~(MAN_TRANS_X|MAN_SCALE_X); + rv3d->twdrawflag &= ~(MAN_TRANS_X | MAN_SCALE_X); } angle = fabs(angle_v3v3(rv3d->twmat[1], vec)); @@ -622,7 +622,7 @@ static void test_manipulator_axis(const bContext *C) } angle = rv3d->twangle[1] = RAD2DEGF(angle); if (angle < 5.0f) { - rv3d->twdrawflag &= ~(MAN_TRANS_Y|MAN_SCALE_Y); + rv3d->twdrawflag &= ~(MAN_TRANS_Y | MAN_SCALE_Y); } angle = fabs(angle_v3v3(rv3d->twmat[2], vec)); @@ -631,7 +631,7 @@ static void test_manipulator_axis(const bContext *C) } angle = rv3d->twangle[2] = RAD2DEGF(angle); if (angle < 5.0f) { - rv3d->twdrawflag &= ~(MAN_TRANS_Z|MAN_SCALE_Z); + rv3d->twdrawflag &= ~(MAN_TRANS_Z | MAN_SCALE_Z); } } @@ -643,7 +643,7 @@ static float screen_aligned(RegionView3D *rv3d, float mat[][4]) glTranslatef(mat[3][0], mat[3][1], mat[3][2]); /* sets view screen aligned */ - glRotatef(-360.0f*saacos(rv3d->viewquat[0])/(float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]); + glRotatef(-360.0f * saacos(rv3d->viewquat[0]) / (float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]); return len_v3(mat[0]); /* draw scale */ } @@ -666,43 +666,43 @@ static void partial_doughnut(float radring, float radhole, int start, int end, i if (start == 0 && end == nrings) do_caps = FALSE; - ring_delta= 2.0f*(float)M_PI/(float)nrings; - side_delta= 2.0f*(float)M_PI/(float)nsides; + ring_delta = 2.0f * (float)M_PI / (float)nrings; + side_delta = 2.0f * (float)M_PI / (float)nsides; - theta= (float)M_PI+0.5f*ring_delta; - cos_theta= (float)cos(theta); - sin_theta= (float)sin(theta); + theta = (float)M_PI + 0.5f * ring_delta; + cos_theta = (float)cos(theta); + sin_theta = (float)sin(theta); - for (i= nrings - 1; i >= 0; i--) { - theta1= theta + ring_delta; - cos_theta1= (float)cos(theta1); - sin_theta1= (float)sin(theta1); + for (i = nrings - 1; i >= 0; i--) { + theta1 = theta + ring_delta; + cos_theta1 = (float)cos(theta1); + sin_theta1 = (float)sin(theta1); - if (do_caps && i==start) { // cap + if (do_caps && i == start) { // cap glBegin(GL_POLYGON); - phi= 0.0; - for (j= nsides; j >= 0; j--) { + phi = 0.0; + for (j = nsides; j >= 0; j--) { float cos_phi, sin_phi, dist; phi += side_delta; - cos_phi= (float)cos(phi); - sin_phi= (float)sin(phi); - dist= radhole + radring * cos_phi; + cos_phi = (float)cos(phi); + sin_phi = (float)sin(phi); + dist = radhole + radring * cos_phi; glVertex3f(cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi); } glEnd(); } - if (i>=start && i<=end) { + if (i >= start && i <= end) { glBegin(GL_QUAD_STRIP); - phi= 0.0; - for (j= nsides; j >= 0; j--) { + phi = 0.0; + for (j = nsides; j >= 0; j--) { float cos_phi, sin_phi, dist; phi += side_delta; - cos_phi= (float)cos(phi); - sin_phi= (float)sin(phi); - dist= radhole + radring * cos_phi; + cos_phi = (float)cos(phi); + sin_phi = (float)sin(phi); + dist = radhole + radring * cos_phi; glVertex3f(cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi); glVertex3f(cos_theta * dist, -sin_theta * dist, radring * sin_phi); @@ -710,16 +710,16 @@ static void partial_doughnut(float radring, float radhole, int start, int end, i glEnd(); } - if (do_caps && i==end) { // cap + if (do_caps && i == end) { // cap glBegin(GL_POLYGON); - phi= 0.0; - for (j= nsides; j >= 0; j--) { + phi = 0.0; + for (j = nsides; j >= 0; j--) { float cos_phi, sin_phi, dist; phi -= side_delta; - cos_phi= (float)cos(phi); - sin_phi= (float)sin(phi); - dist= radhole + radring * cos_phi; + cos_phi = (float)cos(phi); + sin_phi = (float)sin(phi); + dist = radhole + radring * cos_phi; glVertex3f(cos_theta * dist, -sin_theta * dist, radring * sin_phi); } @@ -727,9 +727,9 @@ static void partial_doughnut(float radring, float radhole, int start, int end, i } - theta= theta1; - cos_theta= cos_theta1; - sin_theta= sin_theta1; + theta = theta1; + cos_theta = cos_theta1; + sin_theta = sin_theta1; } } @@ -751,43 +751,43 @@ static char axisBlendAngle(float angle) */ static void manipulator_setcolor(View3D *v3d, char axis, int colcode, unsigned char alpha) { - unsigned char col[4]= {0}; - col[3]= alpha; + unsigned char col[4] = {0}; + col[3] = alpha; - if (colcode==MAN_GHOST) { - col[3]= 70; + if (colcode == MAN_GHOST) { + col[3] = 70; } - else if (colcode==MAN_MOVECOL) { + else if (colcode == MAN_MOVECOL) { UI_GetThemeColor3ubv(TH_TRANSFORM, col); } else { switch (axis) { - case 'C': - UI_GetThemeColor3ubv(TH_TRANSFORM, col); - if (v3d->twmode == V3D_MANIP_LOCAL) { - col[0]= col[0]>200?255:col[0]+55; - col[1]= col[1]>200?255:col[1]+55; - col[2]= col[2]>200?255:col[2]+55; - } - else if (v3d->twmode == V3D_MANIP_NORMAL) { - col[0]= col[0]<55?0:col[0]-55; - col[1]= col[1]<55?0:col[1]-55; - col[2]= col[2]<55?0:col[2]-55; - } - break; - case 'X': - col[0]= 220; - break; - case 'Y': - col[1]= 220; - break; - case 'Z': - col[0]= 30; - col[1]= 30; - col[2]= 220; - break; - default: - BLI_assert(!"invalid axis arg"); + case 'C': + UI_GetThemeColor3ubv(TH_TRANSFORM, col); + if (v3d->twmode == V3D_MANIP_LOCAL) { + col[0] = col[0] > 200 ? 255 : col[0] + 55; + col[1] = col[1] > 200 ? 255 : col[1] + 55; + col[2] = col[2] > 200 ? 255 : col[2] + 55; + } + else if (v3d->twmode == V3D_MANIP_NORMAL) { + col[0] = col[0] < 55 ? 0 : col[0] - 55; + col[1] = col[1] < 55 ? 0 : col[1] - 55; + col[2] = col[2] < 55 ? 0 : col[2] - 55; + } + break; + case 'X': + col[0] = 220; + break; + case 'Y': + col[1] = 220; + break; + case 'Z': + col[0] = 30; + col[1] = 30; + col[2] = 220; + break; + default: + BLI_assert(!"invalid axis arg"); } } @@ -836,7 +836,7 @@ static void preOrthoFront(int ortho, float twmat[][4], int axis) orthogonalize_m4(omat, axis); glPushMatrix(); glMultMatrixf(omat); - glFrontFace(is_negative_m4(omat) ? GL_CW:GL_CCW); + glFrontFace(is_negative_m4(omat) ? GL_CW : GL_CCW); } } @@ -853,42 +853,42 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, double plane[4]; float matt[4][4]; float size, unitmat[4][4]; - float cywid= 0.33f*0.01f*(float)U.tw_handlesize; - float cusize= cywid*0.65f; - int arcs= (G.rt!=2); + float cywid = 0.33f * 0.01f * (float)U.tw_handlesize; + float cusize = cywid * 0.65f; + int arcs = (G.rt != 2); int colcode; int ortho; - if (moving) colcode= MAN_MOVECOL; - else colcode= MAN_RGB; + if (moving) colcode = MAN_MOVECOL; + else colcode = MAN_RGB; /* when called while moving in mixed mode, do not draw when... */ - if ((drawflags & MAN_ROT_C)==0) return; + if ((drawflags & MAN_ROT_C) == 0) return; /* Init stuff */ glDisable(GL_DEPTH_TEST); unit_m4(unitmat); - qobj= gluNewQuadric(); + qobj = gluNewQuadric(); gluQuadricDrawStyle(qobj, GLU_FILL); /* prepare for screen aligned draw */ - size= len_v3(rv3d->twmat[0]); + size = len_v3(rv3d->twmat[0]); glPushMatrix(); glTranslatef(rv3d->twmat[3][0], rv3d->twmat[3][1], rv3d->twmat[3][2]); if (arcs) { /* clipplane makes nice handles, calc here because of multmatrix but with translate! */ copy_v3db_v3fl(plane, rv3d->viewinv[2]); - plane[3]= -0.02f*size; // clip just a bit more + plane[3] = -0.02f * size; // clip just a bit more glClipPlane(GL_CLIP_PLANE0, plane); } /* sets view screen aligned */ - glRotatef(-360.0f*saacos(rv3d->viewquat[0])/(float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]); + glRotatef(-360.0f * saacos(rv3d->viewquat[0]) / (float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]); /* Screen aligned help circle */ if (arcs) { - if ((G.f & G_PICKSEL)==0) { + if ((G.f & G_PICKSEL) == 0) { UI_ThemeColorShade(TH_BACK, -30); drawcircball(GL_LINE_LOOP, unitmat[3], size, unitmat); } @@ -899,22 +899,22 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, if (G.f & G_PICKSEL) glLoadName(MAN_ROT_T); UI_ThemeColor(TH_TRANSFORM); - drawcircball(GL_LINE_LOOP, unitmat[3], 0.2f*size, unitmat); + drawcircball(GL_LINE_LOOP, unitmat[3], 0.2f * size, unitmat); } /* Screen aligned view rot circle */ if (drawflags & MAN_ROT_V) { if (G.f & G_PICKSEL) glLoadName(MAN_ROT_V); UI_ThemeColor(TH_TRANSFORM); - drawcircball(GL_LINE_LOOP, unitmat[3], 1.2f*size, unitmat); + drawcircball(GL_LINE_LOOP, unitmat[3], 1.2f * size, unitmat); if (moving) { float vec[3]; - vec[0]= 0; // XXX (float)(t->imval[0] - t->center2d[0]); - vec[1]= 0; // XXX (float)(t->imval[1] - t->center2d[1]); - vec[2]= 0.0f; + vec[0] = 0; // XXX (float)(t->imval[0] - t->center2d[0]); + vec[1] = 0; // XXX (float)(t->imval[1] - t->center2d[1]); + vec[2] = 0.0f; normalize_v3(vec); - mul_v3_fl(vec, 1.2f*size); + mul_v3_fl(vec, 1.2f * size); glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3fv(vec); @@ -932,22 +932,22 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, // XXX mul_m4_m3m4(matt, t->mat, rv3d->twmat); if (ortho) { glMultMatrixf(matt); - glFrontFace(is_negative_m4(matt) ? GL_CW:GL_CCW); + glFrontFace(is_negative_m4(matt) ? GL_CW : GL_CCW); } } else { if (ortho) { - glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW:GL_CCW); + glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW : GL_CCW); glMultMatrixf(rv3d->twmat); } } /* axes */ - if (arcs==0) { + if (arcs == 0) { if (!(G.f & G_PICKSEL)) { - if ( (combo & V3D_MANIP_SCALE)==0) { + if ((combo & V3D_MANIP_SCALE) == 0) { /* axis */ - if ( (drawflags & MAN_ROT_X) || (moving && (drawflags & MAN_ROT_Z)) ) { + if ((drawflags & MAN_ROT_X) || (moving && (drawflags & MAN_ROT_Z))) { preOrthoFront(ortho, rv3d->twmat, 2); manipulator_setcolor(v3d, 'X', colcode, 255); glBegin(GL_LINES); @@ -956,7 +956,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, glEnd(); postOrtho(ortho); } - if ( (drawflags & MAN_ROT_Y) || (moving && (drawflags & MAN_ROT_X)) ) { + if ((drawflags & MAN_ROT_Y) || (moving && (drawflags & MAN_ROT_X))) { preOrthoFront(ortho, rv3d->twmat, 0); manipulator_setcolor(v3d, 'Y', colcode, 255); glBegin(GL_LINES); @@ -965,7 +965,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, glEnd(); postOrtho(ortho); } - if ( (drawflags & MAN_ROT_Z) || (moving && (drawflags & MAN_ROT_Y)) ) { + if ((drawflags & MAN_ROT_Z) || (moving && (drawflags & MAN_ROT_Y))) { preOrthoFront(ortho, rv3d->twmat, 1); manipulator_setcolor(v3d, 'Z', colcode, 255); glBegin(GL_LINES); @@ -978,7 +978,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, } } - if (arcs==0 && moving) { + if (arcs == 0 && moving) { /* Z circle */ if (drawflags & MAN_ROT_Z) { @@ -1020,7 +1020,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, preOrthoFront(ortho, rv3d->twmat, 2); if (G.f & G_PICKSEL) glLoadName(MAN_ROT_Z); manipulator_setcolor(v3d, 'Z', colcode, 255); - partial_doughnut(cusize/4.0f, 1.0f, 0, 48, 8, 48); + partial_doughnut(cusize / 4.0f, 1.0f, 0, 48, 8, 48); postOrtho(ortho); } /* X circle */ @@ -1029,7 +1029,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, if (G.f & G_PICKSEL) glLoadName(MAN_ROT_X); glRotatef(90.0, 0.0, 1.0, 0.0); manipulator_setcolor(v3d, 'X', colcode, 255); - partial_doughnut(cusize/4.0f, 1.0f, 0, 48, 8, 48); + partial_doughnut(cusize / 4.0f, 1.0f, 0, 48, 8, 48); glRotatef(-90.0, 0.0, 1.0, 0.0); postOrtho(ortho); } @@ -1039,7 +1039,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, if (G.f & G_PICKSEL) glLoadName(MAN_ROT_Y); glRotatef(-90.0, 1.0, 0.0, 0.0); manipulator_setcolor(v3d, 'Y', colcode, 255); - partial_doughnut(cusize/4.0f, 1.0f, 0, 48, 8, 48); + partial_doughnut(cusize / 4.0f, 1.0f, 0, 48, 8, 48); glRotatef(90.0, 1.0, 0.0, 0.0); postOrtho(ortho); } @@ -1047,7 +1047,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, glDisable(GL_CLIP_PLANE0); } - if (arcs==0) { + if (arcs == 0) { /* Z handle on X axis */ if (drawflags & MAN_ROT_Z) { @@ -1056,7 +1056,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, if (G.f & G_PICKSEL) glLoadName(MAN_ROT_Z); manipulator_setcolor(v3d, 'Z', colcode, 255); - partial_doughnut(0.7f*cusize, 1.0f, 31, 33, 8, 64); + partial_doughnut(0.7f * cusize, 1.0f, 31, 33, 8, 64); glPopMatrix(); postOrtho(ortho); @@ -1071,7 +1071,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, glRotatef(90.0, 1.0, 0.0, 0.0); glRotatef(90.0, 0.0, 0.0, 1.0); - partial_doughnut(0.7f*cusize, 1.0f, 31, 33, 8, 64); + partial_doughnut(0.7f * cusize, 1.0f, 31, 33, 8, 64); glPopMatrix(); postOrtho(ortho); @@ -1086,7 +1086,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, glRotatef(-90.0, 0.0, 1.0, 0.0); glRotatef(90.0, 0.0, 0.0, 1.0); - partial_doughnut(0.7f*cusize, 1.0f, 31, 33, 8, 64); + partial_doughnut(0.7f * cusize, 1.0f, 31, 33, 8, 64); glPopMatrix(); postOrtho(ortho); @@ -1104,56 +1104,57 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, static void drawsolidcube(float size) { static float cube[8][3] = { - {-1.0, -1.0, -1.0}, - {-1.0, -1.0, 1.0}, - {-1.0, 1.0, 1.0}, - {-1.0, 1.0, -1.0}, - { 1.0, -1.0, -1.0}, - { 1.0, -1.0, 1.0}, - { 1.0, 1.0, 1.0}, - { 1.0, 1.0, -1.0}, }; + {-1.0, -1.0, -1.0}, + {-1.0, -1.0, 1.0}, + {-1.0, 1.0, 1.0}, + {-1.0, 1.0, -1.0}, + { 1.0, -1.0, -1.0}, + { 1.0, -1.0, 1.0}, + { 1.0, 1.0, 1.0}, + { 1.0, 1.0, -1.0}, + }; float n[3] = {0.0f}; glPushMatrix(); glScalef(size, size, size); glBegin(GL_QUADS); - n[0]= -1.0; + n[0] = -1.0; glNormal3fv(n); glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]); - n[0]=0; + n[0] = 0; glEnd(); glBegin(GL_QUADS); - n[1]= -1.0; + n[1] = -1.0; glNormal3fv(n); glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]); - n[1]=0; + n[1] = 0; glEnd(); glBegin(GL_QUADS); - n[0]= 1.0; + n[0] = 1.0; glNormal3fv(n); glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]); - n[0]=0; + n[0] = 0; glEnd(); glBegin(GL_QUADS); - n[1]= 1.0; + n[1] = 1.0; glNormal3fv(n); glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]); - n[1]=0; + n[1] = 0; glEnd(); glBegin(GL_QUADS); - n[2]= 1.0; + n[2] = 1.0; glNormal3fv(n); glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]); - n[2]=0; + n[2] = 0; glEnd(); glBegin(GL_QUADS); - n[2]= -1.0; + n[2] = -1.0; glNormal3fv(n); glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]); glEnd(); @@ -1164,32 +1165,32 @@ static void drawsolidcube(float size) static void draw_manipulator_scale(View3D *v3d, RegionView3D *rv3d, int moving, int drawflags, int combo, int colcode) { - float cywid= 0.25f*0.01f*(float)U.tw_handlesize; - float cusize= cywid*0.75f, dz; + float cywid = 0.25f * 0.01f * (float)U.tw_handlesize; + float cusize = cywid * 0.75f, dz; /* when called while moving in mixed mode, do not draw when... */ - if ((drawflags & MAN_SCALE_C)==0) return; + if ((drawflags & MAN_SCALE_C) == 0) return; glDisable(GL_DEPTH_TEST); /* not in combo mode */ - if ( (combo & (V3D_MANIP_TRANSLATE|V3D_MANIP_ROTATE))==0) { + if ((combo & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE)) == 0) { float size, unitmat[4][4]; - int shift= 0; // XXX + int shift = 0; // XXX /* center circle, do not add to selection when shift is pressed (planar constraint) */ - if ( (G.f & G_PICKSEL) && shift==0) glLoadName(MAN_SCALE_C); + if ((G.f & G_PICKSEL) && shift == 0) glLoadName(MAN_SCALE_C); manipulator_setcolor(v3d, 'C', colcode, 255); glPushMatrix(); - size= screen_aligned(rv3d, rv3d->twmat); + size = screen_aligned(rv3d, rv3d->twmat); unit_m4(unitmat); - drawcircball(GL_LINE_LOOP, unitmat[3], 0.2f*size, unitmat); + drawcircball(GL_LINE_LOOP, unitmat[3], 0.2f * size, unitmat); glPopMatrix(); - dz= 1.0; + dz = 1.0; } - else dz= 1.0f-4.0f*cusize; + else dz = 1.0f - 4.0f * cusize; if (moving) { float matt[4][4]; @@ -1197,11 +1198,11 @@ static void draw_manipulator_scale(View3D *v3d, RegionView3D *rv3d, int moving, copy_m4_m4(matt, rv3d->twmat); // to copy the parts outside of [3][3] // XXX mul_m4_m3m4(matt, t->mat, rv3d->twmat); glMultMatrixf(matt); - glFrontFace(is_negative_m4(matt) ? GL_CW:GL_CCW); + glFrontFace(is_negative_m4(matt) ? GL_CW : GL_CCW); } else { glMultMatrixf(rv3d->twmat); - glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW:GL_CCW); + glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW : GL_CCW); } /* axis */ @@ -1233,7 +1234,7 @@ static void draw_manipulator_scale(View3D *v3d, RegionView3D *rv3d, int moving, /* if shiftkey, center point as last, for selectbuffer order */ if (G.f & G_PICKSEL) { - int shift= 0; // XXX + int shift = 0; // XXX if (shift) { glTranslatef(0.0, -dz, 0.0); @@ -1254,55 +1255,55 @@ static void draw_manipulator_scale(View3D *v3d, RegionView3D *rv3d, int moving, static void draw_cone(GLUquadricObj *qobj, float len, float width) { - glTranslatef(0.0, 0.0, -0.5f*len); + glTranslatef(0.0, 0.0, -0.5f * len); gluCylinder(qobj, width, 0.0, len, 8, 1); gluQuadricOrientation(qobj, GLU_INSIDE); gluDisk(qobj, 0.0, width, 8, 1); gluQuadricOrientation(qobj, GLU_OUTSIDE); - glTranslatef(0.0, 0.0, 0.5f*len); + glTranslatef(0.0, 0.0, 0.5f * len); } static void draw_cylinder(GLUquadricObj *qobj, float len, float width) { - width*= 0.8f; // just for beauty + width *= 0.8f; // just for beauty - glTranslatef(0.0, 0.0, -0.5f*len); + glTranslatef(0.0, 0.0, -0.5f * len); gluCylinder(qobj, width, width, len, 8, 1); gluQuadricOrientation(qobj, GLU_INSIDE); gluDisk(qobj, 0.0, width, 8, 1); gluQuadricOrientation(qobj, GLU_OUTSIDE); glTranslatef(0.0, 0.0, len); gluDisk(qobj, 0.0, width, 8, 1); - glTranslatef(0.0, 0.0, -0.5f*len); + glTranslatef(0.0, 0.0, -0.5f * len); } static void draw_manipulator_translate(View3D *v3d, RegionView3D *rv3d, int UNUSED(moving), int drawflags, int combo, int colcode) { GLUquadricObj *qobj; - float cylen= 0.01f*(float)U.tw_handlesize; - float cywid= 0.25f*cylen, dz, size; + float cylen = 0.01f * (float)U.tw_handlesize; + float cywid = 0.25f * cylen, dz, size; float unitmat[4][4]; - int shift= 0; // XXX + int shift = 0; // XXX /* when called while moving in mixed mode, do not draw when... */ - if ((drawflags & MAN_TRANS_C)==0) return; + if ((drawflags & MAN_TRANS_C) == 0) return; // XXX if (moving) glTranslatef(t->vec[0], t->vec[1], t->vec[2]); glDisable(GL_DEPTH_TEST); - qobj= gluNewQuadric(); + qobj = gluNewQuadric(); gluQuadricDrawStyle(qobj, GLU_FILL); /* center circle, do not add to selection when shift is pressed (planar constraint) */ - if ( (G.f & G_PICKSEL) && shift==0) glLoadName(MAN_TRANS_C); + if ((G.f & G_PICKSEL) && shift == 0) glLoadName(MAN_TRANS_C); manipulator_setcolor(v3d, 'C', colcode, 255); glPushMatrix(); - size= screen_aligned(rv3d, rv3d->twmat); + size = screen_aligned(rv3d, rv3d->twmat); unit_m4(unitmat); - drawcircball(GL_LINE_LOOP, unitmat[3], 0.2f*size, unitmat); + drawcircball(GL_LINE_LOOP, unitmat[3], 0.2f * size, unitmat); glPopMatrix(); /* and now apply matrix, we move to local matrix drawing */ @@ -1312,14 +1313,14 @@ static void draw_manipulator_translate(View3D *v3d, RegionView3D *rv3d, int UNUS glLoadName(-1); // translate drawn as last, only axis when no combo with scale, or for ghosting - if ((combo & V3D_MANIP_SCALE)==0 || colcode==MAN_GHOST) + if ((combo & V3D_MANIP_SCALE) == 0 || colcode == MAN_GHOST) draw_manipulator_axes(v3d, rv3d, colcode, drawflags & MAN_TRANS_X, drawflags & MAN_TRANS_Y, drawflags & MAN_TRANS_Z); /* offset in combo mode, for rotate a bit more */ - if (combo & (V3D_MANIP_ROTATE)) dz= 1.0f+2.0f*cylen; - else if (combo & (V3D_MANIP_SCALE)) dz= 1.0f+0.5f*cylen; - else dz= 1.0f; + if (combo & (V3D_MANIP_ROTATE)) dz = 1.0f + 2.0f * cylen; + else if (combo & (V3D_MANIP_SCALE)) dz = 1.0f + 0.5f * cylen; + else dz = 1.0f; /* Z Cone */ glTranslatef(0.0, 0.0, dz); @@ -1357,35 +1358,35 @@ static void draw_manipulator_rotate_cyl(View3D *v3d, RegionView3D *rv3d, int mov { GLUquadricObj *qobj; float size; - float cylen= 0.01f*(float)U.tw_handlesize; - float cywid= 0.25f*cylen; + float cylen = 0.01f * (float)U.tw_handlesize; + float cywid = 0.25f * cylen; /* when called while moving in mixed mode, do not draw when... */ - if ((drawflags & MAN_ROT_C)==0) return; + if ((drawflags & MAN_ROT_C) == 0) return; /* prepare for screen aligned draw */ glPushMatrix(); - size= screen_aligned(rv3d, rv3d->twmat); + size = screen_aligned(rv3d, rv3d->twmat); glDisable(GL_DEPTH_TEST); - qobj= gluNewQuadric(); + qobj = gluNewQuadric(); /* Screen aligned view rot circle */ if (drawflags & MAN_ROT_V) { - float unitmat[4][4]= MAT4_UNITY; + float unitmat[4][4] = MAT4_UNITY; if (G.f & G_PICKSEL) glLoadName(MAN_ROT_V); UI_ThemeColor(TH_TRANSFORM); - drawcircball(GL_LINE_LOOP, unitmat[3], 1.2f*size, unitmat); + drawcircball(GL_LINE_LOOP, unitmat[3], 1.2f * size, unitmat); if (moving) { float vec[3]; - vec[0]= 0; // XXX (float)(t->imval[0] - t->center2d[0]); - vec[1]= 0; // XXX (float)(t->imval[1] - t->center2d[1]); - vec[2]= 0.0f; + vec[0] = 0; // XXX (float)(t->imval[0] - t->center2d[0]); + vec[1] = 0; // XXX (float)(t->imval[1] - t->center2d[1]); + vec[2] = 0.0f; normalize_v3(vec); - mul_v3_fl(vec, 1.2f*size); + mul_v3_fl(vec, 1.2f * size); glBegin(GL_LINES); glVertex3f(0.0, 0.0, 0.0); glVertex3fv(vec); @@ -1398,8 +1399,8 @@ static void draw_manipulator_rotate_cyl(View3D *v3d, RegionView3D *rv3d, int mov if (moving) { float matt[4][4]; copy_m4_m4(matt, rv3d->twmat); // to copy the parts outside of [3][3] - // XXX if (t->flag & T_USES_MANIPULATOR) { - // XXX mul_m4_m3m4(matt, t->mat, rv3d->twmat); + // XXX if (t->flag & T_USES_MANIPULATOR) { + // XXX mul_m4_m3m4(matt, t->mat, rv3d->twmat); // XXX } glMultMatrixf(matt); } @@ -1407,13 +1408,13 @@ static void draw_manipulator_rotate_cyl(View3D *v3d, RegionView3D *rv3d, int mov glMultMatrixf(rv3d->twmat); } - glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW:GL_CCW); + glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW : GL_CCW); /* axis */ - if ( (G.f & G_PICKSEL)==0 ) { + if ((G.f & G_PICKSEL) == 0) { // only draw axis when combo didn't draw scale axes - if ((combo & V3D_MANIP_SCALE)==0) + if ((combo & V3D_MANIP_SCALE) == 0) draw_manipulator_axes(v3d, rv3d, colcode, drawflags & MAN_ROT_X, drawflags & MAN_ROT_Y, drawflags & MAN_ROT_Z); /* only has to be set when not in picking */ @@ -1459,15 +1460,15 @@ static void draw_manipulator_rotate_cyl(View3D *v3d, RegionView3D *rv3d, int mov /* main call, does calc centers & orientation too */ /* uses global G.moving */ -static int drawflags= 0xFFFF; // only for the calls below, belongs in scene...? +static int drawflags = 0xFFFF; // only for the calls below, belongs in scene...? void BIF_draw_manipulator(const bContext *C) { - ScrArea *sa= CTX_wm_area(C); - ARegion *ar= CTX_wm_region(C); - Scene *scene= CTX_data_scene(C); - View3D *v3d= sa->spacedata.first; - RegionView3D *rv3d= ar->regiondata; + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + View3D *v3d = sa->spacedata.first; + RegionView3D *rv3d = ar->regiondata; int totsel; if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return; @@ -1477,38 +1478,38 @@ void BIF_draw_manipulator(const bContext *C) { v3d->twflag &= ~V3D_DRAW_MANIPULATOR; - totsel= calc_manipulator_stats(C); - if (totsel==0) return; + totsel = calc_manipulator_stats(C); + if (totsel == 0) return; v3d->twflag |= V3D_DRAW_MANIPULATOR; /* now we can define center */ switch (v3d->around) { - case V3D_CENTER: - case V3D_ACTIVE: - rv3d->twmat[3][0]= (scene->twmin[0] + scene->twmax[0])/2.0f; - rv3d->twmat[3][1]= (scene->twmin[1] + scene->twmax[1])/2.0f; - rv3d->twmat[3][2]= (scene->twmin[2] + scene->twmax[2])/2.0f; - if (v3d->around==V3D_ACTIVE && scene->obedit==NULL) { - Object *ob= OBACT; - if (ob && !(ob->mode & OB_MODE_POSE)) - copy_v3_v3(rv3d->twmat[3], ob->obmat[3]); - } - break; - case V3D_LOCAL: - case V3D_CENTROID: - copy_v3_v3(rv3d->twmat[3], scene->twcent); - break; - case V3D_CURSOR: - copy_v3_v3(rv3d->twmat[3], give_cursor(scene, v3d)); - break; + case V3D_CENTER: + case V3D_ACTIVE: + rv3d->twmat[3][0] = (scene->twmin[0] + scene->twmax[0]) / 2.0f; + rv3d->twmat[3][1] = (scene->twmin[1] + scene->twmax[1]) / 2.0f; + rv3d->twmat[3][2] = (scene->twmin[2] + scene->twmax[2]) / 2.0f; + if (v3d->around == V3D_ACTIVE && scene->obedit == NULL) { + Object *ob = OBACT; + if (ob && !(ob->mode & OB_MODE_POSE)) + copy_v3_v3(rv3d->twmat[3], ob->obmat[3]); + } + break; + case V3D_LOCAL: + case V3D_CENTROID: + copy_v3_v3(rv3d->twmat[3], scene->twcent); + break; + case V3D_CURSOR: + copy_v3_v3(rv3d->twmat[3], give_cursor(scene, v3d)); + break; } mul_mat3_m4_fl(rv3d->twmat, ED_view3d_pixel_size(rv3d, rv3d->twmat[3]) * U.tw_size * 5.0f); } test_manipulator_axis(C); - drawflags= rv3d->twdrawflag; /* set in calc_manipulator_stats */ + drawflags = rv3d->twdrawflag; /* set in calc_manipulator_stats */ if (v3d->twflag & V3D_DRAW_MANIPULATOR) { @@ -1516,7 +1517,7 @@ void BIF_draw_manipulator(const bContext *C) glEnable(GL_BLEND); if (v3d->twtype & V3D_MANIP_ROTATE) { - if (G.rt==3) { + if (G.rt == 3) { if (G.moving) draw_manipulator_rotate_cyl(v3d, rv3d, 1, drawflags, v3d->twtype, MAN_MOVECOL); else draw_manipulator_rotate_cyl(v3d, rv3d, 0, drawflags, v3d->twtype, MAN_RGB); } @@ -1536,31 +1537,31 @@ void BIF_draw_manipulator(const bContext *C) static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], float hotspot) { - View3D *v3d= sa->spacedata.first; - RegionView3D *rv3d= ar->regiondata; + View3D *v3d = sa->spacedata.first; + RegionView3D *rv3d = ar->regiondata; rctf rect; - GLuint buffer[64]; // max 4 items per select, so large enuf + GLuint buffer[64]; // max 4 items per select, so large enuf short hits; extern void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); // XXX check a bit later on this... (ton) G.f |= G_PICKSEL; - rect.xmin = mval[0]-hotspot; - rect.xmax = mval[0]+hotspot; - rect.ymin = mval[1]-hotspot; - rect.ymax = mval[1]+hotspot; + rect.xmin = mval[0] - hotspot; + rect.xmax = mval[0] + hotspot; + rect.ymin = mval[1] - hotspot; + rect.ymax = mval[1] + hotspot; setwinmatrixview3d(ar, v3d, &rect); mult_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat); glSelectBuffer(64, buffer); glRenderMode(GL_SELECT); - glInitNames(); /* these two calls whatfor? It doesnt work otherwise */ + glInitNames(); /* these two calls whatfor? It doesnt work otherwise */ glPushName(-2); /* do the drawing */ if (v3d->twtype & V3D_MANIP_ROTATE) { - if (G.rt==3) draw_manipulator_rotate_cyl(v3d, rv3d, 0, MAN_ROT_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB); + if (G.rt == 3) draw_manipulator_rotate_cyl(v3d, rv3d, 0, MAN_ROT_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB); else draw_manipulator_rotate(v3d, rv3d, 0, MAN_ROT_C & rv3d->twdrawflag, v3d->twtype); } if (v3d->twtype & V3D_MANIP_SCALE) @@ -1569,37 +1570,37 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl draw_manipulator_translate(v3d, rv3d, 0, MAN_TRANS_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB); glPopName(); - hits= glRenderMode(GL_RENDER); + hits = glRenderMode(GL_RENDER); G.f &= ~G_PICKSEL; setwinmatrixview3d(ar, v3d, NULL); mult_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat); - if (hits==1) return buffer[3]; - else if (hits>1) { - GLuint val, dep, mindep=0, mindeprot=0, minval=0, minvalrot=0; + if (hits == 1) return buffer[3]; + else if (hits > 1) { + GLuint val, dep, mindep = 0, mindeprot = 0, minval = 0, minvalrot = 0; int a; /* we compare the hits in buffer, but value centers highest */ /* we also store the rotation hits separate (because of arcs) and return hits on other widgets if there are */ - for (a=0; aspacedata.first; - ARegion *ar= CTX_wm_region(C); + ScrArea *sa = CTX_wm_area(C); + View3D *v3d = sa->spacedata.first; + ARegion *ar = CTX_wm_region(C); int constraint_axis[3] = {0, 0, 0}; int val; int shift = event->shift; @@ -1631,41 +1632,41 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op) RNA_enum_set(op->ptr, "constraint_orientation", v3d->twmode); // find the hotspots first test narrow hotspot - val= manipulator_selectbuf(sa, ar, event->mval, 0.5f*(float)U.tw_hotspot); + val = manipulator_selectbuf(sa, ar, event->mval, 0.5f * (float)U.tw_hotspot); if (val) { // drawflags still global, for drawing call above - drawflags= manipulator_selectbuf(sa, ar, event->mval, 0.2f*(float)U.tw_hotspot); - if (drawflags==0) drawflags= val; + drawflags = manipulator_selectbuf(sa, ar, event->mval, 0.2f * (float)U.tw_hotspot); + if (drawflags == 0) drawflags = val; if (drawflags & MAN_TRANS_C) { switch (drawflags) { - case MAN_TRANS_C: - break; - case MAN_TRANS_X: - if (shift) { - constraint_axis[1] = 1; - constraint_axis[2] = 1; - } - else - constraint_axis[0] = 1; - break; - case MAN_TRANS_Y: - if (shift) { - constraint_axis[0] = 1; - constraint_axis[2] = 1; - } - else - constraint_axis[1] = 1; - break; - case MAN_TRANS_Z: - if (shift) { - constraint_axis[0] = 1; - constraint_axis[1] = 1; - } - else - constraint_axis[2] = 1; - break; + case MAN_TRANS_C: + break; + case MAN_TRANS_X: + if (shift) { + constraint_axis[1] = 1; + constraint_axis[2] = 1; + } + else + constraint_axis[0] = 1; + break; + case MAN_TRANS_Y: + if (shift) { + constraint_axis[0] = 1; + constraint_axis[2] = 1; + } + else + constraint_axis[1] = 1; + break; + case MAN_TRANS_Z: + if (shift) { + constraint_axis[0] = 1; + constraint_axis[1] = 1; + } + else + constraint_axis[2] = 1; + break; } RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); WM_operator_name_call(C, "TRANSFORM_OT_translate", WM_OP_INVOKE_DEFAULT, op->ptr); @@ -1673,30 +1674,30 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op) } else if (drawflags & MAN_SCALE_C) { switch (drawflags) { - case MAN_SCALE_X: - if (shift) { - constraint_axis[1] = 1; - constraint_axis[2] = 1; - } - else - constraint_axis[0] = 1; - break; - case MAN_SCALE_Y: - if (shift) { - constraint_axis[0] = 1; - constraint_axis[2] = 1; - } - else - constraint_axis[1] = 1; - break; - case MAN_SCALE_Z: - if (shift) { - constraint_axis[0] = 1; - constraint_axis[1] = 1; - } - else - constraint_axis[2] = 1; - break; + case MAN_SCALE_X: + if (shift) { + constraint_axis[1] = 1; + constraint_axis[2] = 1; + } + else + constraint_axis[0] = 1; + break; + case MAN_SCALE_Y: + if (shift) { + constraint_axis[0] = 1; + constraint_axis[2] = 1; + } + else + constraint_axis[1] = 1; + break; + case MAN_SCALE_Z: + if (shift) { + constraint_axis[0] = 1; + constraint_axis[1] = 1; + } + else + constraint_axis[2] = 1; + break; } RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); WM_operator_name_call(C, "TRANSFORM_OT_resize", WM_OP_INVOKE_DEFAULT, op->ptr); @@ -1708,15 +1709,15 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op) } else if (drawflags & MAN_ROT_C) { switch (drawflags) { - case MAN_ROT_X: - constraint_axis[0] = 1; - break; - case MAN_ROT_Y: - constraint_axis[1] = 1; - break; - case MAN_ROT_Z: - constraint_axis[2] = 1; - break; + case MAN_ROT_X: + constraint_axis[0] = 1; + break; + case MAN_ROT_Y: + constraint_axis[1] = 1; + break; + case MAN_ROT_Z: + constraint_axis[2] = 1; + break; } RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); WM_operator_name_call(C, "TRANSFORM_OT_rotate", WM_OP_INVOKE_DEFAULT, op->ptr); @@ -1724,7 +1725,7 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op) } } /* after transform, restore drawflags */ - drawflags= 0xFFFF; + drawflags = 0xFFFF; return val; } diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 91f62291450..97fc173f9a1 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -75,16 +75,16 @@ void BIF_clearTransformOrientation(bContext *C) // Need to loop over all view3d if (v3d && v3d->twmode >= V3D_MANIP_CUSTOM) { - v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ + v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ } } -static TransformOrientation* findOrientationName(ListBase *lb, const char *name) +static TransformOrientation *findOrientationName(ListBase *lb, const char *name) { - TransformOrientation *ts= NULL; + TransformOrientation *ts = NULL; - for (ts= lb->first; ts; ts = ts->next) { - if (strncmp(ts->name, name, sizeof(ts->name)-1) == 0) { + for (ts = lb->first; ts; ts = ts->next) { + if (strncmp(ts->name, name, sizeof(ts->name) - 1) == 0) { return ts; } } @@ -115,7 +115,7 @@ void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name ts = createBoneSpace(C, reports, name, overwrite); } else if (ob && (ob->mode & OB_MODE_POSE)) { - ts = createBoneSpace(C, reports, name, overwrite); + ts = createBoneSpace(C, reports, name, overwrite); } else { ts = createObjectSpace(C, reports, name, overwrite); @@ -143,7 +143,7 @@ TransformOrientation *createObjectSpace(bContext *C, ReportList *UNUSED(reports) /* use object name if no name is given */ if (name[0] == 0) { - strncpy(name, ob->id.name+2, MAX_ID_NAME-2); + strncpy(name, ob->id.name + 2, MAX_ID_NAME - 2); } return addMatrixSpace(C, mat, name, overwrite); @@ -262,7 +262,7 @@ int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]) return 1; } -TransformOrientation* addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite) +TransformOrientation *addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite) { ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts = NULL; @@ -301,7 +301,7 @@ void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target) // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D if (selected_index == i) { - v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ + v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ } else if (selected_index > i) { v3d->twmode--; @@ -318,7 +318,7 @@ void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target) void BIF_removeTransformOrientationIndex(bContext *C, int index) { ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; - TransformOrientation *ts= BLI_findlink(transform_spaces, index); + TransformOrientation *ts = BLI_findlink(transform_spaces, index); if (ts) { View3D *v3d = CTX_wm_view3d(C); @@ -327,7 +327,7 @@ void BIF_removeTransformOrientationIndex(bContext *C, int index) // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D if (selected_index == index) { - v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ + v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ } else if (selected_index > index) { v3d->twmode--; @@ -365,15 +365,15 @@ EnumPropertyItem *BIF_enumTransformOrientation(bContext *C) { Scene *scene; ListBase *transform_spaces; - TransformOrientation *ts= NULL; + TransformOrientation *ts = NULL; - EnumPropertyItem global = {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""}; + EnumPropertyItem global = {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""}; EnumPropertyItem normal = {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""}; EnumPropertyItem local = {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""}; EnumPropertyItem view = {V3D_MANIP_VIEW, "VIEW", 0, "View", ""}; EnumPropertyItem tmp = {0, "", 0, "", ""}; - EnumPropertyItem *item= NULL; - int i = V3D_MANIP_CUSTOM, totitem= 0; + EnumPropertyItem *item = NULL; + int i = V3D_MANIP_CUSTOM, totitem = 0; RNA_enum_item_add(&item, &totitem, &global); RNA_enum_item_add(&item, &totitem, &normal); @@ -381,7 +381,7 @@ EnumPropertyItem *BIF_enumTransformOrientation(bContext *C) RNA_enum_item_add(&item, &totitem, &view); if (C) { - scene= CTX_data_scene(C); + scene = CTX_data_scene(C); if (scene) { transform_spaces = &scene->transform_spaces; @@ -394,7 +394,7 @@ EnumPropertyItem *BIF_enumTransformOrientation(bContext *C) for (; ts; ts = ts->next) { tmp.identifier = "CUSTOM"; - tmp.name= ts->name; + tmp.name = ts->name; tmp.value = i++; RNA_enum_item_add(&item, &totitem, &tmp); } @@ -404,9 +404,9 @@ EnumPropertyItem *BIF_enumTransformOrientation(bContext *C) return item; } -const char * BIF_menustringTransformOrientation(const bContext *C, const char *title) +const char *BIF_menustringTransformOrientation(const bContext *C, const char *title) { - const char* menu = IFACE_("%t|Global%x0|Local%x1|Gimbal%x4|Normal%x2|View%x3"); + const char *menu = IFACE_("%t|Global%x0|Local%x1|Gimbal%x4|Normal%x2|View%x3"); ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts; int i = V3D_MANIP_CUSTOM; @@ -459,7 +459,7 @@ void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) break; } } - } + } } static int count_bone_select(bArmature *arm, ListBase *lb, int do_it) @@ -468,7 +468,7 @@ static int count_bone_select(bArmature *arm, ListBase *lb, int do_it) int do_next; int total = 0; - for (bone= lb->first; bone; bone= bone->next) { + for (bone = lb->first; bone; bone = bone->next) { bone->flag &= ~BONE_TRANSFORM; do_next = do_it; if (do_it) { @@ -476,7 +476,7 @@ static int count_bone_select(bArmature *arm, ListBase *lb, int do_it) if (bone->flag & BONE_SELECTED) { bone->flag |= BONE_TRANSFORM; total++; - do_next = FALSE; // no transform on children if one parent bone is selected + do_next = FALSE; // no transform on children if one parent bone is selected } } } @@ -493,55 +493,55 @@ void initTransformOrientation(bContext *C, TransInfo *t) Object *obedit = CTX_data_active_object(C); switch (t->current_orientation) { - case V3D_MANIP_GLOBAL: - unit_m3(t->spacemtx); - strcpy(t->spacename, "global"); - break; - - case V3D_MANIP_GIMBAL: - unit_m3(t->spacemtx); - if (gimbal_axis(ob, t->spacemtx)) { - strcpy(t->spacename, "gimbal"); + case V3D_MANIP_GLOBAL: + unit_m3(t->spacemtx); + strcpy(t->spacename, "global"); break; - } + + case V3D_MANIP_GIMBAL: + unit_m3(t->spacemtx); + if (gimbal_axis(ob, t->spacemtx)) { + strcpy(t->spacename, "gimbal"); + break; + } /* no gimbal fallthrough to normal */ - case V3D_MANIP_NORMAL: - if (obedit || (ob && ob->mode & OB_MODE_POSE)) { - strcpy(t->spacename, "normal"); - ED_getTransformOrientationMatrix(C, t->spacemtx, (v3d->around == V3D_ACTIVE)); - break; - } + case V3D_MANIP_NORMAL: + if (obedit || (ob && ob->mode & OB_MODE_POSE)) { + strcpy(t->spacename, "normal"); + ED_getTransformOrientationMatrix(C, t->spacemtx, (v3d->around == V3D_ACTIVE)); + break; + } /* no break we define 'normal' as 'local' in Object mode */ - case V3D_MANIP_LOCAL: - strcpy(t->spacename, "local"); + case V3D_MANIP_LOCAL: + strcpy(t->spacename, "local"); - if (ob) { - copy_m3_m4(t->spacemtx, ob->obmat); - normalize_m3(t->spacemtx); - } - else { - unit_m3(t->spacemtx); - } + if (ob) { + copy_m3_m4(t->spacemtx, ob->obmat); + normalize_m3(t->spacemtx); + } + else { + unit_m3(t->spacemtx); + } - break; + break; - case V3D_MANIP_VIEW: - if (t->ar->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = t->ar->regiondata; - float mat[3][3]; + case V3D_MANIP_VIEW: + if (t->ar->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d = t->ar->regiondata; + float mat[3][3]; - strcpy(t->spacename, "view"); - copy_m3_m4(mat, rv3d->viewinv); - normalize_m3(mat); - copy_m3_m3(t->spacemtx, mat); - } - else { - unit_m3(t->spacemtx); - } - break; - default: /* V3D_MANIP_CUSTOM */ - applyTransformOrientation(C, t->spacemtx, t->spacename); - break; + strcpy(t->spacename, "view"); + copy_m3_m4(mat, rv3d->viewinv); + normalize_m3(mat); + copy_m3_m3(t->spacemtx, mat); + } + else { + unit_m3(t->spacemtx); + } + break; + default: /* V3D_MANIP_CUSTOM */ + applyTransformOrientation(C, t->spacemtx, t->spacename); + break; } } @@ -549,7 +549,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); - Object *obedit= CTX_data_edit_object(C); + Object *obedit = CTX_data_edit_object(C); Base *base; Object *ob = OBACT; int result = ORIENTATION_NONE; @@ -566,14 +566,14 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], invert_m3_m3(mat, imat); transpose_m3(mat); - ob= obedit; + ob = obedit; - if (ob->type==OB_MESH) { - Mesh *me= ob->data; + if (ob->type == OB_MESH) { + Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; BMVert *eve; BMEditSelection ese; - float vec[3]= {0, 0, 0}; + float vec[3] = {0, 0, 0}; /* USE LAST SELECTED WITH ACTIVE */ if (activeOnly && BM_select_history_active_get(em->bm, &ese)) { @@ -711,17 +711,17 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], } } /* end editmesh */ else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { - Curve *cu= obedit->data; + Curve *cu = obedit->data; Nurb *nu; BezTriple *bezt; int a; - ListBase *nurbs= BKE_curve_editNurbs_get(cu); + ListBase *nurbs = BKE_curve_editNurbs_get(cu); for (nu = nurbs->first; nu; nu = nu->next) { /* only bezier has a normal */ if (nu->type == CU_BEZIER) { - bezt= nu->bezt; - a= nu->pntsu; + bezt = nu->bezt; + a = nu->pntsu; while (a--) { /* exception */ if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) { @@ -747,7 +747,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], result = ORIENTATION_NORMAL; } } - else if (obedit->type==OB_MBALL) { + else if (obedit->type == OB_MBALL) { #if 0 // XXX /* editmball.c */ MetaElem *ml, *ml_sel = NULL; @@ -784,7 +784,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], bArmature *arm = obedit->data; EditBone *ebone; - for (ebone = arm->edbo->first; ebone; ebone=ebone->next) { + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (arm->layer & ebone->layer) { if (ebone->flag & BONE_SELECTED) { float tmat[3][3]; @@ -819,7 +819,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], } } else if (ob && (ob->mode & OB_MODE_POSE)) { - bArmature *arm= ob->data; + bArmature *arm = ob->data; bPoseChannel *pchan; int totsel; @@ -828,7 +828,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], float imat[3][3], mat[3][3]; /* use channels to get stats */ - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) { add_v3_v3(normal, pchan->pose_mat[2]); add_v3_v3(plane, pchan->pose_mat[1]); @@ -847,7 +847,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], result = ORIENTATION_EDGE; } } - else if (ob && (ob->mode & (OB_MODE_ALL_PAINT|OB_MODE_PARTICLE_EDIT))) { + else if (ob && (ob->mode & (OB_MODE_ALL_PAINT | OB_MODE_PARTICLE_EDIT))) { /* pass */ } else { @@ -855,10 +855,10 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], ob = OBACT; if (ob && !(ob->flag & SELECT)) ob = NULL; - for (base= scene->base.first; base; base= base->next) { + for (base = scene->base.first; base; base = base->next) { if (TESTBASELIB(v3d, base)) { if (ob == NULL) { - ob= base->object; + ob = base->object; break; } } @@ -876,8 +876,8 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[][3], int activeOnly) { - float normal[3]={0.0, 0.0, 0.0}; - float plane[3]={0.0, 0.0, 0.0}; + float normal[3] = {0.0, 0.0, 0.0}; + float plane[3] = {0.0, 0.0, 0.0}; int type; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index a04ce1ca213..9ebd43cd0d1 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -129,13 +129,13 @@ int BIF_snappingSupported(Object *obedit) int validSnap(TransInfo *t) { - return (t->tsnap.status & (POINT_INIT|TARGET_INIT)) == (POINT_INIT|TARGET_INIT) || - (t->tsnap.status & (MULTI_POINTS|TARGET_INIT)) == (MULTI_POINTS|TARGET_INIT); + return (t->tsnap.status & (POINT_INIT | TARGET_INIT)) == (POINT_INIT | TARGET_INIT) || + (t->tsnap.status & (MULTI_POINTS | TARGET_INIT)) == (MULTI_POINTS | TARGET_INIT); } int activeSnap(TransInfo *t) { - return (t->modifiers & (MOD_SNAP|MOD_SNAP_INVERT)) == MOD_SNAP || (t->modifiers & (MOD_SNAP|MOD_SNAP_INVERT)) == MOD_SNAP_INVERT; + return (t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP || (t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP_INVERT; } void drawSnapping(const struct bContext *C, TransInfo *t) @@ -144,13 +144,13 @@ void drawSnapping(const struct bContext *C, TransInfo *t) unsigned char col[4], selectedCol[4], activeCol[4]; UI_GetThemeColor3ubv(TH_TRANSFORM, col); - col[3]= 128; + col[3] = 128; UI_GetThemeColor3ubv(TH_SELECT, selectedCol); - selectedCol[3]= 128; + selectedCol[3] = 128; UI_GetThemeColor3ubv(TH_ACTIVE, activeCol); - activeCol[3]= 192; + activeCol[3] = 192; if (t->spacetype == SPACE_VIEW3D) { TransSnapPoint *p; @@ -187,31 +187,31 @@ void drawSnapping(const struct bContext *C, TransInfo *t) glColor4ubv(activeCol); glBegin(GL_LINES); - glVertex3f(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]); - glVertex3f(t->tsnap.snapPoint[0] + t->tsnap.snapNormal[0], - t->tsnap.snapPoint[1] + t->tsnap.snapNormal[1], - t->tsnap.snapPoint[2] + t->tsnap.snapNormal[2]); - glEnd(); + glVertex3f(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]); + glVertex3f(t->tsnap.snapPoint[0] + t->tsnap.snapNormal[0], + t->tsnap.snapPoint[1] + t->tsnap.snapNormal[1], + t->tsnap.snapPoint[2] + t->tsnap.snapNormal[2]); + glEnd(); } if (v3d->zbuf) glEnable(GL_DEPTH_TEST); } - else if (t->spacetype==SPACE_IMAGE) { + else if (t->spacetype == SPACE_IMAGE) { /* This will not draw, and Im nor sure why - campbell */ #if 0 float xuser_asp, yuser_asp; int wi, hi; float w, h; - calc_image_view(G.sima, 'f'); // float + calc_image_view(G.sima, 'f'); // float myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); glLoadIdentity(); ED_space_image_aspect(t->sa->spacedata.first, &xuser_aspx, &yuser_asp); ED_space_image_width(t->sa->spacedata.first, &wi, &hi); - w = (((float)wi)/256.0f)*G.sima->zoom * xuser_asp; - h = (((float)hi)/256.0f)*G.sima->zoom * yuser_asp; + w = (((float)wi) / 256.0f) * G.sima->zoom * xuser_asp; + h = (((float)hi) / 256.0f) * G.sima->zoom * yuser_asp; cpack(0xFFFFFF); glTranslatef(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], 0.0f); @@ -220,10 +220,10 @@ void drawSnapping(const struct bContext *C, TransInfo *t) setlinestyle(0); cpack(0x0); - fdrawline(-0.020/w, 0, -0.1/w, 0); - fdrawline(0.1/w, 0, .020/w, 0); - fdrawline(0, -0.020/h, 0, -0.1/h); - fdrawline(0, 0.1/h, 0, 0.020/h); + fdrawline(-0.020 / w, 0, -0.1 / w, 0); + fdrawline(0.1 / w, 0, .020 / w, 0); + fdrawline(0, -0.020 / h, 0, -0.1 / h); + fdrawline(0, 0.1 / h, 0, 0.020 / h); glTranslatef(-t->tsnap.snapPoint[0], -t->tsnap.snapPoint[1], 0.0f); setlinestyle(0); @@ -261,12 +261,12 @@ void applyProject(TransInfo *t) float imat[4][4]; int i; - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob = t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; invert_m4_m4(imat, ob->obmat); } - for (i = 0 ; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { float iloc[3], loc[3], no[3]; float mval[2]; int dist = 1000; @@ -278,12 +278,12 @@ void applyProject(TransInfo *t) continue; copy_v3_v3(iloc, td->loc); - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob = t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; mul_m4_v3(ob->obmat, iloc); } else if (t->flag & T_OBJECT) { - td->ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; + td->ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; BKE_object_handle_update(t->scene, td->ob); copy_v3_v3(iloc, td->ob->obmat[3]); } @@ -387,7 +387,7 @@ static void initSnappingMode(TransInfo *t) /* Edit mode */ if (t->tsnap.applySnap != NULL && // A snapping function actually exist - (obedit != NULL && ELEM4(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE)) ) // Temporary limited to edit mode meshes, armature, curves + (obedit != NULL && ELEM4(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE)) ) // Temporary limited to edit mode meshes, armature, curves { /* Exclude editmesh if using proportional edit */ if ((obedit->type == OB_MESH) && (t->flag & T_PROP_EDIT)) { @@ -399,13 +399,13 @@ static void initSnappingMode(TransInfo *t) } /* Particles edit mode*/ else if (t->tsnap.applySnap != NULL && // A snapping function actually exist - (obedit == NULL && BASACT && BASACT->object && BASACT->object->mode & OB_MODE_PARTICLE_EDIT )) + (obedit == NULL && BASACT && BASACT->object && BASACT->object->mode & OB_MODE_PARTICLE_EDIT)) { t->tsnap.modeSelect = SNAP_ALL; } /* Object mode */ else if (t->tsnap.applySnap != NULL && // A snapping function actually exist - (obedit == NULL) ) // Object Mode + (obedit == NULL) ) // Object Mode { t->tsnap.modeSelect = SNAP_NOT_SELECTED; } @@ -438,7 +438,7 @@ void initSnapping(TransInfo *t, wmOperator *op) if (RNA_struct_property_is_set(op->ptr, "snap_point")) { RNA_float_get_array(op->ptr, "snap_point", t->tsnap.snapPoint); - t->tsnap.status |= SNAP_FORCED|POINT_INIT; + t->tsnap.status |= SNAP_FORCED | POINT_INIT; } /* snap align only defined in specific cases */ @@ -497,33 +497,33 @@ static void setSnappingCallback(TransInfo *t) } switch (t->mode) { - case TFM_TRANSLATION: - t->tsnap.applySnap = ApplySnapTranslation; - t->tsnap.distance = TranslationBetween; - break; - case TFM_ROTATION: - t->tsnap.applySnap = ApplySnapRotation; - t->tsnap.distance = RotationBetween; - - // Can't do TARGET_CENTER with rotation, use TARGET_MEDIAN instead - if (t->tsnap.target == SCE_SNAP_TARGET_CENTER) { - t->tsnap.target = SCE_SNAP_TARGET_MEDIAN; - t->tsnap.targetSnap = TargetSnapMedian; - } - break; - case TFM_RESIZE: - t->tsnap.applySnap = ApplySnapResize; - t->tsnap.distance = ResizeBetween; - - // Can't do TARGET_CENTER with resize, use TARGET_MEDIAN instead - if (t->tsnap.target == SCE_SNAP_TARGET_CENTER) { - t->tsnap.target = SCE_SNAP_TARGET_MEDIAN; - t->tsnap.targetSnap = TargetSnapMedian; - } - break; - default: - t->tsnap.applySnap = NULL; - break; + case TFM_TRANSLATION: + t->tsnap.applySnap = ApplySnapTranslation; + t->tsnap.distance = TranslationBetween; + break; + case TFM_ROTATION: + t->tsnap.applySnap = ApplySnapRotation; + t->tsnap.distance = RotationBetween; + + // Can't do TARGET_CENTER with rotation, use TARGET_MEDIAN instead + if (t->tsnap.target == SCE_SNAP_TARGET_CENTER) { + t->tsnap.target = SCE_SNAP_TARGET_MEDIAN; + t->tsnap.targetSnap = TargetSnapMedian; + } + break; + case TFM_RESIZE: + t->tsnap.applySnap = ApplySnapResize; + t->tsnap.distance = ResizeBetween; + + // Can't do TARGET_CENTER with resize, use TARGET_MEDIAN instead + if (t->tsnap.target == SCE_SNAP_TARGET_CENTER) { + t->tsnap.target = SCE_SNAP_TARGET_MEDIAN; + t->tsnap.targetSnap = TargetSnapMedian; + } + break; + default: + t->tsnap.applySnap = NULL; + break; } } @@ -550,7 +550,7 @@ int updateSelectedSnapPoint(TransInfo *t) int closest_dist = 0; int screen_loc[2]; - for ( p = t->tsnap.points.first; p; p = p->next ) { + for (p = t->tsnap.points.first; p; p = p->next) { int dx, dy; int dist; @@ -663,8 +663,8 @@ static float RotationBetween(TransInfo *t, float p1[3], float p2[3]) float angle, start[3], end[3], center[3]; copy_v3_v3(center, t->center); - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob= t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; mul_m4_v3(ob->obmat, center); } @@ -719,8 +719,8 @@ static float ResizeBetween(TransInfo *t, float p1[3], float p2[3]) float d1[3], d2[3], center[3], len_d1; copy_v3_v3(center, t->center); - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob= t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; mul_m4_v3(ob->obmat, center); } @@ -739,7 +739,7 @@ static float ResizeBetween(TransInfo *t, float p1[3], float p2[3]) /********************** CALC **************************/ -static void UNUSED_FUNCTION(CalcSnapGrid)(TransInfo *t, float *UNUSED(vec)) +static void UNUSED_FUNCTION(CalcSnapGrid) (TransInfo * t, float *UNUSED(vec)) { snapGridAction(t, t->tsnap.snapPoint, BIG_GEARS); } @@ -830,9 +830,9 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) if (max_dist != FLT_MAX) { copy_v3_v3(loc, p); /* XXX, is there a correct normal in this case ???, for now just z up */ - no[0]= 0.0; - no[1]= 0.0; - no[2]= 1.0; + no[0] = 0.0; + no[1] = 0.0; + no[2] = 1.0; found = 1; } @@ -861,12 +861,12 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) t->tsnap.status &= ~POINT_INIT; } } - else if (t->spacetype == SPACE_IMAGE && t->obedit != NULL && t->obedit->type==OB_MESH) { + else if (t->spacetype == SPACE_IMAGE && t->obedit != NULL && t->obedit->type == OB_MESH) { /* same as above but for UV's */ - Image *ima= ED_space_image(t->sa->spacedata.first); + Image *ima = ED_space_image(t->sa->spacedata.first); float aspx, aspy, co[2]; - UI_view2d_region_to_view(&t->ar->v2d, t->mval[0], t->mval[1], co, co+1); + UI_view2d_region_to_view(&t->ar->v2d, t->mval[0], t->mval[1], co, co + 1); if (ED_uvedit_nearest_uv(t->scene, t->obedit, ima, co, t->tsnap.snapPoint)) { ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); @@ -888,8 +888,8 @@ static void TargetSnapCenter(TransInfo *t) /* Only need to calculate once */ if ((t->tsnap.status & TARGET_INIT) == 0) { copy_v3_v3(t->tsnap.snapTarget, t->center); - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob= t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; mul_m4_v3(ob->obmat, t->tsnap.snapTarget); } @@ -905,7 +905,7 @@ static void TargetSnapActive(TransInfo *t) TransData *active_td = NULL; int i; - for (td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++) { + for (td = t->data, i = 0; i < t->total && td->flag & TD_SELECTED; i++, td++) { if (td->flag & TD_ACTIVE) { active_td = td; break; @@ -915,8 +915,8 @@ static void TargetSnapActive(TransInfo *t) if (active_td) { copy_v3_v3(t->tsnap.snapTarget, active_td->center); - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob= t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; mul_m4_v3(ob->obmat, t->tsnap.snapTarget); } @@ -942,14 +942,14 @@ static void TargetSnapMedian(TransInfo *t) t->tsnap.snapTarget[1] = 0; t->tsnap.snapTarget[2] = 0; - for (td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++) { + for (td = t->data, i = 0; i < t->total && td->flag & TD_SELECTED; i++, td++) { add_v3_v3(t->tsnap.snapTarget, td->center); } mul_v3_fl(t->tsnap.snapTarget, 1.0 / i); - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob= t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; mul_m4_v3(ob->obmat, t->tsnap.snapTarget); } @@ -966,7 +966,7 @@ static void TargetSnapClosest(TransInfo *t) /* Object mode */ if (t->flag & T_OBJECT) { int i; - for (td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++) { + for (td = t->data, i = 0; i < t->total && td->flag & TD_SELECTED; i++, td++) { struct BoundBox *bb = BKE_object_boundbox_get(td->ob); /* use boundbox if possible */ @@ -1008,14 +1008,14 @@ static void TargetSnapClosest(TransInfo *t) } else { int i; - for (td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++) { + for (td = t->data, i = 0; i < t->total && td->flag & TD_SELECTED; i++, td++) { float loc[3]; float dist; copy_v3_v3(loc, td->center); - if (t->flag & (T_EDIT|T_POSE)) { - Object *ob= t->obedit?t->obedit:t->poseobj; + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; mul_m4_v3(ob->obmat, loc); } @@ -1230,10 +1230,10 @@ static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm if (arm->edbo) { EditBone *eBone; - for (eBone=arm->edbo->first; eBone; eBone=eBone->next) { + for (eBone = arm->edbo->first; eBone; eBone = eBone->next) { if (eBone->layer & arm->layer) { /* skip hidden or moving (selected) bones */ - if ((eBone->flag & (BONE_HIDDEN_A|BONE_ROOTSEL|BONE_TIPSEL))==0) { + if ((eBone->flag & (BONE_HIDDEN_A | BONE_ROOTSEL | BONE_TIPSEL)) == 0) { switch (snap_mode) { case SCE_SNAP_MODE_VERTEX: retval |= snapVertex(ar, eBone->head, NULL, obmat, NULL, ray_start, ray_start_local, ray_normal_local, mval, r_loc, NULL, r_dist, r_depth); @@ -1251,10 +1251,10 @@ static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm bPoseChannel *pchan; Bone *bone; - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - bone= pchan->bone; + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + bone = pchan->bone; /* skip hidden bones */ - if (bone && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) { + if (bone && !(bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { float *head_vec = pchan->pose_head; float *tail_vec = pchan->pose_tail; @@ -1313,22 +1313,22 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh switch (snap_mode) { case SCE_SNAP_MODE_FACE: { -#ifdef USE_BVH_FACE_SNAP // Added for durian +#ifdef USE_BVH_FACE_SNAP // Added for durian BVHTreeRayHit hit; BVHTreeFromMesh treeData; /* local scale in normal direction */ float local_scale = len_v3(ray_normal_local); - treeData.em_evil= em; + treeData.em_evil = em; bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6); hit.index = -1; hit.dist = *r_depth * (*r_depth == FLT_MAX ? 1.0f : local_scale); if (treeData.tree && BLI_bvhtree_ray_cast(treeData.tree, ray_start_local, ray_normal_local, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1) { - if (hit.dist/local_scale <= *r_depth) { - *r_depth= hit.dist/local_scale; + if (hit.dist / local_scale <= *r_depth) { + *r_depth = hit.dist / local_scale; copy_v3_v3(r_loc, hit.co); copy_v3_v3(r_no, hit.no); @@ -1356,7 +1356,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh EDBM_index_arrays_init(em, 0, 0, 1); } - for ( i = 0; i < totface; i++) { + for (i = 0; i < totface; i++) { BMFace *efa = NULL; MFace *f = faces + i; @@ -1384,7 +1384,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh BMLoop *l; l = BM_iter_new(&iter, em->bm, BM_LOOPS_OF_FACE, efa); - for ( ; l; l=BM_iter_step(&iter)) { + for (; l; l = BM_iter_step(&iter)) { if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) { test = 0; break; @@ -1430,7 +1430,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh EDBM_index_arrays_init(em, 1, 0, 0); } - for ( i = 0; i < totvert; i++) { + for (i = 0; i < totvert; i++) { BMVert *eve = NULL; MVert *v = verts + i; @@ -1481,7 +1481,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh EDBM_index_arrays_init(em, 0, 1, 0); } - for ( i = 0; i < totedge; i++) { + for (i = 0; i < totedge; i++) { BMEdge *eed = NULL; MEdge *e = edges + i; @@ -1502,8 +1502,8 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh eed = EDBM_edge_at_index(em, index); if (eed && (BM_elem_flag_test(eed, BM_ELEM_HIDDEN) || - BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || - BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))) + BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || + BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))) { test = 0; } @@ -1531,7 +1531,7 @@ static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, flo const float ray_start[3], const float ray_normal[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { - ToolSettings *ts= scene->toolsettings; + ToolSettings *ts = scene->toolsettings; int retval = 0; if (ob->type == OB_MESH) { @@ -1580,18 +1580,18 @@ static int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, c * * To solve that problem, we do it first as an exception. * */ - base= BASACT; + base = BASACT; if (base && base->object && base->object->mode & OB_MODE_PARTICLE_EDIT) { Object *ob = base->object; retval |= snapObject(scene, ar, ob, 0, ob->obmat, ray_start, ray_normal, mval, r_loc, r_no, r_dist, &depth); } - for ( base = FIRSTBASE; base != NULL; base = base->next ) { - if ( (BASE_VISIBLE(v3d, base)) && - (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && + for (base = FIRSTBASE; base != NULL; base = base->next) { + if ((BASE_VISIBLE(v3d, base)) && + (base->flag & (BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA)) == 0 && - ( (mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || - (ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT) && base != BASACT)) ) + ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT | BA_WAS_SEL)) == 0) || + (ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT) && base != BASACT))) { Object *ob = base->object; @@ -1719,7 +1719,7 @@ static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], MFace *faces = dm->getTessFaceArray(dm); int i; - for ( i = 0; i < totface; i++) { + for (i = 0; i < totface; i++) { MFace *f = faces + i; float lambda; int result; @@ -1837,7 +1837,7 @@ static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, L if (ob->type == OB_MESH) { int val = 0; - if (ob != obedit && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT))) { + if (ob != obedit && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT | BA_WAS_SEL)) == 0) || ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT))) { DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels); @@ -1918,7 +1918,7 @@ static void applyGrid(TransInfo *t, float *val, int max_index, float fac[3], Gea if (max_index > 2) { printf("applyGrid: invalid index %d, clamping\n", max_index); - max_index= 2; + max_index = 2; } // Early bailing out if no need to snap @@ -1926,11 +1926,11 @@ static void applyGrid(TransInfo *t, float *val, int max_index, float fac[3], Gea return; /* evil hack - snapping needs to be adapted for image aspect ratio */ - if ((t->spacetype==SPACE_IMAGE) && (t->mode==TFM_TRANSLATION)) { - ED_space_image_uv_aspect(t->sa->spacedata.first, asp, asp+1); + if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION)) { + ED_space_image_uv_aspect(t->sa->spacedata.first, asp, asp + 1); } - for (i=0; i<=max_index; i++) { - val[i]= fac[action]*asp[i]*(float)floor(val[i]/(fac[action]*asp[i]) +0.5f); + for (i = 0; i <= max_index; i++) { + val[i] = fac[action] * asp[i] * (float)floor(val[i] / (fac[action] * asp[i]) + 0.5f); } } From f305261f14254656c888438205887769ad45b8bd Mon Sep 17 00:00:00 2001 From: Dan Eicher Date: Sun, 10 Jun 2012 22:22:26 +0000 Subject: [PATCH 189/360] OUTLINER_OT_material_drop -- Drag & Drop materials onto objects in the outliner Adds the material at materials + 1 unlike the DnD view3d one which replaces the first one --- .../editors/space_outliner/outliner_edit.c | 67 +++++++++++++++++++ .../editors/space_outliner/outliner_intern.h | 1 + .../editors/space_outliner/outliner_ops.c | 1 + .../editors/space_outliner/space_outliner.c | 30 +++++++++ 4 files changed, 99 insertions(+) diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index e5f7b8fd76d..eb740e441b7 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -35,6 +35,7 @@ #include "DNA_group_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_material_types.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" @@ -48,6 +49,7 @@ #include "BKE_main.h" #include "BKE_report.h" #include "BKE_scene.h" +#include "BKE_material.h" #include "ED_object.h" #include "ED_screen.h" @@ -1816,3 +1818,68 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot) RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); RNA_def_string(ot->srna, "scene", "Scene", MAX_ID_NAME, "Scene", "Target Scene"); } + +static int material_drop_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Main *bmain = CTX_data_main(C); + Material *ma = NULL; + Object *ob = NULL; + SpaceOops *soops = CTX_wm_space_outliner(C); + ARegion *ar = CTX_wm_region(C); + TreeElement *te = NULL; + TreeElement *te_found = NULL; + char mat_name[MAX_ID_NAME - 2]; + float fmval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + /* Find object hovered over */ + for (te = soops->tree.first; te; te = te->next) { + te_found = outliner_dropzone_parent(C, event, te, fmval); + if (te_found) + break; + } + + if (te_found) { + RNA_string_set(op->ptr, "object", te_found->name); + ob = (Object *)BKE_libblock_find_name(ID_OB, te_found->name); + + RNA_string_get(op->ptr, "material", mat_name); + ma = (Material *)BKE_libblock_find_name(ID_MA, mat_name); + + if (ELEM(NULL, ob, ma)) { + return OPERATOR_CANCELLED; + } + + assign_material(ob, ma, ob->totcol + 1); + + DAG_ids_flush_update(bmain, 0); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, ma); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void OUTLINER_OT_material_drop(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Drop Material on Object"; + ot->description = "Drag material to object in Outliner"; + ot->idname = "OUTLINER_OT_material_drop"; + + /* api callbacks */ + ot->invoke = material_drop_invoke; + + ot->poll = ED_operator_outliner_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); + RNA_def_string(ot->srna, "material", "Material", MAX_ID_NAME, "Material", "Target Material"); +} + diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 5274410214a..65de2a27568 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -221,6 +221,7 @@ void OUTLINER_OT_drivers_delete_selected(struct wmOperatorType *ot); void OUTLINER_OT_parent_drop(struct wmOperatorType *ot); void OUTLINER_OT_parent_clear(struct wmOperatorType *ot); void OUTLINER_OT_scene_drop(struct wmOperatorType *ot); +void OUTLINER_OT_material_drop(struct wmOperatorType *ot); /* outliner_tools.c ---------------------------------------------- */ diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 0b3a226cca1..1dd043409a5 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -77,6 +77,7 @@ void outliner_operatortypes(void) WM_operatortype_append(OUTLINER_OT_parent_drop); WM_operatortype_append(OUTLINER_OT_parent_clear); WM_operatortype_append(OUTLINER_OT_scene_drop); + WM_operatortype_append(OUTLINER_OT_material_drop); } void outliner_keymap(wmKeyConfig *keyconf) diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index c78be8bd223..489a4efe891 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -194,6 +194,35 @@ static void outliner_scene_drop_copy(wmDrag *drag, wmDropBox *drop) RNA_string_set(drop->ptr, "object", id->name + 2); } +static int outliner_material_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + TreeElement *te = NULL; + float fmval[2]; + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + if (drag->type == WM_DRAG_ID) { + ID *id = (ID *)drag->poin; + if (GS(id->name) == ID_MA) { + /* Ensure item under cursor is valid drop target */ + /* Find object hovered over */ + for (te = soops->tree.first; te; te = te->next) { + if (outliner_dropzone_parent(C, event, te, fmval)) + return 1; + } + } + } + return 0; +} + +static void outliner_material_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id = (ID *)drag->poin; + + RNA_string_set(drop->ptr, "material", id->name + 2); +} + /* region dropbox definition */ static void outliner_dropboxes(void) { @@ -202,6 +231,7 @@ static void outliner_dropboxes(void) WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", outliner_parent_drop_poll, outliner_parent_drop_copy); WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", outliner_parent_clear_poll, outliner_parent_clear_copy); WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", outliner_scene_drop_poll, outliner_scene_drop_copy); + WM_dropbox_add(lb, "OUTLINER_OT_material_drop", outliner_material_drop_poll, outliner_material_drop_copy); } static void outliner_main_area_draw(const bContext *C, ARegion *ar) From 0df68aacb10a7f947673d925e09a539ee8c4bb9c Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 11 Jun 2012 00:21:50 +0000 Subject: [PATCH 190/360] Grease Pencil - Support for Grease Pencil in the Sequence Editor preview/image space works again This commit restores the support for using Grease Pencil in the Sequence Editor image preview region, making it possible to scribble on footage for review purposes again. Due to internal changes in how the Sequencer handles the image drawing for this stuff (i.e. it is now fully based on View2D instead of trying to implement its own little crazy offset+zoom stuff), a lot of the old code for handling those offsets is no longer needed. Instead, one of the "standard" cases is now used, and works quite well. Bugfixes: * View-space Grease Pencil drawing was done in wrong place (before view2d restore) * Grease Pencil entry in RNA had wrong/missing type Credits: * DingTo - initial patch/attempt at restoring support * Aligorith - solved the "offset problems" --- source/blender/editors/gpencil/drawgpencil.c | 50 ++---- source/blender/editors/gpencil/gpencil_edit.c | 28 ++-- .../blender/editors/gpencil/gpencil_paint.c | 155 ++++-------------- source/blender/editors/include/ED_gpencil.h | 2 +- .../space_sequencer/sequencer_buttons.c | 18 +- .../editors/space_sequencer/sequencer_draw.c | 11 +- .../space_sequencer/sequencer_intern.h | 2 +- .../editors/space_sequencer/space_sequencer.c | 14 +- source/blender/makesrna/intern/rna_space.c | 25 ++- 9 files changed, 109 insertions(+), 196 deletions(-) diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 1823bbce3a1..e4a24f13a0e 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -37,10 +37,8 @@ #include "BLO_sys_types.h" -#include "IMB_imbuf_types.h" - -#include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_math.h" #include "BLI_utildefines.h" #include "DNA_gpencil_types.h" @@ -53,8 +51,6 @@ #include "BKE_global.h" #include "BKE_gpencil.h" - - #include "WM_api.h" #include "BIF_gl.h" @@ -64,7 +60,6 @@ #include "ED_sequencer.h" #include "ED_view3d.h" - #include "gpencil_intern.h" /* ************************************************** */ @@ -225,7 +220,7 @@ static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness /* need to roll-back one point to ensure that there are no gaps in the stroke */ if (i != 0) glVertex3fv(&(pt - 1)->x); - + /* now the point we want... */ glVertex3fv(&pt->x); @@ -340,7 +335,7 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s, mt[1] = m2[1] * pthick * 0.5f; sc[0] = s0[0] - (m1[0] * pthick * 0.75f); sc[1] = s0[1] - (m1[1] * pthick * 0.75f); - + t0[0] = sc[0] - mt[0]; t0[1] = sc[1] - mt[1]; t1[0] = sc[0] + mt[0]; @@ -382,7 +377,7 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s, mt[1] = mb[1] * pthick; athick = len_v2(mt); dfac = pthick - (athick * 2); - + if (((athick * 2.0f) < pthick) && (IS_EQF(athick, pthick) == 0)) { mt[0] += (mb[0] * dfac); mt[1] += (mb[1] * dfac); @@ -429,7 +424,7 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s, mt[1] = m2[1] * pthick * 0.5f; sc[0] = s1[0] + (m1[0] * pthick * 0.75f); sc[1] = s1[1] + (m1[1] * pthick * 0.75f); - + t0[0] = sc[0] - mt[0]; t0[1] = sc[1] - mt[1]; t1[0] = sc[0] + mt[0]; @@ -669,7 +664,7 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, // ............................ /* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */ -void draw_gpencil_2dimage(bContext *C /* , ImBuf *ibuf */) +void draw_gpencil_2dimage(bContext *C) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -699,35 +694,20 @@ void draw_gpencil_2dimage(bContext *C /* , ImBuf *ibuf */) dflag |= GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_IEDITHACK; } break; -#if 0 /* removed since 2.5x, needs to be added back */ case SPACE_SEQ: /* sequence */ { - SpaceSeq *sseq = (SpaceSeq *)sa->spacedata.first; - float zoom, zoomx, zoomy; - - /* check that we have grease-pencil stuff to draw */ - if (ELEM(NULL, sa, ibuf)) return; - - /* calculate accessory values */ - zoom = (float)(SEQ_ZOOM_FAC(sseq->zoom)); - if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { - /* XXX sequencer zoom should store it? */ - zoomx = zoom; // * (G.scene->r.xasp / G.scene->r.yasp); - zoomy = zoom; - } - else - zoomx = zoomy = zoom; + /* just draw using standard scaling (settings here are currently ignored anyways) */ + offsx = 0; + offsy = 0; + sizex = ar->winx; + sizey = ar->winy; - /* calculate transforms (Note: we use ibuf here, as we have it) */ - sizex = (int)(zoomx * ibuf->x); - sizey = (int)(zoomy * ibuf->y); - offsx = (int)( (ar->winx - sizex) / 2 + sseq->xof); - offsy = (int)( (ar->winy - sizey) / 2 + sseq->yof); - - dflag |= GP_DRAWDATA_ONLYI2D; + /* NOTE: I2D was used in 2.4x, but the old settings for that have been deprecated + * and everything moved to standard View2d + */ + dflag |= GP_DRAWDATA_ONLYV2D; } break; -#endif default: /* for spacetype not yet handled */ offsx = 0; offsy = 0; diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 71cbabe9114..7094aa086ba 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -80,6 +80,7 @@ /* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it */ bGPdata **gpencil_data_get_pointers(bContext *C, PointerRNA *ptr) { + ID *screen_id = (ID *)CTX_wm_screen(C); Scene *scene = CTX_data_scene(C); ScrArea *sa = CTX_wm_area(C); @@ -122,9 +123,12 @@ bGPdata **gpencil_data_get_pointers(bContext *C, PointerRNA *ptr) case SPACE_SEQ: /* Sequencer */ { - //SpaceSeq *sseq= (SpaceSeq *)CTX_wm_space_data(C); + SpaceSeq *sseq = (SpaceSeq *)CTX_wm_space_data(C); - /* return the GP data for the active strips/image/etc. */ + /* for now, Grease Pencil data is associated with the space (actually preview region only) */ + // XXX our convention for everything else is to link to data though... + if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceSequenceEditor, sseq, ptr); + return &sseq->gpd; } break; @@ -134,7 +138,7 @@ bGPdata **gpencil_data_get_pointers(bContext *C, PointerRNA *ptr) /* for now, Grease Pencil data is associated with the space... */ // XXX our convention for everything else is to link to data though... - if (ptr) RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_SpaceImageEditor, sima, ptr); + if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, ptr); return &sima->gpd; } break; @@ -143,7 +147,7 @@ bGPdata **gpencil_data_get_pointers(bContext *C, PointerRNA *ptr) { SpaceClip *sc = (SpaceClip *)CTX_wm_space_data(C); MovieClip *clip = ED_space_clip(sc); - + if (clip) { if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { MovieTrackingTrack *track = BKE_tracking_active_track(&clip->tracking); @@ -214,7 +218,7 @@ static int gp_data_add_exec(bContext *C, wmOperator *op) else { /* decrement user count and add new datablock */ bGPdata *gpd = (*gpd_ptr); - + id_us_min(&gpd->id); *gpd_ptr = gpencil_data_addnew("GPencil"); } @@ -479,7 +483,7 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect) if (v3d) { RegionView3D *rv3d = ar->regiondata; - + /* for camera view set the subrect */ if (rv3d->persp == RV3D_CAMOB) { Scene *scene = CTX_data_scene(C); @@ -523,26 +527,26 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu /* add points */ for (i = 0, bezt = nu->bezt; i < tot; i++, pt++, bezt++) { float h1[3], h2[3]; - + if (i) interp_v3_v3v3(h1, p3d_cur, p3d_prev, 0.3); else interp_v3_v3v3(h1, p3d_cur, p3d_next, -0.3); - + if (i < tot - 1) interp_v3_v3v3(h2, p3d_cur, p3d_next, 0.3); else interp_v3_v3v3(h2, p3d_cur, p3d_prev, -0.3); - + copy_v3_v3(bezt->vec[0], h1); copy_v3_v3(bezt->vec[1], p3d_cur); copy_v3_v3(bezt->vec[2], h2); - + /* set settings */ bezt->h1 = bezt->h2 = HD_FREE; bezt->f1 = bezt->f2 = bezt->f3 = SELECT; bezt->radius = bezt->weight = pt->pressure * gpl->thickness * 0.1f; - + /* shift coord vects */ copy_v3_v3(p3d_prev, p3d_cur); copy_v3_v3(p3d_cur, p3d_next); - + if (i + 2 < tot) { gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect); } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 89d8ed9c465..5eef34f4afe 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -79,15 +79,6 @@ typedef struct tGPsdata { rctf *subrect; /* for using the camera rect within the 3d view */ rctf subrect_data; - -#if 0 // XXX review this 2d image stuff... - ImBuf *ibuf; /* needed for GP_STROKE_2DIMAGE */ - struct IBufViewSettings { - int offsx, offsy; /* offsets */ - int sizex, sizey; /* dimensions to use as scale-factor */ - } im2d_settings; /* needed for GP_STROKE_2DIMAGE */ -#endif - PointerRNA ownerPtr; /* pointer to owner of gp-datablock */ bGPdata *gpd; /* gp-datablock layer comes from */ bGPDlayer *gpl; /* layer we're working on */ @@ -269,7 +260,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] int mval_prj[2]; float rvec[3], dvec[3]; float mval_f[2]; - + /* Current method just converts each point in screen-coordinates to * 3D-coordinates using the 3D-cursor as reference. In general, this * works OK, but it could of course be improved. @@ -283,7 +274,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] /* method taken from editview.c - mouse_cursor() */ project_int_noclip(p->ar, rvec, mval_prj); - + VECSUB2D(mval_f, mval_prj, mval); ED_view3d_win_to_delta(p->ar, mval_f, dvec); sub_v3_v3v3(out, rvec, dvec); @@ -296,25 +287,6 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] mul_v3_m4v3(out, p->imat, out); } -#if 0 - /* 2d - on image 'canvas' (assume that p->v2d is set) */ - else if (gpd->sbuffer_sflag & GP_STROKE_2DIMAGE) { - int sizex, sizey, offsx, offsy; - - /* get stored settings - * - assume that these have been set already (there are checks that set sane 'defaults' just in case) - */ - sizex = p->im2d_settings.sizex; - sizey = p->im2d_settings.sizey; - offsx = p->im2d_settings.offsx; - offsy = p->im2d_settings.offsy; - - /* calculate new points */ - out[0] = (float)(mval[0] - offsx) / (float)sizex; - out[1] = (float)(mval[1] - offsy) / (float)sizey; - } -#endif - /* 2d - relative to screen (viewport area) */ else { if (p->subrect == NULL) { /* normal 3D view */ @@ -393,11 +365,11 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure) else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) { /* get pointer to destination point */ pt = (tGPspoint *)(gpd->sbuffer); - + /* store settings */ copy_v2_v2_int(&pt->x, mval); pt->pressure = pressure; - + /* if there's stroke for this poly line session add (or replace last) point * to stroke. This allows to draw lines more interactively (see new segment * during mouse slide, i.e.) @@ -405,36 +377,36 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure) if (gp_stroke_added_check(p)) { bGPDstroke *gps = p->gpf->strokes.last; bGPDspoint *pts; - + /* first time point is adding to temporary buffer -- need to allocate new point in stroke */ if (gpd->sbuffer_size == 0) { gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1)); gps->totpoints++; } - + pts = &gps->points[gps->totpoints - 1]; - + /* special case for poly lines: normally, depth is needed only when creating new stroke from buffer, * but poly lines are converting to stroke instantly, so initialize depth buffer before converting coordinates */ if (gpencil_project_check(p)) { View3D *v3d = p->sa->spacedata.first; - + view3d_region_operator_needs_opengl(p->win, p->ar); ED_view3d_autodist_init(p->scene, p->ar, v3d, (p->gpd->flag & GP_DATA_DEPTH_STROKE) ? 1 : 0); } - + /* convert screen-coordinates to appropriate coordinates (and store them) */ gp_stroke_convertcoords(p, &pt->x, &pts->x, NULL); - + /* copy pressure */ pts->pressure = pt->pressure; } - + /* increment counters */ if (gpd->sbuffer_size == 0) gpd->sbuffer_size++; - + return GP_STROKEADD_NORMAL; } @@ -482,7 +454,7 @@ static void gp_stroke_smooth(tGPsdata *p) /* second pass: apply smoothed coordinates */ for (i = 0, spc = smoothArray; i < gpd->sbuffer_size; i++, spc++) { tGPspoint *pc = (((tGPspoint *)gpd->sbuffer) + i); - + copy_v2_v2_int(&pc->x, &spc->x); } @@ -639,10 +611,10 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) { /* first point */ ptc = gpd->sbuffer; - + /* convert screen-coordinates to appropriate coordinates (and store them) */ gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL); - + /* copy pressure */ pt->pressure = ptc->pressure; } @@ -656,10 +628,10 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) int found_depth = 0; depth_arr = MEM_mallocN(sizeof(float) * gpd->sbuffer_size, "depth_points"); - + for (i = 0, ptc = gpd->sbuffer; i < gpd->sbuffer_size; i++, ptc++, pt++) { copy_v2_v2_int(mval, &ptc->x); - + if ((ED_view3d_autodist_depth(p->ar, mval, depth_margin, depth_arr + i) == 0) && (i && (ED_view3d_autodist_depth_seg(p->ar, mval, mval_prev, depth_margin + 1, depth_arr + i) == 0))) { @@ -668,7 +640,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) else { found_depth = TRUE; } - + copy_v2_v2_int(mval_prev, mval); } @@ -835,21 +807,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, int mval[], int mvalo[], shor else if (gps->flag & GP_STROKE_2DSPACE) { UI_view2d_view_to_region(p->v2d, gps->points->x, gps->points->y, &x0, &y0); } -#if 0 - else if (gps->flag & GP_STROKE_2DIMAGE) { - int offsx, offsy, sizex, sizey; - - /* get stored settings */ - sizex = p->im2d_settings.sizex; - sizey = p->im2d_settings.sizey; - offsx = p->im2d_settings.offsx; - offsy = p->im2d_settings.offsy; - - /* calculate new points */ - x0 = (int)((gps->points->x * sizex) + offsx); - y0 = (int)((gps->points->y * sizey) + offsy); - } -#endif else { if (p->subrect == NULL) { /* normal 3D view */ x0 = (int)(gps->points->x / 100 * p->ar->winx); @@ -895,24 +852,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, int mval[], int mvalo[], shor UI_view2d_view_to_region(p->v2d, pt2->x, pt2->y, &x1, &y1); } -#if 0 - else if (gps->flag & GP_STROKE_2DIMAGE) { - int offsx, offsy, sizex, sizey; - - /* get stored settings */ - sizex = p->im2d_settings.sizex; - sizey = p->im2d_settings.sizey; - offsx = p->im2d_settings.offsx; - offsy = p->im2d_settings.offsy; - - /* calculate new points */ - x0 = (int)((pt1->x * sizex) + offsx); - y0 = (int)((pt1->y * sizey) + offsy); - - x1 = (int)((pt2->x * sizex) + offsx); - y1 = (int)((pt2->y * sizey) + offsy); - } -#endif else { if (p->subrect == NULL) { /* normal 3D view */ x0 = (int)(pt1->x / 100 * p->ar->winx); @@ -1062,7 +1001,6 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) #endif } break; -#if 0 // XXX these other spaces will come over time... case SPACE_SEQ: { SpaceSeq *sseq = curarea->spacedata.first; @@ -1079,15 +1017,16 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) printf("Error: In active view (sequencer), active mode doesn't support Grease Pencil\n"); return 0; } +#if 0 // XXX will this sort of antiquated stuff be restored? if ((sseq->flag & SEQ_DRAW_GPENCIL) == 0) { p->status = GP_STATUS_ERROR; if (G.debug & G_DEBUG) printf("Error: In active view, Grease Pencil not shown\n"); return 0; } +#endif } break; -#endif case SPACE_IMAGE: { //SpaceImage *sima= curarea->spacedata.first; @@ -1173,12 +1112,6 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) /* clear out buffer (stored in gp-data), in case something contaminated it */ gp_session_validatebuffer(p); -#if 0 - /* set 'default' im2d_settings just in case something that uses this doesn't set it */ - p->im2d_settings.sizex = 1; - p->im2d_settings.sizey = 1; -#endif - return 1; } @@ -1260,7 +1193,7 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode) if (p->sa->spacetype == SPACE_VIEW3D) { View3D *v3d = p->sa->spacedata.first; RegionView3D *rv3d = p->ar->regiondata; - + /* for camera view set the subrect */ if (rv3d->persp == RV3D_CAMOB) { ED_view3d_calc_camera_border(p->scene, p->ar, v3d, rv3d, &p->subrect_data, TRUE); /* no shift */ @@ -1290,41 +1223,13 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode) p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; } break; -#if 0 // XXX other spacetypes to be restored in due course + case SPACE_SEQ: { - SpaceSeq *sseq = (SpaceSeq *)p->sa->spacedata.first; - int rectx, recty; - float zoom, zoomx, zoomy; - - /* set draw 2d-stroke flag */ - p->gpd->sbuffer_sflag |= GP_STROKE_2DIMAGE; - - /* calculate zoom factor */ - zoom = (float)(SEQ_ZOOM_FAC(sseq->zoom)); - if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { - zoomx = zoom * (p->scene->r.xasp / p->scene->r.yasp); - zoomy = zoom; - } - else - zoomx = zoomy = zoom; - - /* calculate rect size to use to calculate the size of the drawing area - * - We use the size of the output image not the size of the ibuf being shown - * as it is too messy getting the ibuf (and could be too slow). This should be - * a reasonable for most cases anyway. - */ - rectx = (p->scene->r.size * p->scene->r.xsch) / 100; - recty = (p->scene->r.size * p->scene->r.ysch) / 100; - - /* set offset and scale values for opertations to use */ - p->im2d_settings.sizex = (int)(zoomx * rectx); - p->im2d_settings.sizey = (int)(zoomy * recty); - p->im2d_settings.offsx = (int)((p->sa->winx - p->im2d_settings.sizex) / 2 + sseq->xof); - p->im2d_settings.offsy = (int)((p->sa->winy - p->im2d_settings.sizey) / 2 + sseq->yof); + p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; } break; -#endif + case SPACE_IMAGE: { SpaceImage *sima = (SpaceImage *)p->sa->spacedata.first; @@ -1743,13 +1648,13 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, wmEvent *event) } /* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */ -static int gpencil_area_exists(bContext *C, ScrArea *satest) +static int gpencil_area_exists(bContext *C, ScrArea *sa_test) { bScreen *sc = CTX_wm_screen(C); ScrArea *sa; for (sa = sc->areabase.first; sa; sa = sa->next) { - if (sa == satest) + if (sa == sa_test) return 1; } @@ -1839,7 +1744,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) sketch |= GPENCIL_SKETCH_SESSIONS_ON(p->scene); /* polyline drawing is also 'sketching' -- all knots should be added during one session */ sketch |= p->paintmode == GP_PAINTMODE_DRAW_POLY; - + if (sketch) { /* end stroke only, and then wait to resume painting soon */ //printf("\t\tGP - end stroke only\n"); @@ -1847,7 +1752,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) /* we've just entered idling state, so this event was processed (but no others yet) */ estate = OPERATOR_RUNNING_MODAL; - + /* stroke could be smoothed, send notifier to refresh screen */ WM_event_add_notifier(C, NC_SCREEN | ND_GPENCIL | NA_EDITED, NULL); } @@ -1860,7 +1765,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) else if (event->val == KM_PRESS) { /* not painting, so start stroke (this should be mouse-button down) */ p = gpencil_stroke_begin(C, op); - + if (p->status == GP_STATUS_ERROR) { estate = OPERATOR_CANCELLED; } @@ -1916,7 +1821,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) case OPERATOR_CANCELLED: gpencil_draw_exit(C, op); break; - + case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH: /* event doesn't need to be handled */ //printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n", event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE); diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 32eb63a26d5..8a480271635 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -76,7 +76,7 @@ void ED_operatortypes_gpencil(void); /* ------------ Grease-Pencil Drawing API ------------------ */ /* drawgpencil.c */ -void draw_gpencil_2dimage(struct bContext *C /* , struct ImBuf *ibuf */); +void draw_gpencil_2dimage(struct bContext *C); void draw_gpencil_view2d(struct bContext *C, short onlyv2d); void draw_gpencil_view3d(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, short only3d); diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index aeedafa9992..1e452f2052d 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -25,8 +25,6 @@ * \ingroup spseq */ - - #include #include @@ -36,10 +34,13 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "BKE_context.h" #include "BKE_screen.h" #include "ED_screen.h" +#include "ED_gpencil.h" #include "WM_api.h" #include "WM_types.h" @@ -48,6 +49,19 @@ #include "sequencer_intern.h" +/* **************************** buttons ********************************* */ + +void sequencer_buttons_register(ARegionType *art) +{ + PanelType *pt; + + pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel gpencil"); + strcpy(pt->idname, "SEQUENCER_PT_gpencil"); + strcpy(pt->label, N_("Grease Pencil")); + pt->draw= gpencil_panel_standard; + BLI_addtail(&art->paneltypes, pt); +} + /* **************** operator to open/close properties view ************* */ static int sequencer_properties(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index b674943b2dc..3119c2d44f8 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -58,6 +58,7 @@ #include "BIF_glutil.h" #include "ED_anim_api.h" +#include "ED_gpencil.h" #include "ED_markers.h" #include "ED_mask.h" #include "ED_types.h" @@ -976,16 +977,16 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* draw grease-pencil (image aligned) */ // if (sseq->flag & SEQ_DRAW_GPENCIL) -// XXX draw_gpencil_2dimage(sa, ibuf); + draw_gpencil_2dimage(C); IMB_freeImBuf(ibuf); - /* draw grease-pencil (screen aligned) */ -// if (sseq->flag & SEQ_DRAW_GPENCIL) -// XXX draw_gpencil_view2d(sa, 0); - /* ortho at pixel level */ UI_view2d_view_restore(C); + + /* draw grease-pencil (screen aligned) */ +// if (sseq->flag & SEQ_DRAW_GPENCIL) + draw_gpencil_view2d(C, 0); //if (sc->mode == SC_MODE_MASKEDIT) { if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 25a322c6905..14d2ccdbbbe 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -174,7 +174,7 @@ struct ImBuf *make_zebra_view_from_ibuf(struct ImBuf * ibuf, float perc); struct ImBuf *make_histogram_view_from_ibuf(struct ImBuf * ibuf); /* sequencer_buttons.c */ - +void sequencer_buttons_register(struct ARegionType *art); void SEQUENCER_OT_properties(struct wmOperatorType *ot); #endif /* __SEQUENCER_INTERN_H__ */ diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 3643f92d334..dbfc554007a 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -485,6 +485,11 @@ static void sequencer_preview_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch (wmn->category) { + case NC_SCREEN: + if (wmn->data == ND_GPENCIL) { + ED_region_tag_redraw(ar); + } + break; case NC_SCENE: switch (wmn->data) { case ND_FRAME: @@ -534,6 +539,11 @@ static void sequencer_buttons_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch (wmn->category) { + case NC_SCREEN: + if (wmn->data == ND_GPENCIL) { + ED_region_tag_redraw(ar); + } + break; case NC_SCENE: switch (wmn->data) { case ND_FRAME: @@ -590,7 +600,7 @@ void ED_spacetype_sequencer(void) art->init = sequencer_preview_area_init; art->draw = sequencer_preview_area_draw; art->listener = sequencer_preview_area_listener; - art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_ANIMATION; + art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_GPENCIL; BLI_addhead(&st->regiontypes, art); /* regions: listview/buttons */ @@ -602,6 +612,8 @@ void ED_spacetype_sequencer(void) art->init = sequencer_buttons_area_init; art->draw = sequencer_buttons_area_draw; BLI_addhead(&st->regiontypes, art); + + sequencer_buttons_register(art); /* regions: header */ art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer region"); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 3d01f5ba082..3ff54076f82 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1970,10 +1970,12 @@ static void rna_def_space_image(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); +#if 0 // XXX: unused - old stuff which may not be restored prop = RNA_def_property(srna, "use_grease_pencil", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DISPGP); RNA_def_property_ui_text(prop, "Use Grease Pencil", "Display and edit the grease pencil freehand annotations overlay"); +#endif /* update */ prop = RNA_def_property(srna, "use_realtime_update", PROP_BOOLEAN, PROP_NONE); @@ -2050,7 +2052,7 @@ static void rna_def_space_sequencer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Display Mode", "View mode to use for displaying sequencer output"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); - /* flag's */ + /* flags */ prop = RNA_def_property(srna, "show_frame_indicator", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SEQ_NO_DRAW_CFRANUM); RNA_def_property_ui_text(prop, "Show Frame Number Indicator", @@ -2077,23 +2079,10 @@ static void rna_def_space_sequencer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Safe Margin", "Draw title safe margins in preview"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); - prop = RNA_def_property(srna, "use_grease_pencil", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_DRAW_GPENCIL); - RNA_def_property_ui_text(prop, "Use Grease Pencil", - "Display and edit the grease pencil freehand annotations overlay"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); - prop = RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SEQ_DRAWFRAMES); RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); - - /* grease pencil */ - prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "gpd"); - RNA_def_property_struct_type(prop, "UnknownType"); - RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); prop = RNA_def_property(srna, "display_channel", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "chanshown"); @@ -2114,6 +2103,14 @@ static void rna_def_space_sequencer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Proxy render size", "Draw preview using full resolution or different proxy resolutions"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + + /* grease pencil */ + prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "gpd"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); } static void rna_def_space_text(BlenderRNA *brna) From c711665ce2f13fabf8774752e3a7ecc80555b8fb Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 11 Jun 2012 00:46:22 +0000 Subject: [PATCH 191/360] Code cleanup - Removing/commenting out various bits of legacy cruft related to old Grease Pencil stuff --- source/blender/editors/gpencil/drawgpencil.c | 4 +- source/blender/editors/gpencil/gpencil_edit.c | 4 +- .../blender/editors/gpencil/gpencil_paint.c | 59 ++++--------------- source/blender/editors/include/ED_gpencil.h | 8 +-- source/blender/editors/include/ED_sequencer.h | 2 - .../blender/editors/space_image/image_draw.c | 2 - source/blender/editors/space_node/node_draw.c | 8 +-- .../editors/space_sequencer/sequencer_draw.c | 2 - source/blender/makesdna/DNA_space_types.h | 6 +- source/blender/makesrna/intern/rna_space.c | 9 +-- 10 files changed, 26 insertions(+), 78 deletions(-) diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index e4a24f13a0e..fa555b0ddb8 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -664,7 +664,7 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, // ............................ /* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */ -void draw_gpencil_2dimage(bContext *C) +void draw_gpencil_2dimage(const bContext *C) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -726,7 +726,7 @@ void draw_gpencil_2dimage(bContext *C) /* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, second time with onlyv2d=0 for screen-aligned strokes */ -void draw_gpencil_view2d(bContext *C, short onlyv2d) +void draw_gpencil_view2d(const bContext *C, short onlyv2d) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 7094aa086ba..7708d99e990 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -78,7 +78,7 @@ /* Context Wrangling... */ /* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it */ -bGPdata **gpencil_data_get_pointers(bContext *C, PointerRNA *ptr) +bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) { ID *screen_id = (ID *)CTX_wm_screen(C); Scene *scene = CTX_data_scene(C); @@ -181,7 +181,7 @@ bGPdata **gpencil_data_get_pointers(bContext *C, PointerRNA *ptr) } /* Get the active Grease Pencil datablock */ -bGPdata *gpencil_data_get_active(bContext *C) +bGPdata *gpencil_data_get_active(const bContext *C) { bGPdata **gpd_ptr = gpencil_data_get_pointers(C, NULL); return (gpd_ptr) ? *(gpd_ptr) : NULL; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 5eef34f4afe..9d5779e448e 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -968,16 +968,6 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) printf("Error: 3D-View active region doesn't have any region data, so cannot be drawable\n"); return 0; } - -#if 0 // XXX will this sort of antiquated stuff be restored? - /* check that gpencil data is allowed to be drawn */ - if ((v3d->flag2 & V3D_DISPGP) == 0) { - p->status = GP_STATUS_ERROR; - if (G.debug & G_DEBUG) - printf("Error: In active view, Grease Pencil not shown\n"); - return 0; - } -#endif } break; @@ -989,16 +979,6 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) p->sa = curarea; p->ar = ar; p->v2d = &ar->v2d; - -#if 0 // XXX will this sort of antiquated stuff be restored? - /* check that gpencil data is allowed to be drawn */ - if ((snode->flag & SNODE_DISPGP) == 0) { - p->status = GP_STATUS_ERROR; - if (G.debug & G_DEBUG) - printf("Error: In active view, Grease Pencil not shown\n"); - return 0; - } -#endif } break; case SPACE_SEQ: @@ -1017,14 +997,6 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) printf("Error: In active view (sequencer), active mode doesn't support Grease Pencil\n"); return 0; } -#if 0 // XXX will this sort of antiquated stuff be restored? - if ((sseq->flag & SEQ_DRAW_GPENCIL) == 0) { - p->status = GP_STATUS_ERROR; - if (G.debug & G_DEBUG) - printf("Error: In active view, Grease Pencil not shown\n"); - return 0; - } -#endif } break; case SPACE_IMAGE: @@ -1035,48 +1007,36 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) p->sa = curarea; p->ar = ar; p->v2d = &ar->v2d; - //p->ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser); - -#if 0 // XXX disabled for now - /* check that gpencil data is allowed to be drawn */ - if ((sima->flag & SI_DISPGP) == 0) { - p->status = GP_STATUS_ERROR; - if (G.debug & G_DEBUG) - printf("Error: In active view, Grease Pencil not shown\n"); - return 0; - } -#endif } break; case SPACE_CLIP: { SpaceClip *sc = curarea->spacedata.first; - + /* set the current area */ p->sa = curarea; p->ar = ar; p->v2d = &ar->v2d; - //p->ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser); - + invert_m4_m4(p->imat, sc->unistabmat); - + /* custom color for new layer */ p->custom_color[0] = 1.0f; p->custom_color[1] = 0.0f; p->custom_color[2] = 0.5f; p->custom_color[3] = 0.9f; - + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { int framenr = sc->user.framenr; MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); - + p->imat[3][0] -= marker->pos[0]; p->imat[3][1] -= marker->pos[1]; } } break; - + /* unsupported views */ default: { @@ -1157,7 +1117,7 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode) p->gpl = gpencil_layer_getactive(p->gpd); if (p->gpl == NULL) { p->gpl = gpencil_layer_addnew(p->gpd); - + if (p->custom_color[3]) copy_v3_v3(p->gpl->color, p->custom_color); } @@ -1465,8 +1425,9 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event) float mousef[2]; int tablet = 0; - /* convert from window-space to area-space mouse coordintes */ - // NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding... + /* convert from window-space to area-space mouse coordintes + * NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding... + */ p->mval[0] = event->mval[0] + 1; p->mval[1] = event->mval[1] + 1; diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 8a480271635..1d461f797d6 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -64,8 +64,8 @@ typedef struct tGPspoint { /* ----------- Grease Pencil Tools/Context ------------- */ -struct bGPdata **gpencil_data_get_pointers(struct bContext *C, struct PointerRNA *ptr); -struct bGPdata *gpencil_data_get_active(struct bContext *C); +struct bGPdata **gpencil_data_get_pointers(const struct bContext *C, struct PointerRNA *ptr); +struct bGPdata *gpencil_data_get_active(const struct bContext *C); struct bGPdata *gpencil_data_get_active_v3d(struct Scene *scene); /* for offscreen rendering */ /* ----------- Grease Pencil Operators ----------------- */ @@ -76,8 +76,8 @@ void ED_operatortypes_gpencil(void); /* ------------ Grease-Pencil Drawing API ------------------ */ /* drawgpencil.c */ -void draw_gpencil_2dimage(struct bContext *C); -void draw_gpencil_view2d(struct bContext *C, short onlyv2d); +void draw_gpencil_2dimage(const struct bContext *C); +void draw_gpencil_view2d(const struct bContext *C, short onlyv2d); void draw_gpencil_view3d(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, short only3d); void gpencil_panel_standard(const struct bContext *C, struct Panel *pa); diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h index c731245949e..cea567254de 100644 --- a/source/blender/editors/include/ED_sequencer.h +++ b/source/blender/editors/include/ED_sequencer.h @@ -27,8 +27,6 @@ #ifndef __ED_SEQUENCER_H__ #define __ED_SEQUENCER_H__ -#define SEQ_ZOOM_FAC(szoom) ((szoom) > 0.0f) ? (szoom) : ((szoom) == 0.0f) ? (1.0f) : (-1.0f / (szoom)) - struct Scene; struct Sequence; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 998ebac1cb9..ac71eb972f6 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -565,7 +565,6 @@ void draw_image_grease_pencil(bContext *C, short onlyv2d) /* draw in View2D space? */ if (onlyv2d) { /* draw grease-pencil ('image' strokes) */ - //if (sima->flag & SI_DISPGP) draw_gpencil_2dimage(C); } else { @@ -573,7 +572,6 @@ void draw_image_grease_pencil(bContext *C, short onlyv2d) //SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C); /* draw grease-pencil ('screen' strokes) */ - //if (sima->flag & SI_DISPGP) draw_gpencil_view2d(C, 0); } } diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 921aceb7b2e..c65bbd6e15f 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -1138,15 +1138,15 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) glDisable(GL_BLEND); /* draw grease-pencil ('canvas' strokes) */ - if (/*(snode->flag & SNODE_DISPGP) &&*/ (snode->nodetree)) - draw_gpencil_view2d((bContext*)C, 1); + if (snode->nodetree) + draw_gpencil_view2d(C, 1); /* reset view matrix */ UI_view2d_view_restore(C); /* draw grease-pencil (screen strokes, and also paintbuffer) */ - if (/*(snode->flag & SNODE_DISPGP) && */(snode->nodetree)) - draw_gpencil_view2d((bContext*)C, 0); + if (snode->nodetree) + draw_gpencil_view2d(C, 0); /* scrollers */ scrollers= UI_view2d_scrollers_calc(C, v2d, 10, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 3119c2d44f8..e48450e93bd 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -976,7 +976,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq } /* draw grease-pencil (image aligned) */ -// if (sseq->flag & SEQ_DRAW_GPENCIL) draw_gpencil_2dimage(C); IMB_freeImBuf(ibuf); @@ -985,7 +984,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq UI_view2d_view_restore(C); /* draw grease-pencil (screen aligned) */ -// if (sseq->flag & SEQ_DRAW_GPENCIL) draw_gpencil_view2d(C, 0); //if (sc->mode == SC_MODE_MASKEDIT) { diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 0b5b2177342..cb905d7f768 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -491,7 +491,7 @@ typedef enum eSpaceSeq_Flag { SEQ_MARKER_TRANS = (1 << 1), SEQ_DRAW_COLOR_SEPARATED = (1 << 2), SEQ_DRAW_SAFE_MARGINS = (1 << 3), - SEQ_DRAW_GPENCIL = (1 << 4), /* DEPRECATED */ +/* SEQ_DRAW_GPENCIL = (1 << 4), */ /* DEPRECATED */ SEQ_NO_DRAW_CFRANUM = (1 << 5), } eSpaceSeq_Flag; @@ -746,7 +746,7 @@ typedef enum eSpaceImage_Flag { SI_DRAW_TILE = (1 << 19), SI_SMOOTH_UV = (1 << 20), SI_DRAW_STRETCH = (1 << 21), - SI_DISPGP = (1 << 22), /* DEPRECATED */ +/* SI_DISPGP = (1 << 22), */ /* DEPRECATED */ SI_DRAW_OTHER = (1 << 23), SI_COLOR_CORRECTION = (1 << 24), @@ -876,7 +876,7 @@ typedef struct SpaceNode { /* snode->flag */ typedef enum eSpaceNode_Flag { SNODE_BACKDRAW = (1 << 1), - SNODE_DISPGP = (1 << 2), /* XXX: Grease Pencil - deprecated? */ +/* SNODE_DISPGP = (1 << 2), */ /* XXX: Grease Pencil - deprecated? */ SNODE_USE_ALPHA = (1 << 3), SNODE_SHOW_ALPHA = (1 << 4), SNODE_AUTO_RENDER = (1 << 5), diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 3ff54076f82..81538d20a50 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1969,14 +1969,7 @@ static void rna_def_space_image(BlenderRNA *brna) RNA_def_property_struct_type(prop, "GreasePencil"); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); - -#if 0 // XXX: unused - old stuff which may not be restored - prop = RNA_def_property(srna, "use_grease_pencil", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DISPGP); - RNA_def_property_ui_text(prop, "Use Grease Pencil", - "Display and edit the grease pencil freehand annotations overlay"); -#endif - + /* update */ prop = RNA_def_property(srna, "use_realtime_update", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "lock", 0); From 6486d7b35d7081cb62180d26774cd625c092e18b Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 11 Jun 2012 01:09:25 +0000 Subject: [PATCH 192/360] Grease Pencil - Eraser is drawn with the circle/brush indicator again --- .../blender/editors/gpencil/gpencil_paint.c | 61 +++++++++++++++++-- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 9d5779e448e..67242b59d64 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -57,9 +57,12 @@ #include "ED_screen.h" #include "ED_view3d.h" -#include "RNA_access.h" +#include "BIF_gl.h" +#include "BIF_glutil.h" +#include "RNA_access.h" #include "RNA_define.h" + #include "WM_api.h" #include "WM_types.h" @@ -98,8 +101,10 @@ typedef struct tGPsdata { float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space * to region space */ - - float custom_color[4]; /* custom color for (?) */ + + float custom_color[4]; /* custom color - hack for enforcing a particular color for track/mask editing */ + + void *erasercursor; /* radial cursor data for drawing eraser */ } tGPsdata; /* values for tGPsdata->status */ @@ -1265,6 +1270,49 @@ static void gp_paint_cleanup(tGPsdata *p) /* ------------------------------- */ +/* Helper callback for drawing the cursor itself */ +static void gpencil_draw_eraser(bContext *C, int x, int y, void *p_ptr) +{ + tGPsdata *p = (tGPsdata *)p_ptr; + + if (p->paintmode == GP_PAINTMODE_ERASER) { + glPushMatrix(); + + glTranslatef((float)x, (float)y, 0.0f); + + glColor4ub(255, 255, 255, 128); + + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + + glutil_draw_lined_arc(0.0, M_PI*2.0, p->radius, 40); + + glDisable(GL_BLEND); + glDisable(GL_LINE_SMOOTH); + + glPopMatrix(); + } +} + +/* Turn brush cursor in 3D view on/off */ +static void gpencil_draw_toggle_eraser_cursor(bContext *C, tGPsdata *p, short enable) +{ + if (p->erasercursor && !enable) { + /* clear cursor */ + WM_paint_cursor_end(CTX_wm_manager(C), p->erasercursor); + p->erasercursor = NULL; + } + else if (enable) { + /* enable cursor */ + p->erasercursor = WM_paint_cursor_activate(CTX_wm_manager(C), + NULL, // XXX + gpencil_draw_eraser, p); + } +} + +/* ------------------------------- */ + + static void gpencil_draw_exit(bContext *C, wmOperator *op) { tGPsdata *p = op->customdata; @@ -1279,8 +1327,8 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op) if (p) { /* check size of buffer before cleanup, to determine if anything happened here */ if (p->paintmode == GP_PAINTMODE_ERASER) { - // TODO clear radial cursor thing - // XXX draw_sel_circle(NULL, p.mvalo, 0, p.radius, 0); + /* turn off radial brush cursor */ + gpencil_draw_toggle_eraser_cursor(C, p, FALSE); } /* cleanup */ @@ -1331,6 +1379,7 @@ static int gpencil_draw_init(bContext *C, wmOperator *op) return 1; } + /* ------------------------------- */ /* update UI indicators of status, including cursor and header prints */ @@ -1576,7 +1625,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, wmEvent *event) /* if eraser is on, draw radial aid */ if (p->paintmode == GP_PAINTMODE_ERASER) { - // TODO: this involves mucking around with radial control, so we leave this for now.. + gpencil_draw_toggle_eraser_cursor(C, p, TRUE); } /* set cursor */ From 128e2cb125cc9ce71a7b89c5b80141f806afed5a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 11 Jun 2012 01:27:56 +0000 Subject: [PATCH 193/360] Grease Pencil Eraser - Numpad +/- and Scrollwheel Up/Down to change radius of brush while erasing This makes it easier to change the size of the brush without having to jump out to the User Preferences and back --- .../blender/editors/gpencil/gpencil_paint.c | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 67242b59d64..c6b2c1554f0 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1329,6 +1329,10 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op) if (p->paintmode == GP_PAINTMODE_ERASER) { /* turn off radial brush cursor */ gpencil_draw_toggle_eraser_cursor(C, p, FALSE); + + /* if successful, store the new eraser size to be used again next time */ + if (p->status == GP_STATUS_DONE) + U.gp_eraser = p->radius; } /* cleanup */ @@ -1804,8 +1808,37 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) estate = OPERATOR_RUNNING_MODAL; } } + /* eraser size */ + else if ((p->paintmode == GP_PAINTMODE_ERASER) && + ELEM4(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE, PADPLUSKEY, PADMINUS)) + { + /* just resize the brush (local version) + * TODO: fix the hardcoded size jumps (set to make a visible difference) and hardcoded keys + */ + //printf("\t\tGP - resize eraser\n"); + switch (event->type) { + case WHEELUPMOUSE: /* larger */ + case PADPLUSKEY: + p->radius += 5; + break; + + case WHEELDOWNMOUSE: /* smaller */ + case PADMINUS: + p->radius -= 5; + + if (p->radius < 0) + p->radius = 0; + break; + } + + /* force refresh */ + ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */ + + /* event handled, so just tag as running modal */ + estate = OPERATOR_RUNNING_MODAL; + } /* there shouldn't be any other events, but just in case there are, let's swallow them - * (i.e. to prevent problems with with undo) + * (i.e. to prevent problems with undo) */ else { /* swallow event to save ourselves trouble */ From 26164634f8be7b6221cdb8a881b16e05ff56b02b Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 11 Jun 2012 02:01:48 +0000 Subject: [PATCH 194/360] Build-system fix (for r.47710) Need add blenfont to list of include directories for sequence editor buildfiles. Was causing build errors on OSX. Thanks Zavigny (IRC report) --- source/blender/editors/space_sequencer/CMakeLists.txt | 1 + source/blender/editors/space_sequencer/SConscript | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt index bfd9ed95ee4..7bee8c2bebf 100644 --- a/source/blender/editors/space_sequencer/CMakeLists.txt +++ b/source/blender/editors/space_sequencer/CMakeLists.txt @@ -20,6 +20,7 @@ set(INC ../include + ../../blenfont ../../blenkernel ../../blenlib ../../blenloader diff --git a/source/blender/editors/space_sequencer/SConscript b/source/blender/editors/space_sequencer/SConscript index 65aadfa1c8a..ec06eacae9c 100644 --- a/source/blender/editors/space_sequencer/SConscript +++ b/source/blender/editors/space_sequencer/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.c') incs = '../include ../../blenlib ../../blenkernel ../../blenfont ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' -incs += ' ../../makesrna ../../blenloader' +incs += ' ../../makesrna ../../blenloader ../../blenfont' incs += ' #/intern/audaspace/intern' if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'): From be7d15cc2b736e2e529c4da23e62b2ef4be96768 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 11 Jun 2012 02:23:26 +0000 Subject: [PATCH 195/360] Commented out expand_bones(), as this wasn't actually doing anything other than wasting time traversing the list of bones in the Armature --- source/blender/blenloader/intern/readfile.c | 24 +++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c727717dac8..fdaa8f5e193 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5623,10 +5623,10 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) } else if (sl->spacetype == SPACE_CLIP) { SpaceClip *sclip = (SpaceClip *)sl; - + sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 1); sclip->mask = restore_pointer_by_name(newmain, (ID *)sclip->mask, 1); - + sclip->scopes.ok = 0; } } @@ -8068,7 +8068,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) /* Update: the issue is that in file reading, the oldnewmap is OK, but for existing data, it has to be * inserted in the map to be found! */ - + /* Update: previously it was checking for id->flag & LIB_PRE_EXISTING, however that does not affect file * reading. For file reading we may need to insert it into the libmap as well, because you might have * two files indirectly linking the same datablock, and in that case we need this in the libmap for the @@ -8477,6 +8477,7 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb) } } +#if 0 /* Disabled as it doesn't actually do anything except recurse... */ static void expand_bones(FileData *fd, Main *mainvar, Bone *bone) { Bone *curBone; @@ -8485,6 +8486,7 @@ static void expand_bones(FileData *fd, Main *mainvar, Bone *bone) expand_bones(fd, mainvar, curBone); } } +#endif static void expand_pose(FileData *fd, Main *mainvar, bPose *pose) { @@ -8500,15 +8502,19 @@ static void expand_pose(FileData *fd, Main *mainvar, bPose *pose) } static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm) -{ - Bone *curBone; - +{ if (arm->adt) expand_animdata(fd, mainvar, arm->adt); - for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) { - expand_bones(fd, mainvar, curBone); +#if 0 /* Disabled as this currently only recurses down the chain doing nothing */ + { + Bone *curBone; + + for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) { + expand_bones(fd, mainvar, curBone); + } } +#endif } static void expand_object_expandModifiers(void *userData, Object *UNUSED(ob), @@ -8718,7 +8724,7 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) #ifdef DURIAN_CAMERA_SWITCH { TimeMarker *marker; - + for (marker = sce->markers.first; marker; marker = marker->next) { if (marker->camera) { expand_doit(fd, mainvar, marker->camera); From 379cf37b384c143313f0d1cc10dcb30ae1daa378 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Mon, 11 Jun 2012 02:29:25 +0000 Subject: [PATCH 196/360] SVN maintenance. --- extern/libmv/third_party/ceres/bundle.sh | 0 extern/libmv/third_party/ceres/mkfiles.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 extern/libmv/third_party/ceres/bundle.sh mode change 100644 => 100755 extern/libmv/third_party/ceres/mkfiles.sh diff --git a/extern/libmv/third_party/ceres/bundle.sh b/extern/libmv/third_party/ceres/bundle.sh old mode 100644 new mode 100755 diff --git a/extern/libmv/third_party/ceres/mkfiles.sh b/extern/libmv/third_party/ceres/mkfiles.sh old mode 100644 new mode 100755 From a050d23133123abec1ee83c1e80289f6ac931098 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 11 Jun 2012 03:03:36 +0000 Subject: [PATCH 197/360] Bugfix: Crash in Sequencer when trying to undo after using Grease Pencil Grease Pencil data was not getting correctly relinked after file reload (for undo) --- source/blender/blenloader/intern/readfile.c | 33 +++++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fdaa8f5e193..6cc81218a6b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5288,6 +5288,14 @@ static void lib_link_screen(FileData *fd, Main *main) */ sima->gpd = newlibadr_us(fd, sc->id.lib, sima->gpd); } + else if (sl->spacetype == SPACE_SEQ) { + SpaceSeq *sseq = (SpaceSeq *)sl; + + /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data + * so fingers crossed this works fine! + */ + sseq->gpd = newlibadr_us(fd, sc->id.lib, sseq->gpd); + } else if (sl->spacetype == SPACE_NLA) { SpaceNla *snla= (SpaceNla *)sl; bDopeSheet *ads= snla->ads; @@ -5358,15 +5366,20 @@ static void lib_link_screen(FileData *fd, Main *main) } else if (sl->spacetype == SPACE_CLIP) { SpaceClip *sclip = (SpaceClip *)sl; - + sclip->clip = newlibadr_us(fd, sc->id.lib, sclip->clip); sclip->mask = newlibadr_us(fd, sc->id.lib, sclip->mask); - + sclip->scopes.track_search = NULL; sclip->scopes.track_preview = NULL; sclip->draw_context = NULL; sclip->scopes.ok = 0; } + else if (sl->spacetype == SPACE_LOGIC) { + SpaceLogic *slogic = (SpaceLogic *)sl; + + slogic->gpd = newlibadr_us(fd, sc->id.lib, slogic->gpd); + } } } sc->id.flag -= LIB_NEEDLINK; @@ -5559,6 +5572,14 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) */ sima->gpd = restore_pointer_by_name(newmain, (ID *)sima->gpd, 1); } + else if (sl->spacetype == SPACE_SEQ) { + SpaceSeq *sseq = (SpaceSeq *)sl; + + /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data + * so assume that here we're doing for undo only... + */ + sseq->gpd = restore_pointer_by_name(newmain, (ID *)sseq->gpd, 1); + } else if (sl->spacetype == SPACE_NLA) { SpaceNla *snla = (SpaceNla *)sl; bDopeSheet *ads = snla->ads; @@ -5629,6 +5650,11 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) sclip->scopes.ok = 0; } + else if (sl->spacetype == SPACE_LOGIC) { + SpaceLogic *slogic = (SpaceLogic *)sl; + + slogic->gpd = restore_pointer_by_name(newmain, (ID *)slogic->gpd, 1); + } } } } @@ -5869,7 +5895,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc) } else if (sl->spacetype == SPACE_LOGIC) { SpaceLogic *slogic = (SpaceLogic *)sl; - + + /* XXX: this is new stuff, which shouldn't be directly linking to gpd... */ if (slogic->gpd) { slogic->gpd = newdataadr(fd, slogic->gpd); direct_link_gpencil(fd, slogic->gpd); From c2e55ae8e31262eefe7f3f4cd951bdef187baaef Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 11 Jun 2012 04:13:39 +0000 Subject: [PATCH 198/360] Bugfix [#28962] Changing actions via undo/delete all keyframes lacks UI refresh Slightly hacky fix to get updates working for Action Editor header when there are changes of the active action (via undo and/or deleting all keyframes at once). Since the action referenced by the editor only gets updated when anim channel filtering (e.g. as a result of the channel syncing operation) is invoked. Added comments noting where these updates actually occur --- source/blender/blenloader/intern/readfile.c | 6 ++++++ .../editors/space_action/space_action.c | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6cc81218a6b..db4d40dd4c4 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5551,6 +5551,12 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) if (saction->ads.filter_grp) saction->ads.filter_grp= restore_pointer_by_name(newmain, (ID *)saction->ads.filter_grp, 0); + + + /* force recalc of list of channels, potentially updating the active action + * while we're at it (as it can only be updated that way) [#28962] + */ + saction->flag |= SACTION_TEMP_NEEDCHANSYNC; } else if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index c8660179945..db1d4ed1155 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -435,6 +435,12 @@ static void action_listener(ScrArea *sa, wmNotifier *wmn) break; } break; + case NC_WINDOW: + if (saction->flag & SACTION_TEMP_NEEDCHANSYNC) { + /* force redraw/refresh after undo/redo - [#28962] */ + ED_area_tag_refresh(sa); + } + break; } } @@ -464,9 +470,21 @@ static void action_refresh(const bContext *C, ScrArea *sa) * NOTE: the temp flag is used to indicate when this needs to be done, and will be cleared once handled */ if (saction->flag & SACTION_TEMP_NEEDCHANSYNC) { + ARegion *ar; + + /* Perform syncing of channel state incl. selection + * Active action setting also occurs here (as part of anim channel filtering in anim_filter.c) + */ ANIM_sync_animchannels_to_data(C); saction->flag &= ~SACTION_TEMP_NEEDCHANSYNC; + + /* Tag everything for redraw + * - Regions (such as header) need to be manually tagged for redraw too + * or else they don't update [#28962] + */ ED_area_tag_redraw(sa); + for (ar = sa->regionbase.first; ar; ar = ar->next) + ED_region_tag_redraw(ar); } /* region updates? */ From 1022d0c257a395f032023416c6a52ecdda3e4b93 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 11 Jun 2012 04:34:59 +0000 Subject: [PATCH 199/360] Bugfix [#31766] Mouseover Label reads 'Alt Left Arrow' when over the right arrow. Patch by Philipp Oeser --- release/scripts/startup/bl_ui/space_clip.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 1cef4624a04..9ab8fcb5655 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -261,6 +261,7 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel): props = row.operator("clip.track_markers", text="", icon='FRAME_PREV') props.backwards = True + props.sequence = False props = row.operator("clip.track_markers", text="", icon='PLAY_REVERSE') props.backwards = True @@ -268,7 +269,9 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel): props = row.operator("clip.track_markers", text="", icon='PLAY') props.backwards = False props.sequence = True - row.operator("clip.track_markers", text="", icon='FRAME_NEXT') + props = row.operator("clip.track_markers", text="", icon='FRAME_NEXT') + props.backwards = False + props.sequence = False col = layout.column(align=True) props = col.operator("clip.clear_track_path", text="Clear After") From 61fe88aedc27759bcf8abcaa862dfb2cc9164081 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 11 Jun 2012 05:05:05 +0000 Subject: [PATCH 200/360] Bugfix [#27886] Transform constraint maps wrongly with negative scale AFAIK, it is impossible to determine exactly which axes may have negative scaling values from a 4x4 matrix (which is the underlying cause of this bug). However, we can figure out if there is some negative scaling going on in that matrix (i.e. one of the axes has negative scale). So, the fix here is to negatively scale everything if we detect this happening. WARNING: do not rely on being able to accurately detecting positive/negative values for more than a single axis per bone controller. Weird results may occur. You have been warned. --- source/blender/blenkernel/intern/constraint.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 0150646a96c..9d36a66843b 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3278,6 +3278,15 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t switch (data->from) { case 2: /* scale */ mat4_to_size(dvec, ct->matrix); + + if (is_negative_m4(ct->matrix)) { + /* Bugfix [#27886] + * We can't be sure which axis/axes are negative, though we know that something is negative. + * Assume we don't care about negativity of separate axes. <--- This is a limitation that + * riggers will have to live with for now. + */ + negate_v3(dvec); + } break; case 1: /* rotation (convert to degrees first) */ mat4_to_eulO(dvec, cob->rotOrder, ct->matrix); From 05c48fe7d88fc6e92d4fd45177872680a7b71bbd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Jun 2012 06:51:01 +0000 Subject: [PATCH 201/360] quiet 'unused' warning. --- source/blender/editors/gpencil/gpencil_paint.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index c6b2c1554f0..4004efacadc 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1271,7 +1271,7 @@ static void gp_paint_cleanup(tGPsdata *p) /* ------------------------------- */ /* Helper callback for drawing the cursor itself */ -static void gpencil_draw_eraser(bContext *C, int x, int y, void *p_ptr) +static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr) { tGPsdata *p = (tGPsdata *)p_ptr; @@ -1285,7 +1285,7 @@ static void gpencil_draw_eraser(bContext *C, int x, int y, void *p_ptr) glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - glutil_draw_lined_arc(0.0, M_PI*2.0, p->radius, 40); + glutil_draw_lined_arc(0.0, M_PI * 2.0, p->radius, 40); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); @@ -1305,8 +1305,8 @@ static void gpencil_draw_toggle_eraser_cursor(bContext *C, tGPsdata *p, short en else if (enable) { /* enable cursor */ p->erasercursor = WM_paint_cursor_activate(CTX_wm_manager(C), - NULL, // XXX - gpencil_draw_eraser, p); + NULL, // XXX + gpencil_draw_eraser, p); } } From 638211d4e6c3cc291d2c3fffcc35c9bfe7a2df51 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 11 Jun 2012 08:06:42 +0000 Subject: [PATCH 202/360] Move all marker placement into a single omp critical section Could give small speadup. --- source/blender/blenkernel/intern/tracking.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index b4ee4f733e7..a3d66012303 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1767,24 +1767,20 @@ int BKE_tracking_next(MovieTrackingContext *context) marker_new.flag |= MARKER_TRACKED; marker_new.framenr = nextfra; - if (context->first_time) { - #pragma omp critical - { + #pragma omp critical + { + if (context->first_time) { /* check if there's no keyframe/tracked markers before tracking marker. * if so -- create disabled marker before currently tracking "segment" */ + put_disabled_marker(track, &marker_new, !context->backwards, 0); } - } - #pragma omp critical - { + /* insert currently tracked marker */ BKE_tracking_insert_marker(track, &marker_new); - } - /* make currently tracked segment be finished with disabled marker */ - #pragma omp critical - { + /* make currently tracked segment be finished with disabled marker */ put_disabled_marker(track, &marker_new, context->backwards, 0); } } From 31c8f4fbd39374532af0033779f5853e4be7a528 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Jun 2012 08:15:37 +0000 Subject: [PATCH 203/360] fix for crashes in smooth-curves and clean-curves fcurve operators - missing NULL checks. --- source/blender/editors/animation/keyframes_general.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 14bee00a72a..f29be418941 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -184,7 +184,7 @@ void clean_fcurve(FCurve *fcu, float thresh) int totCount, i; /* check if any points */ - if ((fcu == NULL) || (fcu->totvert <= 1)) + if ((fcu == NULL) || (fcu->bezt == NULL) || (fcu->totvert <= 1)) return; /* make a copy of the old BezTriples, and clear IPO curve */ @@ -286,7 +286,11 @@ void smooth_fcurve(FCurve *fcu) { BezTriple *bezt; int i, x, totSel = 0; - + + if (fcu->bezt == NULL) { + return; + } + /* first loop through - count how many verts are selected */ bezt = fcu->bezt; for (i = 0; i < fcu->totvert; i++, bezt++) { From 8a5252c1cb178cd2d57656375804c04a85e88e1b Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 11 Jun 2012 08:28:04 +0000 Subject: [PATCH 204/360] * Blur node had some irregularities at the edge of the screen only visible when doing large size blurs. also solved the catcom/mitch filter that didn't work at low/medium quality PS never use BokehBlur Gausian filter as it is 99%+ identicat as non bokeh <= top for sergey- :) --- source/blender/compositor/nodes/COM_BlurNode.cpp | 3 --- .../compositor/operations/COM_GaussianBokehBlurOperation.cpp | 3 ++- .../compositor/operations/COM_GaussianXBlurOperation.cpp | 5 +++-- .../compositor/operations/COM_GaussianYBlurOperation.cpp | 5 +++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index d9cf2c2fef0..b27b6323f49 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -45,9 +45,6 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext * c CompositorQuality quality = context->getQuality(); - if (data->filtertype == R_FILTER_MITCH || data->filtertype == R_FILTER_CATROM) { - quality = COM_QUALITY_HIGH; - } if (data->filtertype == R_FILTER_FAST_GAUSS) { FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation(); operationfgb->setData(data); diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index e522d334d8b..07cc07880e7 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -131,10 +131,11 @@ void GaussianBokehBlurOperation::executePixel(float *color, int x, int y, Memory maxy = min(maxy, inputBuffer->getRect()->ymax); maxx = min(maxx, inputBuffer->getRect()->xmax); - int index = 0; + int index; int step = QualityStepHelper::getStep(); int offsetadd = QualityStepHelper::getOffsetAdd(); for (int ny = miny ; ny < maxy ; ny +=step) { + index = ((ny-y)+this->rady) * (this->radx*2+1) + (minx-x+this->radx); int bufferindex = ((minx - bufferstartx)*4)+((ny-bufferstarty)*4*bufferwidth); for (int nx = minx ; nx < maxx ; nx +=step) { float multiplyer = gausstab[index]; diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp index 2eb51b4577f..a7e443838a9 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp @@ -93,12 +93,13 @@ void GaussianXBlurOperation::executePixel(float *color, int x, int y, MemoryBuff maxy = min(maxy, inputBuffer->getRect()->ymax); maxx = min(maxx, inputBuffer->getRect()->xmax); - int index = 0; + int index; int step = getStep(); int offsetadd = getOffsetAdd(); int bufferindex = ((minx - bufferstartx)*4)+((miny-bufferstarty)*4*bufferwidth); for (int nx = minx ; nx < maxx ; nx +=step) { - float multiplyer = gausstab[index++]; + index = (nx-x)+this->rad; + float multiplyer = gausstab[index]; tempColor[0] += multiplyer * buffer[bufferindex]; tempColor[1] += multiplyer * buffer[bufferindex+1]; tempColor[2] += multiplyer * buffer[bufferindex+2]; diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp index 28e8e548530..c7da43fc20f 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -91,10 +91,11 @@ void GaussianYBlurOperation::executePixel(float *color, int x, int y, MemoryBuff maxx = min(maxx, inputBuffer->getRect()->xmax); int step = getStep(); - int index = 0; + int index; for (int ny = miny ; ny < maxy ; ny +=step) { + index = (ny-y)+this->rad; int bufferindex = ((minx - bufferstartx)*4)+((ny-bufferstarty)*4*bufferwidth); - float multiplyer = gausstab[index++]; + float multiplyer = gausstab[index]; tempColor[0] += multiplyer * buffer[bufferindex]; tempColor[1] += multiplyer * buffer[bufferindex+1]; tempColor[2] += multiplyer * buffer[bufferindex+2]; From 8015b7a4a5bcf39250b96bc3744498c50d0c641c Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Mon, 11 Jun 2012 08:37:35 +0000 Subject: [PATCH 205/360] Fix applying object transform to multires objects. Bug [#31785] Applying a transform to an object with multires weird result Was reading interleaved coord/mask data incorrectly since paint mask merge. Fixed by using two separate CCGKeys. Some additional code cleanup: deduplicate multires tangent matrix calculation. --- source/blender/blenkernel/intern/multires.c | 70 ++++++++------------- 1 file changed, 25 insertions(+), 45 deletions(-) diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 4cbfb4f0f3e..cb6f6823f48 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -548,13 +548,6 @@ static void multires_reallocate_mdisps(int totloop, MDisps *mdisps, int lvl) } } -static void column_vectors_to_mat3(float mat[][3], float v1[3], float v2[3], float v3[3]) -{ - copy_v3_v3(mat[0], v1); - copy_v3_v3(mat[1], v2); - copy_v3_v3(mat[2], v3); -} - static void multires_copy_grid(float (*gridA)[3], float (*gridB)[3], int sizeA, int sizeB) { int x, y, j, skip; @@ -962,7 +955,7 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updat multires_subdivide(mmd, ob, mmd->totlvl + 1, updateblock, simple); } -void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3]) +static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3]) { if (axis == 0) { if (x == key->grid_size - 1) { @@ -986,6 +979,19 @@ void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, floa } } +/* Construct 3x3 tangent-space matrix in 'mat' */ +static void grid_tangent_matrix(float mat[3][3], const CCGKey *key, + int x, int y, CCGElem *grid) +{ + grid_tangent(key, x, y, 0, grid, mat[0]); + normalize_v3(mat[0]); + + grid_tangent(key, x, y, 1, grid, mat[1]); + normalize_v3(mat[1]); + + copy_v3_v3(mat[2], CCG_grid_elem_no(key, grid, x, y)); +} + static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; @@ -1067,22 +1073,11 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm for (x = 0; x < gridSize; x++) { float *co = CCG_grid_elem_co(&key, grid, x, y); float *sco = CCG_grid_elem_co(&key, subgrid, x, y); - float *no = CCG_grid_elem_no(&key, subgrid, x, y); float *data = dispgrid[dGridSize * y * dSkip + x * dSkip]; - float mat[3][3], tx[3], ty[3], disp[3], d[3], mask; + float mat[3][3], disp[3], d[3], mask; /* construct tangent space matrix */ - grid_tangent(&key, x, y, 0, subGridData[gIndex], tx); - normalize_v3(tx); - - grid_tangent(&key, x, y, 1, subGridData[gIndex], ty); - normalize_v3(ty); - - //mul_v3_fl(tx, 1.0f/(gridSize-1)); - //mul_v3_fl(ty, 1.0f/(gridSize-1)); - //cross_v3_v3v3(no, tx, ty); - - column_vectors_to_mat3(mat, tx, ty, no); + grid_tangent_matrix(mat, &key, x, y, subgrid); switch (op) { case APPLY_DISPLACEMENTS: @@ -1344,17 +1339,11 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) for (y = 0; y < gridSize; y++) { for (x = 0; x < gridSize; x++) { float *data = dispgrid[dGridSize * y * dSkip + x * dSkip]; - float *no = CCG_grid_elem_no(&key, subgrid, x, y); float *co = CCG_grid_elem_co(&key, subgrid, x, y); - float mat[3][3], tx[3], ty[3], dco[3]; + float mat[3][3], dco[3]; /* construct tangent space matrix */ - grid_tangent(&key, x, y, 0, subGridData[gIndex], tx); - normalize_v3(tx); - - grid_tangent(&key, x, y, 1, subGridData[gIndex], ty); - normalize_v3(ty); - column_vectors_to_mat3(mat, tx, ty, no); + grid_tangent_matrix(mat, &key, x, y, subgrid); /* convert to absolute coordinates in space */ if (from == MULTIRES_SPACE_TANGENT) { @@ -1368,8 +1357,6 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) copy_v3_v3(dco, data); } - column_vectors_to_mat3(mat, tx, ty, no); - /*now, convert to desired displacement type*/ if (to == MULTIRES_SPACE_TANGENT) { invert_m3(mat); @@ -2142,7 +2129,7 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3]) { DerivedMesh *dm = NULL, *cddm = NULL, *subdm = NULL; CCGElem **gridData, **subGridData; - CCGKey key; + CCGKey dm_key, subdm_key; Mesh *me = (Mesh *)ob->data; MPoly *mpoly = me->mpoly; /* MLoop *mloop = me->mloop; */ /* UNUSED */ @@ -2180,12 +2167,12 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3]) dm = subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0); cddm->release(cddm); - /*numGrids = dm->getNumGrids(dm);*/ /*UNUSED*/ gridSize = dm->getGridSize(dm); gridData = dm->getGridData(dm); gridOffset = dm->getGridOffset(dm); - dm->getGridKey(dm, &key); + dm->getGridKey(dm, &dm_key); subGridData = subdm->getGridData(subdm); + subdm->getGridKey(subdm, &subdm_key); dGridSize = multires_side_tot[high_mmd.totlvl]; dSkip = (dGridSize - 1) / (gridSize - 1); @@ -2203,20 +2190,13 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3]) for (y = 0; y < gridSize; y++) { for (x = 0; x < gridSize; x++) { - float *co = CCG_grid_elem_co(&key, grid, x, y); - float *sco = CCG_grid_elem_co(&key, subgrid, x, y); - float *no = CCG_grid_elem_no(&key, grid, x, y); + float *co = CCG_grid_elem_co(&dm_key, grid, x, y); + float *sco = CCG_grid_elem_co(&subdm_key, subgrid, x, y); float *data = dispgrid[dGridSize * y * dSkip + x * dSkip]; - float mat[3][3], tx[3], ty[3], disp[3]; + float mat[3][3], disp[3]; /* construct tangent space matrix */ - grid_tangent(&key, x, y, 0, gridData[gIndex], tx); - normalize_v3(tx); - - grid_tangent(&key, x, y, 1, gridData[gIndex], ty); - normalize_v3(ty); - - column_vectors_to_mat3(mat, tx, ty, no); + grid_tangent_matrix(mat, &dm_key, x, y, grid); /* scale subgrid coord and calculate displacement */ mul_m3_v3(smat, sco); From fccd8acb357014a7112ea7f51055edb710b5667c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 11 Jun 2012 09:05:17 +0000 Subject: [PATCH 206/360] UI messages fixes... --- source/blender/makesrna/intern/rna_color.c | 2 +- source/blender/makesrna/intern/rna_tracking.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index ce0b396caf7..ecdfe1505c8 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -589,7 +589,7 @@ static void rna_def_histogram(BlenderRNA *brna) prop = RNA_def_property(srna, "show_line", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", HISTO_FLAG_LINE); - RNA_def_property_ui_text(prop, "Show Line", "Displays lines rather then filled shapes"); + RNA_def_property_ui_text(prop, "Show Line", "Display lines rather then filled shapes"); RNA_def_property_ui_icon(prop, ICON_IPO, 0); } diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 9fae4c496df..f1f962f6701 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -469,17 +469,17 @@ void rna_trackingMarkers_delete_frame(MovieTrackingTrack *track, int framenr) static EnumPropertyItem tracker_motion_model[] = { {TRACK_MOTION_MODEL_HOMOGRAPHY, "Perspective", 0, "Perspective", - "Search for markers that are perspectively deformed (homography) between frames."}, + "Search for markers that are perspectively deformed (homography) between frames"}, {TRACK_MOTION_MODEL_AFFINE, "Affine", 0, "Affine", - "Search for markers that are affine-deformed (t, r, k, and skew) between frames."}, + "Search for markers that are affine-deformed (t, r, k, and skew) between frames"}, {TRACK_MOTION_MODEL_TRANSLATION_ROTATION_SCALE, "LocRotScale", 0, "LocRotScale", - "Search for markers that are translated, rotated, and scaled between frames."}, + "Search for markers that are translated, rotated, and scaled between frames"}, {TRACK_MOTION_MODEL_TRANSLATION_SCALE, "LocScale", 0, "LocScale", - "Search for markers that are translated and scaled between frames."}, + "Search for markers that are translated and scaled between frames"}, {TRACK_MOTION_MODEL_TRANSLATION_ROTATION, "LocRot", 0, "LocRot", - "Search for markers that are translated and rotated between frames."}, + "Search for markers that are translated and rotated between frames"}, {TRACK_MOTION_MODEL_TRANSLATION, "Loc", 0, "Loc", - "Search for markers that are translated between frames."}, + "Search for markers that are translated between frames"}, {0, NULL, 0, NULL, NULL} }; @@ -646,7 +646,7 @@ static void rna_def_trackingSettings(BlenderRNA *brna) /* default use_normalization */ prop = RNA_def_property(srna, "default_use_normalization", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); - RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking. Slower"); + RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking (slower)"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* default minmal correlation */ @@ -831,8 +831,8 @@ static void rna_def_trackingMarker(BlenderRNA *brna) RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x2); RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_ui_text(prop, "Pattern Corners", - "Array of coordinates which represents patter's corners in " - " normalized coordinates relative to marker position"); + "Array of coordinates which represents pattern's corners in " + "normalized coordinates relative to marker position"); RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_markerPattern_update"); /* search */ From 075b35572ecaa6e6e47e2e6e97c3711df74580ed Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 11 Jun 2012 09:18:55 +0000 Subject: [PATCH 207/360] This node was never actually commited to svn. --- source/blender/nodes/NOD_composite.h | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index efa107a2223..33d6327ece1 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -81,7 +81,6 @@ void register_node_type_cmp_bilateralblur(struct bNodeTreeType *ttype); void register_node_type_cmp_vecblur(struct bNodeTreeType *ttype); void register_node_type_cmp_dilateerode(struct bNodeTreeType *ttype); void register_node_type_cmp_defocus(struct bNodeTreeType *ttype); -void register_node_type_cmp_denoise(struct bNodeTreeType *ttype); void register_node_type_cmp_valtorgb(struct bNodeTreeType *ttype); void register_node_type_cmp_rgbtobw(struct bNodeTreeType *ttype); From abfe63d8aacbc07363ab71ad530a7cfbd49b15ac Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Jun 2012 09:24:25 +0000 Subject: [PATCH 208/360] updates to context docs and add missing member to node context 'node_context_dir'. --- doc/python_api/sphinx_doc_gen.py | 5 +++++ source/blender/editors/space_node/space_node.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index bfef94b35d7..d61b5bb7521 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -934,6 +934,8 @@ def pycontext2sphinx(basepath): "image_context_dir", "node_context_dir", "text_context_dir", + "clip_context_dir", + "sequencer_context_dir", ) # Changes in blender will force errors here @@ -943,6 +945,7 @@ def pycontext2sphinx(basepath): "active_object": ("Object", False), "active_operator": ("Operator", False), "active_pose_bone": ("PoseBone", False), + "active_node": ("Node", False), "armature": ("Armature", False), "bone": ("Bone", False), "brush": ("Brush", False), @@ -953,6 +956,8 @@ def pycontext2sphinx(basepath): "dynamic_paint": ("DynamicPaintModifier", False), "edit_bone": ("EditBone", False), "edit_image": ("Image", False), + "edit_mask": ("Mask", False), + "edit_movieclip": ("MovieClip", False), "edit_object": ("Object", False), "edit_text": ("Text", False), "editable_bones": ("EditBone", True), diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 66919935d48..c477e2bcdda 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -468,7 +468,7 @@ static void node_region_listener(ARegion *ar, wmNotifier *wmn) } } -const char *node_context_dir[] = {"selected_nodes", NULL}; +const char *node_context_dir[] = {"selected_nodes", "active_node", NULL}; static int node_context(const bContext *C, const char *member, bContextDataResult *result) { From a18b303a7656c446b41d7b75d7d512e0f8a87040 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Mon, 11 Jun 2012 09:41:08 +0000 Subject: [PATCH 209/360] Fix incorrectly deleted elements in array modifier caps. Add check for merging vertices into vertices that are themselves marked for merge, was already done for array eleements but not end caps. Fixes bug [#31695] Array Modifier: End Cap fails if all vertices are merged Also corrected some reversed assert arguments. --- source/blender/bmesh/intern/bmesh_marking.c | 2 +- source/blender/bmesh/intern/bmesh_operators.c | 2 +- source/blender/modifiers/intern/MOD_array.c | 10 +++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 1720ee4f55a..59817043eed 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -458,7 +458,7 @@ static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag, BMIter iter; int tot = 0; - BLI_assert(ELEM(TRUE, FALSE, test_for_enabled)); + BLI_assert(ELEM(test_for_enabled, TRUE, FALSE)); if (htype & BM_VERT) { for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) { diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 82ad5c1805b..65288522b3b 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -698,7 +698,7 @@ static void bmo_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *sl BMOpSlot *output = BMO_slot_get(op, slotname); int totelement = 0, i = 0; - BLI_assert(ELEM(TRUE, FALSE, test_for_enabled)); + BLI_assert(ELEM(test_for_enabled, TRUE, FALSE)); if (test_for_enabled) totelement = BM_mesh_elem_hflag_count_enabled(bm, htype, hflag, TRUE); diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 39e08c1cb5d..41057234d9b 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -220,9 +220,12 @@ static void bm_merge_dm_transform(BMesh *bm, DerivedMesh *dm, float mat[4][4], const char *dupe_slot_name, BMOperator *weld_op) { - BMVert *v, *v2; + BMVert *v, *v2, *v3; BMIter iter; + /* Add the DerivedMesh's elements to the BMesh. The pre-existing + elements were already tagged, so the new elements can be + identified by not having the BM_ELEM_TAG flag set. */ DM_to_bmesh_ex(dm, bm); if (amd->flags & MOD_ARR_MERGE) { @@ -252,6 +255,11 @@ static void bm_merge_dm_transform(BMesh *bm, DerivedMesh *dm, float mat[4][4], /* add new merge targets to weld operator */ BMO_ITER (v, &oiter, bm, &find_op, "targetmapout", 0) { v2 = BMO_iter_map_value_p(&oiter); + /* check in case the target vertex (v2) is already marked + * for merging */ + while ((v3 = BMO_slot_map_ptr_get(bm, weld_op, "targetmap", v2))) { + v2 = v3; + } BMO_slot_map_ptr_insert(bm, weld_op, "targetmap", v, v2); } From 9a92b0c5c42ff5960efea18bf83526dd815aa64b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Jun 2012 10:11:31 +0000 Subject: [PATCH 210/360] template for python node operators --- release/scripts/templates/operator_node.py | 58 ++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 release/scripts/templates/operator_node.py diff --git a/release/scripts/templates/operator_node.py b/release/scripts/templates/operator_node.py new file mode 100644 index 00000000000..bed2a1300a4 --- /dev/null +++ b/release/scripts/templates/operator_node.py @@ -0,0 +1,58 @@ +import bpy + +def main(operator, context): + space = context.space_data + node_tree = space.node_tree + node_active = context.active_node + node_selected = context.selected_nodes + + # now we have the context, perform a simple operation + if node_active in node_selected: + node_selected.remove(node_active) + if len(node_selected) != 1: + operator.report({'ERROR'}, "2 nodes must be selected") + return + + node_other, = node_selected + + # now we have 2 nodes to operate on + if not node_active.inputs: + operator.report({'ERROR'}, "Active node has no inputs") + return + + if not node_other.outputs: + operator.report({'ERROR'}, "Selected node has no outputs") + return + + socket_in = node_active.inputs[0] + socket_out = node_other.outputs[0] + + # add a link between the two nodes + node_link = node_tree.links.new(socket_in, socket_out) + + +class NodeOperator(bpy.types.Operator): + '''Tooltip''' + bl_idname = "node.simple_operator" + bl_label = "Simple Node Operator" + + @classmethod + def poll(cls, context): + space = context.space_data + return space.type == 'NODE_EDITOR' + + def execute(self, context): + main(context) + return {'FINISHED'} + + +def register(): + bpy.utils.register_class(NodeOperator) + + +def unregister(): + bpy.utils.unregister_class(NodeOperator) + + +if __name__ == "__main__": + register() From d214b140522424a6794a0f70b2bd738ec41a7005 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Mon, 11 Jun 2012 10:14:46 +0000 Subject: [PATCH 211/360] Add missing/incorrect selection flushes. Added selection flush after loop cut, changed select_linked_pick's flush to use the em selection flag. Fixes bug [#31715] Cases where verts and edges are selected but not relevant faces --- source/blender/editors/mesh/editmesh_loopcut.c | 2 ++ source/blender/editors/mesh/editmesh_select.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 185c804661d..15e3033b7eb 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -329,6 +329,8 @@ static void ringsel_finish(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, CTX_data_scene(C)); } + else + EDBM_selectmode_flush(lcd->em); WM_event_add_notifier(C, NC_GEOM | ND_SELECT | ND_DATA, lcd->ob->data); DAG_id_tag_update(lcd->ob->data, 0); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 0a8fe142aaf..57bce6b9de4 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -1889,7 +1889,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent * } BMW_end(&walker); - BM_mesh_select_mode_flush(bm); + EDBM_selectmode_flush(em); } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); From eba2f2320cf1e0415897240b82d9ff892ce85ae7 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Mon, 11 Jun 2012 11:00:58 +0000 Subject: [PATCH 212/360] Fix invalid array index in armature_deform_verts(). Check that the def_nr is non-negative before using as index. Fixes bug [#31700] Crash when opening .blend file on 64bit environment --- source/blender/blenkernel/intern/armature.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 5ad81db1979..9af1d5f52c4 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -986,7 +986,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float for (j = dvert->totweight; j != 0; j--, dw++) { const int index = dw->def_nr; - if (index < defbase_tot && (pchan = defnrToPC[index])) { + if (index >= 0 && index < defbase_tot && (pchan = defnrToPC[index])) { float weight = dw->weight; Bone *bone = pchan->bone; pdef_info = pdef_info_array + defnrToPCIndex[index]; From 2a4a8fd43e83d4961ca25ad16b965217c274e1c1 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 11 Jun 2012 11:11:11 +0000 Subject: [PATCH 213/360] Cosmetic fixes * PoseBone struct didn't have an icon * Comment fixes (stil referenced IPO's) --- source/blender/editors/animation/keyframes_general.c | 6 +++--- source/blender/makesrna/intern/rna_pose.c | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index f29be418941..a8f8d2974e5 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -187,7 +187,7 @@ void clean_fcurve(FCurve *fcu, float thresh) if ((fcu == NULL) || (fcu->bezt == NULL) || (fcu->totvert <= 1)) return; - /* make a copy of the old BezTriples, and clear IPO curve */ + /* make a copy of the old BezTriples, and clear F-Curve */ old_bezts = fcu->bezt; totCount = fcu->totvert; fcu->bezt = NULL; @@ -412,13 +412,13 @@ void sample_fcurve(FCurve *fcu) if (range) { value_cache = MEM_callocN(sizeof(TempFrameValCache) * range, "IcuFrameValCache"); - /* sample values */ + /* sample values */ for (n = 1, fp = value_cache; n < range && fp; n++, fp++) { fp->frame = (float)(sfra + n); fp->val = evaluate_fcurve(fcu, fp->frame); } - /* add keyframes with these, tagging as 'breakdowns' */ + /* add keyframes with these, tagging as 'breakdowns' */ for (n = 1, fp = value_cache; n < range && fp; n++, fp++) { nIndex = insert_vert_fcurve(fcu, fp->frame, fp->val, 1); BEZKEYTYPE(fcu->bezt + nIndex) = BEZT_KEYTYPE_BREAKDOWN; diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 5139e17b06d..eaf1ae09524 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -746,6 +746,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Pose Bone", "Channel defining pose data for a bone in a Pose"); RNA_def_struct_path_func(srna, "rna_PoseBone_path"); RNA_def_struct_idprops_func(srna, "rna_PoseBone_idprops"); + RNA_def_struct_ui_icon(srna, ICON_BONE_DATA); /* Bone Constraints */ prop = RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE); From 6674106d30a010c590aec1e7ab0b929155bde2bd Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 11 Jun 2012 11:40:36 +0000 Subject: [PATCH 214/360] Fixed issue with disappearing Clip/Track menu from GP panel in Clip Editor caused by switching to Track GP without having active track. --- .../blender/editors/gpencil/gpencil_buttons.c | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index c8d03bcbf2f..4c125ebe013 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -231,6 +231,23 @@ typedef enum eGP_Stroke_Ops { STROKE_OPTS_V3D_ON, } eGP_Stroke_Ops; +static void draw_gpencil_space_specials(const bContext *C, uiLayout *layout) +{ + uiLayout *col, *row; + SpaceClip *sc = CTX_wm_space_clip(C); + + col = uiLayoutColumn(layout, 0); + + if (sc) { + bScreen *screen = CTX_wm_screen(C); + PointerRNA sc_ptr; + + RNA_pointer_create(&screen->id, &RNA_SpaceClipEditor, sc, &sc_ptr); + row = uiLayoutRow(col, 1); + uiItemR(row, &sc_ptr, "grease_pencil_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + } +} + /* Draw the contents for a grease-pencil panel*/ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, PointerRNA *ctx_ptr) { @@ -247,15 +264,6 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin /* draw gpd settings first ------------------------------------- */ col = uiLayoutColumn(layout, 0); - if (sc) { - bScreen *screen = CTX_wm_screen(C); - PointerRNA sc_ptr; - - RNA_pointer_create(&screen->id, &RNA_SpaceClipEditor, sc, &sc_ptr); - row = uiLayoutRow(col, 1); - uiItemR(row, &sc_ptr, "grease_pencil_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE); - } - /* current Grease Pencil block */ /* TODO: show some info about who owns this? */ uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink"); @@ -315,6 +323,8 @@ void gpencil_panel_standard(const bContext *C, Panel *pa) /* if (v3d->flag2 & V3D_DISPGP)... etc. */ + draw_gpencil_space_specials(C, pa->layout); + /* get pointer to Grease Pencil Data */ gpd_ptr = gpencil_data_get_pointers((bContext *)C, &ptr); From 6ab087ff994fab9557d99a4ba58393c7821b228c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 11 Jun 2012 11:40:54 +0000 Subject: [PATCH 215/360] Scale search area when doing planar tracking Helps keeping features tracked when there's large scale happens without need to manually re-adjust search area. Currently using factor of pattern's boundbox scale, but probably could be done in more accurate way? --- extern/libmv/libmv-capi.cpp | 8 +++--- extern/libmv/libmv-capi.h | 4 +-- source/blender/blenkernel/BKE_tracking.h | 2 +- source/blender/blenkernel/intern/tracking.c | 29 ++++++++++++++++++--- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index ffa065f08fe..8751e1e190b 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -357,8 +357,8 @@ void libmv_regionTrackerDestroy(libmv_RegionTracker *libmv_tracker) /* TrackRegion (new planar tracker) */ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, - const float *image1, const float *image2, - int width, int height, + const float *image1, int image1_width, int image1_height, + const float *image2, int image2_width, int image2_height, const double *x1, const double *y1, struct libmv_trackRegionResult *result, double *x2, double *y2) @@ -400,8 +400,8 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, /* Convert from raw float buffers to libmv's FloatImage. */ libmv::FloatImage old_patch, new_patch; - floatBufToImage(image1, width, height, 1, &old_patch); - floatBufToImage(image2, width, height, 1, &new_patch); + floatBufToImage(image1, image1_width, image1_height, 1, &old_patch); + floatBufToImage(image2, image2_width, image2_height, 1, &new_patch); libmv::TrackRegionResult track_region_result; libmv::TrackRegion(old_patch, new_patch, xx1, yy1, track_region_options, xx2, yy2, &track_region_result); diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index 6f4b5dea384..fe759b06fe4 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -65,8 +65,8 @@ struct libmv_trackRegionResult { double correlation; }; int libmv_trackRegion(const struct libmv_trackRegionOptions *options, - const float *image1, const float *image2, - int width, int height, + const float *image1, int image1_width, int image1_height, + const float *image2, int image2_width, int image2_height, const double *x1, const double *y1, struct libmv_trackRegionResult *result, double *x2, double *y2); diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index a13674cd6e5..716b65408e1 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -57,7 +57,7 @@ struct MovieTrackingMarker *BKE_tracking_insert_marker(struct MovieTrackingTrack struct MovieTrackingMarker *marker); void BKE_tracking_delete_marker(struct MovieTrackingTrack *track, int framenr); -void BKE_tracking_marker_pattern_minmax(struct MovieTrackingMarker *marker, float min[2], float max[2]); +void BKE_tracking_marker_pattern_minmax(const struct MovieTrackingMarker *marker, float min[2], float max[2]); struct MovieTrackingMarker *BKE_tracking_get_marker(struct MovieTrackingTrack *track, int framenr); struct MovieTrackingMarker *BKE_tracking_ensure_marker(struct MovieTrackingTrack *track, int framenr); struct MovieTrackingMarker *BKE_tracking_exact_marker(struct MovieTrackingTrack *track, int framenr); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index a3d66012303..4cfa8461f2e 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -440,7 +440,7 @@ void BKE_tracking_delete_marker(MovieTrackingTrack *track, int framenr) } } -void BKE_tracking_marker_pattern_minmax(MovieTrackingMarker *marker, float min[2], float max[2]) +void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float min[2], float max[2]) { INIT_MINMAX2(min, max); @@ -1606,6 +1606,25 @@ static ImBuf *get_adjust_ibuf(MovieTrackingContext *context, MovieTrackingTrack return ibuf; } +static void marker_search_scale_after_tracking(const MovieTrackingMarker *old_marker, MovieTrackingMarker *new_marker) +{ + float old_pat_min[2], old_pat_max[2]; + float new_pat_min[2], new_pat_max[2]; + float scale_x, scale_y; + + BKE_tracking_marker_pattern_minmax(old_marker, old_pat_min, old_pat_max); + BKE_tracking_marker_pattern_minmax(new_marker, new_pat_min, new_pat_max); + + scale_x = (new_pat_max[0] - new_pat_min[0]) / (old_pat_max[0] - old_pat_min[0]); + scale_y = (new_pat_max[1] - new_pat_min[1]) / (old_pat_max[1] - old_pat_min[1]); + + new_marker->search_min[0] *= scale_x; + new_marker->search_min[1] *= scale_y; + + new_marker->search_max[0] *= scale_x; + new_marker->search_max[1] *= scale_y; +} + #endif void BKE_tracking_sync(MovieTrackingContext *context) @@ -1752,8 +1771,10 @@ int BKE_tracking_next(MovieTrackingContext *context) /* Run the tracker! */ tracked = libmv_trackRegion(&options, - track_context->search_area, patch_new, - width, height, + track_context->search_area, + track_context->search_area_width, + track_context->search_area_height, + patch_new, width, height, src_pixel_x, src_pixel_y, &result, dst_pixel_x, dst_pixel_y); @@ -1767,6 +1788,8 @@ int BKE_tracking_next(MovieTrackingContext *context) marker_new.flag |= MARKER_TRACKED; marker_new.framenr = nextfra; + marker_search_scale_after_tracking(marker, &marker_new); + #pragma omp critical { if (context->first_time) { From 71a7fb6286637afa44dad7684f0eae80727a41c1 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 11 Jun 2012 11:54:16 +0000 Subject: [PATCH 216/360] Draw grease pencil after masks Looks like drawing grease pencil before masks was affecting projection matrix somehow which made masks invisible Anyway, drawing GP actually shall happen after masks to match how it works in other areas. --- source/blender/editors/space_clip/space_clip.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 6409ad6b171..534ab8eeb95 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -1101,9 +1101,6 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) clip_draw_main(sc, ar, scene); - /* Grease Pencil */ - clip_draw_grease_pencil((bContext *)C, 1); - if (sc->mode == SC_MODE_MASKEDIT) { int x, y; int width, height; @@ -1147,6 +1144,9 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) glPopMatrix(); } + /* Grease Pencil */ + clip_draw_grease_pencil((bContext *)C, 1); + /* reset view matrix */ UI_view2d_view_restore(C); From 5248ec57d97050f48efdd00d3106016ad4553363 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Jun 2012 12:13:41 +0000 Subject: [PATCH 217/360] minor fixes - new compositor could use uninitialized var - profile conversion could use uninitialized var - set better warnings for clang+cmake. - remove picky warnings from sphinx doc gen shell script. --- CMakeLists.txt | 14 +++++ doc/python_api/sphinx_doc_gen.sh | 2 +- release/scripts/templates/operator_node.py | 3 +- .../blender/compositor/nodes/COM_MuteNode.cpp | 61 ++++++++++--------- source/blender/imbuf/intern/divers.c | 20 ++++-- 5 files changed, 62 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 191fb61e1b4..5b70110947b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1605,6 +1605,20 @@ if(CMAKE_COMPILER_IS_GNUCC) ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable) endif() +elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + + ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall) + ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare) + ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas) + ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts) + + ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS C_WARN_ALL -Wall) + ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare) + ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas) + ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts) + ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_OVERLOADED_VIRTUAL -Wno-overloaded-virtual) # we get a lot of these, if its a problem a dev needs to look into it. + ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof) + elseif(CMAKE_C_COMPILER_ID MATCHES "Intel") ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall) diff --git a/doc/python_api/sphinx_doc_gen.sh b/doc/python_api/sphinx_doc_gen.sh index ccb293d7a0e..92461961920 100755 --- a/doc/python_api/sphinx_doc_gen.sh +++ b/doc/python_api/sphinx_doc_gen.sh @@ -61,7 +61,7 @@ if $DO_OUT_HTML ; then # annoying bug in sphinx makes it very slow unless we do this. should report. cd $SPHINXBASE - sphinx-build -n -b html sphinx-in sphinx-out + sphinx-build -b html sphinx-in sphinx-out # XXX, saves space on upload and zip, should move HTML outside # and zip up there, for now this is OK diff --git a/release/scripts/templates/operator_node.py b/release/scripts/templates/operator_node.py index bed2a1300a4..5962651995b 100644 --- a/release/scripts/templates/operator_node.py +++ b/release/scripts/templates/operator_node.py @@ -1,5 +1,6 @@ import bpy + def main(operator, context): space = context.space_data node_tree = space.node_tree @@ -14,7 +15,7 @@ def main(operator, context): return node_other, = node_selected - + # now we have 2 nodes to operate on if not node_active.inputs: operator.report({'ERROR'}, "Active node has no inputs") diff --git a/source/blender/compositor/nodes/COM_MuteNode.cpp b/source/blender/compositor/nodes/COM_MuteNode.cpp index 72303a4d6ee..d02eb2a0b98 100644 --- a/source/blender/compositor/nodes/COM_MuteNode.cpp +++ b/source/blender/compositor/nodes/COM_MuteNode.cpp @@ -44,37 +44,38 @@ void MuteNode::reconnect(ExecutionSystem * graph, OutputSocket * output) } } - NodeOperation * operation; + NodeOperation *operation; switch (output->getDataType()) { - case COM_DT_VALUE: - { - SetValueOperation *valueoperation = new SetValueOperation(); - valueoperation->setValue(0.0f); - operation = valueoperation; - break; - } - case COM_DT_VECTOR: - { - SetVectorOperation *vectoroperation = new SetVectorOperation(); - vectoroperation->setX(0.0f); - vectoroperation->setY(0.0f); - vectoroperation->setW(0.0f); - operation = vectoroperation; - break; - } - case COM_DT_COLOR: - { - SetColorOperation *coloroperation = new SetColorOperation(); - coloroperation->setChannel1(0.0f); - coloroperation->setChannel2(0.0f); - coloroperation->setChannel3(0.0f); - coloroperation->setChannel4(0.0f); - operation = coloroperation; - break; - } - /* quiet warnings */ - case COM_DT_UNKNOWN: - break; + case COM_DT_VALUE: + { + SetValueOperation *valueoperation = new SetValueOperation(); + valueoperation->setValue(0.0f); + operation = valueoperation; + break; + } + case COM_DT_VECTOR: + { + SetVectorOperation *vectoroperation = new SetVectorOperation(); + vectoroperation->setX(0.0f); + vectoroperation->setY(0.0f); + vectoroperation->setW(0.0f); + operation = vectoroperation; + break; + } + case COM_DT_COLOR: + { + SetColorOperation *coloroperation = new SetColorOperation(); + coloroperation->setChannel1(0.0f); + coloroperation->setChannel2(0.0f); + coloroperation->setChannel3(0.0f); + coloroperation->setChannel4(0.0f); + operation = coloroperation; + break; + } + /* quiet warnings */ + case COM_DT_UNKNOWN: + operation = NULL; + break; } if (operation) { diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index 279fd5d59be..1b68c520336 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -538,12 +538,16 @@ void IMB_rect_from_float(ImBuf *ibuf) imb_addrectImBuf(ibuf); /* determine profiles */ - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) + if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { profile_from = IB_PROFILE_LINEAR_RGB; - else if (ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) + } + else if (ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) { profile_from = IB_PROFILE_SRGB; - else + } + else { + profile_from = IB_PROFILE_SRGB; /* should never happen */ BLI_assert(0); + } /* do conversion */ IMB_buffer_byte_from_float((uchar *)ibuf->rect, ibuf->rect_float, @@ -571,12 +575,16 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w imb_addrectImBuf(ibuf); /* determine profiles */ - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) + if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { profile_from = IB_PROFILE_LINEAR_RGB; - else if (ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) + } + else if (ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) { profile_from = IB_PROFILE_SRGB; - else + } + else { + profile_from = IB_PROFILE_SRGB; /* should never happen */ BLI_assert(0); + } /* do conversion */ rect_float = ibuf->rect_float + (x + y * ibuf->x) * ibuf->channels; From 5f1eec564f27c0c542940571d14cd7fdb8194325 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Mon, 11 Jun 2012 13:00:35 +0000 Subject: [PATCH 218/360] Fix compilation of new tracker for MinGW/MinGW64 --- .../ceres/internal/ceres/collections_port.h | 2 +- .../ceres/patches/collections_port.h.mingw.patch | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 extern/libmv/third_party/ceres/patches/collections_port.h.mingw.patch diff --git a/extern/libmv/third_party/ceres/internal/ceres/collections_port.h b/extern/libmv/third_party/ceres/internal/ceres/collections_port.h index e125f3fffcd..55f72539023 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/collections_port.h +++ b/extern/libmv/third_party/ceres/internal/ceres/collections_port.h @@ -53,7 +53,7 @@ struct HashMap : tr1::unordered_map {}; template struct HashSet : tr1::unordered_set {}; -#ifdef _WIN32 +#if defined(_WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__) #define GG_LONGLONG(x) x##I64 #define GG_ULONGLONG(x) x##UI64 #else diff --git a/extern/libmv/third_party/ceres/patches/collections_port.h.mingw.patch b/extern/libmv/third_party/ceres/patches/collections_port.h.mingw.patch new file mode 100644 index 00000000000..bbb366e22bc --- /dev/null +++ b/extern/libmv/third_party/ceres/patches/collections_port.h.mingw.patch @@ -0,0 +1,13 @@ +Index: internal/ceres/collections_port.h +=================================================================== +--- internal/ceres/collections_port.h (revision 47730) ++++ internal/ceres/collections_port.h (working copy) +@@ -53,7 +53,7 @@ + template + struct HashSet : tr1::unordered_set {}; + +-#ifdef _WIN32 ++#if defined(_WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__) + #define GG_LONGLONG(x) x##I64 + #define GG_ULONGLONG(x) x##UI64 + #else From edecf49d8408f565963ed03bc795b7eff712ac5d Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Mon, 11 Jun 2012 15:28:45 +0000 Subject: [PATCH 219/360] Fix for node 'make group' operator in combination with frame nodes. When a selected node is attached to an unselected frame, the parent pointer would end up pointing to a different ID data block. --- source/blender/nodes/intern/node_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 3d1b656fc4e..78d21e5d4e4 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -176,6 +176,10 @@ bNode *node_group_make_from_selected(bNodeTree *ntree) BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); } + /* ensure valid parent pointers, detach if parent stays outside the group */ + if (node->parent && !(node->parent->flag & NODE_SELECT)) + nodeDetachNode(node); + /* change node-collection membership */ BLI_remlink(&ntree->nodes, node); BLI_addtail(&ngroup->nodes, node); From 854502d2e3dc5d0c08721bc3a6a4e08be6189fda Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Mon, 11 Jun 2012 16:23:10 +0000 Subject: [PATCH 220/360] Add user preference "GPU Mipmap Generation" under the System/OpenGL subpanel to calculate image mipmapping on the GPU, saving upload and calculation time. Default is off just in case. --- .../scripts/startup/bl_ui/space_userpref.py | 1 + source/blender/gpu/GPU_draw.h | 3 ++ source/blender/gpu/intern/gpu_draw.c | 31 ++++++++++++++++--- source/blender/makesdna/DNA_userdef_types.h | 2 +- source/blender/makesrna/intern/rna_userdef.c | 10 ++++++ .../windowmanager/intern/wm_init_exit.c | 3 +- 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index dec3960f376..2d349931dc4 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -434,6 +434,7 @@ class USERPREF_PT_system(Panel): col.label(text="OpenGL:") col.prop(system, "gl_clip_alpha", slider=True) col.prop(system, "use_mipmaps") + col.prop(system, "use_gpu_mipmap") col.prop(system, "use_16bit_textures") col.label(text="Anisotropic Filtering") col.prop(system, "anisotropic_filter", text="") diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index 89976699114..438cfd6b741 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -112,6 +112,9 @@ void GPU_paint_set_mipmap(int mipmap); void GPU_set_anisotropic(float value); float GPU_get_anisotropic(void); +/* enable gpu mipmapping */ +void GPU_set_gpu_mipmapping(int gpu_mipmap); + /* Image updates and free * - these deal with images bound as opengl textures */ diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 3e53f2f3836..a1bd8dcb3a3 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -234,11 +234,23 @@ static struct GPUTextureState { int alphablend; float anisotropic; + int gpu_mipmap; MTFace *lasttface; -} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, 0, -1, 1.f, NULL}; +} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, 0, -1, 1.f, 0, NULL}; /* Mipmap settings */ +void GPU_set_gpu_mipmapping(int gpu_mipmap){ + int old_value = GTS.gpu_mipmap; + + /* only actually enable if it's supported */ + GTS.gpu_mipmap = gpu_mipmap && GLEW_EXT_framebuffer_object; + + if(old_value != GTS.gpu_mipmap) { + GPU_free_images(); + } +} + void GPU_set_mipmap(int mipmap) { if (GTS.domipmap != (mipmap != 0)) { @@ -632,10 +644,19 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); } else { - if (use_high_bit_depth) - gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA16, rectw, recth, GL_RGBA, GL_FLOAT, frect); - else - gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect); + if(GTS.gpu_mipmap) { + if (use_high_bit_depth) + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect); + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect); + + glGenerateMipmapEXT(GL_TEXTURE_2D); + } else { + if (use_high_bit_depth) + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA16, rectw, recth, GL_RGBA, GL_FLOAT, frect); + else + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect); + } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 5465dbf6e3c..1c2844cd8a7 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -412,7 +412,7 @@ typedef struct UserDef { short widget_unit; /* defaults to 20 for 72 DPI setting */ short anisotropic_filter; - short use_16bit_textures, pad8; + short use_16bit_textures, use_gpu_mipmap; float ndof_sensitivity; /* overall sensitivity of 3D mouse */ int ndof_flag; /* flags for 3D mouse */ diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 84723e95e80..42eb06b137a 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -144,6 +144,11 @@ static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA rna_userdef_update(bmain, scene, ptr); } +static void rna_userdef_gl_gpu_mipmaps(Main *bmain, Scene *scene, PointerRNA *ptr) { + GPU_set_gpu_mipmapping(U.use_gpu_mipmap); + rna_userdef_update(bmain, scene, ptr); +} + static void rna_userdef_gl_texture_limit_update(Main *bmain, Scene *scene, PointerRNA *ptr) { GPU_free_images(); @@ -3143,6 +3148,11 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_ui_text(prop, "16 Bit Float Textures", "Use 16 bit per component texture for float images"); RNA_def_property_update(prop, 0, "rna_userdef_gl_use_16bit_textures"); + prop = RNA_def_property(srna, "use_gpu_mipmap", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "use_gpu_mipmap", 1); + RNA_def_property_ui_text(prop, "GPU Mipmap Generation", "Generate Image Mipmaps on the GPU"); + RNA_def_property_update(prop, 0, "rna_userdef_gl_gpu_mipmaps"); + prop = RNA_def_property(srna, "use_vertex_buffer_objects", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_VBO); RNA_def_property_ui_text(prop, "VBOs", diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index ab377d53ec7..c82cae8ac92 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -178,7 +178,8 @@ void WM_init(bContext *C, int argc, const char **argv) GPU_extensions_init(); GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP)); GPU_set_anisotropic(U.anisotropic_filter); - + GPU_set_gpu_mipmapping(U.use_gpu_mipmap); + UI_init(); } From 28fa6da77e20e7550036a7081061109d15057d16 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Jun 2012 18:16:26 +0000 Subject: [PATCH 221/360] add missing node RNA booleans. --- source/blender/makesrna/intern/rna_nodetree.c | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 65d572c6c11..01bf3971439 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3912,6 +3912,27 @@ static void rna_def_node(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Color", "Custom color of the node body"); RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_SELECT); + RNA_def_property_ui_text(prop, "Select", ""); + + prop = RNA_def_property(srna, "show_options", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_OPTIONS); + RNA_def_property_ui_text(prop, "Show Options", ""); + + prop = RNA_def_property(srna, "show_preview", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_PREVIEW); + RNA_def_property_ui_text(prop, "Show Preview", ""); + + prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_HIDDEN); + RNA_def_property_ui_text(prop, "Hide", ""); + + prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_MUTED); + RNA_def_property_ui_text(prop, "Mute", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); + prop = RNA_def_property(srna, "show_texture", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_ACTIVE_TEXTURE); RNA_def_property_ui_text(prop, "Show Texture", "Draw node in viewport textured draw mode"); From e376cbedaff869121d979db2730cfd28ea4a75a7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Jun 2012 18:43:16 +0000 Subject: [PATCH 222/360] minor changes to jpeg2k saving based on reading v1.5 source examples. --- source/blender/imbuf/intern/jp2.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index 7d1d5906dd8..38a8e7dfd33 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -43,6 +43,7 @@ static char JP2_HEAD[] = {0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A}; /* We only need this because of how the presets are set */ +/* this typedef is copied from 'openjpeg-1.5.0/applications/codec/image_to_j2k.c' */ typedef struct img_folder { /** The directory path of the folder containing input images*/ char *imgdirpath; @@ -515,7 +516,7 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) /* initialize image components */ - memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); + memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t)); for (i = 0; i < numcomps; i++) { cmptparm[i].prec = prec; cmptparm[i].bpp = prec; @@ -535,9 +536,9 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) /* set image offset and reference grid */ image->x0 = parameters->image_offset_x0; image->y0 = parameters->image_offset_y0; - image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1; - image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1; - + image->x1 = image->x0 + (w - 1) * subsampling_dx + 1 + image->x0; + image->y1 = image->y0 + (h - 1) * subsampling_dy + 1 + image->y0; + /* set image data */ rect = (unsigned char *) ibuf->rect; rect_float = ibuf->rect_float; @@ -720,7 +721,7 @@ int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags) opj_cinfo_t *cinfo = opj_create_compress(CODEC_JP2); /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); + opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); /* setup the encoder parameters using the current image and using user parameters */ opj_setup_encoder(cinfo, ¶meters, image); From c945e03c7578a9cb044ceeb8f7f1e3b5c0e13e01 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Jun 2012 18:43:48 +0000 Subject: [PATCH 223/360] rna read/write access to ... node_tree.nodes.active --- source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/intern/node.c | 11 ++++++ .../blender/editors/space_node/space_node.c | 11 ++---- source/blender/makesrna/intern/rna_nodetree.c | 35 +++++++++++++++++++ 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index b1e5fabc456..e4d96c2219c 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -372,6 +372,7 @@ void nodeSetActive(struct bNodeTree *ntree, struct bNode *node); struct bNode *nodeGetActive(struct bNodeTree *ntree); struct bNode *nodeGetActiveID(struct bNodeTree *ntree, short idtype); int nodeSetActiveID(struct bNodeTree *ntree, short idtype, struct ID *id); +void nodeClearActive(struct bNodeTree *ntree); void nodeClearActiveID(struct bNodeTree *ntree, short idtype); struct bNode *nodeGetActiveTexture(struct bNodeTree *ntree); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index d62e91dbde5..924e6a354ef 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1313,6 +1313,17 @@ void nodeClearActiveID(bNodeTree *ntree, short idtype) node->flag &= ~NODE_ACTIVE_ID; } +void nodeClearActive(bNodeTree *ntree) +{ + bNode *node; + + if (ntree==NULL) return; + + for (node= ntree->nodes.first; node; node= node->next) + node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_ID); +} + + /* two active flags, ID nodes have special flag for buttons display */ void nodeSetActive(bNodeTree *ntree, bNode *node) { diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index c477e2bcdda..e069ba2a5fc 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -492,16 +492,11 @@ static int node_context(const bContext *C, const char *member, bContextDataResul return 1; } else if (CTX_data_equals(member, "active_node")) { - bNode *node; - if (snode->edittree) { - for (node=snode->edittree->nodes.last; node; node=node->prev) { - if (node->flag & NODE_ACTIVE) { - CTX_data_pointer_set(result, &snode->edittree->id, &RNA_Node, node); - break; - } - } + bNode *node = nodeGetActive(snode->edittree); + CTX_data_pointer_set(result, &snode->edittree->id, &RNA_Node, node); } + CTX_data_type_set(result, CTX_DATA_TYPE_POINTER); return 1; } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 01bf3971439..5ffdfe6d71d 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -634,6 +634,22 @@ static EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), PointerRNA return item; } +static PointerRNA rna_NodeTree_active_node_get(PointerRNA *ptr) +{ + bNodeTree *ntree = (bNodeTree *)ptr->data; + bNode *node = nodeGetActive(ntree); + return rna_pointer_inherit_refine(ptr, &RNA_Node, node); +} + +static void rna_NodeTree_active_node_set(PointerRNA *ptr, PointerRNA value) +{ + bNodeTree *ntree = (bNodeTree *)ptr->data; + if (value.data) + nodeSetActive(ntree, (bNode *)value.data); + else + nodeClearActive(ntree); +} + static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *reports, int type, bNodeTree *group) { @@ -3632,6 +3648,19 @@ static void rna_def_nodetree_link_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "remove all node links from the node tree"); } +/* shared between all note tree types*/ +static void rna_def_nodetree_active_api(StructRNA *srna, PropertyRNA *cprop) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "Node"); + RNA_def_property_pointer_funcs(prop, "rna_NodeTree_active_node_get", "rna_NodeTree_active_node_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "Active Node", "Active node in this tree"); + RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL); +} + static void rna_def_composite_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; @@ -3661,6 +3690,8 @@ static void rna_def_composite_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear"); RNA_def_function_ui_description(func, "Remove all nodes from this node tree"); + + rna_def_nodetree_active_api(srna, cprop); } static void rna_def_shader_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop) @@ -3692,6 +3723,8 @@ static void rna_def_shader_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear"); RNA_def_function_ui_description(func, "Remove all nodes from this node tree"); + + rna_def_nodetree_active_api(srna, cprop); } static void rna_def_texture_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop) @@ -3723,6 +3756,8 @@ static void rna_def_texture_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear"); RNA_def_function_ui_description(func, "Remove all nodes from this node tree"); + + rna_def_nodetree_active_api(srna, cprop); } static void rna_def_node_socket(BlenderRNA *brna) From cf0d350b5199b2a5ecc4b70e9fba51ae780b3711 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 11 Jun 2012 18:58:34 +0000 Subject: [PATCH 224/360] Fixing first part of [#31760] Assignments not working properly for Object.dimensions Problem was in fact that non-linear-contiguous axis assignement was broken (i.e. location.xy would work as expected, but location.xz would only affect .x part)... Now all possibilities should work fine. Did not try to fix the problem specific to obj.dimension (when assigning multiple times to this array, only the last one is taken into account - in fact, a simple print() shows that assigning to dimension is not taken into account immediately), not sure whether this is normal behavior, or if we need a specific "update" of some kind for this prop? --- source/blender/python/mathutils/mathutils_Vector.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index 07bda4c2b91..54044b62e04 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -2268,6 +2268,11 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure axis_from = 0; swizzleClosure = GET_INT_FROM_POINTER(closure); + /* We must first copy current vec into tvec, else some org values may be lost. + * See [#31760]. + * Assuming self->size can't be higher than MAX_DIMENSIONS! */ + memcpy(tvec, self->vec, self->size * sizeof(float)); + while (swizzleClosure & SWIZZLE_VALID_AXIS) { axis_to = swizzleClosure & SWIZZLE_AXIS; tvec[axis_to] = vec_assign[axis_from]; @@ -2275,7 +2280,9 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure axis_from++; } - memcpy(self->vec, tvec, axis_from * sizeof(float)); + /* We must copy back the whole tvec into vec, else some changes may be lost (e.g. xz...). + * See [#31760]. */ + memcpy(self->vec, tvec, self->size * sizeof(float)); /* continue with BaseMathObject_WriteCallback at the end */ if (BaseMath_WriteCallback(self) == -1) From 21e4b12e7a1b821e0eab2c1223e8519a0e85df5e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Jun 2012 19:12:45 +0000 Subject: [PATCH 225/360] safety check when making a node local- make sure its already in the node tree. --- source/blender/makesrna/intern/rna_nodetree.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 5ffdfe6d71d..ca61b532862 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -644,8 +644,9 @@ static PointerRNA rna_NodeTree_active_node_get(PointerRNA *ptr) static void rna_NodeTree_active_node_set(PointerRNA *ptr, PointerRNA value) { bNodeTree *ntree = (bNodeTree *)ptr->data; - if (value.data) - nodeSetActive(ntree, (bNode *)value.data); + bNode *node = (bNode *)value.data; + if (node && BLI_findindex(&ntree->nodes, node) != -1) + nodeSetActive(ntree, node); else nodeClearActive(ntree); } From 234a0d8c513e0124ba569868c501668519ab958b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Jun 2012 20:50:57 +0000 Subject: [PATCH 226/360] fix for crash drawing grease pencil attached to a tracking marker. also fix for use of uninitialized variable for ED_clip_point_undistorted_pos(). --- source/blender/editors/include/ED_clip.h | 4 ++-- source/blender/editors/space_clip/clip_draw.c | 8 ++++--- .../blender/editors/space_clip/clip_editor.c | 24 ++++++++++--------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 1d42954a416..649266beec7 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -69,9 +69,9 @@ struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2] void ED_clip_update_frame(const struct Main *mainp, int cfra); int ED_clip_view_selection(struct SpaceClip *sc, struct ARegion *ar, int fit); -void ED_clip_point_undistorted_pos(SpaceClip * sc, float co[2], float nco[2]); +void ED_clip_point_undistorted_pos(SpaceClip * sc, const float co[2], float r_co[2]); void ED_clip_point_stable_pos(struct bContext *C, float x, float y, float *xr, float *yr); -void ED_clip_point_stable_pos__reverse(SpaceClip * sc, ARegion *ar, float co[2], float nco[2]); +void ED_clip_point_stable_pos__reverse(SpaceClip * sc, ARegion *ar, const float co[2], float r_co[2]); void ED_clip_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]); int ED_space_clip_texture_buffer_supported(struct SpaceClip *sc); diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index a9b23d5b939..655a09ec90c 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -1467,9 +1467,11 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d) if (track) { int framenr = sc->user.framenr; - MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); - - glTranslatef(marker->pos[0], marker->pos[1], 0.0f); + /* don't get the exact marker since it may not exist for the frame */ + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + if (marker) { + glTranslatef(marker->pos[0], marker->pos[1], 0.0f); + } } } diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 504d96df072..b24ff58e590 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -425,9 +425,9 @@ int ED_clip_view_selection(SpaceClip *sc, ARegion *ar, int fit) return TRUE; } -void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2]) +void ED_clip_point_undistorted_pos(SpaceClip *sc, const float co[2], float r_co[2]) { - copy_v2_v2(nco, co); + copy_v2_v2(r_co, co); if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { MovieClip *clip = ED_space_clip(sc); @@ -436,13 +436,13 @@ void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2]) ED_space_clip_size(sc, &width, &height); - nco[0] *= width; - nco[1] *= height * aspy; + r_co[0] *= width; + r_co[1] *= height * aspy; - BKE_tracking_invert_intrinsics(&clip->tracking, nco, nco); + BKE_tracking_invert_intrinsics(&clip->tracking, r_co, r_co); - nco[0] /= width; - nco[1] /= height * aspy; + r_co[0] /= width; + r_co[1] /= height * aspy; } } @@ -451,7 +451,7 @@ void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *y ARegion *ar = CTX_wm_region(C); SpaceClip *sc = CTX_wm_space_clip(C); int sx, sy, width, height; - float zoomx, zoomy, pos[3] = {0.0f, 0.0f, 0.0f}, imat[4][4]; + float zoomx, zoomy, pos[3], imat[4][4]; ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); ED_space_clip_size(sc, &width, &height); @@ -460,6 +460,7 @@ void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *y pos[0] = (x - sx) / zoomx; pos[1] = (y - sy) / zoomy; + pos[2] = 0.0f; invert_m4_m4(imat, sc->stabmat); mul_v3_m4v3(pos, imat, pos); @@ -484,7 +485,7 @@ void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *y * \brief the reverse of ED_clip_point_stable_pos(), gets the marker region coords. * better name here? view_to_track / track_to_view or so? */ -void ED_clip_point_stable_pos__reverse(SpaceClip *sc, ARegion *ar, float co[2], float nco[2]) +void ED_clip_point_stable_pos__reverse(SpaceClip *sc, ARegion *ar, const float co[2], float r_co[2]) { float zoomx, zoomy; float pos[3]; @@ -496,12 +497,13 @@ void ED_clip_point_stable_pos__reverse(SpaceClip *sc, ARegion *ar, float co[2], ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); ED_clip_point_undistorted_pos(sc, co, pos); + pos[2] = 0.0f; /* untested */ mul_v3_m4v3(pos, sc->stabmat, pos); - nco[0] = (pos[0] * width * zoomx) + (float)sx; - nco[1] = (pos[1] * height * zoomy) + (float)sy; + r_co[0] = (pos[0] * width * zoomx) + (float)sx; + r_co[1] = (pos[1] * height * zoomy) + (float)sy; } void ED_clip_mouse_pos(bContext *C, wmEvent *event, float co[2]) From 7977078227d6da77e294dd860f4685387f0bae56 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 Jun 2012 20:58:16 +0000 Subject: [PATCH 227/360] fix for using freed memory with mask point slide -- This line, and those below, will be ignored-- M source/blender/editors/mask/mask_ops.c --- source/blender/editors/mask/mask_ops.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 67fd57ed50b..7c94b79010c 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -758,11 +758,10 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) } } - free_slide_point_data(op->customdata); - WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); DAG_id_tag_update(&data->mask->id, 0); + free_slide_point_data(op->customdata); /* keep this last! */ return OPERATOR_FINISHED; } @@ -771,11 +770,10 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) case ESCKEY: cancel_slide_point(op->customdata); - free_slide_point_data(op->customdata); - WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); DAG_id_tag_update(&data->mask->id, 0); + free_slide_point_data(op->customdata); /* keep this last! */ return OPERATOR_CANCELLED; } From ac5a735e3fe9fe29e38e3a20c20da87b27feb112 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 12 Jun 2012 04:23:21 +0000 Subject: [PATCH 228/360] * FIX for - [#31777] Border Crop gives black - [#31768] Crash when connecting a Math node to a translate node in Tiles comp - [#31638] View node in new node compo system crashes when inside a group * make sure a very fast vignette can be made by using a EliipseMask + Fast Gaussian blur --- source/blender/compositor/COM_defines.h | 4 +-- .../intern/COM_CompositorContext.cpp | 1 + .../compositor/intern/COM_CompositorContext.h | 15 ++++++++ .../compositor/intern/COM_ExecutionGroup.cpp | 7 ++-- .../compositor/intern/COM_ExecutionSystem.cpp | 36 ++++++++++++++----- .../intern/COM_ExecutionSystemHelper.cpp | 19 +++++++--- .../intern/COM_ExecutionSystemHelper.h | 4 +-- source/blender/compositor/intern/COM_Node.cpp | 14 ++++---- source/blender/compositor/intern/COM_Node.h | 19 ++++++++++ .../compositor/intern/COM_NodeOperation.h | 14 +++++++- .../compositor/intern/COM_OutputSocket.cpp | 9 +++-- .../compositor/nodes/COM_GroupNode.cpp | 9 ++--- .../compositor/nodes/COM_SplitViewerNode.cpp | 2 +- .../compositor/nodes/COM_ViewerNode.cpp | 2 +- .../operations/COM_BokehBlurOperation.cpp | 5 ++- .../operations/COM_BokehImageOperation.cpp | 2 +- .../operations/COM_CompositorOperation.cpp | 19 ++++++++-- .../operations/COM_PreviewOperation.h | 2 ++ .../operations/COM_ReadBufferOperation.cpp | 8 +++++ .../operations/COM_ReadBufferOperation.h | 2 +- .../operations/COM_RotateOperation.cpp | 32 +++++++++++------ .../operations/COM_RotateOperation.h | 3 ++ .../operations/COM_SetVectorOperation.cpp | 10 ++---- .../operations/COM_SocketProxyOperation.cpp | 4 ++- .../operations/COM_TranslateOperation.cpp | 8 ++--- .../operations/COM_TranslateOperation.h | 12 +++++++ .../COM_VariableSizeBokehBlurOperation.cpp | 21 ++++++----- .../operations/COM_WriteBufferOperation.cpp | 6 ++++ .../operations/COM_WriteBufferOperation.h | 1 + 29 files changed, 214 insertions(+), 76 deletions(-) diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h index f87265c50f5..1aa023bea3a 100644 --- a/source/blender/compositor/COM_defines.h +++ b/source/blender/compositor/COM_defines.h @@ -70,6 +70,7 @@ typedef enum CompositorPriority { // chunk size determination #define COM_PREVIEW_SIZE 140.0f //#define COM_OPENCL_ENABLED +//#define COM_DEBUG // workscheduler threading models /** @@ -106,7 +107,4 @@ typedef enum OrderOfChunks { #define COM_NUMBER_OF_CHANNELS 4 -#define COM_DEFAULT_RESOLUTION_WIDTH 640 -#define COM_DEFAULT_RESOLUTION_HEIGHT 480 - #endif diff --git a/source/blender/compositor/intern/COM_CompositorContext.cpp b/source/blender/compositor/intern/COM_CompositorContext.cpp index 911de822f80..bb8e7d9606d 100644 --- a/source/blender/compositor/intern/COM_CompositorContext.cpp +++ b/source/blender/compositor/intern/COM_CompositorContext.cpp @@ -29,6 +29,7 @@ CompositorContext::CompositorContext() this->scene = NULL; this->quality = COM_QUALITY_HIGH; this->hasActiveOpenCLDevices = false; + this->activegNode = NULL; } const int CompositorContext::getFramenumber() const diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h index 2889f43290e..8425030aec2 100644 --- a/source/blender/compositor/intern/COM_CompositorContext.h +++ b/source/blender/compositor/intern/COM_CompositorContext.h @@ -63,6 +63,11 @@ private: * @see ExecutionSystem */ bNodeTree *bnodetree; + + /** + * @brief activegNode the group node that is currently being edited. + */ + bNode *activegNode; /** * @brief does this system have active opencl devices? @@ -100,6 +105,16 @@ public: */ const bNodeTree * getbNodeTree() const {return this->bnodetree;} + /** + * @brief set the active groupnode of the context + */ + void setActivegNode(bNode *gnode) {this->activegNode = gnode;} + + /** + * @brief get the active groupnode of the context + */ + const bNode * getActivegNode() const {return this->activegNode;} + /** * @brief get the scene of the context */ diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index 481b83c81a3..e46b4934217 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -184,11 +184,8 @@ void ExecutionGroup::deinitExecution() void ExecutionGroup::determineResolution(unsigned int resolution[]) { NodeOperation *operation = this->getOutputNodeOperation(); - unsigned int preferredResolution[2]; - preferredResolution[0] = 0; - preferredResolution[1] = 0; - operation->determineResolution(resolution, preferredResolution); - operation->setResolution(resolution); + resolution[0] = operation->getWidth(); + resolution[1] = operation->getHeight(); this->setResolution(resolution); } diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 8c0b37a0685..1056c6d3f65 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -41,7 +41,14 @@ ExecutionSystem::ExecutionSystem(bNodeTree *editingtree, bool rendering) { - this->context.setbNodeTree(editingtree); + context.setbNodeTree(editingtree); + bNode* gnode; + for (gnode = (bNode*)editingtree->nodes.first ; gnode ; gnode = (bNode*)gnode->next) { + if (gnode->type == NODE_GROUP && gnode->typeinfo->group_edit_get(gnode)) { + context.setActivegNode(gnode); + break; + } + } /* initialize the CompositorContext */ if (rendering) { @@ -55,25 +62,25 @@ ExecutionSystem::ExecutionSystem(bNodeTree *editingtree, bool rendering) Node *mainOutputNode=NULL; - mainOutputNode = ExecutionSystemHelper::addbNodeTree(*this, 0, editingtree); + mainOutputNode = ExecutionSystemHelper::addbNodeTree(*this, 0, editingtree, NULL); if (mainOutputNode) { context.setScene((Scene*)mainOutputNode->getbNode()->id); this->convertToOperations(); this->groupOperations(); /* group operations in ExecutionGroups */ - vector executionGroups; - this->findOutputExecutionGroup(&executionGroups); unsigned int index; unsigned int resolution[2]; - for (index = 0 ; index < executionGroups.size(); index ++) { + for (index = 0 ; index < this->groups.size(); index ++) { resolution[0]=0; resolution[1]=0; - ExecutionGroup *executionGroup = executionGroups[index]; + ExecutionGroup *executionGroup = groups[index]; executionGroup->determineResolution(resolution); } } - if (G.f & G_DEBUG) ExecutionSystemHelper::debugDump(this); +#ifdef COM_DEBUG + ExecutionSystemHelper::debugDump(this); +#endif } ExecutionSystem::~ExecutionSystem() @@ -180,11 +187,13 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) writeoperation->setbNodeTree(this->getContext().getbNodeTree()); this->addOperation(writeoperation); ExecutionSystemHelper::addLink(this->getConnections(), fromsocket, writeoperation->getInputSocket(0)); + writeoperation->readResolutionFromInputSocket(); } ReadBufferOperation *readoperation = new ReadBufferOperation(); readoperation->setMemoryProxy(writeoperation->getMemoryProxy()); connection->setFromSocket(readoperation->getOutputSocket()); readoperation->getOutputSocket()->addConnection(connection); + readoperation->readResolutionFromWriteBuffer(); this->addOperation(readoperation); } } @@ -207,9 +216,11 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) readoperation->setMemoryProxy(writeOperation->getMemoryProxy()); connection->setFromSocket(readoperation->getOutputSocket()); readoperation->getOutputSocket()->addConnection(connection); + readoperation->readResolutionFromWriteBuffer(); this->addOperation(readoperation); } ExecutionSystemHelper::addLink(this->getConnections(), outputsocket, writeOperation->getInputSocket(0)); + writeOperation->readResolutionFromInputSocket(); } } @@ -237,7 +248,16 @@ void ExecutionSystem::convertToOperations() // determine all resolutions of the operations (Width/Height) for (index = 0 ; index < this->operations.size(); index ++) { NodeOperation *operation = this->operations[index]; - if (operation->isOutputOperation(context.isRendering())) { + if (operation->isOutputOperation(context.isRendering()) && !operation->isPreviewOperation()) { + unsigned int resolution[2] = {0,0}; + unsigned int preferredResolution[2] = {0,0}; + operation->determineResolution(resolution, preferredResolution); + operation->setResolution(resolution); + } + } + for (index = 0 ; index < this->operations.size(); index ++) { + NodeOperation *operation = this->operations[index]; + if (operation->isOutputOperation(context.isRendering()) && operation->isPreviewOperation()) { unsigned int resolution[2] = {0,0}; unsigned int preferredResolution[2] = {0,0}; operation->determineResolution(resolution, preferredResolution); diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp index 67554cd464b..75be8df74de 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp @@ -35,16 +35,20 @@ #include "COM_GroupNode.h" #include "COM_WriteBufferOperation.h" #include "COM_ReadBufferOperation.h" +#include "COM_ViewerBaseOperation.h" -Node *ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree) +Node *ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree * tree, bNode *groupnode) { vector& nodes = system.getNodes(); vector& links = system.getConnections(); Node *mainnode = NULL; + const bNode * activeGroupNode = system.getContext().getActivegNode(); + bool isActiveGroup = activeGroupNode == groupnode; + /* add all nodes of the tree to the node list */ bNode *node = (bNode*)tree->nodes.first; while (node != NULL) { - Node *execnode = addNode(nodes, node); + Node *execnode = addNode(nodes, node, isActiveGroup); if (node->type == CMP_NODE_COMPOSITE) { mainnode = execnode; } @@ -77,11 +81,12 @@ void ExecutionSystemHelper::addNode(vector& nodes, Node *node) nodes.push_back(node); } -Node *ExecutionSystemHelper::addNode(vector& nodes, bNode *bNode) +Node *ExecutionSystemHelper::addNode(vector& nodes, bNode *bNode, bool inActiveGroup) { Converter converter; Node * node; node = converter.convert(bNode); + node->setIsInActiveGroup(inActiveGroup); if (node != NULL) { addNode(nodes, node); return node; @@ -232,7 +237,12 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) printf("|"); } if (operation->isViewerOperation()) { - printf("Viewer"); + ViewerBaseOperation * viewer = (ViewerBaseOperation*)operation; + if (viewer->isActiveViewerOutput()) { + printf("Active viewer"); + } else { + printf("Viewer"); + } } else if (operation->isOutputOperation(system->getContext().isRendering())) { printf("Output"); @@ -249,6 +259,7 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) else { printf("O_%p", operation); } + printf(" (%d,%d)", operation->getWidth(), operation->getHeight()); tot2 = operation->getNumberOfOutputSockets(); if (tot2 != 0) { printf("|"); diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.h b/source/blender/compositor/intern/COM_ExecutionSystemHelper.h index a72e269115e..9321cb571e8 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.h +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.h @@ -48,7 +48,7 @@ public: * @param tree bNodeTree to add * @return Node representing the "Compositor node" of the maintree. or NULL when a subtree is added */ - static Node *addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree * tree); + static Node *addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree* tree, bNode *groupnode); /** * @brief add an editor node to the system. @@ -58,7 +58,7 @@ public: * @param bNode node to add * @return Node that represents the bNode or null when not able to convert. */ - static Node *addNode(vector& nodes, bNode *bNode); + static Node *addNode(vector& nodes, bNode *bNode, bool isInActiveGroup); /** * @brief Add a Node to a list diff --git a/source/blender/compositor/intern/COM_Node.cpp b/source/blender/compositor/intern/COM_Node.cpp index 264725b4b2c..2324eacd26c 100644 --- a/source/blender/compositor/intern/COM_Node.cpp +++ b/source/blender/compositor/intern/COM_Node.cpp @@ -85,16 +85,18 @@ void Node::addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket void Node::addPreviewOperation(ExecutionSystem *system, OutputSocket *outputSocket) { - PreviewOperation *operation = new PreviewOperation(); - system->addOperation(operation); - operation->setbNode(this->getbNode()); - operation->setbNodeTree(system->getContext().getbNodeTree()); - this->addLink(system, outputSocket, operation->getInputSocket(0)); + if (this->isInActiveGroup()) { + PreviewOperation *operation = new PreviewOperation(); + system->addOperation(operation); + operation->setbNode(this->getbNode()); + operation->setbNodeTree(system->getContext().getbNodeTree()); + this->addLink(system, outputSocket, operation->getInputSocket(0)); + } } void Node::addPreviewOperation(ExecutionSystem *system, InputSocket *inputSocket) { - if (inputSocket->isConnected()) { + if (inputSocket->isConnected() && this->isInActiveGroup()) { OutputSocket *outputsocket = inputSocket->getConnection()->getFromSocket(); this->addPreviewOperation(system, outputsocket); } diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h index 23744adf642..0546062f790 100644 --- a/source/blender/compositor/intern/COM_Node.h +++ b/source/blender/compositor/intern/COM_Node.h @@ -52,6 +52,11 @@ private: */ bNode *editorNode; + /** + * @brief Is this node part of the active group + */ + bool inActiveGroup; + public: Node(bNode *editorNode, bool create_sockets=true); @@ -60,6 +65,20 @@ public: */ bNode *getbNode(); + /** + * @brief Is this node in the active group (the group that is being edited) + * @param isInActiveGroup + */ + void setIsInActiveGroup(bool isInActiveGroup) {this->inActiveGroup = isInActiveGroup; } + + /** + * @brief Is this node part of the active group + * the active group is the group that is currently being edited. When no group is edited, + * the active group will be the main tree (all nodes that are not part of a group will be active) + * @return bool [false:true] + */ + inline bool isInActiveGroup() {return this->inActiveGroup;} + /** * @brief convert node to operation * diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index 2219907b0c8..db1fdda0bcf 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -160,11 +160,22 @@ public: virtual void deinitExecution(); void deinitMutex(); + bool isResolutionSet() { + return this->width != 0 && height != 0; + } + /** * @brief set the resolution * @param resolution the resolution to set */ - void setResolution(unsigned int resolution[]) {this->width = resolution[0];this->height = resolution[1];} + void setResolution(unsigned int resolution[]) { + if (!isResolutionSet()) { + this->width = resolution[0]; + this->height = resolution[1]; + } + } + + void getConnectedInputSockets(vector *sockets); /** @@ -221,6 +232,7 @@ public: bool isOpenCL() { return this->openCL; } virtual bool isViewerOperation() {return false;} + virtual bool isPreviewOperation() {return false;} protected: NodeOperation(); diff --git a/source/blender/compositor/intern/COM_OutputSocket.cpp b/source/blender/compositor/intern/COM_OutputSocket.cpp index 00d3518cd15..708b2d65d46 100644 --- a/source/blender/compositor/intern/COM_OutputSocket.cpp +++ b/source/blender/compositor/intern/COM_OutputSocket.cpp @@ -47,8 +47,13 @@ void OutputSocket::determineResolution(unsigned int resolution[], unsigned int p NodeBase *node = this->getNode(); if (node->isOperation()) { NodeOperation *operation = (NodeOperation*)node; - operation->determineResolution(resolution, preferredResolution); - operation->setResolution(resolution); + if (operation->isResolutionSet()) { + resolution[0] = operation->getWidth(); + resolution[1] = operation->getHeight(); + } else { + operation->determineResolution(resolution, preferredResolution); + operation->setResolution(resolution); + } } } diff --git a/source/blender/compositor/nodes/COM_GroupNode.cpp b/source/blender/compositor/nodes/COM_GroupNode.cpp index ec06a3acd7e..8a8c1db86b4 100644 --- a/source/blender/compositor/nodes/COM_GroupNode.cpp +++ b/source/blender/compositor/nodes/COM_GroupNode.cpp @@ -34,6 +34,7 @@ void GroupNode::convertToOperations(ExecutionSystem *graph, CompositorContext * void GroupNode::ungroup(ExecutionSystem &system) { + bNode * bnode = this->getbNode(); vector &inputsockets = this->getInputSockets(); vector &outputsockets = this->getOutputSockets(); unsigned int index; @@ -45,7 +46,7 @@ void GroupNode::ungroup(ExecutionSystem &system) InputSocket * inputSocket = inputsockets[index]; bNodeSocket *editorInput = inputSocket->getbNodeSocket(); if (editorInput->groupsock) { - SocketProxyNode * proxy = new SocketProxyNode(this->getbNode(), editorInput, editorInput->groupsock); + SocketProxyNode * proxy = new SocketProxyNode(bnode, editorInput, editorInput->groupsock); inputSocket->relinkConnections(proxy->getInputSocket(0), index, &system); ExecutionSystemHelper::addNode(system.getNodes(), proxy); } @@ -55,12 +56,12 @@ void GroupNode::ungroup(ExecutionSystem &system) OutputSocket * outputSocket = outputsockets[index]; bNodeSocket *editorOutput = outputSocket->getbNodeSocket(); if (editorOutput->groupsock) { - SocketProxyNode * proxy = new SocketProxyNode(this->getbNode(), editorOutput->groupsock, editorOutput); + SocketProxyNode * proxy = new SocketProxyNode(bnode, editorOutput->groupsock, editorOutput); outputSocket->relinkConnections(proxy->getOutputSocket(0)); ExecutionSystemHelper::addNode(system.getNodes(), proxy); } } - bNodeTree *subtree = (bNodeTree*)this->getbNode()->id; - ExecutionSystemHelper::addbNodeTree(system, nodes_start, subtree); + bNodeTree *subtree = (bNodeTree*)bnode->id; + ExecutionSystemHelper::addbNodeTree(system, nodes_start, subtree, bnode); } diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp index bf434c164c0..8bf9fd2bf06 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp @@ -40,7 +40,7 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont SplitViewerOperation *splitViewerOperation = new SplitViewerOperation(); splitViewerOperation->setImage(image); splitViewerOperation->setImageUser(imageUser); - splitViewerOperation->setActive(this->getbNode()->flag & NODE_DO_OUTPUT); + splitViewerOperation->setActive((this->getbNode()->flag & NODE_DO_OUTPUT) && this->isInActiveGroup()); splitViewerOperation->setSplitPercentage(this->getbNode()->custom1); splitViewerOperation->setXSplit(!this->getbNode()->custom2); image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph); diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp index f5dab52d021..67c0df4d6a3 100644 --- a/source/blender/compositor/nodes/COM_ViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp @@ -44,7 +44,7 @@ void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext * viewerOperation->setbNodeTree(context->getbNodeTree()); viewerOperation->setImage(image); viewerOperation->setImageUser(imageUser); - viewerOperation->setActive(editorNode->flag & NODE_DO_OUTPUT); + viewerOperation->setActive((editorNode->flag & NODE_DO_OUTPUT) && this->isInActiveGroup()); viewerOperation->setChunkOrder((OrderOfChunks)editorNode->custom1); viewerOperation->setCenterX(editorNode->custom3); viewerOperation->setCenterY(editorNode->custom4); diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp index 71a87dce2a7..b4811c89dc5 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp @@ -86,6 +86,7 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer * float overallmultiplyerr = 0; float overallmultiplyerg = 0; float overallmultiplyerb = 0; + float overallmultiplyera = 0; MemoryBuffer *inputBuffer = (MemoryBuffer*)data; float *buffer = inputBuffer->getBuffer(); int bufferwidth = inputBuffer->getWidth(); @@ -115,16 +116,18 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer * tempColor[0] += bokeh[0] * buffer[bufferindex]; tempColor[1] += bokeh[1] * buffer[bufferindex+1]; tempColor[2] += bokeh[2]* buffer[bufferindex+2]; + tempColor[3] += bokeh[3]* buffer[bufferindex+3]; overallmultiplyerr += bokeh[0]; overallmultiplyerg += bokeh[1]; overallmultiplyerb += bokeh[2]; + overallmultiplyera += bokeh[3]; bufferindex +=offsetadd; } } color[0] = tempColor[0] * (1.0f / overallmultiplyerr); color[1] = tempColor[1] * (1.0f / overallmultiplyerg); color[2] = tempColor[2] * (1.0f / overallmultiplyerb); - color[3] = 1.0f; + color[3] = tempColor[3] * (1.0f / overallmultiplyera); } else { inputProgram->read(color, x, y, COM_PS_NEAREST, inputBuffers); diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.cpp b/source/blender/compositor/operations/COM_BokehImageOperation.cpp index a0297b12961..189ba98aa57 100644 --- a/source/blender/compositor/operations/COM_BokehImageOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehImageOperation.cpp @@ -105,7 +105,7 @@ void BokehImageOperation::executePixel(float *color, float x, float y, PixelSamp color[1] = insideBokehMed; color[2] = insideBokehMax; } - color[3] = 1.0f; + color[3] = (insideBokehMax+insideBokehMed+insideBokehMin)/3.0f; } void BokehImageOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index d75cb39325f..c6e8faaa638 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -102,7 +102,7 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber, Mem int y1 = rect->ymin; int x2 = rect->xmax; int y2 = rect->ymax; - int offset = (y1*this->getWidth() + x1 ) * 4; + int offset = (y1*this->getWidth() + x1 ) * COM_NUMBER_OF_CHANNELS; int x; int y; bool breaked = false; @@ -117,12 +117,12 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber, Mem buffer[offset+1] = color[1]; buffer[offset+2] = color[2]; buffer[offset+3] = color[3]; - offset +=4; + offset +=COM_NUMBER_OF_CHANNELS; if (tree->test_break && tree->test_break(tree->tbh)) { breaked = true; } } - offset += (this->getWidth()-(x2-x1))*4; + offset += (this->getWidth()-(x2-x1))*COM_NUMBER_OF_CHANNELS; } } @@ -130,6 +130,19 @@ void CompositorOperation::determineResolution(unsigned int resolution[], unsigne { int width = this->scene->r.xsch*this->scene->r.size/100; int height = this->scene->r.ysch*this->scene->r.size/100; + + // check actual render resolution with cropping it may differ with cropped border.rendering + // FIX for: [31777] Border Crop gives black (easy) + Render *re= RE_GetRender(this->scene->id.name); + if (re) { + RenderResult *rr= RE_AcquireResultRead(re); + if (rr) { + width = rr->rectx; + height = rr->recty; + } + RE_ReleaseResult(re); + } + preferredResolution[0] = width; preferredResolution[1] = height; diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h index 3d1cd38a5ea..2b81b914746 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.h +++ b/source/blender/compositor/operations/COM_PreviewOperation.h @@ -50,5 +50,7 @@ public: void setbNode(bNode *node) { this->node = node;} void setbNodeTree(const bNodeTree *tree) { this->tree = tree;} bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + bool isPreviewOperation() {return true;} + }; #endif diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp index d7f95c10cfb..14b6db9037b 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp @@ -75,3 +75,11 @@ bool ReadBufferOperation::determineDependingAreaOfInterest(rcti * input, ReadBuf } return false; } + +void ReadBufferOperation::readResolutionFromWriteBuffer() { + if (this->memoryProxy != NULL) { + WriteBufferOperation * operation = memoryProxy->getWriteBufferOperation(); + this->setWidth(operation->getWidth()); + this->setHeight(operation->getHeight()); + } +} diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.h b/source/blender/compositor/operations/COM_ReadBufferOperation.h index d58d131264b..449b4a82618 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.h +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.h @@ -45,7 +45,7 @@ public: unsigned int getOffset() {return this->offset;} bool determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti *output); MemoryBuffer *getInputMemoryBuffer(MemoryBuffer** memoryBuffers) {return memoryBuffers[offset];} - + void readResolutionFromWriteBuffer(); }; #endif diff --git a/source/blender/compositor/operations/COM_RotateOperation.cpp b/source/blender/compositor/operations/COM_RotateOperation.cpp index af2633f0e53..a391a26b89c 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.cpp +++ b/source/blender/compositor/operations/COM_RotateOperation.cpp @@ -32,6 +32,7 @@ RotateOperation::RotateOperation() : NodeOperation() this->imageSocket = NULL; this->degreeSocket = NULL; this->doDegree2RadConversion = false; + this->isDegreeSet = false; } void RotateOperation::initExecution() { @@ -39,17 +40,6 @@ void RotateOperation::initExecution() this->degreeSocket = this->getInputSocketReader(1); this->centerX = this->getWidth()/2.0; this->centerY = this->getHeight()/2.0; - float degree[4]; - this->degreeSocket->read(degree, 0, 0, COM_PS_NEAREST, NULL); - double rad; - if (this->doDegree2RadConversion) { - rad = DEG2RAD((double)degree[0]); - } - else { - rad = degree[0]; - } - this->cosine = cos(rad); - this->sine = sin(rad); } void RotateOperation::deinitExecution() @@ -58,9 +48,28 @@ void RotateOperation::deinitExecution() this->degreeSocket = NULL; } +inline void RotateOperation::ensureDegree() { + if (!isDegreeSet) { + float degree[4]; + this->degreeSocket->read(degree, 0, 0, COM_PS_NEAREST, NULL); + double rad; + if (this->doDegree2RadConversion) { + rad = DEG2RAD((double)degree[0]); + } + else { + rad = degree[0]; + } + this->cosine = cos(rad); + this->sine = sin(rad); + + isDegreeSet = true; + } +} + void RotateOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + ensureDegree(); const float dy = y - this->centerY; const float dx = x - this->centerX; const float nx = this->centerX+(this->cosine*dx + this->sine*dy); @@ -70,6 +79,7 @@ void RotateOperation::executePixel(float *color,float x, float y, PixelSampler s bool RotateOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + ensureDegree(); rcti newInput; const float dxmin = input->xmin - this->centerX; diff --git a/source/blender/compositor/operations/COM_RotateOperation.h b/source/blender/compositor/operations/COM_RotateOperation.h index 9965d1021da..6afed39908b 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.h +++ b/source/blender/compositor/operations/COM_RotateOperation.h @@ -34,6 +34,7 @@ private: float cosine; float sine; bool doDegree2RadConversion; + bool isDegreeSet; public: RotateOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); @@ -41,6 +42,8 @@ public: void initExecution(); void deinitExecution(); void setDoDegree2RadConversion(bool abool) {this->doDegree2RadConversion = abool;} + + void ensureDegree(); }; #endif diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.cpp b/source/blender/compositor/operations/COM_SetVectorOperation.cpp index 70477de0514..79c0201733e 100644 --- a/source/blender/compositor/operations/COM_SetVectorOperation.cpp +++ b/source/blender/compositor/operations/COM_SetVectorOperation.cpp @@ -38,12 +38,6 @@ void SetVectorOperation::executePixel(float *outputValue, float x, float y, Pixe void SetVectorOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { - if (preferredResolution[0] == 0 ||preferredResolution[1]==0) { - resolution[0] = COM_DEFAULT_RESOLUTION_WIDTH; - resolution[1] = COM_DEFAULT_RESOLUTION_HEIGHT; - } - else { - resolution[0] = preferredResolution[0]; - resolution[1] = preferredResolution[1]; - } + resolution[0] = preferredResolution[0]; + resolution[1] = preferredResolution[1]; } diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp index 6ed877523d1..51b16506dd9 100644 --- a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp +++ b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp @@ -41,5 +41,7 @@ void SocketProxyOperation::deinitExecution() void SocketProxyOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { - this->inputOperation->read(color, x, y, sampler, inputBuffers); + if (this->inputOperation) { + this->inputOperation->read(color, x, y, sampler, inputBuffers); + } } diff --git a/source/blender/compositor/operations/COM_TranslateOperation.cpp b/source/blender/compositor/operations/COM_TranslateOperation.cpp index 6d2fdfc11d0..b9b06d6d356 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.cpp +++ b/source/blender/compositor/operations/COM_TranslateOperation.cpp @@ -32,6 +32,7 @@ TranslateOperation::TranslateOperation() : NodeOperation() this->inputOperation = NULL; this->inputXOperation = NULL; this->inputYOperation = NULL; + this->isDeltaSet = false; } void TranslateOperation::initExecution() { @@ -39,11 +40,6 @@ void TranslateOperation::initExecution() this->inputXOperation = this->getInputSocketReader(1); this->inputYOperation = this->getInputSocketReader(2); - float tempDelta[4]; - this->inputXOperation->read(tempDelta, 0, 0, COM_PS_NEAREST, NULL); - this->deltaX = tempDelta[0]; - this->inputYOperation->read(tempDelta, 0, 0, COM_PS_NEAREST, NULL); - this->deltaY = tempDelta[0]; } void TranslateOperation::deinitExecution() @@ -56,11 +52,13 @@ void TranslateOperation::deinitExecution() void TranslateOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + ensureDelta(); this->inputOperation->read(color, x-this->getDeltaX(), y-this->getDeltaY(), sampler, inputBuffers); } bool TranslateOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + ensureDelta(); rcti newInput; newInput.xmax = input->xmax - this->getDeltaX(); diff --git a/source/blender/compositor/operations/COM_TranslateOperation.h b/source/blender/compositor/operations/COM_TranslateOperation.h index eab3391041e..63d6ee0d0b5 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.h +++ b/source/blender/compositor/operations/COM_TranslateOperation.h @@ -32,6 +32,7 @@ private: SocketReader*inputYOperation; float deltaX; float deltaY; + float isDeltaSet; public: TranslateOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); @@ -42,6 +43,17 @@ public: float getDeltaX() {return this->deltaX;} float getDeltaY() {return this->deltaY;} + + inline void ensureDelta() { + if (!isDeltaSet) { + float tempDelta[4]; + this->inputXOperation->read(tempDelta, 0, 0, COM_PS_NEAREST, NULL); + this->deltaX = tempDelta[0]; + this->inputYOperation->read(tempDelta, 0, 0, COM_PS_NEAREST, NULL); + this->deltaY = tempDelta[0]; + this->isDeltaSet = true; + } + } }; #endif diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 270fedc174b..562b0fc2bb5 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -64,6 +64,7 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me float overallmultiplyerr = 0; float overallmultiplyerg = 0; float overallmultiplyerb = 0; + float overallmultiplyera = 0; int miny = y - maxBlur; int maxy = y + maxBlur; @@ -74,16 +75,18 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me tempColor[0] += readColor[0]; tempColor[1] += readColor[1]; tempColor[2] += readColor[2]; + tempColor[3] += readColor[3]; overallmultiplyerr += 1; overallmultiplyerg += 1; overallmultiplyerb += 1; + overallmultiplyera += 1; for (int ny = miny ; ny < maxy ; ny += QualityStepHelper::getStep()) { for (int nx = minx ; nx < maxx ; nx += QualityStepHelper::getStep()) { if (nx >=0 && nx < this->getWidth() && ny >= 0 && ny < getHeight()) { inputSizeProgram->read(tempSize, nx, ny, COM_PS_NEAREST, inputBuffers); float size = tempSize[0]; - size += this->threshold; +// size += this->threshold; float dx = nx - x; float dy = ny - y; if (nx == x && ny == y) { @@ -94,20 +97,22 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me float v = 256 + dy*256/size; inputBokehProgram->read(bokeh, u, v, COM_PS_NEAREST, inputBuffers); inputProgram->read(readColor, nx, ny, COM_PS_NEAREST, inputBuffers); - tempColor[0] += bokeh[0] * readColor[0]; - tempColor[1] += bokeh[1] * readColor[1]; - tempColor[2] += bokeh[2]* readColor[2]; + tempColor[0] += bokeh[1]*readColor[0]; + tempColor[1] += bokeh[2]*readColor[1]; + tempColor[2] += bokeh[2]*readColor[2]; + tempColor[3] += bokeh[3]*readColor[3]; overallmultiplyerr += bokeh[0]; overallmultiplyerg += bokeh[1]; overallmultiplyerb += bokeh[2]; + overallmultiplyera += bokeh[3]; } } } } - color[0] = tempColor[0] * (1.0f / overallmultiplyerr); - color[1] = tempColor[1] * (1.0f / overallmultiplyerg); - color[2] = tempColor[2] * (1.0f / overallmultiplyerb); - color[3] = 1.0f; + color[0] = tempColor[0] / overallmultiplyerr; + color[1] = tempColor[1] / overallmultiplyerg; + color[2] = tempColor[2] / overallmultiplyerb; + color[3] = tempColor[3] / overallmultiplyera; } } diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index 222b879645c..8888d30ba2f 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -175,3 +175,9 @@ void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program pr } delete clKernelsToCleanUp; } + +void WriteBufferOperation::readResolutionFromInputSocket() { + NodeOperation* inputOperation = this->getInputOperation(0); + this->setWidth(inputOperation->getWidth()); + this->setHeight(inputOperation->getHeight()); +} diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h index 6f2c49c49bd..068adc03293 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.h +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h @@ -47,6 +47,7 @@ public: void deinitExecution(); void setbNodeTree(const bNodeTree *tree) {this->tree = tree;} void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers, MemoryBuffer* outputBuffer); + void readResolutionFromInputSocket(); }; #endif From 2127e62c9b2d05351013ceb5996cddc38925b457 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 12 Jun 2012 06:22:23 +0000 Subject: [PATCH 229/360] "Fix" for [#30704] Action Constraint mapping bug Feature request rather than a real bug: allow constrained bone to use "object" part of the linked action, in addition to "same-named bone" part. --- .../bl_ui/properties_object_constraint.py | 1 + source/blender/blenkernel/intern/constraint.c | 18 +++++++++--------- source/blender/makesdna/DNA_constraint_types.h | 8 +++++++- .../blender/makesrna/intern/rna_constraint.c | 7 +++++++ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index bfa2b4f60ef..e4da581ab83 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -444,6 +444,7 @@ class ConstraintButtonsPanel(): col = split.column() col.label(text="To Action:") col.prop(con, "action", text="") + col.prop(con, "use_bone_object_action") split = layout.split() diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 9d36a66843b..62fb791df3a 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -2159,7 +2159,15 @@ static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintT printf("do Action Constraint %s - Ob %s Pchan %s\n", con->name, cob->ob->id.name + 2, (cob->pchan) ? cob->pchan->name : NULL); /* Get the appropriate information from the action */ - if (cob->type == CONSTRAINT_OBTYPE_BONE) { + if (cob->type == CONSTRAINT_OBTYPE_OBJECT || (data->flag & BONE_USE_OBJECT_ACTION)) { + Object workob; + + /* evaluate using workob */ + // FIXME: we don't have any consistent standards on limiting effects on object... + what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t); + BKE_object_to_mat4(&workob, ct->matrix); + } + else if (cob->type == CONSTRAINT_OBTYPE_BONE) { Object workob; bPose *pose; bPoseChannel *pchan, *tchan; @@ -2185,14 +2193,6 @@ static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintT /* Clean up */ BKE_pose_free(pose); } - else if (cob->type == CONSTRAINT_OBTYPE_OBJECT) { - Object workob; - - /* evaluate using workob */ - // FIXME: we don't have any consistent standards on limiting effects on object... - what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t); - BKE_object_to_mat4(&workob, ct->matrix); - } else { /* behavior undefined... */ puts("Error: unknown owner type for Action Constraint"); diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 59d8e81de39..aae167d05c6 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -247,7 +247,7 @@ typedef struct bActionConstraint { int end; float min; float max; - int pad; + int flag; struct bAction *act; char subtarget[64]; /* MAX_ID_NAME-2 */ } bActionConstraint; @@ -561,6 +561,12 @@ typedef enum eSameVolume_Modes { SAMEVOL_Z } eSameVolume_Modes; +/* bActionConstraint.flag + * WARNING: bitwise! */ +typedef enum eAction_flags { + BONE_USE_OBJECT_ACTION = 1 << 0, /* Bones use "object" part of target action, instead of "same bone name" part. */ +} eAction_flags; + /* Locked-Axis Values (Locked Track) */ typedef enum eLockAxis_Modes { LOCK_X = 0, diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 8e29e5c2e79..f02df6c30ed 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -1111,6 +1111,13 @@ static void rna_def_constraint_action(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); + prop = RNA_def_property(srna, "use_bone_object_action", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_USE_OBJECT_ACTION); + RNA_def_property_ui_text(prop, "Object Action", + "Bones only: apply the object's transformation channels of the action " + "to the constrained bone, instead of bone's channels"); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); + prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME); RNA_def_property_int_sdna(prop, NULL, "start"); RNA_def_property_range(prop, MINAFRAME, MAXFRAME); From 43d1df9f47e3729eecd35b83a3483f525f29ec3e Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Tue, 12 Jun 2012 07:27:50 +0000 Subject: [PATCH 230/360] Fix #31675 Reroute nodes aren't working for cycles. Note that currently the reroute nodes are hardcoded to color values, which means they will not work for shader type connections (and possibly cause overhead for float and vector conversion). Looking into a solution. --- intern/cycles/blender/blender_shader.cpp | 102 ++++++++++-------- source/blender/makesrna/intern/rna_nodetree.c | 12 ++- 2 files changed, 66 insertions(+), 48 deletions(-) diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 35fe4c67673..d5b58298e18 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -75,6 +75,52 @@ static float get_node_output_value(BL::Node b_node, const string& name) return sock.default_value(); } +static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type) +{ + switch (b_type) { + case BL::NodeSocket::type_VALUE: + return SHADER_SOCKET_FLOAT; + case BL::NodeSocket::type_VECTOR: + return SHADER_SOCKET_VECTOR; + case BL::NodeSocket::type_RGBA: + return SHADER_SOCKET_COLOR; + case BL::NodeSocket::type_SHADER: + return SHADER_SOCKET_CLOSURE; + + case BL::NodeSocket::type_BOOLEAN: + case BL::NodeSocket::type_MESH: + case BL::NodeSocket::type_INT: + default: + return SHADER_SOCKET_FLOAT; + } +} + +static void set_default_value(ShaderInput *input, BL::NodeSocket sock) +{ + /* copy values for non linked inputs */ + switch(input->type) { + case SHADER_SOCKET_FLOAT: { + BL::NodeSocketFloatNone value_sock(sock); + input->set(value_sock.default_value()); + break; + } + case SHADER_SOCKET_COLOR: { + BL::NodeSocketRGBA rgba_sock(sock); + input->set(get_float3(rgba_sock.default_value())); + break; + } + case SHADER_SOCKET_NORMAL: + case SHADER_SOCKET_POINT: + case SHADER_SOCKET_VECTOR: { + BL::NodeSocketVectorNone vec_sock(sock); + input->set(get_float3(vec_sock.default_value())); + break; + } + case SHADER_SOCKET_CLOSURE: + break; + } +} + static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping b_mapping) { if(!b_mapping) @@ -122,10 +168,18 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph /* handled outside this function */ case BL::ShaderNode::type_GROUP: break; /* existing blender nodes */ + case BL::ShaderNode::type_REROUTE: { + BL::Node::inputs_iterator b_input; + b_node.inputs.begin(b_input); + BL::Node::outputs_iterator b_output; + b_node.outputs.begin(b_output); + ProxyNode *proxy = new ProxyNode(convert_socket_type(b_input->type()), convert_socket_type(b_output->type())); + node = proxy; + break; + } case BL::ShaderNode::type_CURVE_RGB: { RGBCurvesNode *ramp = new RGBCurvesNode(); node = ramp; - break; } case BL::ShaderNode::type_VALTORGB: { RGBRampNode *ramp = new RGBRampNode(); @@ -488,52 +542,6 @@ static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL return SocketPair(node_map[b_node.ptr.data], name); } -static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type) -{ - switch (b_type) { - case BL::NodeSocket::type_VALUE: - return SHADER_SOCKET_FLOAT; - case BL::NodeSocket::type_VECTOR: - return SHADER_SOCKET_VECTOR; - case BL::NodeSocket::type_RGBA: - return SHADER_SOCKET_COLOR; - case BL::NodeSocket::type_SHADER: - return SHADER_SOCKET_CLOSURE; - - case BL::NodeSocket::type_BOOLEAN: - case BL::NodeSocket::type_MESH: - case BL::NodeSocket::type_INT: - default: - return SHADER_SOCKET_FLOAT; - } -} - -static void set_default_value(ShaderInput *input, BL::NodeSocket sock) -{ - /* copy values for non linked inputs */ - switch(input->type) { - case SHADER_SOCKET_FLOAT: { - BL::NodeSocketFloatNone value_sock(sock); - input->set(value_sock.default_value()); - break; - } - case SHADER_SOCKET_COLOR: { - BL::NodeSocketRGBA rgba_sock(sock); - input->set(get_float3(rgba_sock.default_value())); - break; - } - case SHADER_SOCKET_NORMAL: - case SHADER_SOCKET_POINT: - case SHADER_SOCKET_VECTOR: { - BL::NodeSocketVectorNone vec_sock(sock); - input->set(get_float3(vec_sock.default_value())); - break; - } - case SHADER_SOCKET_CLOSURE: - break; - } -} - static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map) { /* add nodes */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index ca61b532862..92de882d48b 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1058,6 +1058,7 @@ static void init(void) reg_node(NODE_FORLOOP, Category_LoopNode, "FORLOOP", "NodeForLoop", "Node", "ForLoop", ""); reg_node(NODE_WHILELOOP, Category_LoopNode, "WHILELOOP", "NodeWhileLoop", "Node", "WhileLoop", ""); reg_node(NODE_FRAME, Category_LayoutNode, "FRAME", "NodeFrame", "Node", "Frame", ""); + reg_node(NODE_REROUTE, Category_LayoutNode, "REROUTE", "NodeReroute", "Node", "Reroute", ""); } static StructRNA *def_node(BlenderRNA *brna, int node_id) @@ -1075,7 +1076,7 @@ static StructRNA *def_node(BlenderRNA *brna, int node_id) static void alloc_node_type_items(EnumPropertyItem *items, int category) { int i; - int count = 3; + int count = 4; EnumPropertyItem *item = items; for (i = 0; i < MaxNodes; i++) @@ -1105,6 +1106,14 @@ static void alloc_node_type_items(EnumPropertyItem *items, int category) item++; + item->value = NODE_REROUTE; + item->identifier = "REROUTE"; + item->icon = 0; + item->name = "Reroute"; + item->description = ""; + + item++; + /* NOTE!, increase 'count' when adding items here */ memset(item, 0, sizeof(EnumPropertyItem)); @@ -4208,6 +4217,7 @@ void RNA_def_nodetree(BlenderRNA *brna) define_specific_node(brna, NODE_FORLOOP, def_forloop); define_specific_node(brna, NODE_WHILELOOP, def_whileloop); define_specific_node(brna, NODE_FRAME, def_frame); + define_specific_node(brna, NODE_REROUTE, 0); /* special socket types */ rna_def_cmp_output_file_slot_file(brna); From c9ddb96750e0fd8b9cc842c992dfeaa523d5a7f1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 12 Jun 2012 08:10:34 +0000 Subject: [PATCH 231/360] optimize jpeg2000 saving - expand loops to avoid checks for each iteration - use unsigned ints for looping over pixels - use inline functions for color conversion --- source/blender/imbuf/intern/jp2.c | 304 +++++++++++++++++++++--------- 1 file changed, 220 insertions(+), 84 deletions(-) diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index 38a8e7dfd33..1a807530281 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -95,8 +95,7 @@ static void info_callback(const char *msg, void *client_data) -struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags) -{ +struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags){ struct ImBuf *ibuf = NULL; int use_float = FALSE; /* for precision higher then 8 use float */ @@ -287,13 +286,38 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags) //static opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) { /* prec can be 8, 12, 16 */ +/* use inline because the float passed can be a function call that would end up being called many times */ +#if 0 #define UPSAMPLE_8_TO_12(_val) ((_val << 4) | (_val & ((1 << 4) - 1))) #define UPSAMPLE_8_TO_16(_val) ((_val << 8) + _val) #define DOWNSAMPLE_FLOAT_TO_8BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val))) #define DOWNSAMPLE_FLOAT_TO_12BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val))) #define DOWNSAMPLE_FLOAT_TO_16BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val))) +#else +BLI_INLINE int UPSAMPLE_8_TO_12(const unsigned char _val) +{ + return (_val << 4) | (_val & ((1 << 4) - 1)); +} +BLI_INLINE int UPSAMPLE_8_TO_16(const unsigned char _val) +{ + return (_val << 8) + _val; +} + +BLI_INLINE int DOWNSAMPLE_FLOAT_TO_8BIT(const float _val) +{ + return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val))); +} +BLI_INLINE int DOWNSAMPLE_FLOAT_TO_12BIT(const float _val) +{ + return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val))); +} +BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val) +{ + return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val))); +} +#endif /* * 2048x1080 (2K) at 24 fps or 48 fps, or 4096x2160 (4K) at 24 fps; 3x12 bits per pixel, XYZ color space @@ -461,12 +485,12 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) unsigned char *rect; float *rect_float; - int subsampling_dx = parameters->subsampling_dx; - int subsampling_dy = parameters->subsampling_dy; + unsigned int subsampling_dx = parameters->subsampling_dx; + unsigned int subsampling_dy = parameters->subsampling_dy; - - int i, numcomps, w, h, prec; - int x, y, y_row; + unsigned int i, i_next, numcomps, w, h, prec; + unsigned int y; + int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */ OPJ_COLOR_SPACE color_space; opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */ opj_image_t *image = NULL; @@ -543,71 +567,161 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) rect = (unsigned char *) ibuf->rect; rect_float = ibuf->rect_float; + /* set the destination channels */ + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + a = (numcomps == 4) ? image->comps[3].data : NULL; + if (rect_float && rect && prec == 8) { /* No need to use the floating point buffer, just write the 8 bits from the char buffer */ rect_float = NULL; } +# define PIXEL_LOOPER_BEGIN(_rect) \ + for (y = h - 1; y != (unsigned int)(-1); y--) { \ + for (i = y * w, i_next = (y + 1) * w; \ + i < i_next; \ + i++, _rect += 4) \ + { \ + +# define PIXEL_LOOPER_END \ + } \ + } (void)0 \ if (rect_float) { - float rgb[3]; - switch (prec) { case 8: /* Convert blenders float color channels to 8, 12 or 16bit ints */ - for (y = h - 1; y >= 0; y--) { - y_row = y * w; - for (x = 0; x < w; x++, rect_float += 4) { - i = y_row + x; - - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) - linearrgb_to_srgb_v3_v3(rgb, rect_float); - else - copy_v3_v3(rgb, rect_float); - - image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[0]); - image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[1]); - image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[2]); - if (numcomps > 3) - image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]); + if (numcomps == 4) { + if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[2])); + a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]); + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[0]); + g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[1]); + b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[2]); + a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]); + } + PIXEL_LOOPER_END; + } + } + else { + if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[2])); + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[0]); + g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[1]); + b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[2]); + } + PIXEL_LOOPER_END; } } break; case 12: - for (y = h - 1; y >= 0; y--) { - y_row = y * w; - for (x = 0; x < w; x++, rect_float += 4) { - i = y_row + x; - - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) - linearrgb_to_srgb_v3_v3(rgb, rect_float); - else - copy_v3_v3(rgb, rect_float); - - image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[0]); - image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[1]); - image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[2]); - if (numcomps > 3) - image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]); + if (numcomps == 4) { + if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[2])); + a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]); + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[0]); + g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[1]); + b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[2]); + a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]); + } + PIXEL_LOOPER_END; + } + } + else { + if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[2])); + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[0]); + g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[1]); + b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[2]); + } + PIXEL_LOOPER_END; } } break; + case 16: - for (y = h - 1; y >= 0; y--) { - y_row = y * w; - for (x = 0; x < w; x++, rect_float += 4) { - i = y_row + x; - - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) - linearrgb_to_srgb_v3_v3(rgb, rect_float); - else - copy_v3_v3(rgb, rect_float); - - image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[0]); - image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[1]); - image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[2]); - if (numcomps > 3) - image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]); + if (numcomps == 4) { + if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[2])); + a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]); + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[0]); + g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[1]); + b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[2]); + a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]); + } + PIXEL_LOOPER_END; + } + } + else { + if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[2])); + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_float) + { + r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[0]); + g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[1]); + b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[2]); + } + PIXEL_LOOPER_END; } } break; @@ -617,46 +731,68 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) /* just use rect*/ switch (prec) { case 8: - for (y = h - 1; y >= 0; y--) { - y_row = y * w; - for (x = 0; x < w; x++, rect += 4) { - i = y_row + x; - - image->comps[0].data[i] = rect[0]; - image->comps[1].data[i] = rect[1]; - image->comps[2].data[i] = rect[2]; - if (numcomps > 3) - image->comps[3].data[i] = rect[3]; + if (numcomps == 4) { + PIXEL_LOOPER_BEGIN(rect) + { + r[i] = rect[0]; + g[i] = rect[1]; + b[i] = rect[2]; + a[i] = rect[3]; } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect) + { + r[i] = rect[0]; + g[i] = rect[1]; + b[i] = rect[2]; + } + PIXEL_LOOPER_END; } break; case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */ - for (y = h - 1; y >= 0; y--) { - y_row = y * w; - for (x = 0; x < w; x++, rect += 4) { - i = y_row + x; - - image->comps[0].data[i] = UPSAMPLE_8_TO_12(rect[0]); - image->comps[1].data[i] = UPSAMPLE_8_TO_12(rect[1]); - image->comps[2].data[i] = UPSAMPLE_8_TO_12(rect[2]); - if (numcomps > 3) - image->comps[3].data[i] = UPSAMPLE_8_TO_12(rect[3]); + if (numcomps == 4) { + PIXEL_LOOPER_BEGIN(rect) + { + r[i] = UPSAMPLE_8_TO_12(rect[0]); + g[i] = UPSAMPLE_8_TO_12(rect[1]); + b[i] = UPSAMPLE_8_TO_12(rect[2]); + a[i] = UPSAMPLE_8_TO_12(rect[3]); } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect) + { + r[i] = UPSAMPLE_8_TO_12(rect[0]); + g[i] = UPSAMPLE_8_TO_12(rect[1]); + b[i] = UPSAMPLE_8_TO_12(rect[2]); + } + PIXEL_LOOPER_END; } break; - case 16: - for (y = h - 1; y >= 0; y--) { - y_row = y * w; - for (x = 0; x < w; x++, rect += 4) { - i = y_row + x; - image->comps[0].data[i] = UPSAMPLE_8_TO_16(rect[0]); - image->comps[1].data[i] = UPSAMPLE_8_TO_16(rect[1]); - image->comps[2].data[i] = UPSAMPLE_8_TO_16(rect[2]); - if (numcomps > 3) - image->comps[3].data[i] = UPSAMPLE_8_TO_16(rect[3]); + case 16: + if (numcomps == 4) { + PIXEL_LOOPER_BEGIN(rect) + { + r[i] = UPSAMPLE_8_TO_16(rect[0]); + g[i] = UPSAMPLE_8_TO_16(rect[1]); + b[i] = UPSAMPLE_8_TO_16(rect[2]); + a[i] = UPSAMPLE_8_TO_16(rect[3]); } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect) + { + r[i] = UPSAMPLE_8_TO_16(rect[0]); + g[i] = UPSAMPLE_8_TO_16(rect[1]); + b[i] = UPSAMPLE_8_TO_16(rect[2]); + } + PIXEL_LOOPER_END; } break; } From caa59446ab1da8fee812e82cc9fb1b2024d180df Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Tue, 12 Jun 2012 08:28:25 +0000 Subject: [PATCH 232/360] Reroute node socket types update automatically from connections when possible. This prevents unnecessary conversions and breaking connections when linking incompatible types to the reroute color sockets (point in case: cycles shaders). --- source/blender/nodes/intern/node_common.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 78d21e5d4e4..24d1bd70e5a 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -853,7 +853,7 @@ static bNodeSocketTemplate node_reroute_out[]= { }; /* simple, only a single input and output here */ -ListBase node_reroute_internal_connect(bNodeTree *ntree, bNode *node) +static ListBase node_reroute_internal_connect(bNodeTree *ntree, bNode *node) { bNodeLink *link; ListBase ret; @@ -876,6 +876,23 @@ ListBase node_reroute_internal_connect(bNodeTree *ntree, bNode *node) return ret; } +static void node_reroute_update(bNodeTree *UNUSED(ntree), bNode *node) +{ + bNodeSocket *input = node->inputs.first; + bNodeSocket *output = node->outputs.first; + int type = SOCK_FLOAT; + + /* determine socket type from unambiguous input/output connection if possible */ + if (input->limit==1 && input->link) + type = input->link->fromsock->type; + else if (output->limit==1 && output->link) + type = output->link->tosock->type; + + /* same type for input/output */ + nodeSocketSetType(input, type); + nodeSocketSetType(output, type); +} + void register_node_type_reroute(bNodeTreeType *ttype) { /* frame type is used for all tree types, needs dynamic allocation */ @@ -884,6 +901,7 @@ void register_node_type_reroute(bNodeTreeType *ttype) node_type_base(ttype, ntype, NODE_REROUTE, "Reroute", NODE_CLASS_LAYOUT, 0); node_type_socket_templates(ntype, node_reroute_in, node_reroute_out); node_type_internal_connect(ntype, node_reroute_internal_connect); + node_type_update(ntype, node_reroute_update, NULL); ntype->needs_free = 1; nodeRegisterType(ttype, ntype); From b36b9f15eaf6810d907e70fa111e47cf2449a31b Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 12 Jun 2012 08:32:06 +0000 Subject: [PATCH 233/360] Few minors style and type fixes (and a nice, harmless copy/paste error! ;) ) --- source/blender/blenkernel/intern/anim_sys.c | 8 +++++--- source/blender/blenkernel/intern/constraint.c | 8 ++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 7fc80529753..a0da23a8f8f 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1287,9 +1287,11 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime /* check if this driver's curve should be skipped */ if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) { /* check if driver itself is tagged for recalculation */ - if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID) /*&& (driver->flag & DRIVER_FLAG_RECALC)*/) { // XXX driver recalc flag is not set yet by depsgraph! - /* evaluate this using values set already in other places */ - // NOTE: for 'layering' option later on, we should check if we should remove old value before adding new to only be done when drivers only changed + /* XXX driver recalc flag is not set yet by depsgraph! */ + if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID) /*&& (driver->flag & DRIVER_FLAG_RECALC)*/) { + /* evaluate this using values set already in other places + * NOTE: for 'layering' option later on, we should check if we should remove old value before adding + * new to only be done when drivers only changed */ calculate_fcurve(fcu, ctime); ok = animsys_execute_fcurve(ptr, NULL, fcu); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 62fb791df3a..09351f36bdb 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -822,12 +822,12 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar if (data->flag == CHILDOF_ALL) { /* multiply target (parent matrix) by offset (parent inverse) to get - * the effect of the parent that will be exherted on the owner + * the effect of the parent that will be exerted on the owner */ mult_m4_m4m4(parmat, ct->matrix, data->invmat); /* now multiply the parent matrix by the owner matrix to get the - * the effect of this constraint (i.e. owner is 'parented' to parent) + * the effect of this constraint (i.e. owner is 'parented' to parent) */ mult_m4_m4m4(cob->matrix, parmat, cob->matrix); } @@ -864,7 +864,7 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar loc_eulO_size_to_mat4(invmat, loco, eulo, sizo, cob->rotOrder); /* multiply target (parent matrix) by offset (parent inverse) to get - * the effect of the parent that will be exherted on the owner + * the effect of the parent that will be exerted on the owner */ mult_m4_m4m4(parmat, ct->matrix, invmat); @@ -1620,7 +1620,7 @@ static void rotlike_new_data(void *cdata) static void rotlike_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata) { - bChildOfConstraint *data = con->data; + bRotateLikeConstraint *data = con->data; /* target only */ func(con, (ID **)&data->tar, FALSE, userdata); From 6c4510f681a3be71a73ffaa8da3627b284add9e4 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Tue, 12 Jun 2012 08:44:46 +0000 Subject: [PATCH 234/360] Modification of node groups by adding/removing nodes is not possible yet. This patch extends the 'Make Group' operator and adds a new 'Separate' operator to add such functionality. 1) For inserting into existing groups: The 'Make Group from selected' (CTRL+g) operator shows a selection popup (like the object parenting operator), with options depending on the type of the active node (last selected): * "New" -> regular operator, creates new group type with all selected nodes inside. * "Insert" (only if active node is a group) -> adds all other selected nodes into the group. Currently still prohibits groups inside groups in general, though would be technically possible as long as no actual recursion occurs (group containing itself). 2) For extracting from an existing group: New 'Separate from group' operator (p), works similar to separating vertices/edges/faces from mesh. Two modes: * "Copy" makes a copy of the nodes in the parent tree, but keeps the original group intact. * "Move" removes selected nodes from the node group and adds them to the parent tree --- source/blender/blenkernel/BKE_node.h | 4 +- source/blender/editors/space_node/node_edit.c | 626 +++++++++++++++++- .../blender/editors/space_node/node_intern.h | 1 + source/blender/editors/space_node/node_ops.c | 2 + source/blender/nodes/intern/node_common.c | 296 --------- source/blender/nodes/intern/node_common.h | 2 - 6 files changed, 621 insertions(+), 310 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index e4d96c2219c..ef664f8fc4f 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -448,9 +448,7 @@ struct bNodeSocket *node_group_add_socket(struct bNodeTree *ngroup, const char * struct bNodeSocket *node_group_expose_socket(struct bNodeTree *ngroup, struct bNodeSocket *sock, int in_out); void node_group_expose_all_sockets(struct bNodeTree *ngroup); void node_group_remove_socket(struct bNodeTree *ngroup, struct bNodeSocket *gsock, int in_out); - -struct bNode *node_group_make_from_selected(struct bNodeTree *ntree); -int node_group_ungroup(struct bNodeTree *ntree, struct bNode *gnode); +struct bNodeSocket *node_group_add_extern_socket(struct bNodeTree *ntree, ListBase *lb, int in_out, struct bNodeSocket *gsock); /* in node_common.c */ void register_node_type_frame(struct bNodeTreeType *ttype); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index b4e07546fa9..81e375f26bc 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -46,11 +46,15 @@ #include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "DNA_world_types.h" +#include "DNA_action_types.h" +#include "DNA_anim_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BKE_action.h" +#include "BKE_animsys.h" #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_global.h" @@ -94,6 +98,7 @@ #include "GPU_material.h" #include "node_intern.h" +#include "NOD_socket.h" static EnumPropertyItem socket_in_out_items[] = { { SOCK_IN, "SOCK_IN", 0, "Input", "" }, @@ -1109,6 +1114,155 @@ void NODE_OT_group_socket_move_down(wmOperatorType *ot) /* ******************** Ungroup operator ********************** */ +/* returns 1 if its OK */ +static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) +{ + bNodeLink *link, *linkn; + bNode *node, *nextn; + bNodeTree *ngroup, *wgroup; + ListBase anim_basepaths = {NULL, NULL}; + + ngroup= (bNodeTree *)gnode->id; + if (ngroup==NULL) return 0; + + /* clear new pointers, set in copytree */ + for (node= ntree->nodes.first; node; node= node->next) + node->new_node= NULL; + + /* wgroup is a temporary copy of the NodeTree we're merging in + * - all of wgroup's nodes are transferred across to their new home + * - ngroup (i.e. the source NodeTree) is left unscathed + */ + wgroup= ntreeCopyTree(ngroup); + + /* add the nodes into the ntree */ + for (node= wgroup->nodes.first; node; node= nextn) { + nextn= node->next; + + /* keep track of this node's RNA "base" path (the part of the path identifying the node) + * if the old nodetree has animation data which potentially covers this node + */ + if (wgroup->adt) { + PointerRNA ptr; + char *path; + + RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr); + path = RNA_path_from_ID_to_struct(&ptr); + + if (path) + BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); + } + + /* migrate node */ + BLI_remlink(&wgroup->nodes, node); + BLI_addtail(&ntree->nodes, node); + + node->locx += gnode->locx; + node->locy += gnode->locy; + + node->flag |= NODE_SELECT; + } + + /* restore external links to and from the gnode */ + for (link= ntree->links.first; link; link= link->next) { + if (link->fromnode==gnode) { + if (link->fromsock->groupsock) { + bNodeSocket *gsock= link->fromsock->groupsock; + if (gsock->link) { + if (gsock->link->fromnode) { + /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */ + link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL); + link->fromsock = gsock->link->fromsock->new_sock; + } + else { + /* group output directly maps to group input */ + bNodeSocket *insock= node_group_find_input(gnode, gsock->link->fromsock); + if (insock->link) { + link->fromnode = insock->link->fromnode; + link->fromsock = insock->link->fromsock; + } + } + } + else { + /* copy the default input value from the group socket default to the external socket */ + node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value); + } + } + } + } + /* remove internal output links, these are not used anymore */ + for (link=wgroup->links.first; link; link= linkn) { + linkn = link->next; + if (!link->tonode) + nodeRemLink(wgroup, link); + } + /* restore links from internal nodes */ + for (link= wgroup->links.first; link; link= link->next) { + /* indicates link to group input */ + if (!link->fromnode) { + /* NB: can't use find_group_node_input here, + * because gnode sockets still point to the old tree! + */ + bNodeSocket *insock; + for (insock= gnode->inputs.first; insock; insock= insock->next) + if (insock->groupsock->new_sock == link->fromsock) + break; + if (insock->link) { + link->fromnode = insock->link->fromnode; + link->fromsock = insock->link->fromsock; + } + else { + /* copy the default input value from the group node socket default to the internal socket */ + node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value); + nodeRemLink(wgroup, link); + } + } + } + + /* add internal links to the ntree */ + for (link= wgroup->links.first; link; link= linkn) { + linkn= link->next; + BLI_remlink(&wgroup->links, link); + BLI_addtail(&ntree->links, link); + } + + /* and copy across the animation, + * note that the animation data's action can be NULL here */ + if (wgroup->adt) { + LinkData *ld, *ldn=NULL; + bAction *waction; + + /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */ + waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action); + + /* now perform the moving */ + BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths); + + /* paths + their wrappers need to be freed */ + for (ld = anim_basepaths.first; ld; ld = ldn) { + ldn = ld->next; + + MEM_freeN(ld->data); + BLI_freelinkN(&anim_basepaths, ld); + } + + /* free temp action too */ + if (waction) { + BKE_libblock_free(&G.main->action, waction); + } + } + + /* delete the group instance. this also removes old input links! */ + nodeFreeNode(ntree, gnode); + + /* free the group tree (takes care of user count) */ + BKE_libblock_free(&G.main->nodetree, wgroup); + + ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; + + return 1; +} + static int node_group_ungroup_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); @@ -1129,7 +1283,10 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_WARNING, "Not a group"); return OPERATOR_CANCELLED; } - else if (!node_group_ungroup(snode->edittree, gnode)) { + else if (node_group_ungroup(snode->nodetree, gnode)) { + ntreeUpdateTree(snode->nodetree); + } + else { BKE_report(op->reports, RPT_WARNING, "Can't ungroup"); return OPERATOR_CANCELLED; } @@ -1155,6 +1312,200 @@ void NODE_OT_group_ungroup(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } +/* ******************** Separate operator ********************** */ + +/* returns 1 if its OK */ +static int node_group_separate_selected(bNodeTree *ntree, bNode *gnode, int make_copy) +{ + bNodeLink *link, *link_next; + bNode *node, *node_next, *newnode; + bNodeTree *ngroup; + ListBase anim_basepaths = {NULL, NULL}; + + ngroup= (bNodeTree *)gnode->id; + if (ngroup==NULL) return 0; + + /* deselect all nodes in the target tree */ + for (node=ntree->nodes.first; node; node=node->next) + node_deselect(node); + + /* clear new pointers, set in nodeCopyNode */ + for (node= ngroup->nodes.first; node; node= node->next) + node->new_node= NULL; + + /* add selected nodes into the ntree */ + for (node= ngroup->nodes.first; node; node= node_next) { + node_next = node->next; + if (!(node->flag & NODE_SELECT)) + continue; + + if (make_copy) { + /* make a copy */ + newnode = nodeCopyNode(ngroup, node); + } + else { + /* use the existing node */ + newnode = node; + } + + /* keep track of this node's RNA "base" path (the part of the path identifying the node) + * if the old nodetree has animation data which potentially covers this node + */ + if (ngroup->adt) { + PointerRNA ptr; + char *path; + + RNA_pointer_create(&ngroup->id, &RNA_Node, newnode, &ptr); + path = RNA_path_from_ID_to_struct(&ptr); + + if (path) + BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); + } + + /* ensure valid parent pointers, detach if parent stays inside the group */ + if (newnode->parent && !(newnode->parent->flag & NODE_SELECT)) + nodeDetachNode(newnode); + + /* migrate node */ + BLI_remlink(&ngroup->nodes, newnode); + BLI_addtail(&ntree->nodes, newnode); + + newnode->locx += gnode->locx; + newnode->locy += gnode->locy; + } + + /* add internal links to the ntree */ + for (link= ngroup->links.first; link; link= link_next) { + int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT)); + int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT)); + link_next = link->next; + + if (make_copy) { + /* make a copy of internal links */ + if (fromselect && toselect) + nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock, link->tonode->new_node, link->tosock->new_sock); + } + else { + /* move valid links over, delete broken links */ + if (fromselect && toselect) { + BLI_remlink(&ngroup->links, link); + BLI_addtail(&ntree->links, link); + } + else if (fromselect || toselect) { + nodeRemLink(ngroup, link); + } + } + } + + /* and copy across the animation, + * note that the animation data's action can be NULL here */ + if (ngroup->adt) { + LinkData *ld, *ldn=NULL; + + /* now perform the moving */ + BKE_animdata_separate_by_basepath(&ngroup->id, &ntree->id, &anim_basepaths); + + /* paths + their wrappers need to be freed */ + for (ld = anim_basepaths.first; ld; ld = ldn) { + ldn = ld->next; + + MEM_freeN(ld->data); + BLI_freelinkN(&anim_basepaths, ld); + } + } + + ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; + if (!make_copy) + ngroup->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; + + return 1; +} + +typedef enum eNodeGroupSeparateType { + NODE_GS_COPY, + NODE_GS_MOVE +} eNodeGroupSeparateType; + +/* Operator Property */ +EnumPropertyItem node_group_separate_types[] = { + {NODE_GS_COPY, "COPY", 0, "Copy", "Copy to parent node tree, keep group intact"}, + {NODE_GS_MOVE, "MOVE", 0, "Move", "Move to parent node tree, remove from group"}, + {0, NULL, 0, NULL, NULL} +}; + +static int node_group_separate_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *gnode; + int type = RNA_enum_get(op->ptr, "type"); + + ED_preview_kill_jobs(C); + + /* are we inside of a group? */ + gnode= node_tree_get_editgroup(snode->nodetree); + if (!gnode) { + BKE_report(op->reports, RPT_WARNING, "Not inside node group"); + return OPERATOR_CANCELLED; + } + + switch (type) { + case NODE_GS_COPY: + if (!node_group_separate_selected(snode->nodetree, gnode, 1)) { + BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); + return OPERATOR_CANCELLED; + } + break; + case NODE_GS_MOVE: + if (!node_group_separate_selected(snode->nodetree, gnode, 0)) { + BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); + return OPERATOR_CANCELLED; + } + break; + } + + /* switch to parent tree */ + snode_make_group_editable(snode, NULL); + + ntreeUpdateTree(snode->nodetree); + + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; +} + +static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event)) +{ + uiPopupMenu *pup = uiPupMenuBegin(C, "Separate", ICON_NONE); + uiLayout *layout = uiPupMenuLayout(pup); + + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); + uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_COPY); + uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_MOVE); + + uiPupMenuEnd(C, pup); + + return OPERATOR_CANCELLED; +} + +void NODE_OT_group_separate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Separate"; + ot->description = "Separate selected nodes from the node group"; + ot->idname = "NODE_OT_group_separate"; + + /* api callbacks */ + ot->invoke = node_group_separate_invoke; + ot->exec = node_group_separate_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", node_group_separate_types, NODE_GS_COPY, "Type", ""); +} + /* ************************** Node generic ************** */ /* is rct in visible part of node? */ @@ -3249,10 +3600,219 @@ void NODE_OT_render_changed(wmOperatorType *ot) /* ****************** Make Group operator ******************* */ +static int node_group_make_test(bNodeTree *ntree, bNode *gnode) +{ + bNode *node; + bNodeLink *link; + int totnode = 0; + + /* is there something to group? also do some clearing */ + for (node= ntree->nodes.first; node; node= node->next) { + if (node == gnode) + continue; + + if (node->flag & NODE_SELECT) { + /* no groups in groups */ + if (node->type==NODE_GROUP) + return 0; + totnode++; + } + + node->done = 0; + } + if (totnode==0) return 0; + + /* check if all connections are OK, no unselected node has both + * inputs and outputs to a selection */ + for (link= ntree->links.first; link; link= link->next) { + if (link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT && link->fromnode != gnode) + link->tonode->done |= 1; + if (link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT && link->tonode != gnode) + link->fromnode->done |= 2; + } + + for (node= ntree->nodes.first; node; node= node->next) { + if (node == gnode) + continue; + if ((node->flag & NODE_SELECT)==0) + if (node->done==3) + break; + } + if (node) + return 0; + + return 1; +} + +static void node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min, float *max) +{ + bNode *node; + INIT_MINMAX2(min, max); + for (node= ntree->nodes.first; node; node= node->next) { + if (node == gnode) + continue; + if (node->flag & NODE_SELECT) { + DO_MINMAX2((&node->locx), min, max); + } + } +} + +static int node_group_make_insert_selected(bNodeTree *ntree, bNode *gnode) +{ + bNodeTree *ngroup = (bNodeTree *)gnode->id; + bNodeLink *link, *linkn; + bNode *node, *nextn; + bNodeSocket *gsock; + ListBase anim_basepaths = {NULL, NULL}; + float min[2], max[2]; + + /* deselect all nodes in the target tree */ + for (node = ngroup->nodes.first; node; node=node->next) + node_deselect(node); + + node_get_selected_minmax(ntree, gnode, min, max); + + /* move nodes over */ + for (node= ntree->nodes.first; node; node= nextn) { + nextn= node->next; + if (node == gnode) + continue; + if (node->flag & NODE_SELECT) { + /* keep track of this node's RNA "base" path (the part of the pat identifying the node) + * if the old nodetree has animation data which potentially covers this node + */ + if (ntree->adt) { + PointerRNA ptr; + char *path; + + RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + path = RNA_path_from_ID_to_struct(&ptr); + + if (path) + BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); + } + + /* ensure valid parent pointers, detach if parent stays outside the group */ + if (node->parent && !(node->parent->flag & NODE_SELECT)) + nodeDetachNode(node); + + /* change node-collection membership */ + BLI_remlink(&ntree->nodes, node); + BLI_addtail(&ngroup->nodes, node); + + node->locx-= 0.5f*(min[0]+max[0]); + node->locy-= 0.5f*(min[1]+max[1]); + } + } + + /* move animation data over */ + if (ntree->adt) { + LinkData *ld, *ldn=NULL; + + BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths); + + /* paths + their wrappers need to be freed */ + for (ld = anim_basepaths.first; ld; ld = ldn) { + ldn = ld->next; + + MEM_freeN(ld->data); + BLI_freelinkN(&anim_basepaths, ld); + } + } + + /* node groups don't use internal cached data */ + ntreeFreeCache(ngroup); + + /* relink external sockets */ + for (link= ntree->links.first; link; link= linkn) { + int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT) && link->fromnode != gnode); + int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT) && link->tonode != gnode); + linkn= link->next; + + if (gnode && ((fromselect && link->tonode == gnode) || (toselect && link->fromnode == gnode))) { + /* remove all links to/from the gnode. + * this can remove link information, but there's no general way to preserve it. + */ + nodeRemLink(ntree, link); + } + else if (fromselect && toselect) { + BLI_remlink(&ntree->links, link); + BLI_addtail(&ngroup->links, link); + } + else if (toselect) { + gsock = node_group_expose_socket(ngroup, link->tosock, SOCK_IN); + link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock); + link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, gsock); + link->tonode = gnode; + } + else if (fromselect) { + /* search for existing group node socket */ + for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next) + if (gsock->link && gsock->link->fromsock==link->fromsock) + break; + if (!gsock) { + gsock = node_group_expose_socket(ngroup, link->fromsock, SOCK_OUT); + gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock); + link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, gsock); + } + else + link->fromsock = node_group_find_output(gnode, gsock); + link->fromnode = gnode; + } + } + + /* update of the group tree */ + ngroup->update |= NTREE_UPDATE; + /* update of the tree containing the group instance node */ + ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; + + return 1; +} + +static bNode *node_group_make_from_selected(bNodeTree *ntree) +{ + bNode *gnode; + bNodeTree *ngroup; + float min[2], max[2]; + bNodeTemplate ntemp; + + node_get_selected_minmax(ntree, NULL, min, max); + + /* new nodetree */ + ngroup= ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP); + + /* make group node */ + ntemp.type = NODE_GROUP; + ntemp.ngroup = ngroup; + gnode= nodeAddNode(ntree, &ntemp); + gnode->locx= 0.5f*(min[0]+max[0]); + gnode->locy= 0.5f*(min[1]+max[1]); + + node_group_make_insert_selected(ntree, gnode); + + /* update of the tree containing the group instance node */ + ntree->update |= NTREE_UPDATE_NODES; + + return gnode; +} + +typedef enum eNodeGroupMakeType { + NODE_GM_NEW, + NODE_GM_INSERT +} eNodeGroupMakeType; + +/* Operator Property */ +EnumPropertyItem node_group_make_types[] = { + {NODE_GM_NEW, "NEW", 0, "New", "Create a new node group from selected nodes"}, + {NODE_GM_INSERT, "INSERT", 0, "Insert", "Insert into active node group"}, + {0, NULL, 0, NULL, NULL} +}; + static int node_group_make_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); bNode *gnode; + int type = RNA_enum_get(op->ptr, "type"); if (snode->edittree!=snode->nodetree) { BKE_report(op->reports, RPT_WARNING, "Can not add a new Group in a Group"); @@ -3272,25 +3832,70 @@ static int node_group_make_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } } - + ED_preview_kill_jobs(C); - - gnode= node_group_make_from_selected(snode->nodetree); - if (gnode==NULL) { - BKE_report(op->reports, RPT_WARNING, "Can not make Group"); - return OPERATOR_CANCELLED; + + switch (type) { + case NODE_GM_NEW: + if (node_group_make_test(snode->nodetree, NULL)) { + gnode = node_group_make_from_selected(snode->nodetree); + } + else { + BKE_report(op->reports, RPT_WARNING, "Can not make Group"); + return OPERATOR_CANCELLED; + } + break; + case NODE_GM_INSERT: + gnode = nodeGetActive(snode->nodetree); + if (!gnode || gnode->type != NODE_GROUP) { + BKE_report(op->reports, RPT_WARNING, "No active Group node"); + return OPERATOR_CANCELLED; + } + if (node_group_make_test(snode->nodetree, gnode)) { + node_group_make_insert_selected(snode->nodetree, gnode); + } + else { + BKE_report(op->reports, RPT_WARNING, "Can not insert into Group"); + return OPERATOR_CANCELLED; + } + break; } - else { + + if (gnode) { nodeSetActive(snode->nodetree, gnode); - ntreeUpdateTree(snode->nodetree); + snode_make_group_editable(snode, gnode); } + if (gnode) + ntreeUpdateTree((bNodeTree *)gnode->id); + ntreeUpdateTree(snode->nodetree); + snode_notify(C, snode); snode_dag_update(C, snode); return OPERATOR_FINISHED; } +static int node_group_make_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *act = nodeGetActive(snode->edittree); + uiPopupMenu *pup = uiPupMenuBegin(C, "Make Group", ICON_NONE); + uiLayout *layout = uiPupMenuLayout(pup); + + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); + uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_NEW); + + /* if active node is a group, add insert option */ + if (act && act->type == NODE_GROUP) { + uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_INSERT); + } + + uiPupMenuEnd(C, pup); + + return OPERATOR_CANCELLED; +} + void NODE_OT_group_make(wmOperatorType *ot) { /* identifiers */ @@ -3299,11 +3904,14 @@ void NODE_OT_group_make(wmOperatorType *ot) ot->idname = "NODE_OT_group_make"; /* api callbacks */ + ot->invoke = node_group_make_invoke; ot->exec = node_group_make_exec; ot->poll = ED_operator_node_active; /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", node_group_make_types, NODE_GM_NEW, "Type", ""); } /* ****************** Hide operator *********************** */ diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 9e873799f1c..d9dbd646fa5 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -149,6 +149,7 @@ void NODE_OT_add_reroute(struct wmOperatorType *ot); void NODE_OT_group_make(struct wmOperatorType *ot); void NODE_OT_group_ungroup(struct wmOperatorType *ot); +void NODE_OT_group_separate(struct wmOperatorType *ot); void NODE_OT_group_edit(struct wmOperatorType *ot); void NODE_OT_group_socket_add(struct wmOperatorType *ot); void NODE_OT_group_socket_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 8a977d2f112..ff1661f0327 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -83,6 +83,7 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_group_make); WM_operatortype_append(NODE_OT_group_ungroup); + WM_operatortype_append(NODE_OT_group_separate); WM_operatortype_append(NODE_OT_group_edit); WM_operatortype_append(NODE_OT_group_socket_add); WM_operatortype_append(NODE_OT_group_socket_remove); @@ -269,6 +270,7 @@ void node_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "NODE_OT_group_make", GKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "NODE_OT_group_ungroup", GKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "NODE_OT_group_separate", PKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_group_edit", TABKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_read_renderlayers", RKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 24d1bd70e5a..150bede4b7c 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -32,8 +32,6 @@ #include -#include "DNA_action_types.h" -#include "DNA_anim_types.h" #include "DNA_node_types.h" #include "BLI_listbase.h" @@ -42,8 +40,6 @@ #include "BLF_translation.h" -#include "BKE_action.h" -#include "BKE_animsys.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" @@ -112,298 +108,6 @@ bNodeSocket *node_group_add_extern_socket(bNodeTree *UNUSED(ntree), ListBase *lb return sock; } -bNode *node_group_make_from_selected(bNodeTree *ntree) -{ - bNodeLink *link, *linkn; - bNode *node, *gnode, *nextn; - bNodeTree *ngroup; - bNodeSocket *gsock; - ListBase anim_basepaths = {NULL, NULL}; - float min[2], max[2]; - int totnode=0; - bNodeTemplate ntemp; - - INIT_MINMAX2(min, max); - - /* is there something to group? also do some clearing */ - for (node= ntree->nodes.first; node; node= node->next) { - if (node->flag & NODE_SELECT) { - /* no groups in groups */ - if (node->type==NODE_GROUP) - return NULL; - DO_MINMAX2((&node->locx), min, max); - totnode++; - } - node->done = FALSE; - } - if (totnode==0) return NULL; - - /* check if all connections are OK, no unselected node has both - * inputs and outputs to a selection */ - for (link= ntree->links.first; link; link= link->next) { - if (link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT) - link->tonode->done |= 1; - if (link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT) - link->fromnode->done |= 2; - } - - for (node= ntree->nodes.first; node; node= node->next) { - if ((node->flag & NODE_SELECT)==0) - if (node->done==3) - break; - } - if (node) - return NULL; - - /* OK! new nodetree */ - ngroup= ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP); - - /* move nodes over */ - for (node= ntree->nodes.first; node; node= nextn) { - nextn= node->next; - if (node->flag & NODE_SELECT) { - /* keep track of this node's RNA "base" path (the part of the pat identifying the node) - * if the old nodetree has animation data which potentially covers this node - */ - if (ntree->adt) { - PointerRNA ptr; - char *path; - - RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); - path = RNA_path_from_ID_to_struct(&ptr); - - if (path) - BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); - } - - /* ensure valid parent pointers, detach if parent stays outside the group */ - if (node->parent && !(node->parent->flag & NODE_SELECT)) - nodeDetachNode(node); - - /* change node-collection membership */ - BLI_remlink(&ntree->nodes, node); - BLI_addtail(&ngroup->nodes, node); - - node->locx-= 0.5f*(min[0]+max[0]); - node->locy-= 0.5f*(min[1]+max[1]); - } - } - - /* move animation data over */ - if (ntree->adt) { - LinkData *ld, *ldn=NULL; - - BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths); - - /* paths + their wrappers need to be freed */ - for (ld = anim_basepaths.first; ld; ld = ldn) { - ldn = ld->next; - - MEM_freeN(ld->data); - BLI_freelinkN(&anim_basepaths, ld); - } - } - - /* node groups don't use internal cached data */ - ntreeFreeCache(ngroup); - - /* make group node */ - ntemp.type = NODE_GROUP; - ntemp.ngroup = ngroup; - gnode= nodeAddNode(ntree, &ntemp); - gnode->locx= 0.5f*(min[0]+max[0]); - gnode->locy= 0.5f*(min[1]+max[1]); - - /* relink external sockets */ - for (link= ntree->links.first; link; link= linkn) { - linkn= link->next; - - if (link->fromnode && link->tonode && (link->fromnode->flag & link->tonode->flag & NODE_SELECT)) { - BLI_remlink(&ntree->links, link); - BLI_addtail(&ngroup->links, link); - } - else if (link->tonode && (link->tonode->flag & NODE_SELECT)) { - gsock = node_group_expose_socket(ngroup, link->tosock, SOCK_IN); - link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock); - link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, gsock); - link->tonode = gnode; - } - else if (link->fromnode && (link->fromnode->flag & NODE_SELECT)) { - /* search for existing group node socket */ - for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next) - if (gsock->link && gsock->link->fromsock==link->fromsock) - break; - if (!gsock) { - gsock = node_group_expose_socket(ngroup, link->fromsock, SOCK_OUT); - gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock); - link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, gsock); - } - else - link->fromsock = node_group_find_output(gnode, gsock); - link->fromnode = gnode; - } - } - - /* update of the group tree */ - ngroup->update |= NTREE_UPDATE; - ntreeUpdateTree(ngroup); - /* update of the tree containing the group instance node */ - ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; - ntreeUpdateTree(ntree); - - return gnode; -} - -/* returns 1 if its OK */ -int node_group_ungroup(bNodeTree *ntree, bNode *gnode) -{ - bNodeLink *link, *linkn; - bNode *node, *nextn; - bNodeTree *ngroup, *wgroup; - ListBase anim_basepaths = {NULL, NULL}; - - ngroup= (bNodeTree *)gnode->id; - if (ngroup==NULL) return 0; - - /* clear new pointers, set in copytree */ - for (node= ntree->nodes.first; node; node= node->next) - node->new_node= NULL; - - /* wgroup is a temporary copy of the NodeTree we're merging in - * - all of wgroup's nodes are transferred across to their new home - * - ngroup (i.e. the source NodeTree) is left unscathed - */ - wgroup= ntreeCopyTree(ngroup); - - /* add the nodes into the ntree */ - for (node= wgroup->nodes.first; node; node= nextn) { - nextn= node->next; - - /* keep track of this node's RNA "base" path (the part of the pat identifying the node) - * if the old nodetree has animation data which potentially covers this node - */ - if (wgroup->adt) { - PointerRNA ptr; - char *path; - - RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr); - path = RNA_path_from_ID_to_struct(&ptr); - - if (path) - BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); - } - - /* migrate node */ - BLI_remlink(&wgroup->nodes, node); - BLI_addtail(&ntree->nodes, node); - - node->locx += gnode->locx; - node->locy += gnode->locy; - - node->flag |= NODE_SELECT; - } - - /* restore external links to and from the gnode */ - for (link= ntree->links.first; link; link= link->next) { - if (link->fromnode==gnode) { - if (link->fromsock->groupsock) { - bNodeSocket *gsock= link->fromsock->groupsock; - if (gsock->link) { - if (gsock->link->fromnode) { - /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */ - link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL); - link->fromsock = gsock->link->fromsock->new_sock; - } - else { - /* group output directly maps to group input */ - bNodeSocket *insock= node_group_find_input(gnode, gsock->link->fromsock); - if (insock->link) { - link->fromnode = insock->link->fromnode; - link->fromsock = insock->link->fromsock; - } - } - } - else { - /* copy the default input value from the group socket default to the external socket */ - node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value); - } - } - } - } - /* remove internal output links, these are not used anymore */ - for (link=wgroup->links.first; link; link= linkn) { - linkn = link->next; - if (!link->tonode) - nodeRemLink(wgroup, link); - } - /* restore links from internal nodes */ - for (link= wgroup->links.first; link; link= link->next) { - /* indicates link to group input */ - if (!link->fromnode) { - /* NB: can't use find_group_node_input here, - * because gnode sockets still point to the old tree! - */ - bNodeSocket *insock; - for (insock= gnode->inputs.first; insock; insock= insock->next) - if (insock->groupsock->new_sock == link->fromsock) - break; - if (insock->link) { - link->fromnode = insock->link->fromnode; - link->fromsock = insock->link->fromsock; - } - else { - /* copy the default input value from the group node socket default to the internal socket */ - node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value); - nodeRemLink(wgroup, link); - } - } - } - - /* add internal links to the ntree */ - for (link= wgroup->links.first; link; link= linkn) { - linkn= link->next; - BLI_remlink(&wgroup->links, link); - BLI_addtail(&ntree->links, link); - } - - /* and copy across the animation, - * note that the animation data's action can be NULL here */ - if (wgroup->adt) { - LinkData *ld, *ldn=NULL; - bAction *waction; - - /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */ - waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action); - - /* now perform the moving */ - BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths); - - /* paths + their wrappers need to be freed */ - for (ld = anim_basepaths.first; ld; ld = ldn) { - ldn = ld->next; - - MEM_freeN(ld->data); - BLI_freelinkN(&anim_basepaths, ld); - } - - /* free temp action too */ - if (waction) { - BKE_libblock_free(&G.main->action, waction); - } - } - - /* delete the group instance. this also removes old input links! */ - nodeFreeNode(ntree, gnode); - - /* free the group tree (takes care of user count) */ - BKE_libblock_free(&G.main->nodetree, wgroup); - - ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; - ntreeUpdateTree(ntree); - - return 1; -} - bNodeSocket *node_group_add_socket(bNodeTree *ngroup, const char *name, int type, int in_out) { bNodeSocketType *stype = ntreeGetSocketType(type); diff --git a/source/blender/nodes/intern/node_common.h b/source/blender/nodes/intern/node_common.h index 616221d6658..f1bb837e483 100644 --- a/source/blender/nodes/intern/node_common.h +++ b/source/blender/nodes/intern/node_common.h @@ -37,8 +37,6 @@ struct bNodeTree; -struct bNodeSocket *node_group_add_extern_socket(struct bNodeTree *ntree, ListBase *lb, int in_out, struct bNodeSocket *gsock); - void node_group_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp); void node_forloop_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp); void node_whileloop_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp); From bc6929fcdd87a1eaa721459cd57a25ecfa8bf0d4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 12 Jun 2012 08:50:40 +0000 Subject: [PATCH 235/360] optimize jpeg2000 loading. --- source/blender/imbuf/intern/jp2.c | 212 ++++++++++++++++++------------ 1 file changed, 125 insertions(+), 87 deletions(-) diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index 1a807530281..a5826634724 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -93,26 +93,35 @@ static void info_callback(const char *msg, void *client_data) fprintf(stdout, "[INFO] %s", msg); } +# define PIXEL_LOOPER_BEGIN(_rect) \ + for (y = h - 1; y != (unsigned int)(-1); y--) { \ + for (i = y * w, i_next = (y + 1) * w; \ + i < i_next; \ + i++, _rect += 4) \ + { \ +# define PIXEL_LOOPER_END \ + } \ + } (void)0 \ -struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags){ +struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags) +{ struct ImBuf *ibuf = NULL; int use_float = FALSE; /* for precision higher then 8 use float */ + int use_alpha = FALSE; long signed_offsets[4] = {0, 0, 0, 0}; int float_divs[4] = {1, 1, 1, 1}; - int index; - - int w, h, planes; + unsigned int i, i_next, w, h, planes; + unsigned int y; + int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */ opj_dparameters_t parameters; /* decompression parameters */ opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; - - int i; - + opj_dinfo_t *dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; @@ -169,9 +178,11 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags){ case 1: /* Greyscale */ case 3: /* Color */ planes = 24; + use_alpha = FALSE; break; default: /* 2 or 4 - Greyscale or Color + alpha */ planes = 32; /* greyscale + alpha */ + use_alpha = TRUE; break; } @@ -206,64 +217,102 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags){ float *rect_float = ibuf->rect_float; if (image->numcomps < 3) { + r = image->comps[0].data; + a = (use_alpha) ? image->comps[1].data : NULL; + /* greyscale 12bits+ */ - for (i = 0; i < w * h; i++, rect_float += 4) { - index = w * h - ((i) / (w) + 1) * w + (i) % (w); - - rect_float[0] = rect_float[1] = rect_float[2] = (float)(image->comps[0].data[index] + signed_offsets[0]) / float_divs[0]; - - if (image->numcomps == 2) - rect_float[3] = (image->comps[1].data[index] + signed_offsets[1]) / float_divs[1]; - else + if (use_alpha) { + a = image->comps[1].data; + PIXEL_LOOPER_BEGIN(rect_float) { + rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; + rect_float[3] = (a[i] + signed_offsets[1]) / float_divs[1]; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_float) { + rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; rect_float[3] = 1.0f; + } + PIXEL_LOOPER_END; } } else { + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + /* rgb or rgba 12bits+ */ - for (i = 0; i < w * h; i++, rect_float += 4) { - index = w * h - ((i) / (w) + 1) * w + (i) % (w); - - rect_float[0] = (float)(image->comps[0].data[index] + signed_offsets[0]) / float_divs[0]; - rect_float[1] = (float)(image->comps[1].data[index] + signed_offsets[1]) / float_divs[1]; - rect_float[2] = (float)(image->comps[2].data[index] + signed_offsets[2]) / float_divs[2]; - - if (image->numcomps >= 4) - rect_float[3] = (float)(image->comps[3].data[index] + signed_offsets[3]) / float_divs[3]; - else + if (use_alpha) { + a = image->comps[3].data; + PIXEL_LOOPER_BEGIN(rect_float) { + rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; + rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1]; + rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2]; + rect_float[3] = (float)(a[i] + signed_offsets[3]) / float_divs[3]; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_float) { + rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; + rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1]; + rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2]; rect_float[3] = 1.0f; + } + PIXEL_LOOPER_END; } } } else { - unsigned char *rect = (unsigned char *)ibuf->rect; + unsigned char *rect_uchar = (unsigned char *)ibuf->rect; if (image->numcomps < 3) { + r = image->comps[0].data; + a = (use_alpha) ? image->comps[1].data : NULL; + /* greyscale */ - for (i = 0; i < w * h; i++, rect += 4) { - index = w * h - ((i) / (w) + 1) * w + (i) % (w); - - rect[0] = rect[1] = rect[2] = (image->comps[0].data[index] + signed_offsets[0]); - - if (image->numcomps == 2) - rect[3] = image->comps[1].data[index] + signed_offsets[1]; - else - rect[3] = 255; + if (use_alpha) { + a = image->comps[3].data; + PIXEL_LOOPER_BEGIN(rect_uchar) { + rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]); + rect_uchar[3] = a[i] + signed_offsets[1]; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_uchar) { + rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]); + rect_uchar[3] = 255; + } + PIXEL_LOOPER_END; } } else { + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + /* 8bit rgb or rgba */ - for (i = 0; i < w * h; i++, rect += 4) { - int index = w * h - ((i) / (w) + 1) * w + (i) % (w); - - rect[0] = image->comps[0].data[index] + signed_offsets[0]; - rect[1] = image->comps[1].data[index] + signed_offsets[1]; - rect[2] = image->comps[2].data[index] + signed_offsets[2]; - - if (image->numcomps >= 4) - rect[3] = image->comps[3].data[index] + signed_offsets[3]; - else - rect[3] = 255; + if (use_alpha) { + a = image->comps[3].data; + PIXEL_LOOPER_BEGIN(rect_uchar) { + rect_uchar[0] = r[i] + signed_offsets[0]; + rect_uchar[1] = g[i] + signed_offsets[1]; + rect_uchar[2] = b[i] + signed_offsets[2]; + rect_uchar[3] = a[i] + signed_offsets[3]; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_uchar) { + rect_uchar[0] = r[i] + signed_offsets[0]; + rect_uchar[1] = g[i] + signed_offsets[1]; + rect_uchar[2] = b[i] + signed_offsets[2]; + rect_uchar[3] = 255; + } + PIXEL_LOOPER_END; } } } @@ -482,7 +531,7 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *ima static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) { - unsigned char *rect; + unsigned char *rect_uchar; float *rect_float; unsigned int subsampling_dx = parameters->subsampling_dx; @@ -564,7 +613,7 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) image->y1 = image->y0 + (h - 1) * subsampling_dy + 1 + image->y0; /* set image data */ - rect = (unsigned char *) ibuf->rect; + rect_uchar = (unsigned char *) ibuf->rect; rect_float = ibuf->rect_float; /* set the destination channels */ @@ -573,22 +622,11 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) b = image->comps[2].data; a = (numcomps == 4) ? image->comps[3].data : NULL; - if (rect_float && rect && prec == 8) { + if (rect_float && rect_uchar && prec == 8) { /* No need to use the floating point buffer, just write the 8 bits from the char buffer */ rect_float = NULL; } -# define PIXEL_LOOPER_BEGIN(_rect) \ - for (y = h - 1; y != (unsigned int)(-1); y--) { \ - for (i = y * w, i_next = (y + 1) * w; \ - i < i_next; \ - i++, _rect += 4) \ - { \ - -# define PIXEL_LOOPER_END \ - } \ - } (void)0 \ - if (rect_float) { switch (prec) { case 8: /* Convert blenders float color channels to 8, 12 or 16bit ints */ @@ -732,21 +770,21 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) switch (prec) { case 8: if (numcomps == 4) { - PIXEL_LOOPER_BEGIN(rect) + PIXEL_LOOPER_BEGIN(rect_uchar) { - r[i] = rect[0]; - g[i] = rect[1]; - b[i] = rect[2]; - a[i] = rect[3]; + r[i] = rect_uchar[0]; + g[i] = rect_uchar[1]; + b[i] = rect_uchar[2]; + a[i] = rect_uchar[3]; } PIXEL_LOOPER_END; } else { - PIXEL_LOOPER_BEGIN(rect) + PIXEL_LOOPER_BEGIN(rect_uchar) { - r[i] = rect[0]; - g[i] = rect[1]; - b[i] = rect[2]; + r[i] = rect_uchar[0]; + g[i] = rect_uchar[1]; + b[i] = rect_uchar[2]; } PIXEL_LOOPER_END; } @@ -754,21 +792,21 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */ if (numcomps == 4) { - PIXEL_LOOPER_BEGIN(rect) + PIXEL_LOOPER_BEGIN(rect_uchar) { - r[i] = UPSAMPLE_8_TO_12(rect[0]); - g[i] = UPSAMPLE_8_TO_12(rect[1]); - b[i] = UPSAMPLE_8_TO_12(rect[2]); - a[i] = UPSAMPLE_8_TO_12(rect[3]); + r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]); + g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]); + b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]); + a[i] = UPSAMPLE_8_TO_12(rect_uchar[3]); } PIXEL_LOOPER_END; } else { - PIXEL_LOOPER_BEGIN(rect) + PIXEL_LOOPER_BEGIN(rect_uchar) { - r[i] = UPSAMPLE_8_TO_12(rect[0]); - g[i] = UPSAMPLE_8_TO_12(rect[1]); - b[i] = UPSAMPLE_8_TO_12(rect[2]); + r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]); + g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]); + b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]); } PIXEL_LOOPER_END; } @@ -776,21 +814,21 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) case 16: if (numcomps == 4) { - PIXEL_LOOPER_BEGIN(rect) + PIXEL_LOOPER_BEGIN(rect_uchar) { - r[i] = UPSAMPLE_8_TO_16(rect[0]); - g[i] = UPSAMPLE_8_TO_16(rect[1]); - b[i] = UPSAMPLE_8_TO_16(rect[2]); - a[i] = UPSAMPLE_8_TO_16(rect[3]); + r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]); + g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]); + b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]); + a[i] = UPSAMPLE_8_TO_16(rect_uchar[3]); } PIXEL_LOOPER_END; } else { - PIXEL_LOOPER_BEGIN(rect) + PIXEL_LOOPER_BEGIN(rect_uchar) { - r[i] = UPSAMPLE_8_TO_16(rect[0]); - g[i] = UPSAMPLE_8_TO_16(rect[1]); - b[i] = UPSAMPLE_8_TO_16(rect[2]); + r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]); + g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]); + b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]); } PIXEL_LOOPER_END; } From 552887251fa984cc7ff8e15aed59e82227d47c22 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 12 Jun 2012 11:13:53 +0000 Subject: [PATCH 236/360] Masking support for motion tracks Added option to use Grease Pencil datablock as a mask for pattern when doing motion tracking. Option could be found in Tracking Settings panel. All strokes would be rasterized separately from each other and every stroke is treating as a closed spline. Also added option to apply a mask on track preview which is situated just after B/B/W channel button under track preview. --- extern/libmv/libmv-capi.cpp | 27 +++- extern/libmv/libmv-capi.h | 24 ++-- extern/libmv/libmv/tracking/track_region.cc | 9 +- extern/libmv/libmv/tracking/track_region.h | 6 +- release/scripts/startup/bl_ui/space_clip.py | 6 + source/blender/blenkernel/BKE_tracking.h | 7 +- source/blender/blenkernel/intern/movieclip.c | 8 +- source/blender/blenkernel/intern/tracking.c | 116 ++++++++++-------- .../editors/interface/interface_draw.c | 9 +- .../editors/interface/interface_handlers.c | 2 +- .../blender/editors/space_clip/space_clip.c | 10 ++ source/blender/makesdna/DNA_movieclip_types.h | 5 +- source/blender/makesdna/DNA_tracking_types.h | 6 +- source/blender/makesrna/intern/rna_tracking.c | 23 +++- 14 files changed, 178 insertions(+), 80 deletions(-) diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index 8751e1e190b..3d3b7398c9b 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -243,7 +243,7 @@ void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int fclose(fp); } -static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0) +static void saveImage(const char *prefix, libmv::FloatImage image, int x0, int y0) { int x, y; png_bytep *row_pointers; @@ -283,7 +283,7 @@ static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0) free(row_pointers); } -static void saveBytesImage(char *prefix, unsigned char *data, int width, int height) +static void saveBytesImage(const char *prefix, unsigned char *data, int width, int height) { int x, y; png_bytep *row_pointers; @@ -376,6 +376,8 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, } libmv::TrackRegionOptions track_region_options; + libmv::FloatImage image1_mask; + switch (options->motion_model) { #define LIBMV_CONVERT(the_model) \ case libmv::TrackRegionOptions::the_model: \ @@ -398,6 +400,12 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, track_region_options.use_brute_initialization = options->use_brute; track_region_options.use_normalized_intensities = options->use_normalization; + if (options->image1_mask) { + floatBufToImage(options->image1_mask, image1_width, image1_height, 1, &image1_mask); + + track_region_options.image1_mask = &image1_mask; + } + /* Convert from raw float buffers to libmv's FloatImage. */ libmv::FloatImage old_patch, new_patch; floatBufToImage(image1, image1_width, image1_height, 1, &old_patch); @@ -437,15 +445,24 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, void libmv_samplePlanarPatch(const float *image, int width, int height, int channels, const double *xs, const double *ys, - int num_samples_x, int num_samples_y, float *patch, + int num_samples_x, int num_samples_y, + const float *mask, float *patch, double *warped_position_x, double *warped_position_y) { - libmv::FloatImage libmv_image, libmv_patch; + libmv::FloatImage libmv_image, libmv_patch, libmv_mask; + libmv::FloatImage *libmv_mask_for_sample = NULL; floatBufToImage(image, width, height, channels, &libmv_image); + if (mask) { + floatBufToImage(mask, width, height, 1, &libmv_mask); + + libmv_mask_for_sample = &libmv_mask; + } + libmv::SamplePlanarPatch(libmv_image, xs, ys, num_samples_x, num_samples_y, - &libmv_patch, warped_position_x, warped_position_y); + libmv_mask_for_sample, &libmv_patch, + warped_position_x, warped_position_y); imageToFloatBuf(&libmv_patch, channels, patch); } diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index fe759b06fe4..fc3b6f94f62 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -52,18 +52,21 @@ void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker); /* TrackRegion (new planar tracker) */ struct libmv_trackRegionOptions { - int motion_model; - int num_iterations; - int use_brute; - int use_normalization; - double minimum_correlation; - double sigma; + int motion_model; + int num_iterations; + int use_brute; + int use_normalization; + double minimum_correlation; + double sigma; + float *image1_mask; }; + struct libmv_trackRegionResult { - int termination; - const char *termination_reason; - double correlation; + int termination; + const char *termination_reason; + double correlation; }; + int libmv_trackRegion(const struct libmv_trackRegionOptions *options, const float *image1, int image1_width, int image1_height, const float *image2, int image2_width, int image2_height, @@ -73,7 +76,8 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options, void libmv_samplePlanarPatch(const float *image, int width, int height, int channels, const double *xs, const double *ys, - int num_samples_x, int num_samples_y, float *patch, + int num_samples_x, int num_samples_y, + const float *mask, float *patch, double *warped_position_x, double *warped_position_y); /* Tracks */ diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index e65ead50c80..f52919b2a61 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -1351,7 +1351,7 @@ void TrackRegion(const FloatImage &image1, bool SamplePlanarPatch(const FloatImage &image, const double *xs, const double *ys, int num_samples_x, int num_samples_y, - FloatImage *patch, + FloatImage *mask, FloatImage *patch, double *warped_position_x, double *warped_position_y) { // Bail early if the points are outside the image. if (!AllInBounds(image, xs, ys)) { @@ -1376,6 +1376,13 @@ bool SamplePlanarPatch(const FloatImage &image, SampleLinear(image, image_position(1), image_position(0), &(*patch)(r, c, 0)); + if (mask) { + float maskValue = SampleLinear(*mask, image_position(1), + image_position(0), 0); + + for (int d = 0; d < image.Depth(); d++) + (*patch)(r, c, d) *= maskValue; + } } } diff --git a/extern/libmv/libmv/tracking/track_region.h b/extern/libmv/libmv/tracking/track_region.h index 0de11239da6..22ecfc54a15 100644 --- a/extern/libmv/libmv/tracking/track_region.h +++ b/extern/libmv/libmv/tracking/track_region.h @@ -135,10 +135,14 @@ void TrackRegion(const FloatImage &image1, // pixels of border around them. (so e.g. a corner of the patch cannot lie // directly on the edge of the image). Four corners are always required. All // channels are interpolated. +// When mask is not null it'll be used as a pattern mask. Ot should match +// the size of image. +// Warped coordinates of marker's position would be returned in +// warped_position_x and warped_position_y bool SamplePlanarPatch(const FloatImage &image, const double *xs, const double *ys, int num_samples_x, int num_samples_y, - FloatImage *patch, + FloatImage *mask, FloatImage *patch, double *warped_position_x, double *warped_position_y); } // namespace libmv diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 9ab8fcb5655..2f2d95f78df 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -233,6 +233,7 @@ class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel): col.prop(settings, "default_motion_model") col.prop(settings, "default_use_brute") col.prop(settings, "default_use_normalization") + col.prop(settings, "default_use_mask") col.prop(settings, "default_correlation_min") col.separator() @@ -541,6 +542,10 @@ class CLIP_PT_track(CLIP_PT_tracking_panel, Panel): sub = row.row() sub.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True) + row.separator() + sub = row.row() + sub.prop(act_track, "use_alpha_preview", text="", toggle=True, icon='IMAGE_ALPHA') + layout.separator() row = layout.row(align=True) @@ -580,6 +585,7 @@ class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel): col.prop(active, "motion_model") col.prop(active, "use_brute") col.prop(active, "use_normalization") + col.prop(active, "use_mask") col.prop(active, "correlation_min") col.separator() diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 716b65408e1..11013d54951 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -72,14 +72,15 @@ void BKE_tracking_join_tracks(struct MovieTrackingTrack *dst_track, struct Movie void BKE_tracking_free(struct MovieTracking *tracking); struct ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, - struct ImBuf *struct_ibuf, struct MovieTrackingMarker *marker, + struct ImBuf *struct_ibuf, struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker, int use_mask, int num_samples_x, int num_samples_y, float pos[2]); struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int anchored, int disable_channels); struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int anchored, int disable_channels); -struct ImBuf *BKE_tracking_track_mask_get(struct MovieTracking *tracking, struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker, int width, int height); +float *BKE_tracking_track_mask_get(int frame_width, int frame_height, struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker); void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 8b91ee29c59..92184a38695 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1039,6 +1039,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip scopes->marker = NULL; scopes->track = NULL; + scopes->track_locked = TRUE; if (clip) { MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking); @@ -1055,6 +1056,8 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user); scopes->track_disabled = FALSE; + scopes->marker = marker; + scopes->track = track; if (ibuf && (ibuf->rect || ibuf->rect_float)) { ImBuf *search_ibuf; @@ -1087,6 +1090,8 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip scopes->frame_width = ibuf->x; scopes->frame_height = ibuf->y; + + scopes->use_track_mask = track->flag & TRACK_PREVIEW_ALPHA; } IMB_freeImBuf(ibuf); @@ -1095,8 +1100,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip if ((track->flag & TRACK_LOCKED) == 0) { float pat_min[2], pat_max[2]; - scopes->marker = marker; - scopes->track = track; + scopes->track_locked = FALSE; /* XXX: would work fine with non-transformed patterns, but would likely fail * with transformed patterns, but that would be easier to debug when diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 4cfa8461f2e..a9e75449811 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1052,6 +1052,8 @@ typedef struct TrackContext { int search_area_height; int search_area_width; int framenr; + + float *mask; #else int pad; #endif @@ -1158,6 +1160,9 @@ static void track_context_free(void *customdata) if (track_context->search_area) MEM_freeN(track_context->search_area); + if (track_context->mask) + MEM_freeN(track_context->mask); + #else (void)track_context; #endif @@ -1244,14 +1249,16 @@ static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int g track->flag & TRACK_DISABLE_GREEN, track->flag & TRACK_DISABLE_BLUE, grayscale); } -ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, - ImBuf *search_ibuf, MovieTrackingMarker *marker, - int num_samples_x, int num_samples_y, float pos[2]) +ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, ImBuf *search_ibuf, + MovieTrackingTrack *track, MovieTrackingMarker *marker, + int use_mask, int num_samples_x, int num_samples_y, + float pos[2]) { #ifdef WITH_LIBMV ImBuf *pattern_ibuf; double src_pixel_x[5], src_pixel_y[5]; double warped_position_x, warped_position_y; + float *mask = NULL; pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); pattern_ibuf->profile = IB_PROFILE_LINEAR_RGB; @@ -1262,9 +1269,13 @@ ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y); + if (use_mask) { + mask = BKE_tracking_track_mask_get(frame_width, frame_height, track, marker); + } + libmv_samplePlanarPatch(search_ibuf->rect_float, search_ibuf->x, search_ibuf->y, 4, src_pixel_x, src_pixel_y, num_samples_x, - num_samples_y, pattern_ibuf->rect_float, + num_samples_y, mask, pattern_ibuf->rect_float, &warped_position_x, &warped_position_y); if (pos) { @@ -1272,6 +1283,10 @@ ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, pos[1] = warped_position_y; } + if (mask) { + MEM_freeN(mask); + } + return pattern_ibuf; #else ImBuf *pattern_ibuf; @@ -1310,8 +1325,8 @@ ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mo search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels); - pattern_ibuf = BKE_tracking_sample_pattern_imbuf(ibuf->x, ibuf->y, search_ibuf, marker, - num_samples_x, num_samples_y, NULL); + pattern_ibuf = BKE_tracking_sample_pattern_imbuf(ibuf->x, ibuf->y, search_ibuf, track, marker, + FALSE, num_samples_x, num_samples_y, NULL); IMB_freeImBuf(search_ibuf); @@ -1366,8 +1381,21 @@ static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track) layer = track->gpd->layers.first; while (layer) { - if (layer->flag & GP_LAYER_ACTIVE) - return layer; + if (layer->flag & GP_LAYER_ACTIVE) { + bGPDframe *frame = layer->frames.first; + int ok = FALSE; + + while (frame) { + if (frame->strokes.first) { + ok = TRUE; + } + + frame = frame->next; + } + + if (ok) + return layer; + } layer = layer->next; } @@ -1375,15 +1403,11 @@ static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track) return NULL; } -static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTrackingMarker *marker, - bGPDlayer *layer, ImBuf *ibuf, int width, int height) +static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height, + MovieTrackingMarker *marker, bGPDlayer *layer, + float *mask, int mask_width, int mask_height) { bGPDframe *frame = layer->frames.first; - float *mask; - int x, y; - float aspy = 1.0f / tracking->camera.pixel_aspect; - - mask = MEM_callocN(ibuf->x * ibuf->y * sizeof(float), "track mask"); while (frame) { bGPDstroke *stroke = frame->strokes.first; @@ -1398,11 +1422,11 @@ static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTra "track mask rasterization points"); for (i = 0; i < stroke->totpoints; i++, fp += 2) { - fp[0] = stroke_points[i].x * width / ibuf->x - marker->search_min[0]; - fp[1] = stroke_points[i].y * height * aspy / ibuf->x - marker->search_min[1]; + fp[0] = (stroke_points[i].x - marker->search_min[0]) * frame_width / mask_width; + fp[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height / mask_height; } - PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y); + PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height); MEM_freeN(mask_points); } @@ -1412,45 +1436,26 @@ static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTra frame = frame->next; } - - for (y = 0; y < ibuf->y; y++) { - for (x = 0; x < ibuf->x; x++) { - float *pixel = &ibuf->rect_float[4 * (y * ibuf->x + x)]; - float val = mask[y * ibuf->x + x]; - - pixel[0] = val; - pixel[1] = val; - pixel[2] = val; - pixel[3] = 1.0f; - } - } - - MEM_freeN(mask); - - IMB_rect_from_float(ibuf); } -ImBuf *BKE_tracking_track_mask_get(MovieTracking *tracking, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int width, int height) +float *BKE_tracking_track_mask_get(int frame_width, int frame_height, + MovieTrackingTrack *track, MovieTrackingMarker *marker) { - ImBuf *ibuf; + float *mask = NULL; bGPDlayer *layer = track_mask_gpencil_layer_get(track); int mask_width, mask_height; - mask_width = (marker->search_max[0] - marker->search_min[0]) * width; - mask_height = (marker->search_max[1] - marker->search_min[1]) * height; - - ibuf = IMB_allocImBuf(mask_width, mask_height, 32, IB_rect | IB_rectfloat); + mask_width = (marker->search_max[0] - marker->search_min[0]) * frame_width; + mask_height = (marker->search_max[1] - marker->search_min[1]) * frame_height; if (layer) { - track_mask_gpencil_layer_rasterize(tracking, marker, layer, ibuf, width, height); - } - else { - float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - IMB_rectfill(ibuf, white); + mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask"); + + track_mask_gpencil_layer_rasterize(frame_width, frame_height, marker, layer, + mask, mask_width, mask_height); } - return ibuf; + return mask; } #ifdef WITH_LIBMV @@ -1676,7 +1681,7 @@ int BKE_tracking_next(MovieTrackingContext *context) frame_width = destination_ibuf->x; frame_height = destination_ibuf->y; - #pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1) + //#pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1) for (a = 0; a < map_size; a++) { TrackContext *track_context = NULL; MovieTrackingTrack *track; @@ -1724,7 +1729,7 @@ int BKE_tracking_next(MovieTrackingContext *context) double src_pixel_y[5]; /* settings for the tracker */ - struct libmv_trackRegionOptions options; + struct libmv_trackRegionOptions options = {0}; struct libmv_trackRegionResult result; float *patch_new; @@ -1744,6 +1749,14 @@ int BKE_tracking_next(MovieTrackingContext *context) track_context->search_area_width = width; IMB_freeImBuf(reference_ibuf); + + if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) { + if (track_context->mask) + MEM_freeN(track_context->mask); + + track_context->mask = BKE_tracking_track_mask_get(frame_width, frame_height, + track, marker); + } } /* for now track to the same search area dimension as marker has got for current frame @@ -1765,6 +1778,9 @@ int BKE_tracking_next(MovieTrackingContext *context) options.minimum_correlation = track->minimum_correlation; options.sigma = 0.9; + if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) + options.image1_mask = track_context->mask; + /* Convert the marker corners and center into pixel coordinates in the search/destination images. */ get_marker_coords_for_tracking(frame_width, frame_height, &track_context->marker, src_pixel_x, src_pixel_y); get_marker_coords_for_tracking(frame_width, frame_height, marker, dst_pixel_x, dst_pixel_y); @@ -1790,7 +1806,7 @@ int BKE_tracking_next(MovieTrackingContext *context) marker_search_scale_after_tracking(marker, &marker_new); - #pragma omp critical + //#pragma omp critical { if (context->first_time) { /* check if there's no keyframe/tracked markers before tracking marker. diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 7b69e820467..22aa1031f48 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1550,7 +1550,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc IMB_freeImBuf(scopes->track_preview); tmpibuf = BKE_tracking_sample_pattern_imbuf(scopes->frame_width, scopes->frame_height, - scopes->track_search, &scopes->undist_marker, + scopes->track_search, scopes->track, + &scopes->undist_marker, scopes->use_track_mask, width, height, scopes->track_pos); if (tmpibuf->rect_float) @@ -1582,6 +1583,12 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc if (width > 0 && height > 0) { drawibuf = scopes->track_preview; + if (scopes->use_track_mask) { + glColor4f(0.0f, 0.0f, 0.0f, 0.3f); + uiSetRoundBox(15); + uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); + } + glaDrawPixelsSafe(rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y, drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index a2adbd7a143..4615906b0da 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4201,7 +4201,7 @@ static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDa scopes->track_preview_height = (but->y2 - but->y1) + (data->dragstarty - my); } else { - if (scopes->marker) { + if (!scopes->track_locked) { if (scopes->marker->framenr != scopes->framenr) scopes->marker = BKE_tracking_ensure_marker(scopes->track, scopes->framenr); diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 534ab8eeb95..9a8e0de3e84 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -215,6 +215,15 @@ static void clip_scopes_tag_refresh(ScrArea *sa) sc->scopes.ok = FALSE; } +static void clip_scopes_check_gpencil_change(ScrArea *sa) +{ + SpaceClip *sc = (SpaceClip *)sa->spacedata.first; + + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + clip_scopes_tag_refresh(sa); + } +} + static void clip_stabilization_tag_refresh(ScrArea *sa) { SpaceClip *sc = (SpaceClip *) sa->spacedata.first; @@ -400,6 +409,7 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) switch (wmn->data) { case ND_ANIMPLAY: case ND_GPENCIL: + clip_scopes_check_gpencil_change(sa); ED_area_tag_redraw(sa); break; } diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h index b5ab7898bd9..19004dbc8b8 100644 --- a/source/blender/makesdna/DNA_movieclip_types.h +++ b/source/blender/makesdna/DNA_movieclip_types.h @@ -90,7 +90,8 @@ typedef struct MovieClip { } MovieClip; typedef struct MovieClipScopes { - int ok; /* 1 means scopes are ok and recalculation is unneeded */ + short ok; /* 1 means scopes are ok and recalculation is unneeded */ + short use_track_mask; /* whether track's mask should be applied on preview */ int track_preview_height; /* height of track preview widget */ int frame_width, frame_height; /* width and height of frame for which scopes are calculated */ struct MovieTrackingMarker undist_marker; /* undistorted position of marker used for pattern sampling */ @@ -98,7 +99,7 @@ typedef struct MovieClipScopes { struct ImBuf *track_preview; /* ImBuf displayed in track preview */ float track_pos[2]; /* sub-pizel position of marker in track ImBuf */ short track_disabled; /* active track is disabled, special notifier should be drawn */ - char pad[2]; + short track_locked; /* active track is locked, no transformation should be allowed */ int framenr; /* frame number scopes are created for */ struct MovieTrackingTrack *track; /* track scopes are created for */ struct MovieTrackingMarker *marker; /* marker scopes are created for */ diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 6ca63f2c1c9..84ae1835751 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -287,6 +287,7 @@ enum { #define TRACK_USE_2D_STAB (1 << 8) #define TRACK_PREVIEW_GRAYSCALE (1 << 9) #define TRACK_DOPE_SEL (1 << 10) +#define TRACK_PREVIEW_ALPHA (1 << 11) /* MovieTrackingTrack->motion_model */ #define TRACK_MOTION_MODEL_TRANSLATION 0 @@ -297,8 +298,9 @@ enum { #define TRACK_MOTION_MODEL_HOMOGRAPHY 5 /* MovieTrackingTrack->algorithm_flag */ -#define TRACK_ALGORITHM_FLAG_USE_BRUTE 1 -#define TRACK_ALGORITHM_FLAG_USE_NORMALIZATION 2 +#define TRACK_ALGORITHM_FLAG_USE_BRUTE (1 << 0) +#define TRACK_ALGORITHM_FLAG_USE_NORMALIZATION (1 << 2) +#define TRACK_ALGORITHM_FLAG_USE_MASK (1 << 3) /* MovieTrackingTrack->adjframes */ #define TRACK_MATCH_KEYFRAME 0 diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index f1f962f6701..c95d04d005a 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -637,13 +637,19 @@ static void rna_def_trackingSettings(BlenderRNA *brna) RNA_def_property_enum_items(prop, tracker_motion_model); RNA_def_property_ui_text(prop, "Motion model", "Default motion model to use for tracking"); - /* use_brute */ + /* default_use_brute */ prop = RNA_def_property(srna, "default_use_brute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation-only initialization when tracking"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); - /* default use_normalization */ + /* default_use_brute */ + prop = RNA_def_property(srna, "default_use_mask", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_MASK); + RNA_def_property_ui_text(prop, "Use Mask", "Use a grease pencil datablock as a mask to use only specified areas of pattern when tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); + + /* default_use_normalization */ prop = RNA_def_property(srna, "default_use_normalization", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking (slower)"); @@ -965,6 +971,12 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* use_brute */ + prop = RNA_def_property(srna, "use_mask", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_MASK); + RNA_def_property_ui_text(prop, "Use Mask", "Use a grease pencil datablock as a mask to use only specified areas of pattern when tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); + + /* use_normalization */ prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -1008,6 +1020,13 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Grayscale", "Display what the tracking algorithm sees in the preview"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); + /* preview_alpha */ + prop = RNA_def_property(srna, "use_alpha_preview", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_PREVIEW_ALPHA); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Alpha", "Apply track's mask on displaying preview"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); + /* has bundle */ prop = RNA_def_property(srna, "has_bundle", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_HAS_BUNDLE); From 2062ca6b6ce8393a85089df3a2b1fd51333450bb Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Tue, 12 Jun 2012 11:22:10 +0000 Subject: [PATCH 237/360] Decrease frequency of mallocs during multires sculpt smoothing Patch from Jason Wilkins. Creates a pool of allocations (one for each OpenMP thread) rather than allocating every time do_multires_smooth_brush() is called. --- source/blender/editors/sculpt_paint/sculpt.c | 118 +++++++++++++------ 1 file changed, 82 insertions(+), 36 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 98735139136..89dbe14f62a 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -212,6 +212,11 @@ typedef struct StrokeCache { float clip_tolerance[3]; float initial_mouse[2]; + /* Pre-allocated temporary storage used during smoothing */ + int num_threads; + float (**tmpgrid_co)[3], (**tmprow_co)[3]; + float **tmpgrid_mask, **tmprow_mask; + /* Variants */ float radius; float radius_squared; @@ -1257,6 +1262,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no float (*tmpgrid_co)[3], (*tmprow_co)[3]; float *tmpgrid_mask, *tmprow_mask; int v1, v2, v3, v4; + int thread_num; int *grid_indices, totgrid, gridsize, i, x, y; sculpt_brush_test_init(ss, &test); @@ -1267,17 +1273,15 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no NULL, &gridsize, &griddata, &gridadj); BLI_pbvh_get_grid_key(ss->pbvh, &key); - #pragma omp critical - { - if (smooth_mask) { - tmpgrid_mask = MEM_mallocN(sizeof(float) * gridsize * gridsize, "tmpgrid_mask"); - tmprow_mask = MEM_mallocN(sizeof(float) * gridsize, "tmprow_mask"); - } - else { - tmpgrid_co = MEM_mallocN(sizeof(float) * 3 * gridsize * gridsize, "tmpgrid_co"); - tmprow_co = MEM_mallocN(sizeof(float) * 3 * gridsize, "tmprow_co"); - } - } + thread_num = 0; +#ifdef _OPENMP + if (sd->flags & SCULPT_USE_OPENMP) + thread_num = omp_get_thread_num(); +#endif + tmpgrid_co = ss->cache->tmpgrid_co[thread_num]; + tmprow_co = ss->cache->tmprow_co[thread_num]; + tmpgrid_mask = ss->cache->tmpgrid_mask[thread_num]; + tmprow_mask = ss->cache->tmprow_mask[thread_num]; for (i = 0; i < totgrid; ++i) { data = griddata[grid_indices[i]]; @@ -1393,18 +1397,6 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no } } } - - #pragma omp critical - { - if (smooth_mask) { - MEM_freeN(tmpgrid_mask); - MEM_freeN(tmprow_mask); - } - else { - MEM_freeN(tmpgrid_co); - MEM_freeN(tmprow_co); - } - } } static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, @@ -3233,6 +3225,69 @@ static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss) } } +static void sculpt_omp_start(Sculpt *sd, SculptSession *ss) +{ + StrokeCache *cache = ss->cache; + +#ifdef _OPENMP + /* If using OpenMP then create a number of threads two times the + * number of processor cores. + * Justification: Empirically I've found that two threads per + * processor gives higher throughput. */ + if (sd->flags & SCULPT_USE_OPENMP) { + cache->num_threads = 2 * omp_get_num_procs(); + omp_set_num_threads(cache->num_threads); + } + else +#endif + { + (void)sd; + cache->num_threads = 1; + } + + if (ss->multires) { + int i, gridsize, array_mem_size; + BLI_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL, + &gridsize, NULL, NULL); + + array_mem_size = cache->num_threads * sizeof(void*); + + cache->tmpgrid_co = MEM_mallocN(array_mem_size, "tmpgrid_co array"); + cache->tmprow_co = MEM_mallocN(array_mem_size, "tmprow_co array"); + cache->tmpgrid_mask = MEM_mallocN(array_mem_size, "tmpgrid_mask array"); + cache->tmprow_mask = MEM_mallocN(array_mem_size, "tmprow_mask array"); + + for (i = 0; i < cache->num_threads; i++) { + const size_t row_size = sizeof(float) * gridsize; + const size_t co_row_size = 3 * row_size; + + cache->tmprow_co[i] = MEM_mallocN(co_row_size, "tmprow_co"); + cache->tmpgrid_co[i] = MEM_mallocN(co_row_size * gridsize, "tmpgrid_co"); + cache->tmprow_mask[i] = MEM_mallocN(row_size, "tmprow_mask"); + cache->tmpgrid_mask[i] = MEM_mallocN(row_size * gridsize, "tmpgrid_mask"); + } + } +} + +static void sculpt_omp_done(SculptSession *ss) +{ + if (ss->multires) { + int i; + + for (i = 0; i < ss->cache->num_threads; i++) { + MEM_freeN(ss->cache->tmpgrid_co[i]); + MEM_freeN(ss->cache->tmprow_co[i]); + MEM_freeN(ss->cache->tmpgrid_mask[i]); + MEM_freeN(ss->cache->tmprow_mask[i]); + } + + MEM_freeN(ss->cache->tmpgrid_co); + MEM_freeN(ss->cache->tmprow_co); + MEM_freeN(ss->cache->tmpgrid_mask); + MEM_freeN(ss->cache->tmprow_mask); + } +} + /* Initialize the stroke cache invariants from operator properties */ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSession *ss, wmOperator *op, const float mouse[2]) { @@ -3346,6 +3401,8 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio cache->first_time = 1; cache->vertex_rotation = 0; + + sculpt_omp_start(sd, ss); } static void sculpt_update_brush_delta(Sculpt *sd, Object *ob, Brush *brush) @@ -3798,19 +3855,6 @@ static int sculpt_stroke_test_start(bContext *C, struct wmOperator *op, sculpt_undo_push_begin(sculpt_tool_name(sd)); -#ifdef _OPENMP - /* If using OpenMP then create a number of threads two times the - * number of processor cores. - * Justification: Empirically I've found that two threads per - * processor gives higher throughput. */ - if (sd->flags & SCULPT_USE_OPENMP) { - int num_procs; - - num_procs = omp_get_num_procs(); - omp_set_num_threads(2 * num_procs); - } -#endif - return 1; } else @@ -3847,6 +3891,8 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + sculpt_omp_done(ss); + /* reset values used to draw brush after completing the stroke */ sd->draw_anchored = 0; sd->draw_pressure = 0; From 8489e100dc2ba50f4475469b190047a9b99cb6bc Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 12 Jun 2012 11:54:31 +0000 Subject: [PATCH 238/360] Naming + Style tweaks for newly added flag for Action Constraint Old names used could conflict with other things too easily in future --- source/blender/blenkernel/intern/constraint.c | 2 +- source/blender/makesdna/DNA_constraint_types.h | 10 +++++----- source/blender/makesrna/intern/rna_constraint.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 09351f36bdb..9bb0980ad5c 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -2159,7 +2159,7 @@ static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintT printf("do Action Constraint %s - Ob %s Pchan %s\n", con->name, cob->ob->id.name + 2, (cob->pchan) ? cob->pchan->name : NULL); /* Get the appropriate information from the action */ - if (cob->type == CONSTRAINT_OBTYPE_OBJECT || (data->flag & BONE_USE_OBJECT_ACTION)) { + if (cob->type == CONSTRAINT_OBTYPE_OBJECT || (data->flag & ACTCON_BONE_USE_OBJECT_ACTION)) { Object workob; /* evaluate using workob */ diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index aae167d05c6..6ca9a95400d 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -561,11 +561,11 @@ typedef enum eSameVolume_Modes { SAMEVOL_Z } eSameVolume_Modes; -/* bActionConstraint.flag - * WARNING: bitwise! */ -typedef enum eAction_flags { - BONE_USE_OBJECT_ACTION = 1 << 0, /* Bones use "object" part of target action, instead of "same bone name" part. */ -} eAction_flags; +/* bActionConstraint.flag */ +typedef enum eActionConstraint_Flags { + /* Bones use "object" part of target action, instead of "same bone name" part */ + ACTCON_BONE_USE_OBJECT_ACTION = (1 << 0), +} eActionConstraint_Flags; /* Locked-Axis Values (Locked Track) */ typedef enum eLockAxis_Modes { diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index f02df6c30ed..ae8b0c51544 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -1112,7 +1112,7 @@ static void rna_def_constraint_action(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "use_bone_object_action", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_USE_OBJECT_ACTION); + RNA_def_property_boolean_sdna(prop, NULL, "flag", ACTCON_BONE_USE_OBJECT_ACTION); RNA_def_property_ui_text(prop, "Object Action", "Bones only: apply the object's transformation channels of the action " "to the constrained bone, instead of bone's channels"); From 1719b86f74a757998c6edc8ffc578a14c724d1ff Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 12 Jun 2012 14:59:36 +0000 Subject: [PATCH 239/360] Tracking dopesheet's scrollbat now updates to channels number nicely. --- source/blender/editors/space_clip/clip_dopesheet_draw.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index e9ea70cafea..2ce0e13b8bd 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -158,6 +158,12 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) MovieTrackingDopesheetChannel *channel; float y, xscale, yscale; float strip[4], selected_strip[4]; + float height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT * 2); + + /* don't use totrect set, as the width stays the same + * (NOTE: this is ok here, the configuration is pretty straightforward) + */ + v2d->tot.ymin = (float)(-height); y = (float) CHANNEL_FIRST; From 55ca0e7636b77a408ea70bf3117eff569e49954b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 12 Jun 2012 17:10:24 +0000 Subject: [PATCH 240/360] Make dopesheet settings per-tracking data It was a bit confusing to synchronize settings used in pre-calculated dopesheet channels which was storing in tracking data with settings used for display which is in space data. This was initially done by converting one flags to other and checking if space's settings matches pre-calculated one, but that had several issues if two different dopesheet are using different settings: - Channels would be re-calculated on every redraw for each of spaces - Dopesheet operators could fail due to the could be using channels calculated for other space. That was also quite nasty code checking if requested settings matches pre-calculated one. --- release/scripts/startup/bl_ui/space_clip.py | 5 ++- source/blender/blenkernel/BKE_tracking.h | 8 +--- source/blender/blenkernel/intern/tracking.c | 32 ++++++-------- .../blender/editors/space_clip/space_clip.c | 4 +- source/blender/makesdna/DNA_space_types.h | 19 +------- source/blender/makesdna/DNA_tracking_types.h | 18 ++++++-- source/blender/makesrna/intern/rna_space.c | 23 ---------- source/blender/makesrna/intern/rna_tracking.c | 43 +++++++++++++++++++ 8 files changed, 77 insertions(+), 75 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 2f2d95f78df..cef2a20710a 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -82,11 +82,12 @@ class CLIP_HT_header(Header): row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_RIGHT', text="Filters") elif sc.view == 'DOPESHEET': + dopesheet = tracking.dopesheet layout.prop(sc, "view", text="", expand=True) layout.label(text="Sort by:") - layout.prop(sc, "dopesheet_sort_method", text="") - layout.prop(sc, "invert_dopesheet_sort", text="Invert") + layout.prop(dopesheet, "sort_method", text="") + layout.prop(dopesheet, "use_invert_sort", text="Invert") else: layout.prop(sc, "view", text="", expand=True) diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 11013d54951..e6c98c72b55 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -171,7 +171,7 @@ void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area); /* Dopesheet */ void BKE_tracking_dopesheet_tag_update(struct MovieTracking *tracking); -void BKE_tracking_dopesheet_update(struct MovieTracking *tracking, int sort_method, int inverse); +void BKE_tracking_dopesheet_update(struct MovieTracking *tracking); #define TRACK_SELECTED(track) ((track)->flag & SELECT || (track)->pat_flag & SELECT || (track)->search_flag & SELECT) @@ -202,10 +202,4 @@ void BKE_tracking_dopesheet_update(struct MovieTracking *tracking, int sort_meth #define TRACK_AREA_ALL (TRACK_AREA_POINT | TRACK_AREA_PAT | TRACK_AREA_SEARCH) -#define TRACK_SORT_NONE -1 -#define TRACK_SORT_NAME 0 -#define TRACK_SORT_LONGEST 1 -#define TRACK_SORT_TOTAL 2 -#define TRACK_SORT_AVERAGE_ERROR 3 - #endif diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index a9e75449811..33f7b22f64a 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -3545,40 +3545,34 @@ static void tracking_dopesheet_sort(MovieTracking *tracking, int sort_method, i { MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; - if (dopesheet->sort_method == sort_method && dopesheet->sort_inverse == inverse) - return; - if (inverse) { - if (sort_method == TRACK_SORT_NAME) { + if (sort_method == TRACKING_DOPE_SORT_NAME) { BLI_sortlist(&dopesheet->channels, channels_alpha_inverse_sort); } - else if (sort_method == TRACK_SORT_LONGEST) { + else if (sort_method == TRACKING_DOPE_SORT_LONGEST) { BLI_sortlist(&dopesheet->channels, channels_longest_segment_inverse_sort); } - else if (sort_method == TRACK_SORT_TOTAL) { + else if (sort_method == TRACKING_DOPE_SORT_TOTAL) { BLI_sortlist(&dopesheet->channels, channels_total_track_inverse_sort); } - else if (sort_method == TRACK_SORT_AVERAGE_ERROR) { + else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) { BLI_sortlist(&dopesheet->channels, channels_average_error_inverse_sort); } } else { - if (sort_method == TRACK_SORT_NAME) { + if (sort_method == TRACKING_DOPE_SORT_NAME) { BLI_sortlist(&dopesheet->channels, channels_alpha_sort); } - else if (sort_method == TRACK_SORT_LONGEST) { + else if (sort_method == TRACKING_DOPE_SORT_LONGEST) { BLI_sortlist(&dopesheet->channels, channels_longest_segment_sort); } - else if (sort_method == TRACK_SORT_TOTAL) { + else if (sort_method == TRACKING_DOPE_SORT_TOTAL) { BLI_sortlist(&dopesheet->channels, channels_total_track_sort); } - else if (sort_method == TRACK_SORT_AVERAGE_ERROR) { + else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) { BLI_sortlist(&dopesheet->channels, channels_average_error_sort); } } - - dopesheet->sort_method = sort_method; - dopesheet->sort_inverse = inverse; } void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking) @@ -3588,17 +3582,17 @@ void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking) dopesheet->ok = FALSE; } -void BKE_tracking_dopesheet_update(MovieTracking *tracking, int sort_method, int inverse) +void BKE_tracking_dopesheet_update(MovieTracking *tracking) { MovieTrackingObject *object = BKE_tracking_active_object(tracking); MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; MovieTrackingTrack *track; ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + short sort_method = dopesheet->sort_method; + short inverse = dopesheet->flag & TRACKING_DOPE_SORT_INVERSE; - if (dopesheet->ok) { - tracking_dopesheet_sort(tracking, sort_method, inverse); + if (dopesheet->ok) return; - } tracking_dopesheet_free(dopesheet); @@ -3616,8 +3610,6 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking, int sort_method, int } } - dopesheet->sort_method = TRACK_SORT_NONE; - tracking_dopesheet_sort(tracking, sort_method, inverse); dopesheet->ok = TRUE; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 9a8e0de3e84..2f684f9e330 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -1233,7 +1233,7 @@ static void dopesheet_area_draw(const bContext *C, ARegion *ar) short unit = 0; if (clip) - BKE_tracking_dopesheet_update(&clip->tracking, sc->dope_sort, sc->dope_flag & SC_DOPE_SORT_INVERSE); + BKE_tracking_dopesheet_update(&clip->tracking); /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); @@ -1294,7 +1294,7 @@ static void clip_channels_area_draw(const bContext *C, ARegion *ar) View2DScrollers *scrollers; if (clip) - BKE_tracking_dopesheet_update(&clip->tracking, sc->dope_sort, sc->dope_flag & SC_DOPE_SORT_INVERSE); + BKE_tracking_dopesheet_update(&clip->tracking); /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index cb905d7f768..e9a07bfbf29 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1006,11 +1006,7 @@ typedef struct SpaceClip { void *draw_context; - /* dopesheet */ - short dope_sort; /* sort order in dopesheet view */ - short dope_flag; /* dopsheet view flags */ - - int around; /* pivot point for transforms */ + int around, pad4; /* pivot point for transforms */ /* **** mask editing **** */ struct Mask *mask; @@ -1058,19 +1054,6 @@ typedef enum eSpaceClip_View { SC_VIEW_DOPESHEET, } eSpaceClip_View; -/* SpaceClip->dope_sort */ -typedef enum eSpaceClip_Dopesheet_Sort { - SC_DOPE_SORT_NAME = 0, - SC_DOPE_SORT_LONGEST, - SC_DOPE_SORT_TOTAL, - SC_DOPE_SORT_AVERAGE_ERROR, -} eSpaceClip_Dopesheet_Sort; - -/* SpaceClip->dope_flag */ -typedef enum eSpaceClip_Dopesheet_Flag { - SC_DOPE_SORT_INVERSE = (1 << 0), -} eSpaceClip_Dopesheet_Flag; - /* SpaceClip->gpencil_src */ typedef enum eSpaceClip_GPencil_Source { SC_GPENCIL_SRC_CLIP = 0, diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 84ae1835751..850d4361ab7 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -238,13 +238,16 @@ typedef struct MovieTrackingDopesheetChannel { } MovieTrackingDopesheetChannel; typedef struct MovieTrackingDopesheet { - int ok, pad; /* flag if dopesheet information is still relevant */ + int ok; /* flag if dopesheet information is still relevant */ + short sort_method; /* method to be used to sort tracks */ + short flag; /* dopesheet building flag such as inverted order of sort */ + + /* runtime stuff */ ListBase channels; int tot_channel; - short sort_method; /* method to be used to sort tracks */ - short sort_inverse; /* order of tracks is inverted */ + int pad; } MovieTrackingDopesheet; typedef struct MovieTracking { @@ -347,4 +350,13 @@ enum { #define TRACKING_CLEAN_DELETE_TRACK 1 #define TRACKING_CLEAN_DELETE_SEGMENT 2 +/* MovieTrackingDopesheet->sort_method */ +#define TRACKING_DOPE_SORT_NAME 0 +#define TRACKING_DOPE_SORT_LONGEST 1 +#define TRACKING_DOPE_SORT_TOTAL 2 +#define TRACKING_DOPE_SORT_AVERAGE_ERROR 3 + +/* MovieTrackingDopesheet->flag */ +#define TRACKING_DOPE_SORT_INVERSE (1 << 0) + #endif diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 81538d20a50..941e44e9f78 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2985,14 +2985,6 @@ static void rna_def_space_clip(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static EnumPropertyItem dope_sort_items[] = { - {SC_DOPE_SORT_NAME, "NAME", 0, "Name", "Sort channels by their names"}, - {SC_DOPE_SORT_LONGEST, "LONGEST", 0, "Longest", "Sort channels by longest tracked segment"}, - {SC_DOPE_SORT_TOTAL, "TOTAL", 0, "Total", "Sort channels by overall amount of tracked segments"}, - {SC_DOPE_SORT_AVERAGE_ERROR, "AVERAGE_ERROR", 0, "Average Error", "Sort channels by average reprojection error of tracks after solve"}, - {0, NULL, 0, NULL, NULL} - }; - static EnumPropertyItem gpencil_source_items[] = { {SC_GPENCIL_SRC_CLIP, "CLIP", 0, "Clip", "Show grease pencil datablock which belongs to movie clip"}, {SC_GPENCIL_SRC_TRACK, "TRACK", 0, "Track", "Show grease pencil datablock which belongs to active track"}, @@ -3221,21 +3213,6 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_enum_items(prop, pivot_items); RNA_def_property_ui_text(prop, "Pivot Point", "Pivot center for rotation/scaling"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); - - /* ** dopesheet ** */ - - /* dopesheet sort */ - prop = RNA_def_property(srna, "dopesheet_sort_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "dope_sort"); - RNA_def_property_enum_items(prop, dope_sort_items); - RNA_def_property_ui_text(prop, "Dopesheet Sort Field", "Method to be used to sort channels in dopesheet view"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); - - /* invert_dopesheet_sort */ - prop = RNA_def_property(srna, "invert_dopesheet_sort", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "dope_flag", SC_DOPE_SORT_INVERSE); - RNA_def_property_ui_text(prop, "Invert Dopesheet Sort", "Invert sort order of dopesheet channels"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); } diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index c95d04d005a..a2869a842ee 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -382,6 +382,14 @@ static void rna_tracking_markerSearch_update(Main *UNUSED(bmain), Scene *UNUSED( BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_DIM); } +static void rna_trackingDopesheet_tagUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) +{ + MovieClip *clip = (MovieClip *)ptr->id.data; + MovieTrackingDopesheet *dopesheet = &clip->tracking.dopesheet; + + dopesheet->ok = 0; +} + /* API */ static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, int frame, int number) @@ -1396,6 +1404,36 @@ static void rna_def_trackingObjects(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_ui_text(prop, "Active Object", "Active object in this tracking data object"); } +static void rna_def_trackingDopesheet(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem sort_items[] = { + {TRACKING_DOPE_SORT_NAME, "NAME", 0, "Name", "Sort channels by their names"}, + {TRACKING_DOPE_SORT_LONGEST, "LONGEST", 0, "Longest", "Sort channels by longest tracked segment"}, + {TRACKING_DOPE_SORT_TOTAL, "TOTAL", 0, "Total", "Sort channels by overall amount of tracked segments"}, + {TRACKING_DOPE_SORT_AVERAGE_ERROR, "AVERAGE_ERROR", 0, "Average Error", "Sort channels by average reprojection error of tracks after solve"}, + {0, NULL, 0, NULL, NULL} + }; + + srna = RNA_def_struct(brna, "MovieTrackingDopesheet", NULL); + RNA_def_struct_ui_text(srna, "Movie Tracking Dopesheet", "Match-moving dopesheet data"); + + /* dopesheet sort */ + prop = RNA_def_property(srna, "sort_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "sort_method"); + RNA_def_property_enum_items(prop, sort_items); + RNA_def_property_ui_text(prop, "Dopesheet Sort Field", "Method to be used to sort channels in dopesheet view"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_trackingDopesheet_tagUpdate"); + + /* invert_dopesheet_sort */ + prop = RNA_def_property(srna, "use_invert_sort", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_DOPE_SORT_INVERSE); + RNA_def_property_ui_text(prop, "Invert Dopesheet Sort", "Invert sort order of dopesheet channels"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_trackingDopesheet_tagUpdate"); +} + static void rna_def_tracking(BlenderRNA *brna) { StructRNA *srna; @@ -1409,6 +1447,7 @@ static void rna_def_tracking(BlenderRNA *brna) rna_def_trackingStabilization(brna); rna_def_trackingReconstruction(brna); rna_def_trackingObject(brna); + rna_def_trackingDopesheet(brna); srna = RNA_def_struct(brna, "MovieTracking", NULL); RNA_def_struct_path_func(srna, "rna_tracking_path"); @@ -1456,6 +1495,10 @@ static void rna_def_tracking(BlenderRNA *brna) "rna_tracking_active_object_index_range"); RNA_def_property_ui_text(prop, "Active Object Index", "Index of active object"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); + + /* dopesheet */ + prop = RNA_def_property(srna, "dopesheet", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieTrackingDopesheet"); } void RNA_def_tracking(BlenderRNA *brna) From 37612200fd6ce86dcece90c491238b4d6bd0d662 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 12 Jun 2012 17:10:47 +0000 Subject: [PATCH 241/360] Added options to display only selected tracks and show hidden tracks in motion tracking dopesheet view. By default all channels are displaying now. --- release/scripts/startup/bl_ui/space_clip.py | 4 ++++ source/blender/blenkernel/intern/tracking.c | 22 ++++++++++++------- source/blender/makesdna/DNA_tracking_types.h | 2 ++ source/blender/makesrna/intern/rna_tracking.c | 14 ++++++++++++ 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index cef2a20710a..5c98cafb732 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -85,6 +85,10 @@ class CLIP_HT_header(Header): dopesheet = tracking.dopesheet layout.prop(sc, "view", text="", expand=True) + row = layout.row(align=True) + row.prop(dopesheet, "show_only_selected", text="") + row.prop(dopesheet, "show_hidden", text="") + layout.label(text="Sort by:") layout.prop(dopesheet, "sort_method", text="") layout.prop(dopesheet, "use_invert_sort", text="Invert") diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 33f7b22f64a..f1b251f54dd 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -3590,6 +3590,8 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking) ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); short sort_method = dopesheet->sort_method; short inverse = dopesheet->flag & TRACKING_DOPE_SORT_INVERSE; + short sel_only = dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY; + short show_hidden = dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN; if (dopesheet->ok) return; @@ -3597,17 +3599,21 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking) tracking_dopesheet_free(dopesheet); for (track = tracksbase->first; track; track = track->next) { - if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingDopesheetChannel *channel; + MovieTrackingDopesheetChannel *channel; - channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), "tracking dopesheet channel"); - channel->track = track; + if (!show_hidden && (track->flag & TRACK_HIDDEN) != 0) + continue; - channels_segments_calc(channel); + if (sel_only && !TRACK_SELECTED(track)) + continue; - BLI_addtail(&dopesheet->channels, channel); - dopesheet->tot_channel++; - } + channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), "tracking dopesheet channel"); + channel->track = track; + + channels_segments_calc(channel); + + BLI_addtail(&dopesheet->channels, channel); + dopesheet->tot_channel++; } tracking_dopesheet_sort(tracking, sort_method, inverse); diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 850d4361ab7..4eb1626f1cb 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -358,5 +358,7 @@ enum { /* MovieTrackingDopesheet->flag */ #define TRACKING_DOPE_SORT_INVERSE (1 << 0) +#define TRACKING_DOPE_SELECTED_ONLY (1 << 1) +#define TRACKING_DOPE_SHOW_HIDDEN (1 << 2) #endif diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index a2869a842ee..337f13b5af8 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -1432,6 +1432,20 @@ static void rna_def_trackingDopesheet(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_DOPE_SORT_INVERSE); RNA_def_property_ui_text(prop, "Invert Dopesheet Sort", "Invert sort order of dopesheet channels"); RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_trackingDopesheet_tagUpdate"); + + /* show_only_selected */ + prop = RNA_def_property(srna, "show_only_selected", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_DOPE_SELECTED_ONLY); + RNA_def_property_ui_text(prop, "Only Selected", "Only include channels relating to selected objects and data"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 0); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, "rna_trackingDopesheet_tagUpdate"); + + /* show_hidden */ + prop = RNA_def_property(srna, "show_hidden", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_DOPE_SHOW_HIDDEN); + RNA_def_property_ui_text(prop, "Display Hidden", "Include channels from objects/bone that aren't visible"); + RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, "rna_trackingDopesheet_tagUpdate"); } static void rna_def_tracking(BlenderRNA *brna) From d3e098bb42dd9eb6346c41f1f400050010161549 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 12 Jun 2012 17:11:00 +0000 Subject: [PATCH 242/360] Some Clip Editor interface clean-ups: - Display track's reprojection error in dopesheet - Make sure track is selected when clicking on dopesheet channel - Attempt to make headers a bit cleaner without long labels which doesn't actually make sense. --- release/scripts/startup/bl_ui/space_clip.py | 8 ++++---- source/blender/blenkernel/intern/tracking.c | 11 +++++++++++ .../blender/editors/space_clip/clip_dopesheet_draw.c | 4 ++-- .../blender/editors/space_clip/clip_dopesheet_ops.c | 3 +++ source/blender/makesdna/DNA_tracking_types.h | 2 ++ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 5c98cafb732..8d55d678c5d 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -62,7 +62,7 @@ class CLIP_HT_header(Header): r = active_object.reconstruction if r.is_valid and sc.view == 'CLIP': - layout.label(text="Average solve error: %.4f" % + layout.label(text="Solve error: %.4f" % (r.average_error)) elif sc.view == 'GRAPH': layout.prop(sc, "view", text="", expand=True) @@ -89,9 +89,9 @@ class CLIP_HT_header(Header): row.prop(dopesheet, "show_only_selected", text="") row.prop(dopesheet, "show_hidden", text="") - layout.label(text="Sort by:") - layout.prop(dopesheet, "sort_method", text="") - layout.prop(dopesheet, "use_invert_sort", text="Invert") + row = layout.row(align=True) + row.prop(dopesheet, "sort_method", text="") + row.prop(dopesheet, "use_invert_sort", text="Invert", toggle=True) else: layout.prop(sc, "view", text="", expand=True) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index f1b251f54dd..57983062e3f 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -3587,7 +3587,9 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking) MovieTrackingObject *object = BKE_tracking_active_object(tracking); MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; MovieTrackingTrack *track; + MovieTrackingReconstruction *reconstruction; ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + short sort_method = dopesheet->sort_method; short inverse = dopesheet->flag & TRACKING_DOPE_SORT_INVERSE; short sel_only = dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY; @@ -3598,6 +3600,8 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking) tracking_dopesheet_free(dopesheet); + reconstruction = BKE_tracking_object_reconstruction(tracking, object); + for (track = tracksbase->first; track; track = track->next) { MovieTrackingDopesheetChannel *channel; @@ -3610,6 +3614,13 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking) channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), "tracking dopesheet channel"); channel->track = track; + if (reconstruction->flag & TRACKING_RECONSTRUCTED) { + BLI_snprintf(channel->name, sizeof(channel->name), "%s (%.4f)", track->name, track->error); + } + else { + BLI_strncpy(channel->name, track->name, sizeof(channel->name)); + } + channels_segments_calc(channel); BLI_addtail(&dopesheet->channels, channel); diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index 2ce0e13b8bd..361a3a7d906 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -313,10 +313,10 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) else UI_ThemeColor(TH_TEXT); - font_height = BLF_height(fontid, track->name); + font_height = BLF_height(fontid, channel->name); BLF_position(fontid, v2d->cur.xmin + CHANNEL_PAD, y - font_height / 2.0f, 0.0f); - BLF_draw(fontid, track->name, strlen(track->name)); + BLF_draw(fontid, channel->name, strlen(channel->name)); } /* adjust y-position for next one */ diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c index 914e82472bb..744c7ba46fd 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_ops.c +++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c @@ -76,8 +76,10 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *object = BKE_tracking_active_object(tracking); MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; MovieTrackingDopesheetChannel *channel; + ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); float location[2]; int extend = RNA_boolean_get(op->ptr, "extend"); int current_channel_index = 0, channel_index; @@ -96,6 +98,7 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op) if (track->flag & TRACK_DOPE_SEL) { tracking->act_track = track; + BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, TRUE); } } else if (!extend) diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 4eb1626f1cb..e1e7408fe14 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -232,6 +232,8 @@ typedef struct MovieTrackingDopesheetChannel { MovieTrackingTrack *track; /* motion track for which channel is created */ int pad; + char name[64]; /* name of channel */ + int tot_segment; /* total number of segments */ int *segments; /* tracked segments */ int max_segment, total_frames; /* longest segment length and total number of tracked frames */ From 128b0f97889c75c7de511ce11e601a3762501103 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 12 Jun 2012 17:11:16 +0000 Subject: [PATCH 243/360] Added Selected Only and Show Hidden flags to clip editor's curve view --- release/scripts/startup/bl_ui/space_clip.py | 4 ++ .../editors/space_clip/clip_graph_draw.c | 11 +++-- .../editors/space_clip/clip_graph_ops.c | 18 ++++++-- .../blender/editors/space_clip/clip_intern.h | 4 +- .../blender/editors/space_clip/clip_utils.c | 44 ++++++++++--------- source/blender/makesdna/DNA_space_types.h | 2 + source/blender/makesrna/intern/rna_space.c | 14 ++++++ source/blender/makesrna/intern/rna_tracking.c | 4 +- 8 files changed, 68 insertions(+), 33 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 8d55d678c5d..e9997d43c04 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -67,6 +67,10 @@ class CLIP_HT_header(Header): elif sc.view == 'GRAPH': layout.prop(sc, "view", text="", expand=True) + row = layout.row(align=True) + row.prop(sc, "show_graph_only_selected", text="") + row.prop(sc, "show_graph_hidden", text="") + row = layout.row(align=True) if sc.show_filters: diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 7da5dae1b50..ce48681c5bd 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -162,17 +162,20 @@ static void draw_tracks_curves(View2D *v2d, SpaceClip *sc) userdata.sel = FALSE; userdata.act_track = act_track; UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale); - clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL); + clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, sc->flag & SC_SHOW_GRAPH_HIDDEN, + &userdata, tracking_segment_knot_cb, NULL, NULL); /* draw graph lines */ glEnable(GL_BLEND); - clip_graph_tracking_values_iterate(sc, act_track, tracking_segment_point_cb, - tracking_segment_start_cb, tracking_segment_end_cb); + clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, sc->flag & SC_SHOW_GRAPH_HIDDEN, + act_track, tracking_segment_point_cb, tracking_segment_start_cb, + tracking_segment_end_cb); glDisable(GL_BLEND); /* selected knot handles on top of curves */ userdata.sel = TRUE; - clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL); + clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, sc->flag & SC_SHOW_GRAPH_HIDDEN, + &userdata, tracking_segment_knot_cb, NULL, NULL); } static void draw_frame_curves(SpaceClip *sc) diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index 9af67a2b104..64547d32889 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -190,7 +190,9 @@ static int mouse_select_knot(bContext *C, float co[2], int extend) if (!extend) { SelectUserData selectdata = {SEL_DESELECT}; - clip_graph_tracking_iterate(sc, &selectdata, toggle_selection_cb); + clip_graph_tracking_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, + sc->flag & SC_SHOW_GRAPH_HIDDEN, &selectdata, + toggle_selection_cb); } if (userdata.coord == 0) @@ -215,7 +217,8 @@ static int mouse_select_curve(bContext *C, float co[2], int extend) MouseSelectUserData userdata; mouse_select_init_data(&userdata, co); - clip_graph_tracking_values_iterate(sc, &userdata, find_nearest_tracking_segment_cb, + clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, sc->flag & SC_SHOW_GRAPH_HIDDEN, + &userdata, find_nearest_tracking_segment_cb, NULL, find_nearest_tracking_segment_end_cb); if (userdata.track) { @@ -227,11 +230,16 @@ static int mouse_select_curve(bContext *C, float co[2], int extend) } else if (act_track != userdata.track) { SelectUserData selectdata = {SEL_DESELECT}; + MovieTrackingObject *object = BKE_tracking_active_object(tracking); + ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); tracking->act_track = userdata.track; + BKE_tracking_select_track(tracksbase, userdata.track, TRACK_AREA_ALL, TRUE); /* deselect all knots on newly selected curve */ - clip_graph_tracking_iterate(sc, &selectdata, toggle_selection_cb); + clip_graph_tracking_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, + sc->flag & SC_SHOW_GRAPH_HIDDEN, &selectdata, + toggle_selection_cb); } return TRUE; @@ -556,7 +564,9 @@ static int view_all_exec(bContext *C, wmOperator *UNUSED(op)) userdata.max = -FLT_MAX; userdata.min = FLT_MAX; - clip_graph_tracking_values_iterate(sc, &userdata, view_all_cb, NULL, NULL); + clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, + sc->flag & SC_SHOW_GRAPH_HIDDEN, &userdata, + view_all_cb, NULL, NULL); /* set extents of view to start/end frames */ v2d->cur.xmin = (float) SFRA; diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index dd1addd715c..e0db3b1c995 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -114,12 +114,12 @@ void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc, struct Movie void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord), void (*segment_end)(void *userdata)); -void clip_graph_tracking_values_iterate(struct SpaceClip *sc, void *userdata, +void clip_graph_tracking_values_iterate(struct SpaceClip *sc, int selected_only, int include_hidden, void *userdata, void (*func)(void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord), void (*segment_end)(void *userdata)); -void clip_graph_tracking_iterate(struct SpaceClip *sc, void *userdata, +void clip_graph_tracking_iterate(struct SpaceClip *sc, int selected_only, int include_hidden, void *userdata, void (*func)(void *userdata, struct MovieTrackingMarker *marker)); void clip_delete_track(struct bContext *C, struct MovieClip *clip, struct ListBase *tracksbase, struct MovieTrackingTrack *track); diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 8175a84e188..51870c6e43d 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -121,7 +121,7 @@ void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack } } -void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata, +void clip_graph_tracking_values_iterate(SpaceClip *sc, int selected_only, int include_hidden, void *userdata, void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord), void (*segment_end)(void *userdata)) @@ -131,17 +131,18 @@ void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata, ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track)) { - clip_graph_tracking_values_iterate_track(sc, track, userdata, func, segment_start, segment_end); - } + for (track = tracksbase->first; track; track = track->next) { + if (!include_hidden && (track->flag & TRACK_HIDDEN) != 0) + continue; - track = track->next; + if (selected_only && !TRACK_SELECTED(track)) + continue; + + clip_graph_tracking_values_iterate_track(sc, track, userdata, func, segment_start, segment_end); } } -void clip_graph_tracking_iterate(SpaceClip *sc, void *userdata, +void clip_graph_tracking_iterate(SpaceClip *sc, int selected_only, int include_hidden, void *userdata, void (*func)(void *userdata, MovieTrackingMarker *marker)) { MovieClip *clip = ED_space_clip(sc); @@ -149,23 +150,24 @@ void clip_graph_tracking_iterate(SpaceClip *sc, void *userdata, ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track)) { - int i; + for (track = tracksbase->first; track; track = track->next) { + int i; - for (i = 0; i < track->markersnr; i++) { - MovieTrackingMarker *marker = &track->markers[i]; + if (!include_hidden && (track->flag & TRACK_HIDDEN) != 0) + continue; - if (marker->flag & MARKER_DISABLED) - continue; + if (selected_only && !TRACK_SELECTED(track)) + continue; - if (func) - func(userdata, marker); - } + for (i = 0; i < track->markersnr; i++) { + MovieTrackingMarker *marker = &track->markers[i]; + + if (marker->flag & MARKER_DISABLED) + continue; + + if (func) + func(userdata, marker); } - - track = track->next; } } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index e9a07bfbf29..6a95628b650 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1037,6 +1037,8 @@ typedef enum eSpaceClip_Flag { /* SC_SHOW_PYRAMID_LEVELS = (1 << 16), */ /* UNUSED */ SC_LOCK_TIMECURSOR = (1 << 17), SC_SHOW_SECONDS = (1 << 18), + SC_SHOW_GRAPH_SEL_ONLY = (1 << 19), + SC_SHOW_GRAPH_HIDDEN = (1 << 20), } eSpaceClip_Flag; /* SpaceClip->mode */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 941e44e9f78..50a682f56bd 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -3168,6 +3168,20 @@ static void rna_def_space_clip(BlenderRNA *brna) "for the selected tracks"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + /* show_only_selected */ + prop = RNA_def_property(srna, "show_graph_only_selected", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_SEL_ONLY); + RNA_def_property_ui_text(prop, "Only Selected", "Only include channels relating to selected objects and data"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 0); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + + /* show_hidden */ + prop = RNA_def_property(srna, "show_graph_hidden", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_HIDDEN); + RNA_def_property_ui_text(prop, "Display Hidden", "Include channels from objects/bone that aren't visible"); + RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + /* ** channels ** */ /* show_red_channel */ diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 337f13b5af8..c74b5569857 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -1438,14 +1438,14 @@ static void rna_def_trackingDopesheet(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_DOPE_SELECTED_ONLY); RNA_def_property_ui_text(prop, "Only Selected", "Only include channels relating to selected objects and data"); RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 0); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, "rna_trackingDopesheet_tagUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_trackingDopesheet_tagUpdate"); /* show_hidden */ prop = RNA_def_property(srna, "show_hidden", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_DOPE_SHOW_HIDDEN); RNA_def_property_ui_text(prop, "Display Hidden", "Include channels from objects/bone that aren't visible"); RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, "rna_trackingDopesheet_tagUpdate"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_trackingDopesheet_tagUpdate"); } static void rna_def_tracking(BlenderRNA *brna) From ca6290228f63490b777d7862ce50f537e604ab75 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 12 Jun 2012 18:35:36 +0000 Subject: [PATCH 244/360] Minor fix [#31798] [minor] simpledeform modifier tooltip --- source/blender/makesrna/intern/rna_modifier.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index e54654e2b32..e9b3faa2c86 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -2450,12 +2450,12 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna) prop = RNA_def_property(srna, "lock_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "axis", MOD_SIMPLEDEFORM_LOCK_AXIS_X); - RNA_def_property_ui_text(prop, "Lock X Axis", "Do not allow tapering along the X axis"); + RNA_def_property_ui_text(prop, "Lock X Axis", "Do not allow deformation along the X axis"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "lock_y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "axis", MOD_SIMPLEDEFORM_LOCK_AXIS_Y); - RNA_def_property_ui_text(prop, "Lock Y Axis", "Do not allow tapering along the Y axis"); + RNA_def_property_ui_text(prop, "Lock Y Axis", "Do not allow deformation along the Y axis"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); } From 16dededdf399b0fcb62f8e062d2877873ed52b34 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 12 Jun 2012 18:36:49 +0000 Subject: [PATCH 245/360] remove input socket of mask node, this wasnt used. --- source/blender/blenkernel/BKE_mask.h | 2 +- source/blender/blenkernel/intern/mask.c | 22 ++-------------- source/blender/blenkernel/intern/sequencer.c | 4 +-- .../blender/compositor/nodes/COM_MaskNode.cpp | 10 ++------ .../operations/COM_MaskOperation.cpp | 15 +++-------- .../composite/nodes/node_composite_mask.c | 25 +++++-------------- 6 files changed, 16 insertions(+), 62 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index ec2eb82a9eb..345a2190e89 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -169,7 +169,7 @@ void BKE_mask_layer_shape_changed_remove(struct MaskLayer *masklay, int index, i /* rasterization */ int BKE_mask_get_duration(struct Mask *mask); void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer, - const short do_aspect_correct, const short do_linear); + const short do_aspect_correct); #define MASKPOINT_ISSEL_ANY(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT) #define MASKPOINT_ISSEL_KNOT(p) ( (p)->bezt.f2 & SELECT) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index bb2940091e4..a28ff3a175d 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -2061,19 +2061,6 @@ static void m_invert_vn_vn(float *array, const float f, const int size) } } -static void clamp_vn_vn_linear(float *array, const int size) -{ - float *arr = array + (size - 1); - - int i = size; - while (i--) { - if (*arr <= 0.0f) *arr = 0.0f; - else if (*arr >= 1.0f) *arr = 1.0f; - else *arr = srgb_to_linearrgb(*arr); - arr--; - } -} - static void clamp_vn_vn(float *array, const int size) { float *arr = array + (size - 1); @@ -2093,7 +2080,7 @@ int BKE_mask_get_duration(Mask *mask) /* rasterization */ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer, - const short do_aspect_correct, const short do_linear) + const short do_aspect_correct) { MaskLayer *masklay; @@ -2213,12 +2200,7 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer, } /* clamp at the end */ - if (do_linear) { - clamp_vn_vn_linear(buffer, buffer_size); - } - else { - clamp_vn_vn(buffer, buffer_size); - } + clamp_vn_vn(buffer, buffer_size); } MEM_freeN(buffer_tmp); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index af5b7716bbc..889eee25d6b 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2081,7 +2081,7 @@ static ImBuf *seq_render_mask_strip( BKE_mask_rasterize(seq->mask, context.rectx, context.recty, maskbuf, - TRUE, FALSE); + TRUE); fp_src = maskbuf; fp_dst = ibuf->rect_float; @@ -2104,7 +2104,7 @@ static ImBuf *seq_render_mask_strip( BKE_mask_rasterize(seq->mask, context.rectx, context.recty, maskbuf, - TRUE, FALSE); + TRUE); fp_src = maskbuf; ub_dst = (unsigned char *)ibuf->rect; diff --git a/source/blender/compositor/nodes/COM_MaskNode.cpp b/source/blender/compositor/nodes/COM_MaskNode.cpp index 991c3f75e05..e26756cfc5b 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.cpp +++ b/source/blender/compositor/nodes/COM_MaskNode.cpp @@ -37,7 +37,6 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * c { const RenderData *data = &context->getScene()->r; - InputSocket *inputImage = this->getInputSocket(0); OutputSocket *outputMask = this->getOutputSocket(0); bNode *editorNode = this->getbNode(); @@ -46,13 +45,8 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * c // always connect the output image MaskOperation *operation = new MaskOperation(); - if (inputImage->isConnected()) { - inputImage->relinkConnections(operation->getInputSocket(0), 0, graph); - } - else { - operation->setMaskWidth(data->xsch * data->size / 100.0f); - operation->setMaskHeight(data->ysch * data->size / 100.0f); - } + operation->setMaskWidth(data->xsch * data->size / 100.0f); + operation->setMaskHeight(data->ysch * data->size / 100.0f); if (outputMask->isConnected()) { outputMask->relinkConnections(operation->getOutputSocket()); diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index a7c1de323f1..35174349a63 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -36,8 +36,7 @@ extern "C" { MaskOperation::MaskOperation(): NodeOperation() { - this->addInputSocket(COM_DT_COLOR); - this->addOutputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VALUE); this->mask = NULL; this->maskWidth = 0; this->maskHeight = 0; @@ -75,7 +74,7 @@ void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers float *buffer; buffer = (float *)MEM_callocN(sizeof(float) * width * height, "rasterized mask"); - BKE_mask_rasterize(mask, width, height, buffer, TRUE, TRUE); + BKE_mask_rasterize(mask, width, height, buffer, TRUE); this->rasterizedMask = buffer; } @@ -105,20 +104,12 @@ void MaskOperation::determineResolution(unsigned int resolution[], unsigned int void MaskOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { if (!data) { - color[0] = 0; - color[1] = 0; - color[2] = 0; - color[3] = 1.0f; + color[0] = 0.0f; } else { float *buffer = (float*) data; int index = (y * this->getWidth() + x); color[0] = buffer[index]; - color[1] = buffer[index]; - color[2] = buffer[index]; - color[3] = 1.0f; } } - - diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c index 01461aec08d..dbe3c11ab55 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mask.c +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -40,17 +40,12 @@ /* **************** Translate ******************** */ -static bNodeSocketTemplate cmp_node_mask_in[] = { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } -}; - static bNodeSocketTemplate cmp_node_mask_out[] = { - { SOCK_RGBA, 0, "Image"}, + { SOCK_FLOAT, 0, "Mask"}, { -1, 0, "" } }; -static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +static void exec(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { if (node->id) { Mask *mask = (Mask *)node->id; @@ -66,22 +61,14 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) return; } - if (in[0]->hasinput && in[0]->data) { - CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA); - - sx = cbuf->x; - sy = cbuf->y; - } - else { - sx = (rd->size * rd->xsch) / 100; - sy = (rd->size * rd->ysch) / 100; - } + sx = (rd->size * rd->xsch) / 100; + sy = (rd->size * rd->ysch) / 100; /* allocate the output buffer */ stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE); res = stackbuf->rect; - BKE_mask_rasterize(mask, sx, sy, res, TRUE, TRUE); + BKE_mask_rasterize(mask, sx, sy, res, TRUE); /* pass on output and free */ out[0]->data = stackbuf; @@ -93,7 +80,7 @@ void register_node_type_cmp_mask(bNodeTreeType *ttype) static bNodeType ntype; node_type_base(ttype, &ntype, CMP_NODE_MASK, "Mask", NODE_CLASS_INPUT, NODE_OPTIONS); - node_type_socket_templates(&ntype, cmp_node_mask_in, cmp_node_mask_out); + node_type_socket_templates(&ntype, NULL, cmp_node_mask_out); node_type_size(&ntype, 140, 100, 320); node_type_exec(&ntype, exec); From 72c668a84adfe0c683e2cf03a3ad78172dbc6276 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 12 Jun 2012 19:04:12 +0000 Subject: [PATCH 246/360] Cycles: * Add back a break, which was deleted in r47773. --- intern/cycles/blender/blender_shader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index d5b58298e18..2c15a60dab6 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -180,6 +180,7 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph case BL::ShaderNode::type_CURVE_RGB: { RGBCurvesNode *ramp = new RGBCurvesNode(); node = ramp; + break; } case BL::ShaderNode::type_VALTORGB: { RGBRampNode *ramp = new RGBRampNode(); From 7fec7070d7fcf7bde53768e555b40b57ef4a7552 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Tue, 12 Jun 2012 19:37:30 +0000 Subject: [PATCH 247/360] fix: Collada build warning about inconsistent usage of Camera structure/class --- source/blender/collada/DocumentExporter.cpp | 99 +++++++++++---------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 69f302eaec7..e224ffce731 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -27,54 +27,10 @@ #include #include #include +#include +#include // std::find -extern "C" -{ -#include "DNA_scene_types.h" -#include "DNA_object_types.h" -#include "DNA_group_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_mesh_types.h" -#include "DNA_image_types.h" -#include "DNA_material_types.h" -#include "DNA_texture_types.h" -#include "DNA_anim_types.h" -#include "DNA_action_types.h" -#include "DNA_curve_types.h" -#include "DNA_armature_types.h" -#include "DNA_modifier_types.h" -#include "DNA_userdef_types.h" - -#include "BKE_DerivedMesh.h" -#include "BKE_fcurve.h" -#include "BKE_animsys.h" -#include "BLI_path_util.h" -#include "BLI_fileops.h" -#include "ED_keyframing.h" -#ifdef WITH_BUILDINFO -extern char build_rev[]; -#endif -} - -#include "MEM_guardedalloc.h" - -#include "BKE_blender.h" // version info -#include "BKE_scene.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_material.h" -#include "BKE_action.h" // pose functions -#include "BKE_armature.h" -#include "BKE_image.h" -#include "BKE_utildefines.h" -#include "BKE_object.h" - -#include "BLI_math.h" -#include "BLI_string.h" -#include "BLI_listbase.h" - -#include "RNA_access.h" - +#include "COLLADASWCamera.h" #include "COLLADASWAsset.h" #include "COLLADASWLibraryVisualScenes.h" #include "COLLADASWNode.h" @@ -106,6 +62,53 @@ extern char build_rev[]; #include "COLLADASWInstanceNode.h" #include "COLLADASWBaseInputElement.h" +extern "C" +{ +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_group_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_mesh_types.h" +#include "DNA_image_types.h" +#include "DNA_material_types.h" +#include "DNA_texture_types.h" +#include "DNA_anim_types.h" +#include "DNA_action_types.h" +#include "DNA_curve_types.h" +#include "DNA_armature_types.h" +#include "DNA_modifier_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_DerivedMesh.h" +#include "BKE_fcurve.h" +#include "BKE_animsys.h" +#include "BLI_path_util.h" +#include "BLI_fileops.h" +#include "ED_keyframing.h" +#ifdef WITH_BUILDINFO +extern char build_rev[]; +#endif + +#include "MEM_guardedalloc.h" + +#include "BKE_blender.h" // version info +#include "BKE_scene.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_action.h" // pose functions +#include "BKE_armature.h" +#include "BKE_image.h" +#include "BKE_utildefines.h" +#include "BKE_object.h" + +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_listbase.h" + +#include "RNA_access.h" +} + #include "collada_internal.h" #include "DocumentExporter.h" #include "ExportSettings.h" @@ -124,8 +127,6 @@ extern char build_rev[]; #include "LightExporter.h" #include "MaterialExporter.h" -#include -#include // std::find char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n) { From e1241030db424ce10e9fee04076ff7e209eac98c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 12 Jun 2012 20:04:55 +0000 Subject: [PATCH 248/360] yse BLI_math for the compositor in more places. --- source/blender/blenkernel/intern/curve.c | 8 +-- source/blender/blenkernel/intern/tracking.c | 2 + source/blender/blenlib/BLI_math_vector.h | 4 ++ .../blenlib/intern/math_vector_inline.c | 32 ++++++++++ .../compositor/intern/COM_MemoryBuffer.cpp | 4 +- .../compositor/intern/COM_NodeOperation.h | 3 + .../operations/COM_AlphaOverKeyOperation.cpp | 10 +-- .../COM_AlphaOverMixedOperation.cpp | 10 +-- .../COM_AlphaOverPremultiplyOperation.cpp | 10 +-- .../operations/COM_BilateralBlurOperation.cpp | 23 +++---- .../operations/COM_BokehBlurOperation.cpp | 29 +++------ .../operations/COM_ColorCurveOperation.cpp | 8 +-- .../COM_ConvertKeyToPremulOperation.cpp | 4 +- .../COM_ConvertPremulToKeyOperation.cpp | 8 +-- .../COM_ConvertRGBToYCCOperation.cpp | 5 +- .../COM_ConvertYCCToRGBOperation.cpp | 5 +- .../COM_ConvolutionEdgeFilterOperation.cpp | 54 ++++++++-------- .../COM_ConvolutionFilterOperation.cpp | 61 +++++-------------- .../COM_DirectionalBlurOperation.cpp | 11 +--- .../COM_GaussianBokehBlurOperation.cpp | 14 ++--- .../operations/COM_GaussianXBlurOperation.cpp | 15 ++--- .../operations/COM_GaussianYBlurOperation.cpp | 13 +--- .../COM_GlareSimpleStarOperation.cpp | 40 ++++-------- .../operations/COM_InvertOperation.cpp | 4 +- .../operations/COM_TonemapOperation.cpp | 22 ++----- .../COM_VariableSizeBokehBlurOperation.cpp | 30 +++------ 26 files changed, 157 insertions(+), 272 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index ce62b9c10dc..623d4b8a931 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1002,9 +1002,7 @@ void BKE_nurb_makeFaces(Nurb *nu, float *coord_array, int rowstride, int resolu, bp++; if (*fp != 0.0f) { - in[0] += (*fp) * bp->vec[0]; - in[1] += (*fp) * bp->vec[1]; - in[2] += (*fp) * bp->vec[2]; + madd_v3_v3fl(in, bp->vec, *fp); } } } @@ -1106,9 +1104,7 @@ void BKE_nurb_makeCurve(Nurb *nu, float *coord_array, float *tilt_array, float * bp++; if (*fp != 0.0f) { - coord_fp[0] += (*fp) * bp->vec[0]; - coord_fp[1] += (*fp) * bp->vec[1]; - coord_fp[2] += (*fp) * bp->vec[2]; + madd_v3_v3fl(coord_fp, bp->vec, *fp); if (tilt_fp) (*tilt_fp) += (*fp) * bp->alfa; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 57983062e3f..b61a39a2cd2 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1301,6 +1301,8 @@ ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, ImBu (void) frame_height; (void) search_ibuf; (void) marker; + (void) track; + (void) use_mask; pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 7ff52a5824f..be492fb6fdd 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -87,6 +87,8 @@ MINLINE void add_v2_v2(float r[2], const float a[2]); MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2]); MINLINE void add_v3_v3(float r[3], const float a[3]); MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3]); +MINLINE void add_v4_v4(float r[4], const float a[4]); +MINLINE void add_v4_v4v4(float r[4], const float a[4], const float b[4]); MINLINE void sub_v2_v2(float r[2], const float a[2]); MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2]); @@ -103,6 +105,7 @@ MINLINE void mul_v2_v2(float r[2], const float a[2]); MINLINE void mul_v3_v3(float r[3], const float a[3]); MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3]); MINLINE void mul_v4_fl(float r[4], float f); +MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f); MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f); MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3]); @@ -110,6 +113,7 @@ MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], floa MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f); MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]); MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f); +MINLINE void madd_v4_v4v4(float r[4], const float a[4], const float b[4]); MINLINE void negate_v2(float r[2]); MINLINE void negate_v2_v2(float r[2], const float a[2]); diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 56188048c02..e89b2ece467 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -272,6 +272,22 @@ MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3]) r[2] = a[2] + b[2]; } +MINLINE void add_v4_v4(float r[4], const float a[4]) +{ + r[0] += a[0]; + r[1] += a[1]; + r[2] += a[2]; + r[3] += a[3]; +} + +MINLINE void add_v4_v4v4(float r[4], const float a[4], const float b[4]) +{ + r[0] = a[0] + b[0]; + r[1] = a[1] + b[1]; + r[2] = a[2] + b[2]; + r[3] = a[3] + b[3]; +} + MINLINE void sub_v2_v2(float r[2], const float a[2]) { r[0] -= a[0]; @@ -361,6 +377,14 @@ MINLINE void mul_v4_fl(float r[4], float f) r[3] *= f; } +MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f) +{ + r[0] = a[0] * f; + r[1] = a[1] * f; + r[2] = a[2] * f; + r[3] = a[3] * f; +} + MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f) { r[0] += a[0] * f; @@ -409,6 +433,14 @@ MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f) r[3] += a[3] * f; } +MINLINE void madd_v4_v4v4(float r[4], const float a[4], const float b[4]) +{ + r[0] += a[0] * b[0]; + r[1] += a[1] * b[1]; + r[2] += a[2] * b[2]; + r[3] += a[3] * b[3]; +} + MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3]) { r[0] = v1[0] * v2[0]; diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp index 3ebf8398c02..b88d42ea8d0 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp @@ -329,9 +329,7 @@ void MemoryBuffer::readEWA(float result[4], float fx, float fy, float dx, float float tc[4]; const float wt = EWA_WTS[(Q < 0.f) ? 0 : (unsigned int)Q]; read(tc, clipuv(u, width), clipuv(v, height)); - result[0] += tc[0]*wt; - result[1] += tc[1]*wt; - result[2] += tc[2]*wt; + madd_v3_v3fl(result, tc, wt); result[3] += result[3] ? tc[3]*wt : 0.f; d += wt; } diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index db1fdda0bcf..3f536fb3f2d 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -35,6 +35,9 @@ class NodeOperation; #include "list" #include "BLI_threads.h" +#include "BLI_math_color.h" +#include "BLI_math_vector.h" + class ReadBufferOperation; /** diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp index c891142b808..0c9f9b97031 100644 --- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp @@ -37,16 +37,10 @@ void AlphaOverKeyOperation::executePixel(float *outputValue, float x, float y, P inputColor2Operation->read(inputOverColor, x, y, sampler, inputBuffers); if (inputOverColor[3] <= 0.0f) { - outputValue[0] = inputColor1[0]; - outputValue[1] = inputColor1[1]; - outputValue[2] = inputColor1[2]; - outputValue[3] = inputColor1[3]; + copy_v4_v4(outputValue, inputColor1); } else if (value[0] == 1.0f && inputOverColor[3] >= 1.0f) { - outputValue[0] = inputOverColor[0]; - outputValue[1] = inputOverColor[1]; - outputValue[2] = inputOverColor[2]; - outputValue[3] = inputOverColor[3]; + copy_v4_v4(outputValue, inputOverColor); } else { float premul = value[0]*inputOverColor[3]; diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp index 7d489ce856e..850bbd5cc00 100644 --- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp @@ -38,16 +38,10 @@ void AlphaOverMixedOperation::executePixel(float outputValue[4], float x, float inputColor2Operation->read(inputOverColor, x, y, sampler, inputBuffers); if (inputOverColor[3] <= 0.0f) { - outputValue[0] = inputColor1[0]; - outputValue[1] = inputColor1[1]; - outputValue[2] = inputColor1[2]; - outputValue[3] = inputColor1[3]; + copy_v4_v4(outputValue, inputColor1); } else if (value[0] == 1.0f && inputOverColor[3] >= 1.0f) { - outputValue[0] = inputOverColor[0]; - outputValue[1] = inputOverColor[1]; - outputValue[2] = inputOverColor[2]; - outputValue[3] = inputOverColor[3]; + copy_v4_v4(outputValue, inputOverColor); } else { float addfac = 1.0f - this->x + inputOverColor[3]*this->x; diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp index 6cc33387917..db67f2e0406 100644 --- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp @@ -38,16 +38,10 @@ void AlphaOverPremultiplyOperation::executePixel(float *outputValue, float x, fl /* Zero alpha values should still permit an add of RGB data */ if (inputOverColor[3]<0.0f) { - outputValue[0] = inputColor1[0]; - outputValue[1] = inputColor1[1]; - outputValue[2] = inputColor1[2]; - outputValue[3] = inputColor1[3]; + copy_v4_v4(outputValue, inputColor1); } else if (value[0] == 1.0f && inputOverColor[3] >= 1.0f) { - outputValue[0] = inputOverColor[0]; - outputValue[1] = inputOverColor[1]; - outputValue[2] = inputOverColor[2]; - outputValue[3] = inputOverColor[3]; + copy_v4_v4(outputValue, inputOverColor); } else { float mul = 1.0f - value[0]*inputOverColor[3]; diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp b/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp index 88fe17f633e..7129e7c140a 100644 --- a/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp @@ -62,36 +62,27 @@ void BilateralBlurOperation::executePixel(float *color, int x, int y, MemoryBuff int maxy = ceil(y + space); float deltaColor; this->inputDeterminatorProgram->read(determinatorReferenceColor, x, y, inputBuffers, data); - - blurColor[0] = 0.0f; - blurColor[1] = 0.0f; - blurColor[2] = 0.0f; - blurColor[3] = 0.0f; + + zero_v4(blurColor); blurDivider = 0.0f; for (int yi = miny ; yi < maxy ; yi+=QualityStepHelper::getStep()) { for (int xi = minx ; xi < maxx ; xi+=QualityStepHelper::getStep()) { // read determinator this->inputDeterminatorProgram->read(determinator, xi, yi, inputBuffers, data); - deltaColor = fabsf(determinatorReferenceColor[0] - determinator[0])+ - fabsf(determinatorReferenceColor[1] - determinator[1])+ - fabsf(determinatorReferenceColor[2] - determinator[2]); // do not take the alpha channel into account + deltaColor = (fabsf(determinatorReferenceColor[0] - determinator[0]) + + fabsf(determinatorReferenceColor[1] - determinator[1]) + + fabsf(determinatorReferenceColor[2] - determinator[2])); // do not take the alpha channel into account if (deltaColor< sigmacolor) { // add this to the blur this->inputColorProgram->read(tempColor, xi, yi, inputBuffers, data); - blurColor[0]+=tempColor[0]; - blurColor[1]+=tempColor[1]; - blurColor[2]+=tempColor[2]; - blurColor[3]+=tempColor[3]; + add_v4_v4(blurColor, tempColor); blurDivider += 1.0f; } } } if (blurDivider > 0.0f) { - color[0] = blurColor[0]/blurDivider; - color[1] = blurColor[1]/blurDivider; - color[2] = blurColor[2]/blurDivider; - color[3] = blurColor[3]/blurDivider; + mul_v4_v4fl(color, blurColor, 1.0f / blurDivider); } else { color[0] = 0.0f; diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp index b4811c89dc5..67e24496cbe 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp @@ -79,14 +79,7 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer * inputBoundingBoxReader->read(tempBoundingBox, x, y, COM_PS_NEAREST, inputBuffers); if (tempBoundingBox[0] >0.0f) { - tempColor[0] = 0; - tempColor[1] = 0; - tempColor[2] = 0; - tempColor[3] = 0; - float overallmultiplyerr = 0; - float overallmultiplyerg = 0; - float overallmultiplyerb = 0; - float overallmultiplyera = 0; + float overallmultiplyer[4] = {0.0f, 0.0f, 0.0f, 0.0f}; MemoryBuffer *inputBuffer = (MemoryBuffer*)data; float *buffer = inputBuffer->getBuffer(); int bufferwidth = inputBuffer->getWidth(); @@ -103,6 +96,8 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer * maxy = min(maxy, inputBuffer->getRect()->ymax); maxx = min(maxx, inputBuffer->getRect()->xmax); + zero_v4(tempColor); + int step = getStep(); int offsetadd = getOffsetAdd(); @@ -113,21 +108,15 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer * float u = this->bokehMidX - (nx-x) *m; float v = this->bokehMidY - (ny-y) *m; inputBokehProgram->read(bokeh, u, v, COM_PS_NEAREST, inputBuffers); - tempColor[0] += bokeh[0] * buffer[bufferindex]; - tempColor[1] += bokeh[1] * buffer[bufferindex+1]; - tempColor[2] += bokeh[2]* buffer[bufferindex+2]; - tempColor[3] += bokeh[3]* buffer[bufferindex+3]; - overallmultiplyerr += bokeh[0]; - overallmultiplyerg += bokeh[1]; - overallmultiplyerb += bokeh[2]; - overallmultiplyera += bokeh[3]; + madd_v4_v4v4(tempColor, bokeh, &buffer[bufferindex]); + add_v4_v4(overallmultiplyer, bokeh); bufferindex +=offsetadd; } } - color[0] = tempColor[0] * (1.0f / overallmultiplyerr); - color[1] = tempColor[1] * (1.0f / overallmultiplyerg); - color[2] = tempColor[2] * (1.0f / overallmultiplyerb); - color[3] = tempColor[3] * (1.0f / overallmultiplyera); + color[0] = tempColor[0] * (1.0f / overallmultiplyer[0]); + color[1] = tempColor[1] * (1.0f / overallmultiplyer[1]); + color[2] = tempColor[2] * (1.0f / overallmultiplyer[2]); + color[3] = tempColor[3] * (1.0f / overallmultiplyer[3]); } else { inputProgram->read(color, x, y, COM_PS_NEAREST, inputBuffers); diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp index a38012271f1..c4336ed5e06 100644 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp @@ -79,9 +79,7 @@ void ColorCurveOperation::executePixel(float *color, float x, float y, PixelSamp if (*fac >= 1.0f) curvemapping_evaluate_premulRGBF(workingCopy, color, image); else if (*fac <= 0.0f) { - color[0] = image[0]; - color[1] = image[1]; - color[2] = image[2]; + copy_v3_v3(color, image); } else { float col[4], mfac = 1.0f - *fac; @@ -140,9 +138,7 @@ void ConstantLevelColorCurveOperation::executePixel(float *color, float x, float if (*fac >= 1.0f) curvemapping_evaluate_premulRGBF(this->curveMapping, color, image); else if (*fac <= 0.0f) { - color[0] = image[0]; - color[1] = image[1]; - color[2] = image[2]; + copy_v3_v3(color, image); } else { float col[4], mfac = 1.0f - *fac; diff --git a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp index 547915f58c9..db27e07d52f 100644 --- a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp @@ -43,9 +43,7 @@ void ConvertKeyToPremulOperation::executePixel(float *outputValue, float x, floa this->inputColor->read(inputValue, x, y, sampler, inputBuffers); alpha = inputValue[3]; - outputValue[0] = inputValue[0] * alpha; - outputValue[1] = inputValue[1] * alpha; - outputValue[2] = inputValue[2] * alpha; + mul_v3_v3fl(outputValue, inputValue, alpha); /* never touches the alpha */ outputValue[3] = alpha; diff --git a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp index 16636ee2afc..920b5f8a775 100644 --- a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp @@ -44,14 +44,10 @@ void ConvertPremulToKeyOperation::executePixel(float *outputValue, float x, floa alpha = inputValue[3]; if (fabsf(alpha) < 1e-5f) { - outputValue[0] = 0.f; - outputValue[1] = 0.f; - outputValue[2] = 0.f; + zero_v3(outputValue); } else { - outputValue[0] = inputValue[0] / alpha; - outputValue[1] = inputValue[1] / alpha; - outputValue[2] = inputValue[2] / alpha; + mul_v3_v3fl(outputValue, inputValue, 1.0f / alpha); } /* never touches the alpha */ diff --git a/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp b/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp index c626dc03000..ce62cf0ae49 100644 --- a/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp @@ -60,9 +60,8 @@ void ConvertRGBToYCCOperation::executePixel(float *outputValue, float x, float y rgb_to_ycc(inputColor[0], inputColor[1], inputColor[2], &color[0], &color[1], &color[2], this->mode); /* divided by 255 to normalize for viewing in */ - outputValue[0] = color[0]/255.f; /* Y */ - outputValue[1] = color[1]/255.f; /* Cb*/ - outputValue[2] = color[2]/255.f; /* Cr*/ + /* R,G,B --> Y,Cb,Cr */ + mul_v3_v3fl(outputValue, color, 1.0f / 255.0f); outputValue[3] = inputColor[3]; } diff --git a/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp b/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp index d3048c131e4..dbfe4847c78 100644 --- a/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp @@ -57,9 +57,8 @@ void ConvertYCCToRGBOperation::executePixel(float *outputValue, float x, float y inputOperation->read(inputColor, x, y, sampler, inputBuffers); /* need to un-normalize the data */ - inputColor[0] *= 255.f; /* Y */ - inputColor[1] *= 255.f; /* Cb*/ - inputColor[2] *= 255.f; /* Cr*/ + /* R,G,B --> Y,Cb,Cr */ + mul_v3_fl(inputColor, 255.0f); ycc_to_rgb(inputColor[0], inputColor[1], inputColor[2], &outputValue[0], &outputValue[1], &outputValue[2], this->mode); outputValue[3] = inputColor[3]; diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp index db67412f3e7..6edb046a070 100644 --- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp @@ -26,12 +26,6 @@ ConvolutionEdgeFilterOperation::ConvolutionEdgeFilterOperation() : ConvolutionFilterOperation() { } -inline void addFilter(float *result, float*input, float value) -{ - result[0] += input[0] * value; - result[1] += input[1] * value; - result[2] += input[2] * value; -} void ConvolutionEdgeFilterOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data) { @@ -64,48 +58,48 @@ void ConvolutionEdgeFilterOperation::executePixel(float *color,int x, int y, Mem res2[3] = 0.0f; this->inputOperation->read(in1, x1, y1, inputBuffers, NULL); - addFilter(res1, in1, this->filter[0]); - addFilter(res2, in1, this->filter[0]); + madd_v3_v3fl(res1, in1, this->filter[0]); + madd_v3_v3fl(res2, in1, this->filter[0]); this->inputOperation->read(in1, x2, y1, inputBuffers, NULL); - addFilter(res1, in1, this->filter[1]); - addFilter(res2, in1, this->filter[3]); + madd_v3_v3fl(res1, in1, this->filter[1]); + madd_v3_v3fl(res2, in1, this->filter[3]); this->inputOperation->read(in1, x3, y1, inputBuffers, NULL); - addFilter(res1, in1, this->filter[2]); - addFilter(res2, in1, this->filter[6]); + madd_v3_v3fl(res1, in1, this->filter[2]); + madd_v3_v3fl(res2, in1, this->filter[6]); this->inputOperation->read(in1, x1, y2, inputBuffers, NULL); - addFilter(res1, in1, this->filter[3]); - addFilter(res2, in1, this->filter[1]); + madd_v3_v3fl(res1, in1, this->filter[3]); + madd_v3_v3fl(res2, in1, this->filter[1]); this->inputOperation->read(in2, x2, y2, inputBuffers, NULL); - addFilter(res1, in2, this->filter[4]); - addFilter(res2, in2, this->filter[4]); + madd_v3_v3fl(res1, in2, this->filter[4]); + madd_v3_v3fl(res2, in2, this->filter[4]); this->inputOperation->read(in1, x3, y2, inputBuffers, NULL); - addFilter(res1, in1, this->filter[5]); - addFilter(res2, in1, this->filter[7]); + madd_v3_v3fl(res1, in1, this->filter[5]); + madd_v3_v3fl(res2, in1, this->filter[7]); this->inputOperation->read(in1, x1, y3, inputBuffers, NULL); - addFilter(res1, in1, this->filter[6]); - addFilter(res2, in1, this->filter[2]); + madd_v3_v3fl(res1, in1, this->filter[6]); + madd_v3_v3fl(res2, in1, this->filter[2]); this->inputOperation->read(in1, x2, y3, inputBuffers, NULL); - addFilter(res1, in1, this->filter[7]); - addFilter(res2, in1, this->filter[5]); + madd_v3_v3fl(res1, in1, this->filter[7]); + madd_v3_v3fl(res2, in1, this->filter[5]); this->inputOperation->read(in1, x3, y3, inputBuffers, NULL); - addFilter(res1, in1, this->filter[8]); - addFilter(res2, in1, this->filter[8]); + madd_v3_v3fl(res1, in1, this->filter[8]); + madd_v3_v3fl(res2, in1, this->filter[8]); - color[0] = sqrt(res1[0]*res1[0]+res2[0]*res2[0]); - color[1] = sqrt(res1[1]*res1[1]+res2[1]*res2[1]); - color[2] = sqrt(res1[2]*res1[2]+res2[2]*res2[2]); + color[0] = sqrt(res1[0] * res1[0] + res2[0] * res2[0]); + color[1] = sqrt(res1[1] * res1[1] + res2[1] * res2[1]); + color[2] = sqrt(res1[2] * res1[2] + res2[2] * res2[2]); - color[0] = color[0]*value[0] + in2[0] * mval; - color[1] = color[1]*value[0] + in2[1] * mval; - color[2] = color[2]*value[0] + in2[2] * mval; + color[0] = color[0] * value[0] + in2[0] * mval; + color[1] = color[1] * value[0] + in2[1] * mval; + color[2] = color[2] * value[0] + in2[2] * mval; color[3] = in2[3]; } diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp index 2720a0a4146..3c9cde92e2e 100644 --- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp @@ -69,10 +69,6 @@ void ConvolutionFilterOperation::deinitExecution() void ConvolutionFilterOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data) { - color[0] = 0.0; - color[1] = 0.0; - color[2] = 0.0; - color[3] = 0.0; float in1[4]; float in2[4]; int x1 = x - 1; @@ -89,57 +85,32 @@ void ConvolutionFilterOperation::executePixel(float *color,int x, int y, MemoryB CLAMP(y3, 0, getHeight()-1); float value[4]; this->inputValueOperation->read(value, x2, y2, inputBuffers, NULL); - float mval = 1.0f - value[0]; + const float mval = 1.0f - value[0]; + + zero_v4(color); this->inputOperation->read(in1, x1, y1, inputBuffers, NULL); - color[0] += in1[0] * this->filter[0]; - color[1] += in1[1] * this->filter[0]; - color[2] += in1[2] * this->filter[0]; - color[3] += in1[3] * this->filter[0]; + madd_v4_v4fl(color, in1, this->filter[0]); this->inputOperation->read(in1, x2, y1, inputBuffers, NULL); - color[0] += in1[0] * this->filter[1]; - color[1] += in1[1] * this->filter[1]; - color[2] += in1[2] * this->filter[1]; - color[3] += in1[3] * this->filter[1]; + madd_v4_v4fl(color, in1, this->filter[1]); this->inputOperation->read(in1, x3, y1, inputBuffers, NULL); - color[0] += in1[0] * this->filter[2]; - color[1] += in1[1] * this->filter[2]; - color[2] += in1[2] * this->filter[2]; - color[3] += in1[3] * this->filter[2]; + madd_v4_v4fl(color, in1, this->filter[2]); this->inputOperation->read(in1, x1, y2, inputBuffers, NULL); - color[0] += in1[0] * this->filter[3]; - color[1] += in1[1] * this->filter[3]; - color[2] += in1[2] * this->filter[3]; - color[3] += in1[3] * this->filter[3]; + madd_v4_v4fl(color, in1, this->filter[3]); this->inputOperation->read(in2, x2, y2, inputBuffers, NULL); - color[0] += in2[0] * this->filter[4]; - color[1] += in2[1] * this->filter[4]; - color[2] += in2[2] * this->filter[4]; - color[3] += in2[3] * this->filter[4]; + madd_v4_v4fl(color, in2, this->filter[4]); this->inputOperation->read(in1, x3, y2, inputBuffers, NULL); - color[0] += in1[0] * this->filter[5]; - color[1] += in1[1] * this->filter[5]; - color[2] += in1[2] * this->filter[5]; - color[3] += in1[3] * this->filter[5]; + madd_v4_v4fl(color, in1, this->filter[5]); this->inputOperation->read(in1, x1, y3, inputBuffers, NULL); - color[0] += in1[0] * this->filter[6]; - color[1] += in1[1] * this->filter[6]; - color[2] += in1[2] * this->filter[6]; - color[3] += in1[3] * this->filter[6]; + madd_v4_v4fl(color, in1, this->filter[6]); this->inputOperation->read(in1, x2, y3, inputBuffers, NULL); - color[0] += in1[0] * this->filter[7]; - color[1] += in1[1] * this->filter[7]; - color[2] += in1[2] * this->filter[7]; - color[3] += in1[3] * this->filter[7]; + madd_v4_v4fl(color, in1, this->filter[7]); this->inputOperation->read(in1, x3, y3, inputBuffers, NULL); - color[0] += in1[0] * this->filter[8]; - color[1] += in1[1] * this->filter[8]; - color[2] += in1[2] * this->filter[8]; - color[3] += in1[3] * this->filter[8]; + madd_v4_v4fl(color, in1, this->filter[8]); - color[0] = color[0]*value[0] + in2[0] * mval; - color[1] = color[1]*value[0] + in2[1] * mval; - color[2] = color[2]*value[0] + in2[2] * mval; - color[3] = color[3]*value[0] + in2[3] * mval; + color[0] = color[0] * value[0] + in2[0] * mval; + color[1] = color[1] * value[0] + in2[1] * mval; + color[2] = color[2] * value[0] + in2[2] * mval; + color[3] = color[3] * value[0] + in2[3] * mval; } bool ConvolutionFilterOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp index 43cba09d16f..60c31400eca 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp @@ -85,10 +85,7 @@ void DirectionalBlurOperation::executePixel(float *color, int x, int y, MemoryBu this->inputProgram->read(col, cs * u + ss * v + center_x_pix, cs * v - ss * u + center_y_pix, COM_PS_NEAREST, inputBuffers); - col2[0] += col[0]; - col2[1] += col[1]; - col2[2] += col[2]; - col2[3] += col[3]; + add_v4_v4(col2, col); /* double transformations */ ltx += tx; @@ -96,10 +93,8 @@ void DirectionalBlurOperation::executePixel(float *color, int x, int y, MemoryBu lrot += rot; lsc += sc; } - color[0] = col2[0]/iterations; - color[1] = col2[1]/iterations; - color[2] = col2[2]/iterations; - color[3] = col2[3]/iterations; + + mul_v4_v4fl(color, col2, 1.0f / iterations); } void DirectionalBlurOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index 07cc07880e7..80e35f63ac5 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -138,21 +138,15 @@ void GaussianBokehBlurOperation::executePixel(float *color, int x, int y, Memory index = ((ny-y)+this->rady) * (this->radx*2+1) + (minx-x+this->radx); int bufferindex = ((minx - bufferstartx)*4)+((ny-bufferstarty)*4*bufferwidth); for (int nx = minx ; nx < maxx ; nx +=step) { - float multiplyer = gausstab[index]; - tempColor[0] += multiplyer * buffer[bufferindex]; - tempColor[1] += multiplyer * buffer[bufferindex+1]; - tempColor[2] += multiplyer * buffer[bufferindex+2]; - tempColor[3] += multiplyer * buffer[bufferindex+3]; + const float multiplyer = gausstab[index]; + madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplyer); overallmultiplyer += multiplyer; index += step; bufferindex +=offsetadd; } } - float divider = 1.0f / overallmultiplyer; - color[0] = tempColor[0] * divider; - color[1] = tempColor[1] * divider; - color[2] = tempColor[2] * divider; - color[3] = tempColor[3] * divider; + + mul_v4_v4fl(color, tempColor, 1.0f / overallmultiplyer); } void GaussianBokehBlurOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp index a7e443838a9..e30cbfeff7e 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp @@ -99,19 +99,12 @@ void GaussianXBlurOperation::executePixel(float *color, int x, int y, MemoryBuff int bufferindex = ((minx - bufferstartx)*4)+((miny-bufferstarty)*4*bufferwidth); for (int nx = minx ; nx < maxx ; nx +=step) { index = (nx-x)+this->rad; - float multiplyer = gausstab[index]; - tempColor[0] += multiplyer * buffer[bufferindex]; - tempColor[1] += multiplyer * buffer[bufferindex+1]; - tempColor[2] += multiplyer * buffer[bufferindex+2]; - tempColor[3] += multiplyer * buffer[bufferindex+3]; + const float multiplyer = gausstab[index]; + madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplyer); overallmultiplyer += multiplyer; - bufferindex +=offsetadd; + bufferindex += offsetadd; } - float divider = 1.0f / overallmultiplyer; - color[0] = tempColor[0] * divider; - color[1] = tempColor[1] * divider; - color[2] = tempColor[2] * divider; - color[3] = tempColor[3] * divider; + mul_v4_v4fl(color, tempColor, 1.0f / overallmultiplyer); } void GaussianXBlurOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp index c7da43fc20f..c0561704596 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -95,18 +95,11 @@ void GaussianYBlurOperation::executePixel(float *color, int x, int y, MemoryBuff for (int ny = miny ; ny < maxy ; ny +=step) { index = (ny-y)+this->rad; int bufferindex = ((minx - bufferstartx)*4)+((ny-bufferstarty)*4*bufferwidth); - float multiplyer = gausstab[index]; - tempColor[0] += multiplyer * buffer[bufferindex]; - tempColor[1] += multiplyer * buffer[bufferindex+1]; - tempColor[2] += multiplyer * buffer[bufferindex+2]; - tempColor[3] += multiplyer * buffer[bufferindex+3]; + const float multiplyer = gausstab[index]; + madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplyer); overallmultiplyer += multiplyer; } - float divider = 1.0f / overallmultiplyer; - color[0] = tempColor[0] * divider; - color[1] = tempColor[1] * divider; - color[2] = tempColor[2] * divider; - color[3] = tempColor[3] * divider; + mul_v4_v4fl(color, tempColor, 1.0f / overallmultiplyer); } void GaussianYBlurOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp index 602e18521ee..fba3eca4af9 100644 --- a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp @@ -42,28 +42,20 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTil xm = x - i; xp = x + i; tbuf1->read(c, x, y); - c[0]*=f1; c[1]*=f1 ; c[2] *=f1; + mul_v3_fl(c, f1); tbuf1->read(tc, (settings->angle ? xm : x), ym); - c[0]+=tc[0]*f2; - c[1]+=tc[1]*f2; - c[2]+=tc[2]*f2; + madd_v3_v3fl(c, tc, f2); tbuf1->read(tc, (settings->angle ? xp : x), yp); - c[0]+=tc[0]*f2; - c[1]+=tc[1]*f2; - c[2]+=tc[2]*f2; + madd_v3_v3fl(c, tc, f2); c[3] = 1.0f; tbuf1->writePixel(x, y, c); tbuf2->read(c, x, y); - c[0]*=f1; c[1]*=f1 ; c[2] *=f1; + mul_v3_fl(c, f1); tbuf2->read(tc, xm, (settings->angle ? yp : y)); - c[0]+=tc[0]*f2; - c[1]+=tc[1]*f2; - c[2]+=tc[2]*f2; + madd_v3_v3fl(c, tc, f2); tbuf2->read(tc, xp, (settings->angle ? ym : y)); - c[0]+=tc[0]*f2; - c[1]+=tc[1]*f2; - c[2]+=tc[2]*f2; + madd_v3_v3fl(c, tc, f2); c[3] = 1.0f; tbuf2->writePixel(x, y, c); @@ -77,28 +69,20 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTil xm = x - i; xp = x + i; tbuf1->read(c, x, y); - c[0]*=f1; c[1]*=f1 ; c[2] *=f1; + mul_v3_fl(c, f1); tbuf1->read(tc, (settings->angle ? xm : x), ym); - c[0]+=tc[0]*f2; - c[1]+=tc[1]*f2; - c[2]+=tc[2]*f2; + madd_v3_v3fl(c, tc, f2); tbuf1->read(tc, (settings->angle ? xp : x), yp); - c[0]+=tc[0]*f2; - c[1]+=tc[1]*f2; - c[2]+=tc[2]*f2; + madd_v3_v3fl(c, tc, f2); c[3] = 1.0f; tbuf1->writePixel(x, y, c); tbuf2->read(c, x, y); - c[0]*=f1; c[1]*=f1 ; c[2] *=f1; + mul_v3_fl(c, f1); tbuf2->read(tc, xm, (settings->angle ? yp : y)); - c[0]+=tc[0]*f2; - c[1]+=tc[1]*f2; - c[2]+=tc[2]*f2; + madd_v3_v3fl(c, tc, f2); tbuf2->read(tc, xp, (settings->angle ? ym : y)); - c[0]+=tc[0]*f2; - c[1]+=tc[1]*f2; - c[2]+=tc[2]*f2; + madd_v3_v3fl(c, tc, f2); c[3] = 1.0f; tbuf2->writePixel(x, y, c); } diff --git a/source/blender/compositor/operations/COM_InvertOperation.cpp b/source/blender/compositor/operations/COM_InvertOperation.cpp index 982fe1a5450..82158c4adad 100644 --- a/source/blender/compositor/operations/COM_InvertOperation.cpp +++ b/source/blender/compositor/operations/COM_InvertOperation.cpp @@ -55,9 +55,7 @@ void InvertOperation::executePixel(float *out, float x, float y, PixelSampler sa out[2] = (1.0f - inputColor[2])*value + inputColor[2]*invertedValue; } else { - out[0] = inputColor[0]; - out[1] = inputColor[1]; - out[2] = inputColor[2]; + copy_v3_v3(out, inputColor); } if (alpha) diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cpp b/source/blender/compositor/operations/COM_TonemapOperation.cpp index d8089bdf3ea..75adcf524c4 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.cpp +++ b/source/blender/compositor/operations/COM_TonemapOperation.cpp @@ -47,9 +47,7 @@ void TonemapOperation::executePixel(float *color, int x, int y, MemoryBuffer *in float output[4]; this->imageReader->read(output, x, y, inputBuffers, NULL); - output[0] *= avg->al; - output[1] *= avg->al; - output[2] *= avg->al; + mul_v3_fl(output, avg->al); float dr = output[0] + this->data->offset; float dg = output[1] + this->data->offset; float db = output[2] + this->data->offset; @@ -63,10 +61,7 @@ void TonemapOperation::executePixel(float *color, int x, int y, MemoryBuffer *in output[2] = powf(MAX2(output[2], 0.0f), igm); } - color[0] = output[0]; - color[1] = output[1]; - color[2] = output[2]; - color[3] = output[3]; + copy_v4_v4(color, output); } void PhotoreceptorTonemapOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { @@ -94,10 +89,7 @@ void PhotoreceptorTonemapOperation::executePixel(float *color, int x, int y, Mem I_a = I_l + ia * (I_g - I_l); output[2] /= (output[2] + powf(f * I_a, m)); - color[0] = output[0]; - color[1] = output[1]; - color[2] = output[2]; - color[3] = output[3]; + copy_v4_v4(color, output); } void TonemapOperation::deinitExecution() @@ -143,18 +135,14 @@ void *TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuff while (p--) { float L = 0.212671f * bc[0] + 0.71516f * bc[1] + 0.072169f * bc[2]; Lav += L; - cav[0] += bc[0]; - cav[1] += bc[1]; - cav[2] += bc[2]; + add_v3_v3(cav, bc); lsum += logf(MAX2(L, 0.0f) + 1e-5f); maxl = (L > maxl) ? L : maxl; minl = (L < minl) ? L : minl; bc+=4; } data->lav = Lav * sc; - data->cav[0] = cav[0]*sc; - data->cav[1] = cav[1]*sc; - data->cav[2] = cav[2]*sc; + mul_v3_v3fl(data->cav, cav, sc); maxl = log((double)maxl + 1e-5); minl = log((double)minl + 1e-5); avl = lsum * sc; data->auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.f; float al = exp((double)avl); diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 562b0fc2bb5..1544b1c8d06 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -61,10 +61,7 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me tempColor[2] = 0; tempColor[3] = 0; float tempSize[4]; - float overallmultiplyerr = 0; - float overallmultiplyerg = 0; - float overallmultiplyerb = 0; - float overallmultiplyera = 0; + float overallmultiplyer[4] = {0.0f, 0.0f, 0.0f, 0.0f}; int miny = y - maxBlur; int maxy = y + maxBlur; @@ -76,10 +73,8 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me tempColor[1] += readColor[1]; tempColor[2] += readColor[2]; tempColor[3] += readColor[3]; - overallmultiplyerr += 1; - overallmultiplyerg += 1; - overallmultiplyerb += 1; - overallmultiplyera += 1; + add_v4_v4(tempColor, readColor); + add_v3_fl(overallmultiplyer, 1.0f); for (int ny = miny ; ny < maxy ; ny += QualityStepHelper::getStep()) { for (int nx = minx ; nx < maxx ; nx += QualityStepHelper::getStep()) { @@ -97,22 +92,17 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me float v = 256 + dy*256/size; inputBokehProgram->read(bokeh, u, v, COM_PS_NEAREST, inputBuffers); inputProgram->read(readColor, nx, ny, COM_PS_NEAREST, inputBuffers); - tempColor[0] += bokeh[1]*readColor[0]; - tempColor[1] += bokeh[2]*readColor[1]; - tempColor[2] += bokeh[2]*readColor[2]; - tempColor[3] += bokeh[3]*readColor[3]; - overallmultiplyerr += bokeh[0]; - overallmultiplyerg += bokeh[1]; - overallmultiplyerb += bokeh[2]; - overallmultiplyera += bokeh[3]; + madd_v4_v4v4(tempColor, bokeh, readColor); + add_v4_v4(overallmultiplyer, bokeh); } } } } - color[0] = tempColor[0] / overallmultiplyerr; - color[1] = tempColor[1] / overallmultiplyerg; - color[2] = tempColor[2] / overallmultiplyerb; - color[3] = tempColor[3] / overallmultiplyera; + + color[0] = tempColor[0] * (1.0f / overallmultiplyer[0]); + color[1] = tempColor[1] * (1.0f / overallmultiplyer[1]); + color[2] = tempColor[2] * (1.0f / overallmultiplyer[2]); + color[3] = tempColor[3] * (1.0f / overallmultiplyer[3]); } } From aace651e51cfaa725847ef1345418ec6a6e42b6e Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 12 Jun 2012 21:07:14 +0000 Subject: [PATCH 249/360] Fix camera curve in clip editor not being remapped by a clip's start frame --- source/blender/editors/space_clip/clip_graph_draw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index ce48681c5bd..d3d01f9f87e 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -189,6 +189,7 @@ static void draw_frame_curves(SpaceClip *sc) for (i = 0; i < reconstruction->camnr; i++) { MovieReconstructedCamera *camera = &reconstruction->cameras[i]; + int framenr; if (lines && camera->framenr != prevfra + 1) { glEnd(); @@ -200,7 +201,8 @@ static void draw_frame_curves(SpaceClip *sc) lines = 1; } - glVertex2f(camera->framenr, camera->error); + framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, camera->framenr); + glVertex2f(framenr, camera->error); prevfra = camera->framenr; } From 92d948307549ce1d69ec4e41e42b442360b9bade Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Tue, 12 Jun 2012 21:23:51 +0000 Subject: [PATCH 250/360] patch #31794 Added new function BKE_object_relational_superset() --- source/blender/blenkernel/BKE_object.h | 20 ++++ source/blender/blenkernel/intern/object.c | 134 ++++++++++++++++++++++ 2 files changed, 154 insertions(+) diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 890fc40c284..29979f62d60 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -158,6 +158,26 @@ void BKE_object_relink(struct Object *ob); struct MovieClip *BKE_object_movieclip_get(struct Scene *scene, struct Object *ob, int use_default); +/* this function returns a superset of the scenes selection based on relationships */ + +typedef enum eObRelationTypes { + OB_REL_NONE = 0, /* just the selection as is */ + OB_REL_PARENT = (1<<0), /* immediate parent */ + OB_REL_PARENT_RECURSIVE = (1<<1), /* parents up to root of selection tree*/ + OB_REL_CHILDREN = (1<<2), /* immediate children */ + OB_REL_CHILDREN_RECURSIVE = (1<<3), /* All children */ + OB_REL_MOD_ARMATURE = (1<<4), /* Armatures related to the selected objects */ + OB_REL_SCENE_CAMERA = (1<<5), /* you might want the scene camera too even if unselected? */ +} eObRelationTypes; + +typedef enum eObjectSet { + OB_SET_SELECTED, /* Selected Objects */ + OB_SET_VISIBLE, /* Visible Objects */ + OB_SET_ALL /* All Objects */ +} eObjectSet; + +struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a01024acfd3..91fd5811911 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -63,6 +63,7 @@ #include "BLI_math.h" #include "BLI_pbvh.h" #include "BLI_utildefines.h" +#include "BLI_linklist.h" #include "BKE_main.h" #include "BKE_global.h" @@ -3076,3 +3077,136 @@ MovieClip *BKE_object_movieclip_get(Scene *scene, Object *ob, int use_default) return clip; } + + +/* + * Find an associated Armature object + */ +static Object *obrel_armature_find(Object *ob) +{ + Object *ob_arm = NULL; + + if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) { + ob_arm = ob->parent; + } + else { + ModifierData *mod = (ModifierData*)ob->modifiers.first; + while (mod) { + if (mod->type == eModifierType_Armature) { + ob_arm = ((ArmatureModifierData*)mod)->object; + } + + mod = mod->next; + } + } + + return ob_arm; +} + +static int obrel_is_recursive_child(Object *ob, Object *child) { + Object *ancestor = child->parent; + while (ancestor) + { + if(ancestor == ob) return TRUE; + ancestor = ancestor->parent; + } + return FALSE; +} + + +static int obrel_list_test(Object *ob) +{ + return ob && !(ob->id.flag & LIB_DOIT); +} + +static void obrel_list_add(LinkNode **links, Object *ob) +{ + BLI_linklist_prepend(links, ob); + ob->id.flag |= LIB_DOIT; +} + +/* + * Iterates over all objects of the given scene. + * Depending on the eObjectSet flag: + * collect either OB_SET_ALL, OB_SET_VISIBLE or OB_SET_SELECTED objects. + * If OB_SET_VISIBLE or OB_SET_SELECTED are collected, + * then also add related objects according to the given includeFilters. + */ +struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter) +{ + LinkNode *links = NULL; + + Base *base; + + /* Remove markers from all objects */ + for (base = scene->base.first; base; base = base->next) { + base->object->id.flag &= ~LIB_DOIT; + } + + /* iterate over all selected and visible objects */ + for (base = scene->base.first; base; base = base->next) { + if (objectSet == OB_SET_ALL) { + // as we get all anyways just add it + Object *ob = base->object; + obrel_list_add(&links, ob); + } + else { + if ( (objectSet == OB_SET_SELECTED && TESTBASELIB_BGMODE(((View3D *)NULL), scene, base)) + || (objectSet == OB_SET_VISIBLE && BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, base)) + ) { + Object *ob = base->object; + + if (obrel_list_test(ob)) + obrel_list_add(&links, ob); + + /* parent relationship */ + if (includeFilter & ( OB_REL_PARENT | OB_REL_PARENT_RECURSIVE )) { + Object *parent = ob->parent; + if (obrel_list_test(parent)) { + + obrel_list_add(&links, parent); + + /* recursive parent relationship */ + if (includeFilter & OB_REL_PARENT_RECURSIVE) { + parent = parent->parent; + while (obrel_list_test(parent)){ + + obrel_list_add(&links, parent); + parent = parent->parent; + } + } + } + } + + /* child relationship */ + if (includeFilter & ( OB_REL_CHILDREN | OB_REL_CHILDREN_RECURSIVE )) { + Base *local_base; + for (local_base = scene->base.first; local_base; local_base = local_base->next) { + if (BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, local_base)) { + + Object *child = local_base->object; + if (obrel_list_test(child)) { + if ((includeFilter & OB_REL_CHILDREN_RECURSIVE && obrel_is_recursive_child(ob,child)) + || (includeFilter & OB_REL_CHILDREN && child->parent && child->parent == ob )) { + obrel_list_add(&links, child); + } + } + } + } + } + + + /* include related armatures */ + if (includeFilter & OB_REL_MOD_ARMATURE) { + Object *arm = obrel_armature_find(ob); + if (obrel_list_test(arm)) { + obrel_list_add(&links, arm); + } + } + + } + } + } // end for + + return links; +} From 5dc0b35a019651e052c7770330aafc7f2d7fb690 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 12 Jun 2012 21:25:23 +0000 Subject: [PATCH 251/360] Added frame offset slider to clip datablocks In contrast to start_frame (which affects on where footage actually starts to play and also affects on all data associated with a clip such as motion tracking, reconstruction and so on) this slider only affects on a way how frame number is mapping to a filename, without touching any kind of tracking data. The formula is: file_name = clip_file_name + frame_offset - (start_frame - 1) --- release/scripts/startup/bl_ui/space_clip.py | 1 + source/blender/blenkernel/intern/movieclip.c | 7 ++++--- source/blender/editors/space_clip/clip_editor.c | 4 +++- source/blender/makesdna/DNA_movieclip_types.h | 9 ++++++++- source/blender/makesrna/intern/rna_movieclip.c | 10 ++++++++-- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index e9997d43c04..55922da3892 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -1013,6 +1013,7 @@ class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel): col = layout.column() col.template_movieclip(sc, "clip", compact=True) col.prop(clip, "start_frame") + col.prop(clip, "frame_offset") class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel): diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 92184a38695..d6fa39fd789 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -159,7 +159,7 @@ static void get_sequence_fname(MovieClip *clip, int framenr, char *name) offset = sequence_guess_offset(clip->name, strlen(head), numlen); if (numlen) - BLI_stringenc(name, head, tail, numlen, offset + framenr - clip->start_frame); + BLI_stringenc(name, head, tail, numlen, offset + framenr - clip->start_frame + clip->frame_offset); else BLI_strncpy(name, clip->name, sizeof(clip->name)); @@ -171,7 +171,7 @@ static void get_proxy_fname(MovieClip *clip, int proxy_render_size, int undistor { int size = rendersize_to_number(proxy_render_size); char dir[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX]; - int proxynr = framenr - clip->start_frame + 1; + int proxynr = framenr - clip->start_frame + 1 + clip->frame_offset; BLI_split_dirfile(clip->name, clipdir, clipfile, FILE_MAX, FILE_MAX); @@ -250,7 +250,7 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, in int fra; dur = IMB_anim_get_duration(clip->anim, tc); - fra = framenr - clip->start_frame; + fra = framenr - clip->start_frame + clip->frame_offset; if (fra < 0) fra = 0; @@ -446,6 +446,7 @@ static MovieClip *movieclip_alloc(const char *name) clip->proxy.quality = 90; clip->start_frame = 1; + clip->frame_offset = 1; return clip; } diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index b24ff58e590..30965362d37 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -523,7 +523,7 @@ typedef struct SpaceClipDrawContext { unsigned last_texture; /* ID of previously used texture, so it'll be restored after clip drawing */ /* fields to check if cache is still valid */ - int framenr, start_frame; + int framenr, start_frame, frame_offset; short render_size, render_flag; } SpaceClipDrawContext; @@ -565,6 +565,7 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) need_rebind |= context->render_size != sc->user.render_size; need_rebind |= context->render_flag != sc->user.render_flag; need_rebind |= context->start_frame != clip->start_frame; + need_rebind |= context->frame_offset != clip->frame_offset; if (need_rebind) { int width = ibuf->x, height = ibuf->y; @@ -622,6 +623,7 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) context->render_size = sc->user.render_size; context->render_flag = sc->user.render_flag; context->start_frame = clip->start_frame; + context->frame_offset = clip->frame_offset; } else { /* displaying exactly the same image which was loaded t oa texture, diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h index 19004dbc8b8..d8bba4a3bf5 100644 --- a/source/blender/makesdna/DNA_movieclip_types.h +++ b/source/blender/makesdna/DNA_movieclip_types.h @@ -86,7 +86,14 @@ typedef struct MovieClip { int len; /* length of movie */ - int start_frame, pad; + int start_frame; /* scene frame number footage starts playing at */ + /* affects all data which is associated with a clip */ + /* such as motion tracking, camera reconstruciton and so */ + + int frame_offset; /* offset which is adding to a file number when reading frame */ + /* from a file. affects only a way how scene frame is mapping */ + /* to a file name and not touches other data associated with */ + /* a clip */ } MovieClip; typedef struct MovieClipScopes { diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c index a4b7516a930..2a12fa8b116 100644 --- a/source/blender/makesrna/intern/rna_movieclip.c +++ b/source/blender/makesrna/intern/rna_movieclip.c @@ -286,10 +286,16 @@ static void rna_def_movieclip(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this movie clip"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); - /* frame offset */ + /* start_frame */ prop = RNA_def_property(srna, "start_frame", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "start_frame"); - RNA_def_property_ui_text(prop, "Start Frame", "Global scene frame number at which this movie starts playing"); + RNA_def_property_ui_text(prop, "Start Frame", "Global scene frame number at which this movie starts playing. Affects all data associated with a clip"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_reload_update"); + + /* frame_offset */ + prop = RNA_def_property(srna, "frame_offset", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "frame_offset"); + RNA_def_property_ui_text(prop, "Frame Offset", "Offset of footage first frame relative to it's file name. Affects only how footage is loaing, not changes data associated with a clip"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_reload_update"); } From 36ed4818e5944dfb6ae7a71377f3bee4cba5a899 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Tue, 12 Jun 2012 21:25:29 +0000 Subject: [PATCH 252/360] patch #31794 Collada: make exporter more robust, now uses BKE_object_relational_superset() --- source/blender/collada/AnimationExporter.cpp | 14 +- source/blender/collada/AnimationImporter.h | 2 + source/blender/collada/ArmatureExporter.cpp | 2 +- source/blender/collada/CameraExporter.cpp | 17 +- source/blender/collada/CameraExporter.h | 2 + source/blender/collada/DocumentExporter.cpp | 16 +- source/blender/collada/DocumentExporter.h | 4 + source/blender/collada/DocumentImporter.cpp | 3 + source/blender/collada/EffectExporter.cpp | 3 +- source/blender/collada/ExportSettings.h | 7 +- source/blender/collada/GeometryExporter.cpp | 2 +- source/blender/collada/GeometryExporter.h | 18 +-- source/blender/collada/ImageExporter.cpp | 2 +- source/blender/collada/LightExporter.cpp | 13 +- source/blender/collada/MaterialExporter.cpp | 2 +- source/blender/collada/MaterialExporter.h | 4 +- source/blender/collada/SceneExporter.cpp | 152 ++++++++---------- source/blender/collada/collada.cpp | 28 ++-- source/blender/collada/collada.h | 4 +- source/blender/collada/collada_internal.cpp | 17 +- source/blender/collada/collada_internal.h | 4 +- source/blender/collada/collada_utils.cpp | 64 ++++++++ source/blender/collada/collada_utils.h | 23 ++- .../blender/makesrna/intern/rna_scene_api.c | 6 +- .../windowmanager/intern/wm_operators.c | 10 +- 25 files changed, 244 insertions(+), 175 deletions(-) diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index 5898d5da670..beb098ba0fc 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -25,16 +25,12 @@ #include "MaterialExporter.h" template -void forEachObjectInScene(Scene *sce, Functor &f) +void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) { - Base *base= (Base*) sce->base.first; - - while (base) { - Object *ob = base->object; - + LinkNode *node; + for(node=export_set; node; node=node->next) { + Object *ob = (Object *)node->link; f(ob); - - base= base->next; } } @@ -45,7 +41,7 @@ void AnimationExporter::exportAnimations(Scene *sce) openLibrary(); - forEachObjectInScene(sce, *this); + forEachObjectInExportSet(sce, *this, this->export_settings->export_set); closeLibrary(); } diff --git a/source/blender/collada/AnimationImporter.h b/source/blender/collada/AnimationImporter.h index 6324853d91c..d6a93a36c6e 100644 --- a/source/blender/collada/AnimationImporter.h +++ b/source/blender/collada/AnimationImporter.h @@ -41,11 +41,13 @@ #include "COLLADAFWEffect.h" #include "COLLADAFWInstanceGeometry.h" +extern "C" { #include "DNA_anim_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_lamp_types.h" #include "DNA_camera_types.h" +} //#include "ArmatureImporter.h" #include "TransformReader.h" diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index 107a3fc5796..e5548acadb5 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -112,7 +112,7 @@ void ArmatureExporter::export_controllers(Scene *sce) openLibrary(); GeometryFunctor gf; - gf.forEachMeshObjectInScene(sce, *this, this->export_settings->selected); + gf.forEachMeshObjectInExportSet(sce, *this, this->export_settings->export_set); closeLibrary(); } diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp index ce46c681c8c..4e7f2f0434f 100644 --- a/source/blender/collada/CameraExporter.cpp +++ b/source/blender/collada/CameraExporter.cpp @@ -29,10 +29,10 @@ #include #include "COLLADASWCamera.h" -#include "COLLADASWCameraOptic.h" +extern "C" { #include "DNA_camera_types.h" - +} #include "CameraExporter.h" #include "collada_internal.h" @@ -40,16 +40,15 @@ CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): COLLADASW::LibraryCameras(sw), export_settings(export_settings) {} template -void forEachCameraObjectInScene(Scene *sce, Functor &f, bool export_selected) +void forEachCameraObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) { - Base *base = (Base*) sce->base.first; - while (base) { - Object *ob = base->object; + LinkNode *node; + for(node=export_set; node; node = node->next) { + Object *ob = (Object *)node->link; - if (ob->type == OB_CAMERA && ob->data && !(export_selected && !(ob->flag & SELECT))) { + if (ob->type == OB_CAMERA && ob->data) { f(ob, sce); } - base = base->next; } } @@ -57,7 +56,7 @@ void CamerasExporter::exportCameras(Scene *sce) { openLibrary(); - forEachCameraObjectInScene(sce, *this, this->export_settings->selected); + forEachCameraObjectInExportSet(sce, *this, this->export_settings->export_set); closeLibrary(); } diff --git a/source/blender/collada/CameraExporter.h b/source/blender/collada/CameraExporter.h index 1b5898984ba..5405df8ab9e 100644 --- a/source/blender/collada/CameraExporter.h +++ b/source/blender/collada/CameraExporter.h @@ -31,8 +31,10 @@ #include "COLLADASWStreamWriter.h" #include "COLLADASWLibraryCameras.h" +extern "C" { #include "DNA_object_types.h" #include "DNA_scene_types.h" +} #include "ExportSettings.h" diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index e224ffce731..4e84eba500c 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -111,7 +111,8 @@ extern char build_rev[]; #include "collada_internal.h" #include "DocumentExporter.h" -#include "ExportSettings.h" + +extern bool bc_has_object_type(LinkNode *export_set, short obtype); // can probably go after refactor is complete #include "InstanceWriter.h" @@ -227,14 +228,15 @@ void DocumentExporter::exportCurrentScene(Scene *sce) asset.getContributor().mAuthoringTool = version_buf; asset.add(); + LinkNode *export_set = this->export_settings->export_set; // - if (has_object_type(sce, OB_CAMERA)) { + if (bc_has_object_type(export_set, OB_CAMERA)) { CamerasExporter ce(&sw, this->export_settings); ce.exportCameras(sce); } // - if (has_object_type(sce, OB_LAMP)) { + if (bc_has_object_type(export_set, OB_LAMP)) { LightsExporter le(&sw, this->export_settings); le.exportLights(sce); } @@ -252,7 +254,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce) me.exportMaterials(sce); // - if (has_object_type(sce, OB_MESH)) { + if (bc_has_object_type(export_set, OB_MESH)) { GeometryExporter ge(&sw, this->export_settings); ge.exportGeom(sce); } @@ -263,10 +265,8 @@ void DocumentExporter::exportCurrentScene(Scene *sce) // ArmatureExporter arm_exporter(&sw, this->export_settings); - if (this->export_settings->include_armatures) { - if (has_object_type(sce, OB_ARMATURE)) { - arm_exporter.export_controllers(sce); - } + if (bc_has_object_type(export_set, OB_ARMATURE)) { + arm_exporter.export_controllers(sce); } // diff --git a/source/blender/collada/DocumentExporter.h b/source/blender/collada/DocumentExporter.h index 314ba2868e5..05620087d76 100644 --- a/source/blender/collada/DocumentExporter.h +++ b/source/blender/collada/DocumentExporter.h @@ -29,6 +29,10 @@ #include "ExportSettings.h" +extern "C" { +#include "DNA_customdata_types.h" +} + struct Scene; class DocumentExporter diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 6dca7828cc2..fa85e7527ff 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -49,6 +49,7 @@ #include "COLLADASaxFWLLoader.h" #include "COLLADASaxFWLIExtraDataCallbackHandler.h" +extern "C" { #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_string.h" @@ -75,6 +76,8 @@ #include "MEM_guardedalloc.h" +} + #include "ExtraHandler.h" #include "ErrorHandler.h" #include "DocumentImporter.h" diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp index 36ed6867525..644c350e8fe 100644 --- a/source/blender/collada/EffectExporter.cpp +++ b/source/blender/collada/EffectExporter.cpp @@ -31,6 +31,7 @@ #include "COLLADASWEffectProfile.h" #include "EffectExporter.h" +#include "DocumentExporter.h" #include "MaterialExporter.h" #include "DNA_mesh_types.h" @@ -82,7 +83,7 @@ void EffectsExporter::exportEffects(Scene *sce) this->scene = sce; openLibrary(); MaterialFunctor mf; - mf.forEachMaterialInScene(sce, *this, this->export_settings->selected); + mf.forEachMaterialInExportSet(sce, *this, this->export_settings->export_set); closeLibrary(); } diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h index a6ae29bf2b2..97ea6873856 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -24,6 +24,10 @@ * \ingroup collada */ +extern "C" { +#include "BLI_linklist.h" +} + #ifndef __EXPORTSETTINGS_H__ #define __EXPORTSETTINGS_H__ @@ -33,10 +37,11 @@ struct ExportSettings bool selected; bool apply_modifiers; bool include_armatures; - bool include_bone_children; + bool include_children; bool use_object_instantiation; bool second_life; char *filepath; + LinkNode *export_set; }; #endif diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 53d7f1e6449..bc06de4d56b 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -61,7 +61,7 @@ void GeometryExporter::exportGeom(Scene *sce) mScene = sce; GeometryFunctor gf; - gf.forEachMeshObjectInScene(sce, *this, this->export_settings->selected); + gf.forEachMeshObjectInExportSet(sce, *this, this->export_settings->export_set); closeLibrary(); } diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h index 23cdcc0a5ba..f14775b9f44 100644 --- a/source/blender/collada/GeometryExporter.h +++ b/source/blender/collada/GeometryExporter.h @@ -42,6 +42,8 @@ #include "ExportSettings.h" +extern Object *bc_get_highest_selected_ancestor_or_self(Object *ob); + // TODO: optimize UV sets by making indexed list with duplicates removed class GeometryExporter : COLLADASW::LibraryGeometries { @@ -112,21 +114,15 @@ struct GeometryFunctor { // f should have // void operator()(Object* ob) template - void forEachMeshObjectInScene(Scene *sce, Functor &f, bool export_selected) + void forEachMeshObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) { - - Base *base= (Base*) sce->base.first; - while (base) { - Object *ob = base->object; - - if (ob->type == OB_MESH && ob->data && - !(export_selected && !(ob->flag & SELECT)) && - ((sce->lay & ob->lay)!=0)) + LinkNode *node; + for (node=export_set; node; node = node->next) { + Object *ob = (Object *)node->link; + if (ob->type == OB_MESH) { f(ob); } - base= base->next; - } } }; diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp index 4d7c56ab419..1999c68307e 100644 --- a/source/blender/collada/ImageExporter.cpp +++ b/source/blender/collada/ImageExporter.cpp @@ -73,7 +73,7 @@ void ImagesExporter::exportImages(Scene *sce) if (hasImages(sce)) { openLibrary(); MaterialFunctor mf; - mf.forEachMaterialInScene(sce, *this, this->export_settings->selected); + mf.forEachMaterialInExportSet(sce, *this, this->export_settings->export_set); closeLibrary(); } diff --git a/source/blender/collada/LightExporter.cpp b/source/blender/collada/LightExporter.cpp index 6d276cd782f..44306616a85 100644 --- a/source/blender/collada/LightExporter.cpp +++ b/source/blender/collada/LightExporter.cpp @@ -36,16 +36,15 @@ #include "collada_internal.h" template -void forEachLampObjectInScene(Scene *sce, Functor &f, bool export_selected) +void forEachLampObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) { - Base *base= (Base*) sce->base.first; - while (base) { - Object *ob = base->object; + LinkNode *node; + for (node=export_set; node; node = node->next) { + Object *ob = (Object *)node->link; - if (ob->type == OB_LAMP && ob->data && !(export_selected && !(ob->flag & SELECT))) { + if (ob->type == OB_LAMP && ob->data) { f(ob); } - base= base->next; } } @@ -55,7 +54,7 @@ void LightsExporter::exportLights(Scene *sce) { openLibrary(); - forEachLampObjectInScene(sce, *this, this->export_settings->selected); + forEachLampObjectInExportSet(sce, *this, this->export_settings->export_set); closeLibrary(); } diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp index 48fa5b690be..ec075e7dcf8 100644 --- a/source/blender/collada/MaterialExporter.cpp +++ b/source/blender/collada/MaterialExporter.cpp @@ -39,7 +39,7 @@ void MaterialsExporter::exportMaterials(Scene *sce) openLibrary(); MaterialFunctor mf; - mf.forEachMaterialInScene(sce, *this, this->export_settings->selected); + mf.forEachMaterialInExportSet(sce, *this, this->export_settings->export_set); closeLibrary(); } diff --git a/source/blender/collada/MaterialExporter.h b/source/blender/collada/MaterialExporter.h index 4a5422184d4..f65c8849c84 100644 --- a/source/blender/collada/MaterialExporter.h +++ b/source/blender/collada/MaterialExporter.h @@ -89,11 +89,11 @@ struct MaterialFunctor { // f should have // void operator()(Material* ma) template - void forEachMaterialInScene(Scene *sce, Functor &f, bool export_selected) + void forEachMaterialInExportSet(Scene *sce, Functor &f, LinkNode *export_set) { ForEachMaterialFunctor matfunc(&f); GeometryFunctor gf; - gf.forEachMeshObjectInScene >(sce, matfunc, export_selected); + gf.forEachMeshObjectInExportSet >(sce, matfunc, export_set); } }; diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp index 510107272cd..603a700c4a9 100644 --- a/source/blender/collada/SceneExporter.cpp +++ b/source/blender/collada/SceneExporter.cpp @@ -26,6 +26,7 @@ #include "SceneExporter.h" #include "collada_utils.h" +#include "BKE_object.h" SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings) : COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings) @@ -41,112 +42,89 @@ void SceneExporter::exportScene(Scene *sce) closeLibrary(); } -// Returns true if the parent chain does not contain any selected object -// Otherwise return false (ob has selected predecessor) -bool is_exported_base_node(Object *ob, bool selection_only) { +void SceneExporter::exportHierarchy(Scene *sce) +{ + LinkNode *node; + std::vector base_objects; - if (selection_only && ob->flag & SELECT) { - // Move up towards root object, - // stop at first selected predecessor's child, - // or at root, if no parent was selected - while (ob->parent && (ob->parent->type==OB_ARMATURE || !(ob->parent->flag & SELECT))) + // Ensure all objects in the export_set are marked + for(node = this->export_settings->export_set; node; node = node->next) { + Object *ob = (Object*) node->link; + ob->id.flag |= LIB_DOIT; + } + + // Now find all exportable base ojects (highest in export hierarchy) + for(node = this->export_settings->export_set; node; node = node->next) { + Object *ob = (Object*) node->link; + if (bc_is_base_node(this->export_settings->export_set, ob)) { - ob = ob->parent; + switch (ob->type) { + case OB_MESH: + case OB_CAMERA: + case OB_LAMP: + case OB_EMPTY: + case OB_ARMATURE: + base_objects.push_back(ob); + break; + } } } - return !ob->parent; -} - -void SceneExporter::exportHierarchy(Scene *sce) -{ - Base *base= (Base*) sce->base.first; - while (base) { - Object *ob = base->object; - - bool is_export_base_node = is_exported_base_node(ob, this->export_settings->selected); - if (is_export_base_node) { - if (sce->lay & ob->lay) { - switch (ob->type) { - case OB_MESH: - case OB_CAMERA: - case OB_LAMP: - case OB_EMPTY: - if (this->export_settings->selected && !(ob->flag & SELECT)) { - break; - } - // write nodes.... - writeNodes(ob, sce); - break; - } - } + // And now export the base objects: + for(int index=0; index < base_objects.size(); index++) { + Object *ob = base_objects[index]; + if (bc_is_marked(ob)) { + bc_remove_mark(ob); + writeNodes(ob, sce); } - - base= base->next; } } void SceneExporter::writeNodes(Object *ob, Scene *sce) { - // Add associated armature first if available - if (this->export_settings->include_armatures) { - Object *ob_arm = bc_get_assigned_armature(ob); - if(ob_arm != NULL) - writeNodes(ob_arm, sce); + Object *ob_arm = bc_get_assigned_armature(ob); + if(ob_arm != NULL && bc_is_marked(ob_arm)) { + bc_remove_mark(ob_arm); + writeNodes(ob_arm, sce); } - COLLADASW::Node node(mSW); - node.setNodeId(translate_id(id_name(ob))); - node.setNodeName(translate_id(id_name(ob))); - node.setType(COLLADASW::Node::NODE); + COLLADASW::Node colladaNode(mSW); + colladaNode.setNodeId(translate_id(id_name(ob))); + colladaNode.setNodeName(translate_id(id_name(ob))); + colladaNode.setType(COLLADASW::Node::NODE); - node.start(); + colladaNode.start(); bool is_skinned_mesh = arm_exporter->is_skinned_mesh(ob); std::list child_objects; - // XXX Not sure about this. - // For me this looks more like a very special case for a very special purpose. - // Wouldn't it be better to have only one option here ? - // - // - include children - // - // Instead of "include_bone_children" ? - // then we could just ask: - // if (this->export_settings->include_children) - // ... - if (this->export_settings->include_armatures - && this->export_settings->include_bone_children) { + // list child objects + LinkNode *node = this->export_settings->export_set ; + while (node) { + // cob - child object + Object *cob = (Object *)node->link; - // list child objects - Base *b = (Base*) sce->base.first; - while (b) { - // cob - child object - Object *cob = b->object; - - if (cob->parent == ob) { - switch (cob->type) { - case OB_MESH: - case OB_CAMERA: - case OB_LAMP: - case OB_EMPTY: - case OB_ARMATURE: + if (cob->parent == ob) { + switch (cob->type) { + case OB_MESH: + case OB_CAMERA: + case OB_LAMP: + case OB_EMPTY: + case OB_ARMATURE: + if (bc_is_marked(cob)) child_objects.push_back(cob); - break; - } + break; } - - b = b->next; } + node = node->next; } - if (ob->type == OB_MESH && this->export_settings->include_armatures && is_skinned_mesh) // for skinned mesh we write obmat in - TransformWriter::add_node_transform_identity(node); + TransformWriter::add_node_transform_identity(colladaNode); else - TransformWriter::add_node_transform_ob(node, ob); + TransformWriter::add_node_transform_ob(colladaNode, ob); // if (ob->type == OB_MESH) { @@ -167,9 +145,6 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) // else if (ob->type == OB_ARMATURE) { arm_exporter->add_armature_bones(ob, sce, this, child_objects); - - // XXX this looks unstable... - node.end(); } // @@ -196,12 +171,19 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) } } - for (std::list::iterator i= child_objects.begin(); i != child_objects.end(); ++i) { - writeNodes(*i, sce); + if (ob->type == OB_ARMATURE) { + colladaNode.end(); } + for (std::list::iterator i= child_objects.begin(); i != child_objects.end(); ++i) { + if(bc_is_marked(*i)) { + bc_remove_mark(*i); + writeNodes(*i, sce); + } + } - if (ob->type != OB_ARMATURE) - node.end(); + if (ob->type != OB_ARMATURE) { + colladaNode.end(); + } } diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index e880082c9ec..b852190dd4c 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -56,20 +56,12 @@ extern "C" int apply_modifiers, int include_armatures, - int include_bone_children, + int include_children, int use_object_instantiation, int second_life ) { ExportSettings export_settings; - - export_settings.selected = selected != 0; - export_settings.apply_modifiers = apply_modifiers != 0; - export_settings.include_armatures = include_armatures != 0; - export_settings.include_bone_children = include_bone_children != 0; - export_settings.second_life = second_life != 0; - export_settings.use_object_instantiation = use_object_instantiation != 0; - export_settings.filepath = (char *)filepath; /* annoying, collada crashes if file cant be created! [#27162] */ if (!BLI_exists(filepath)) { @@ -80,9 +72,27 @@ extern "C" } /* end! */ + + export_settings.selected = selected != 0; + export_settings.apply_modifiers = apply_modifiers != 0; + export_settings.include_armatures = include_armatures != 0; + export_settings.include_children = include_children != 0; + export_settings.second_life = second_life != 0; + export_settings.use_object_instantiation = use_object_instantiation != 0; + export_settings.filepath = (char *)filepath; + + int includeFilter = OB_REL_NONE; + if (export_settings.include_armatures) includeFilter |= OB_REL_MOD_ARMATURE; + if (export_settings.include_children) includeFilter |= OB_REL_CHILDREN_RECURSIVE; + + eObjectSet objectSet = (export_settings.selected) ? OB_SET_SELECTED : OB_SET_ALL; + export_settings.export_set = BKE_object_relational_superset(sce, objectSet, (eObRelationTypes)includeFilter); + DocumentExporter exporter(&export_settings); exporter.exportCurrentScene(sce); + BLI_linklist_free(export_settings.export_set, NULL); + return 1; } } diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 646c8469e6b..da2179ca135 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -44,11 +44,13 @@ extern "C" { int apply_modifiers, int include_armatures, - int include_bone_children, + int include_children, int use_object_instantiation, int second_life); + + #ifdef __cplusplus } #endif diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index 81e5f88a3f8..06e688a93ac 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -27,9 +27,10 @@ /* COLLADABU_ASSERT, may be able to remove later */ #include "COLLADABUPlatform.h" - #include "collada_internal.h" +#include "BLI_linklist.h" + UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) {} void UnitConverter::read_asset(const COLLADAFW::FileInfo* asset) @@ -277,17 +278,3 @@ std::string get_material_id(Material *mat) { return translate_id(id_name(mat)) + "-material"; } - -bool has_object_type(Scene *sce, short obtype) -{ - Base *base= (Base*) sce->base.first; - while (base) { - Object *ob = base->object; - - if (ob->type == obtype && ob->data) { - return true; - } - base= base->next; - } - return false; -} diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h index d00af791a1f..b64c75e7960 100644 --- a/source/blender/collada/collada_internal.h +++ b/source/blender/collada/collada_internal.h @@ -39,6 +39,8 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "BLI_math.h" +#include "BLI_math.h" +#include "BLI_linklist.h" class UnitConverter { @@ -96,6 +98,4 @@ extern std::string get_camera_id(Object *ob); extern std::string get_material_id(Material *mat); -extern bool has_object_type(Scene* sce, short obtype); - #endif /* __COLLADA_INTERNAL_H__ */ diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index 8693441d7c8..c92131d5359 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -32,6 +32,8 @@ #include "COLLADAFWMeshPrimitive.h" #include "COLLADAFWMeshVertexData.h" +#include "collada_utils.h" + #include "DNA_modifier_types.h" #include "DNA_customdata_types.h" #include "DNA_object_types.h" @@ -49,6 +51,7 @@ extern "C" { #include "BKE_DerivedMesh.h" +#include "BLI_linklist.h" } #include "WM_api.h" // XXX hrm, see if we can do without this @@ -164,3 +167,64 @@ Object *bc_get_assigned_armature(Object *ob) return ob_arm; } +// Returns the highest selected ancestor +// returns NULL if no ancestor is selected +// IMPORTANT: This function expects that +// all exported objects have set: +// ob->id.flag & LIB_DOIT +Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob) +{ + Object *ancestor = ob; + while (ob->parent && bc_is_marked(ob->parent)) + { + ob = ob->parent; + ancestor = ob; + } + return ancestor; +} + +bool bc_is_base_node(LinkNode *export_set, Object *ob) +{ + Object *root = bc_get_highest_selected_ancestor_or_self(export_set, ob); + return (root == ob); +} + +bool bc_is_in_Export_set(LinkNode *export_set, Object *ob) +{ + LinkNode *node = export_set; + + while (node) { + Object *element = (Object *)node->link; + + if (element == ob) + return true; + + node= node->next; + } + return false; +} + +bool bc_has_object_type(LinkNode *export_set, short obtype) +{ + LinkNode *node = export_set; + + while (node) { + Object *ob = (Object *)node->link; + + if (ob->type == obtype && ob->data) { + return true; + } + node= node->next; + } + return false; +} + +int bc_is_marked(Object *ob) +{ + return ob && (ob->id.flag & LIB_DOIT); +} + +void bc_remove_mark(Object *ob) +{ + ob->id.flag &= ~LIB_DOIT; +} diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 9882b44d94c..71365ffb8d0 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -40,18 +40,35 @@ #include "DNA_customdata_types.h" #include "DNA_texture_types.h" #include "BKE_context.h" +#include "BKE_object.h" + #include "DNA_scene_types.h" +extern "C" { +#include "BKE_DerivedMesh.h" +#include "BLI_linklist.h" +} + +#include "ExportSettings.h" + typedef std::map > TexIndexTextureArrayMap; extern float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index); - extern int bc_test_parent_loop(Object *par, Object *ob); extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space=true); -extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n); -extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); extern Object *bc_add_object(Scene *scene, int type, const char *name); extern Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob); + extern Object *bc_get_assigned_armature(Object *ob); +extern Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob); +extern bool bc_is_base_node(LinkNode *export_set, Object *ob); +extern bool bc_is_in_Export_set(LinkNode *export_set, Object *ob); +extern bool bc_has_object_type(LinkNode *export_set, short obtype); + +extern int bc_is_marked(Object *ob); +extern void bc_remove_mark(Object *ob); + +extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n); +extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); #endif diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index b2ff36285e6..8d18f9dd1c2 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -91,12 +91,12 @@ static void rna_Scene_collada_export( int selected, int apply_modifiers, int include_armatures, - int include_bone_children, + int include_children, int use_object_instantiation, int second_life) { collada_export(scene, filepath, selected, apply_modifiers, - include_armatures, include_bone_children, + include_armatures, include_children, use_object_instantiation, second_life); } @@ -128,7 +128,7 @@ void RNA_api_scene(StructRNA *srna) parm = RNA_def_boolean(func, "selected", 0, "Selection Only", "Export only selected elements"); parm = RNA_def_boolean(func, "apply_modifiers", 0, "Apply Modifiers", "Apply modifiers (in Preview resolution)"); parm = RNA_def_boolean(func, "include_armatures", 0, "Include Armatures", "Include armature(s) used by the exported objects"); - parm = RNA_def_boolean(func, "include_bone_children", 0, "Include Bone Children", "Include all objects attached to bones of selected Armature(s)"); + parm = RNA_def_boolean(func, "include_children", 0, "Include Children", "Include all children even if not selected"); parm = RNA_def_boolean(func, "use_object_instantiation", 1, "Use Object Instantiation", "Instantiate multiple Objects from same Data"); parm = RNA_def_boolean(func, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life"); RNA_def_function_ui_description(func, "Export to collada file"); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 425baac25fd..5f4a536d18f 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2165,7 +2165,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) int selected, second_life, include_armatures, apply_modifiers, - include_bone_children, + include_children, use_object_instantiation; if (!RNA_struct_property_is_set(op->ptr, "filepath")) { @@ -2179,7 +2179,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) selected = RNA_boolean_get(op->ptr, "selected"); apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers"); include_armatures = RNA_boolean_get(op->ptr, "include_armatures"); - include_bone_children = RNA_boolean_get(op->ptr, "include_bone_children"); + include_children = RNA_boolean_get(op->ptr, "include_children"); use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation"); second_life = RNA_boolean_get(op->ptr, "second_life"); @@ -2192,7 +2192,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) selected, apply_modifiers, include_armatures, - include_bone_children, + include_children, use_object_instantiation, second_life)) { return OPERATOR_FINISHED; @@ -2225,8 +2225,8 @@ static void WM_OT_collada_export(wmOperatorType *ot) RNA_def_boolean(ot->srna, "include_armatures", 0, "Include Armatures", "Include armature(s) used by the exported objects"); - RNA_def_boolean(ot->srna, "include_bone_children", 0, "Include Bone Children", - "Include all objects attached to bones of selected Armature(s)"); + RNA_def_boolean(ot->srna, "include_children", 0, "Include Children", + "Include all children even if not selected"); RNA_def_boolean(ot->srna, "use_object_instantiation", 1, "Use Object Instantiation", "Instantiate multiple Objects from same Data"); From 46c95d37c6fae2268a7f39f90ef46e9c3c696e3f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 12 Jun 2012 21:29:15 +0000 Subject: [PATCH 253/360] Default value for frame offset should be 0 --- source/blender/blenkernel/intern/movieclip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index d6fa39fd789..adf1a2fd9a8 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -446,7 +446,7 @@ static MovieClip *movieclip_alloc(const char *name) clip->proxy.quality = 90; clip->start_frame = 1; - clip->frame_offset = 1; + clip->frame_offset = 0; return clip; } From 2e8a2f7668e5687a0a9a5087e76eeb739c818b2b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 12 Jun 2012 22:05:33 +0000 Subject: [PATCH 254/360] style cleanup --- source/blender/blenkernel/BKE_object.h | 14 +- source/blender/blenkernel/intern/object.c | 37 +- source/blender/collada/AnimationExporter.cpp | 227 ++++--- source/blender/collada/AnimationImporter.cpp | 641 +++++++++--------- source/blender/collada/ArmatureExporter.cpp | 108 +-- source/blender/collada/ArmatureImporter.cpp | 92 ++- source/blender/collada/CameraExporter.cpp | 52 +- source/blender/collada/DocumentExporter.cpp | 24 +- source/blender/collada/DocumentImporter.cpp | 355 +++++----- source/blender/collada/EffectExporter.cpp | 49 +- source/blender/collada/ErrorHandler.cpp | 22 +- source/blender/collada/ExtraHandler.cpp | 44 +- source/blender/collada/ExtraTags.cpp | 12 +- source/blender/collada/GeometryExporter.cpp | 69 +- source/blender/collada/ImageExporter.cpp | 10 +- source/blender/collada/InstanceWriter.cpp | 6 +- source/blender/collada/LightExporter.cpp | 9 +- source/blender/collada/MaterialExporter.cpp | 11 +- source/blender/collada/MeshImporter.cpp | 312 ++++----- source/blender/collada/SceneExporter.cpp | 27 +- source/blender/collada/SkinInfo.cpp | 56 +- source/blender/collada/TransformReader.cpp | 19 +- source/blender/collada/TransformWriter.cpp | 14 +- source/blender/collada/collada.cpp | 108 +-- source/blender/collada/collada_internal.cpp | 147 ++-- source/blender/collada/collada_utils.cpp | 16 +- .../blender/makesrna/intern/rna_scene_api.c | 18 +- .../windowmanager/intern/wm_operators.c | 48 +- 28 files changed, 1293 insertions(+), 1254 deletions(-) diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 29979f62d60..b8ba3095905 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -161,13 +161,13 @@ struct MovieClip *BKE_object_movieclip_get(struct Scene *scene, struct Object *o /* this function returns a superset of the scenes selection based on relationships */ typedef enum eObRelationTypes { - OB_REL_NONE = 0, /* just the selection as is */ - OB_REL_PARENT = (1<<0), /* immediate parent */ - OB_REL_PARENT_RECURSIVE = (1<<1), /* parents up to root of selection tree*/ - OB_REL_CHILDREN = (1<<2), /* immediate children */ - OB_REL_CHILDREN_RECURSIVE = (1<<3), /* All children */ - OB_REL_MOD_ARMATURE = (1<<4), /* Armatures related to the selected objects */ - OB_REL_SCENE_CAMERA = (1<<5), /* you might want the scene camera too even if unselected? */ + OB_REL_NONE = 0, /* just the selection as is */ + OB_REL_PARENT = (1 << 0), /* immediate parent */ + OB_REL_PARENT_RECURSIVE = (1 << 1), /* parents up to root of selection tree*/ + OB_REL_CHILDREN = (1 << 2), /* immediate children */ + OB_REL_CHILDREN_RECURSIVE = (1 << 3), /* All children */ + OB_REL_MOD_ARMATURE = (1 << 4), /* Armatures related to the selected objects */ + OB_REL_SCENE_CAMERA = (1 << 5), /* you might want the scene camera too even if unselected? */ } eObRelationTypes; typedef enum eObjectSet { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 91fd5811911..1f5ba8ae305 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -3090,13 +3090,11 @@ static Object *obrel_armature_find(Object *ob) ob_arm = ob->parent; } else { - ModifierData *mod = (ModifierData*)ob->modifiers.first; - while (mod) { + ModifierData *mod; + for (mod = (ModifierData *)ob->modifiers.first; mod; mod = mod->next) { if (mod->type == eModifierType_Armature) { - ob_arm = ((ArmatureModifierData*)mod)->object; + ob_arm = ((ArmatureModifierData *)mod)->object; } - - mod = mod->next; } } @@ -3104,11 +3102,11 @@ static Object *obrel_armature_find(Object *ob) } static int obrel_is_recursive_child(Object *ob, Object *child) { - Object *ancestor = child->parent; - while (ancestor) - { - if(ancestor == ob) return TRUE; - ancestor = ancestor->parent; + Object *par; + for (par = child->parent; par; par = par->parent) { + if (par == ob) { + return TRUE; + } } return FALSE; } @@ -3151,16 +3149,16 @@ struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet obrel_list_add(&links, ob); } else { - if ( (objectSet == OB_SET_SELECTED && TESTBASELIB_BGMODE(((View3D *)NULL), scene, base)) - || (objectSet == OB_SET_VISIBLE && BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, base)) - ) { + if ((objectSet == OB_SET_SELECTED && TESTBASELIB_BGMODE(((View3D *)NULL), scene, base)) || + (objectSet == OB_SET_VISIBLE && BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, base))) + { Object *ob = base->object; if (obrel_list_test(ob)) obrel_list_add(&links, ob); /* parent relationship */ - if (includeFilter & ( OB_REL_PARENT | OB_REL_PARENT_RECURSIVE )) { + if (includeFilter & (OB_REL_PARENT | OB_REL_PARENT_RECURSIVE)) { Object *parent = ob->parent; if (obrel_list_test(parent)) { @@ -3169,7 +3167,7 @@ struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet /* recursive parent relationship */ if (includeFilter & OB_REL_PARENT_RECURSIVE) { parent = parent->parent; - while (obrel_list_test(parent)){ + while (obrel_list_test(parent)) { obrel_list_add(&links, parent); parent = parent->parent; @@ -3179,15 +3177,16 @@ struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet } /* child relationship */ - if (includeFilter & ( OB_REL_CHILDREN | OB_REL_CHILDREN_RECURSIVE )) { + if (includeFilter & (OB_REL_CHILDREN | OB_REL_CHILDREN_RECURSIVE)) { Base *local_base; for (local_base = scene->base.first; local_base; local_base = local_base->next) { if (BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, local_base)) { Object *child = local_base->object; if (obrel_list_test(child)) { - if ((includeFilter & OB_REL_CHILDREN_RECURSIVE && obrel_is_recursive_child(ob,child)) - || (includeFilter & OB_REL_CHILDREN && child->parent && child->parent == ob )) { + if ((includeFilter & OB_REL_CHILDREN_RECURSIVE && obrel_is_recursive_child(ob, child)) || + (includeFilter & OB_REL_CHILDREN && child->parent && child->parent == ob)) + { obrel_list_add(&links, child); } } @@ -3206,7 +3205,7 @@ struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet } } - } // end for + } return links; } diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index beb098ba0fc..cb675618ea5 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -28,7 +28,7 @@ template void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) { LinkNode *node; - for(node=export_set; node; node=node->next) { + for (node = export_set; node; node = node->next) { Object *ob = (Object *)node->link; f(ob); } @@ -48,7 +48,7 @@ void AnimationExporter::exportAnimations(Scene *sce) } // called for each exported object -void AnimationExporter::operator() (Object *ob) +void AnimationExporter::operator()(Object *ob) { FCurve *fcu; char *transformName; @@ -56,24 +56,24 @@ void AnimationExporter::operator() (Object *ob) //Export transform animations if (ob->adt && ob->adt->action) { - fcu = (FCurve*)ob->adt->action->curves.first; + fcu = (FCurve *)ob->adt->action->curves.first; //transform matrix export for bones are temporarily disabled here. - if ( ob->type == OB_ARMATURE ) { - bArmature *arm = (bArmature*)ob->data; - for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) + if (ob->type == OB_ARMATURE) { + bArmature *arm = (bArmature *)ob->data; + for (Bone *bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) write_bone_animation_matrix(ob, bone); } while (fcu) { //for armature animations as objects - if ( ob->type == OB_ARMATURE ) + if (ob->type == OB_ARMATURE) transformName = fcu->rna_path; else - transformName = extract_transform_name( fcu->rna_path ); + transformName = extract_transform_name(fcu->rna_path); if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) || - (!strcmp(transformName, "rotation_euler") && ob->rotmode == ROT_MODE_EUL)|| + (!strcmp(transformName, "rotation_euler") && ob->rotmode == ROT_MODE_EUL) || (!strcmp(transformName, "rotation_quaternion"))) { dae_animation(ob, fcu, transformName, false); @@ -84,12 +84,12 @@ void AnimationExporter::operator() (Object *ob) } //Export Lamp parameter animations - if ( (ob->type == OB_LAMP ) && ((Lamp*)ob ->data)->adt && ((Lamp*)ob ->data)->adt->action ) { - fcu = (FCurve*)(((Lamp*)ob ->data)->adt->action->curves.first); + if ( (ob->type == OB_LAMP) && ((Lamp *)ob->data)->adt && ((Lamp *)ob->data)->adt->action) { + fcu = (FCurve *)(((Lamp *)ob->data)->adt->action->curves.first); while (fcu) { - transformName = extract_transform_name( fcu->rna_path ); + transformName = extract_transform_name(fcu->rna_path); - if ((!strcmp(transformName, "color")) || (!strcmp(transformName, "spot_size"))|| + if ((!strcmp(transformName, "color")) || (!strcmp(transformName, "spot_size")) || (!strcmp(transformName, "spot_blend")) || (!strcmp(transformName, "distance"))) { dae_animation(ob, fcu, transformName, true); @@ -99,14 +99,14 @@ void AnimationExporter::operator() (Object *ob) } //Export Camera parameter animations - if ( (ob->type == OB_CAMERA ) && ((Camera*)ob ->data)->adt && ((Camera*)ob ->data)->adt->action ) { - fcu = (FCurve*)(((Camera*)ob ->data)->adt->action->curves.first); + if ( (ob->type == OB_CAMERA) && ((Camera *)ob->data)->adt && ((Camera *)ob->data)->adt->action) { + fcu = (FCurve *)(((Camera *)ob->data)->adt->action->curves.first); while (fcu) { - transformName = extract_transform_name( fcu->rna_path ); + transformName = extract_transform_name(fcu->rna_path); - if ((!strcmp(transformName, "lens"))|| - (!strcmp(transformName, "ortho_scale"))|| - (!strcmp(transformName, "clip_end"))||(!strcmp(transformName, "clip_start"))) + if ((!strcmp(transformName, "lens")) || + (!strcmp(transformName, "ortho_scale")) || + (!strcmp(transformName, "clip_end")) || (!strcmp(transformName, "clip_start"))) { dae_animation(ob, fcu, transformName, true); } @@ -116,19 +116,19 @@ void AnimationExporter::operator() (Object *ob) //Export Material parameter animations. for (int a = 0; a < ob->totcol; a++) { - Material *ma = give_current_material(ob, a+1); + Material *ma = give_current_material(ob, a + 1); if (!ma) continue; if (ma->adt && ma->adt->action) { /* isMatAnim = true; */ - fcu = (FCurve*)ma->adt->action->curves.first; + fcu = (FCurve *)ma->adt->action->curves.first; while (fcu) { - transformName = extract_transform_name( fcu->rna_path ); + transformName = extract_transform_name(fcu->rna_path); - if ((!strcmp(transformName, "specular_hardness"))||(!strcmp(transformName, "specular_color")) || - (!strcmp(transformName, "diffuse_color"))||(!strcmp(transformName, "alpha")) || - (!strcmp(transformName, "ior"))) + if ((!strcmp(transformName, "specular_hardness")) || (!strcmp(transformName, "specular_color")) || + (!strcmp(transformName, "diffuse_color")) || (!strcmp(transformName, "alpha")) || + (!strcmp(transformName, "ior"))) { - dae_animation(ob, fcu, transformName, true, ma ); + dae_animation(ob, fcu, transformName, true, ma); } fcu = fcu->next; } @@ -138,33 +138,33 @@ void AnimationExporter::operator() (Object *ob) } //euler sources from quternion sources -float * AnimationExporter::get_eul_source_for_quat(Object *ob ) +float *AnimationExporter::get_eul_source_for_quat(Object *ob) { - FCurve *fcu = (FCurve*)ob->adt->action->curves.first; + FCurve *fcu = (FCurve *)ob->adt->action->curves.first; const int keys = fcu->totvert; - float *quat = (float*)MEM_callocN(sizeof(float) * fcu->totvert * 4, "quat output source values"); - float *eul = (float*)MEM_callocN(sizeof(float) * fcu->totvert * 3, "quat output source values"); + float *quat = (float *)MEM_callocN(sizeof(float) * fcu->totvert * 4, "quat output source values"); + float *eul = (float *)MEM_callocN(sizeof(float) * fcu->totvert * 3, "quat output source values"); float temp_quat[4]; float temp_eul[3]; while (fcu) { - char * transformName = extract_transform_name( fcu->rna_path ); + char *transformName = extract_transform_name(fcu->rna_path); - if ( !strcmp(transformName, "rotation_quaternion") ) { - for ( int i = 0 ; i < fcu->totvert ; i++) { - *(quat + ( i * 4 ) + fcu->array_index) = fcu->bezt[i].vec[1][1]; + if (!strcmp(transformName, "rotation_quaternion") ) { + for (int i = 0; i < fcu->totvert; i++) { + *(quat + (i * 4) + fcu->array_index) = fcu->bezt[i].vec[1][1]; } } fcu = fcu->next; } - for ( int i = 0 ; i < keys ; i++) { - for ( int j = 0;j<4;j++) - temp_quat[j] = quat[(i*4)+j]; + for (int i = 0; i < keys; i++) { + for (int j = 0; j < 4; j++) + temp_quat[j] = quat[(i * 4) + j]; quat_to_eul(temp_eul, temp_quat); - for (int k = 0;k<3;k++) - eul[i*3 + k] = temp_eul[k]; + for (int k = 0; k < 3; k++) + eul[i * 3 + k] = temp_eul[k]; } MEM_freeN(quat); @@ -173,22 +173,22 @@ float * AnimationExporter::get_eul_source_for_quat(Object *ob ) } //Get proper name for bones -std::string AnimationExporter::getObjectBoneName( Object* ob, const FCurve* fcu ) +std::string AnimationExporter::getObjectBoneName(Object *ob, const FCurve *fcu) { //hard-way to derive the bone name from rna_path. Must find more compact method std::string rna_path = std::string(fcu->rna_path); - char* boneName = strtok((char *)rna_path.c_str(), "\""); + char *boneName = strtok((char *)rna_path.c_str(), "\""); boneName = strtok(NULL, "\""); - if ( boneName != NULL ) + if (boneName != NULL) return /*id_name(ob) + "_" +*/ std::string(boneName); else return id_name(ob); } //convert f-curves to animation curves and write -void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformName, bool is_param, Material * ma ) +void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformName, bool is_param, Material *ma) { const char *axis_name = NULL; char anim_id[200]; @@ -196,15 +196,15 @@ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformNa bool has_tangents = false; bool quatRotation = false; - if ( !strcmp(transformName, "rotation_quaternion") ) { + if (!strcmp(transformName, "rotation_quaternion") ) { fprintf(stderr, "quaternion rotation curves are not supported. rotation curve will not be exported\n"); quatRotation = true; return; } //axis names for colors - else if ( !strcmp(transformName, "color")||!strcmp(transformName, "specular_color")||!strcmp(transformName, "diffuse_color")|| - (!strcmp(transformName, "alpha"))) + else if (!strcmp(transformName, "color") || !strcmp(transformName, "specular_color") || !strcmp(transformName, "diffuse_color") || + (!strcmp(transformName, "alpha"))) { const char *axis_names[] = {"R", "G", "B"}; if (fcu->array_index < 3) @@ -213,7 +213,7 @@ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformNa //axis names for transforms else if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) || - (!strcmp(transformName, "rotation_euler"))||(!strcmp(transformName, "rotation_quaternion"))) + (!strcmp(transformName, "rotation_euler")) || (!strcmp(transformName, "rotation_quaternion"))) { const char *axis_names[] = {"X", "Y", "Z"}; if (fcu->array_index < 3) @@ -229,16 +229,16 @@ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformNa //Create anim Id if (ob->type == OB_ARMATURE) { ob_name = getObjectBoneName(ob, fcu); - BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s.%s", (char*)translate_id(ob_name).c_str(), - transformName, axis_name); + BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s.%s", (char *)translate_id(ob_name).c_str(), + transformName, axis_name); } else { if (ma) ob_name = id_name(ob) + "_material"; else ob_name = id_name(ob); - BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(), - fcu->rna_path, axis_name); + BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(), + fcu->rna_path, axis_name); } openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING); @@ -252,16 +252,16 @@ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformNa //quat rotations are skipped for now, because of complications with determining axis. if (quatRotation) { float *eul = get_eul_source_for_quat(ob); - float *eul_axis = (float*)MEM_callocN(sizeof(float) * fcu->totvert, "quat output source values"); - for (int i = 0 ; i< fcu->totvert ; i++) { - eul_axis[i] = eul[i*3 + fcu->array_index]; + float *eul_axis = (float *)MEM_callocN(sizeof(float) * fcu->totvert, "quat output source values"); + for (int i = 0; i < fcu->totvert; i++) { + eul_axis[i] = eul[i * 3 + fcu->array_index]; } - output_id= create_source_from_array(COLLADASW::InputSemantic::OUTPUT, eul_axis, fcu->totvert, quatRotation, anim_id, axis_name); + output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, eul_axis, fcu->totvert, quatRotation, anim_id, axis_name); MEM_freeN(eul); MEM_freeN(eul_axis); } else { - output_id= create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name); + output_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name); } // create interpolations source std::string interpolation_id = create_interpolation_source(fcu, anim_id, axis_name, &has_tangents); @@ -296,21 +296,21 @@ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu, char* transformNa std::string target; - if ( !is_param ) + if (!is_param) target = translate_id(ob_name) + "/" + get_transform_sid(fcu->rna_path, -1, axis_name, true); else { - if ( ob->type == OB_LAMP ) + if (ob->type == OB_LAMP) target = get_light_id(ob) + "/" + get_light_param_sid(fcu->rna_path, -1, axis_name, true); - if ( ob->type == OB_CAMERA ) + if (ob->type == OB_CAMERA) target = get_camera_id(ob) + "/" + get_camera_param_sid(fcu->rna_path, -1, axis_name, true); - if ( ma ) + if (ma) target = translate_id(id_name(ma)) + "-effect" + - "/common/" /*profile common is only supported */ + get_transform_sid(fcu->rna_path, -1, axis_name, true); + "/common/" /*profile common is only supported */ + get_transform_sid(fcu->rna_path, -1, axis_name, true); } addChannel(COLLADABU::URI(empty, sampler_id), target); @@ -330,18 +330,18 @@ void AnimationExporter::write_bone_animation_matrix(Object *ob_arm, Bone *bone) sample_and_write_bone_animation_matrix(ob_arm, bone); - for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) write_bone_animation_matrix(ob_arm, child); } -bool AnimationExporter::is_bone_deform_group(Bone * bone) +bool AnimationExporter::is_bone_deform_group(Bone *bone) { bool is_def; //Check if current bone is deform - if ((bone->flag & BONE_NO_DEFORM) == 0 ) return true; + if ((bone->flag & BONE_NO_DEFORM) == 0) return true; //Check child bones else { - for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) { + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { //loop through all the children until deform bone is found, and then return is_def = is_bone_deform_group(child); if (is_def) return true; @@ -353,16 +353,16 @@ bool AnimationExporter::is_bone_deform_group(Bone * bone) void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, Bone *bone) { - bArmature *arm = (bArmature*)ob_arm->data; + bArmature *arm = (bArmature *)ob_arm->data; int flag = arm->flag; std::vector fra; //char prefix[256]; - FCurve* fcu = (FCurve*)ob_arm->adt->action->curves.first; + FCurve *fcu = (FCurve *)ob_arm->adt->action->curves.first; while (fcu) { std::string bone_name = getObjectBoneName(ob_arm, fcu); - int val = BLI_strcasecmp((char*)bone_name.c_str(), bone->name); - if (val==0) break; + int val = BLI_strcasecmp((char *)bone_name.c_str(), bone->name); + if (val == 0) break; fcu = fcu->next; } @@ -379,7 +379,7 @@ void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, B } if (fra.size()) { - dae_baked_animation(fra, ob_arm, bone ); + dae_baked_animation(fra, ob_arm, bone); } if (flag & ARM_RESTPOS) @@ -396,8 +396,8 @@ void AnimationExporter::dae_baked_animation(std::vector &fra, Object *ob_ if (!fra.size()) return; - BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(), - (char*)translate_id(bone_name).c_str(), "pose_matrix"); + BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(), + (char *)translate_id(bone_name).c_str(), "pose_matrix"); openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING); @@ -406,7 +406,7 @@ void AnimationExporter::dae_baked_animation(std::vector &fra, Object *ob_ // create output source std::string output_id; - output_id = create_4x4_source( fra, ob_arm, bone, anim_id); + output_id = create_4x4_source(fra, ob_arm, bone, anim_id); // create interpolations source std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, ""); @@ -444,15 +444,15 @@ void AnimationExporter::dae_bone_animation(std::vector &fra, float *value char rna_path[200]; BLI_snprintf(rna_path, sizeof(rna_path), "pose.bones[\"%s\"].%s", bone_name.c_str(), - tm_type == 0 ? "rotation_quaternion" : (tm_type == 1 ? "scale" : "location")); + tm_type == 0 ? "rotation_quaternion" : (tm_type == 1 ? "scale" : "location")); if (axis > -1) axis_name = axis_names[axis]; std::string transform_sid = get_transform_sid(NULL, tm_type, axis_name, false); - BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(), - (char*)translate_id(bone_name).c_str(), (char*)transform_sid.c_str()); + BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(), + (char *)translate_id(bone_name).c_str(), (char *)transform_sid.c_str()); openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING); @@ -518,7 +518,7 @@ std::string AnimationExporter::get_semantic_suffix(COLLADASW::InputSemantic::Sem } void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param, - COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis, bool transform) + COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis, bool transform) { switch (semantic) { case COLLADASW::InputSemantic::INPUT: @@ -533,14 +533,14 @@ void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNa param.push_back(axis); } else - if ( transform ) { - param.push_back("TRANSFORM"); - } - else { //assumes if axis isn't specified all axises are added - param.push_back("X"); - param.push_back("Y"); - param.push_back("Z"); - } + if (transform) { + param.push_back("TRANSFORM"); + } + else { //assumes if axis isn't specified all axises are added + param.push_back("X"); + param.push_back("Y"); + param.push_back("Z"); + } } break; case COLLADASW::InputSemantic::IN_TANGENT: @@ -706,7 +706,7 @@ std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemanti //if (semantic == COLLADASW::InputSemantic::INPUT) val = convert_time(val); /*else if (is_rot) - val = convert_angle(val);*/ + val = convert_angle(val);*/ source.appendValues(val); } @@ -715,7 +715,7 @@ std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemanti return source_id; } -std::string AnimationExporter::create_4x4_source(std::vector &frames, Object * ob_arm, Bone *bone, const std::string& anim_id) +std::string AnimationExporter::create_4x4_source(std::vector &frames, Object *ob_arm, Bone *bone, const std::string& anim_id) { COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT; std::string source_id = anim_id + get_semantic_suffix(semantic); @@ -843,11 +843,11 @@ std::string AnimationExporter::create_interpolation_source(FCurve *fcu, const st *has_tangents = false; for (unsigned int i = 0; i < fcu->totvert; i++) { - if (fcu->bezt[i].ipo==BEZT_IPO_BEZ) { + if (fcu->bezt[i].ipo == BEZT_IPO_BEZ) { source.appendValues(BEZIER_NAME); *has_tangents = true; } - else if (fcu->bezt[i].ipo==BEZT_IPO_CONST) { + else if (fcu->bezt[i].ipo == BEZT_IPO_CONST) { source.appendValues(STEP_NAME); } else { // BEZT_IPO_LIN @@ -987,7 +987,7 @@ std::string AnimationExporter::get_camera_param_sid(char *rna_path, int tm_type, std::string AnimationExporter::get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis) { std::string tm_name; - bool is_rotation =false; + bool is_rotation = false; // when given rna_path, determine tm_type from it if (rna_path) { char *name = extract_transform_name(rna_path); @@ -1052,16 +1052,16 @@ std::string AnimationExporter::get_transform_sid(char *rna_path, int tm_type, co if (is_rotation) return tm_name + std::string(axis_name) + ".ANGLE"; else - if (axis_name[0]) - return tm_name + "." + std::string(axis_name); - else - return tm_name; + if (axis_name[0]) + return tm_name + "." + std::string(axis_name); + else + return tm_name; } return std::string(""); } -char* AnimationExporter::extract_transform_name(char *rna_path) +char *AnimationExporter::extract_transform_name(char *rna_path) { char *dot = strrchr(rna_path, '.'); return dot ? (dot + 1) : rna_path; @@ -1070,7 +1070,7 @@ char* AnimationExporter::extract_transform_name(char *rna_path) //find keyframes of all the objects animations void AnimationExporter::find_frames(Object *ob, std::vector &fra) { - FCurve *fcu= (FCurve*)ob->adt->action->curves.first; + FCurve *fcu = (FCurve *)ob->adt->action->curves.first; for (; fcu; fcu = fcu->next) { @@ -1097,7 +1097,7 @@ void AnimationExporter::enable_fcurves(bAction *act, char *bone_name) if (bone_name) BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone_name); - for (fcu = (FCurve*)act->curves.first; fcu; fcu = fcu->next) { + for (fcu = (FCurve *)act->curves.first; fcu; fcu = fcu->next) { if (bone_name) { if (!strncmp(fcu->rna_path, prefix, strlen(prefix))) fcu->flag &= ~FCURVE_DISABLED; @@ -1110,9 +1110,10 @@ void AnimationExporter::enable_fcurves(bAction *act, char *bone_name) } } +/* TODO - only check NodeLink objects that are exported */ bool AnimationExporter::hasAnimations(Scene *sce) { - Base *base= (Base*) sce->base.first; + Base *base = (Base *) sce->base.first; while (base) { Object *ob = base->object; @@ -1120,26 +1121,26 @@ bool AnimationExporter::hasAnimations(Scene *sce) FCurve *fcu = 0; //Check for object transform animations if (ob->adt && ob->adt->action) - fcu = (FCurve*)ob->adt->action->curves.first; + fcu = (FCurve *)ob->adt->action->curves.first; //Check for Lamp parameter animations - else if ( (ob->type == OB_LAMP ) && ((Lamp*)ob ->data)->adt && ((Lamp*)ob ->data)->adt->action ) - fcu = (FCurve*)(((Lamp*)ob ->data)->adt->action->curves.first); + else if ( (ob->type == OB_LAMP) && ((Lamp *)ob->data)->adt && ((Lamp *)ob->data)->adt->action) + fcu = (FCurve *)(((Lamp *)ob->data)->adt->action->curves.first); //Check for Camera parameter animations - else if ( (ob->type == OB_CAMERA ) && ((Camera*)ob ->data)->adt && ((Camera*)ob ->data)->adt->action ) - fcu = (FCurve*)(((Camera*)ob ->data)->adt->action->curves.first); + else if ( (ob->type == OB_CAMERA) && ((Camera *)ob->data)->adt && ((Camera *)ob->data)->adt->action) + fcu = (FCurve *)(((Camera *)ob->data)->adt->action->curves.first); //Check Material Effect parameter animations. for (int a = 0; a < ob->totcol; a++) { - Material *ma = give_current_material(ob, a+1); + Material *ma = give_current_material(ob, a + 1); if (!ma) continue; if (ma->adt && ma->adt->action) { - fcu = (FCurve*)ma->adt->action->curves.first; + fcu = (FCurve *)ma->adt->action->curves.first; } } - if ( fcu) + if (fcu) return true; - base= base->next; + base = base->next; } return false; } @@ -1152,12 +1153,12 @@ void AnimationExporter::find_rotation_frames(Object *ob, std::vector &fra else if (rotmode == ROT_MODE_QUAT) find_frames(ob, fra, prefix, "rotation_quaternion"); /*else if (rotmode == ROT_MODE_AXISANGLE) - ;*/ + ;*/ } void AnimationExporter::find_frames(Object *ob, std::vector &fra, const char *prefix, const char *tm_name) { - FCurve *fcu= (FCurve*)ob->adt->action->curves.first; + FCurve *fcu = (FCurve *)ob->adt->action->curves.first; for (; fcu; fcu = fcu->next) { if (prefix && strncmp(prefix, fcu->rna_path, strlen(prefix))) @@ -1189,13 +1190,13 @@ void AnimationExporter::write_bone_animation(Object *ob_arm, Bone *bone) for (int i = 0; i < 3; i++) sample_and_write_bone_animation(ob_arm, bone, i); - for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) write_bone_animation(ob_arm, child); } void AnimationExporter::sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type) { - bArmature *arm = (bArmature*)ob_arm->data; + bArmature *arm = (bArmature *)ob_arm->data; int flag = arm->flag; std::vector fra; char prefix[256]; @@ -1227,12 +1228,12 @@ void AnimationExporter::sample_and_write_bone_animation(Object *ob_arm, Bone *bo } //v array will hold all values which will be exported. if (fra.size()) { - float *values = (float*)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames"); + float *values = (float *)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames"); sample_animation(values, fra, transform_type, bone, ob_arm, pchan); if (transform_type == 0) { // write x, y, z curves separately if it is rotation - float *axisValues = (float*)MEM_callocN(sizeof(float) * fra.size(), "temp. anim frames"); + float *axisValues = (float *)MEM_callocN(sizeof(float) * fra.size(), "temp. anim frames"); for (int i = 0; i < 3; i++) { for (unsigned int j = 0; j < fra.size(); j++) diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp index 45d7d4a7684..625804e4ecd 100644 --- a/source/blender/collada/AnimationImporter.cpp +++ b/source/blender/collada/AnimationImporter.cpp @@ -62,8 +62,8 @@ static const char *bc_get_joint_name(T *node) FCurve *AnimationImporter::create_fcurve(int array_index, const char *rna_path) { - FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve"); - fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED); + FCurve *fcu = (FCurve *)MEM_callocN(sizeof(FCurve), "FCurve"); + fcu->flag = (FCURVE_VISIBLE | FCURVE_AUTO_HANDLES | FCURVE_SELECTED); fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path)); fcu->array_index = array_index; return fcu; @@ -92,18 +92,18 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve) size_t dim = curve->getOutDimension(); unsigned int i; - std::vector& fcurves = curve_map[curve->getUniqueId()]; + std::vector& fcurves = curve_map[curve->getUniqueId()]; switch (dim) { - case 1: // X, Y, Z or angle - case 3: // XYZ - case 4: - case 16: // matrix + case 1: // X, Y, Z or angle + case 3: // XYZ + case 4: + case 16: // matrix { - for (i = 0; i < dim; i++ ) { - FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve"); + for (i = 0; i < dim; i++) { + FCurve *fcu = (FCurve *)MEM_callocN(sizeof(FCurve), "FCurve"); - fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED); + fcu->flag = (FCURVE_VISIBLE | FCURVE_AUTO_HANDLES | FCURVE_SELECTED); // fcu->rna_path = BLI_strdupn(path, strlen(path)); fcu->array_index = 0; fcu->totvert = curve->getKeyCount(); @@ -119,19 +119,19 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve) bez.vec[1][1] = bc_get_float_value(output, j * dim + i); - if ( curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER || - curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_STEP) + if (curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER || + curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_STEP) { COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues(); COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues(); // intangent - bez.vec[0][0] = bc_get_float_value(intan, (j * 2 * dim ) + (2 * i)) * fps; - bez.vec[0][1] = bc_get_float_value(intan, (j * 2 * dim )+ (2 * i) + 1); + bez.vec[0][0] = bc_get_float_value(intan, (j * 2 * dim) + (2 * i)) * fps; + bez.vec[0][1] = bc_get_float_value(intan, (j * 2 * dim) + (2 * i) + 1); // outtangent - bez.vec[2][0] = bc_get_float_value(outtan, (j * 2 * dim ) + (2 * i)) * fps; - bez.vec[2][1] = bc_get_float_value(outtan, (j * 2 * dim )+ (2 * i) + 1); + bez.vec[2][0] = bc_get_float_value(outtan, (j * 2 * dim) + (2 * i)) * fps; + bez.vec[2][1] = bc_get_float_value(outtan, (j * 2 * dim) + (2 * i) + 1); if (curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER) bez.ipo = BEZT_IPO_BEZ; else @@ -154,11 +154,11 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve) } } break; - default: - fprintf(stderr, "Output dimension of %d is not yet supported (animation id = %s)\n", (int)dim, curve->getOriginalId().c_str()); + default: + fprintf(stderr, "Output dimension of %d is not yet supported (animation id = %s)\n", (int)dim, curve->getOriginalId().c_str()); } - for (std::vector::iterator it = fcurves.begin(); it != fcurves.end(); it++) + for (std::vector::iterator it = fcurves.begin(); it != fcurves.end(); it++) unused_curves.push_back(*it); } @@ -174,14 +174,14 @@ void AnimationImporter::fcurve_deg_to_rad(FCurve *cu) } -void AnimationImporter::add_fcurves_to_object(Object *ob, std::vector& curves, char *rna_path, int array_index, Animation *animated) +void AnimationImporter::add_fcurves_to_object(Object *ob, std::vector& curves, char *rna_path, int array_index, Animation *animated) { bAction *act; - if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1); + if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID *)&ob->id, 1); else act = ob->adt->action; - std::vector::iterator it; + std::vector::iterator it; int i; #if 0 @@ -211,7 +211,7 @@ void AnimationImporter::add_fcurves_to_object(Object *ob, std::vector& /* no matching groups, so add one */ if (grp == NULL) { /* Add a new group, and make it active */ - grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup"); + grp = (bActionGroup *)MEM_callocN(sizeof(bActionGroup), "bActionGroup"); grp->flag = AGRP_SELECTED; BLI_strncpy(grp->name, bone_name, sizeof(grp->name)); @@ -240,22 +240,23 @@ void AnimationImporter::add_fcurves_to_object(Object *ob, std::vector& } AnimationImporter::AnimationImporter(UnitConverter *conv, ArmatureImporter *arm, Scene *scene) : - TransformReader(conv), armature_importer(arm), scene(scene) { } + TransformReader(conv), armature_importer(arm), scene(scene) { +} AnimationImporter::~AnimationImporter() { // free unused FCurves - for (std::vector::iterator it = unused_curves.begin(); it != unused_curves.end(); it++) + for (std::vector::iterator it = unused_curves.begin(); it != unused_curves.end(); it++) free_fcurve(*it); if (unused_curves.size()) fprintf(stderr, "removed %d unused curves\n", (int)unused_curves.size()); } -bool AnimationImporter::write_animation(const COLLADAFW::Animation* anim) +bool AnimationImporter::write_animation(const COLLADAFW::Animation *anim) { if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) { - COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve*)anim; + COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve *)anim; // XXX Don't know if it's necessary // Should we check outPhysicalDimension? @@ -270,15 +271,15 @@ bool AnimationImporter::write_animation(const COLLADAFW::Animation* anim) if (interp != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED) { switch (interp) { - case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR: - case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER: - case COLLADAFW::AnimationCurve::INTERPOLATION_STEP: - animation_to_fcurves(curve); - break; - default: - // TODO there're also CARDINAL, HERMITE, BSPLINE and STEP types - fprintf(stderr, "CARDINAL, HERMITE and BSPLINE anim interpolation types not supported yet.\n"); - break; + case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR: + case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER: + case COLLADAFW::AnimationCurve::INTERPOLATION_STEP: + animation_to_fcurves(curve); + break; + default: + // TODO there're also CARDINAL, HERMITE, BSPLINE and STEP types + fprintf(stderr, "CARDINAL, HERMITE and BSPLINE anim interpolation types not supported yet.\n"); + break; } } else { @@ -294,7 +295,7 @@ bool AnimationImporter::write_animation(const COLLADAFW::Animation* anim) } // called on post-process stage after writeVisualScenes -bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList* animlist) +bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList *animlist) { const COLLADAFW::UniqueId& animlist_id = animlist->getUniqueId(); @@ -334,14 +335,14 @@ virtual void AnimationImporter::change_eul_to_quat(Object *ob, bAction *act) bActionGroup *grp; int i; - for (grp = (bActionGroup*)act->groups.first; grp; grp = grp->next) { + for (grp = (bActionGroup *)act->groups.first; grp; grp = grp->next) { FCurve *eulcu[3] = {NULL, NULL, NULL}; if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end()) continue; - std::vector &rot_fcurves = fcurves_actionGroup_map[grp]; + std::vector &rot_fcurves = fcurves_actionGroup_map[grp]; if (rot_fcurves.size() > 3) continue; @@ -387,10 +388,10 @@ virtual void AnimationImporter::change_eul_to_quat(Object *ob, bAction *act) /*eul_to_mat3(rot, eul); - mul_m3_m3m3(rel, irest, rot); + mul_m3_m3m3(rel, irest, rot); - mat3_to_quat(quat, rel); - */ + mat3_to_quat(quat, rel); + */ eul_to_quat(quat, eul); @@ -415,7 +416,7 @@ virtual void AnimationImporter::change_eul_to_quat(Object *ob, bAction *act) } bPoseChannel *pchan; - for (pchan = (bPoseChannel*)ob->pose->chanbase.first; pchan; pchan = pchan->next) { + for (pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) { pchan->rotmode = ROT_MODE_QUAT; } } @@ -423,9 +424,9 @@ virtual void AnimationImporter::change_eul_to_quat(Object *ob, bAction *act) //sets the rna_path and array index to curve -void AnimationImporter::modify_fcurve(std::vector* curves, const char* rna_path, int array_index ) +void AnimationImporter::modify_fcurve(std::vector *curves, const char *rna_path, int array_index) { - std::vector::iterator it; + std::vector::iterator it; int i; for (it = curves->begin(), i = 0; it != curves->end(); it++, i++) { FCurve *fcu = *it; @@ -438,19 +439,19 @@ void AnimationImporter::modify_fcurve(std::vector* curves, const char* } } -void AnimationImporter::unused_fcurve(std::vector* curves) +void AnimationImporter::unused_fcurve(std::vector *curves) { // when an error happens and we can't actually use curve remove it from unused_curves - std::vector::iterator it; + std::vector::iterator it; for (it = curves->begin(); it != curves->end(); it++) { FCurve *fcu = *it; unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end()); } } -void AnimationImporter::find_frames( std::vector* frames, std::vector* curves) +void AnimationImporter::find_frames(std::vector *frames, std::vector *curves) { - std::vector::iterator iter; + std::vector::iterator iter; for (iter = curves->begin(); iter != curves->end(); iter++) { FCurve *fcu = *iter; @@ -466,16 +467,16 @@ void AnimationImporter::find_frames( std::vector* frames, std::vector* curves, bool is_joint, char * joint_path) +void AnimationImporter:: Assign_transform_animations(COLLADAFW::Transformation *transform, + const COLLADAFW::AnimationList::AnimationBinding *binding, + std::vector *curves, bool is_joint, char *joint_path) { COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType(); bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX; bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE; //to check if the no of curves are valid - bool xyz = ((tm_type == COLLADAFW::Transformation::TRANSLATE ||tm_type == COLLADAFW::Transformation::SCALE) && binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ); + bool xyz = ((tm_type == COLLADAFW::Transformation::TRANSLATE || tm_type == COLLADAFW::Transformation::SCALE) && binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ); if (!((!xyz && curves->size() == 1) || (xyz && curves->size() == 3) || is_matrix)) { @@ -488,85 +489,85 @@ void AnimationImporter:: Assign_transform_animations(COLLADAFW::Transformation * switch (tm_type) { case COLLADAFW::Transformation::TRANSLATE: case COLLADAFW::Transformation::SCALE: - { - bool loc = tm_type == COLLADAFW::Transformation::TRANSLATE; - if (is_joint) - BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale"); - else - BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path)); + { + bool loc = tm_type == COLLADAFW::Transformation::TRANSLATE; + if (is_joint) + BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale"); + else + BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path)); - switch (binding->animationClass) { - case COLLADAFW::AnimationList::POSITION_X: - modify_fcurve(curves, rna_path, 0 ); - break; - case COLLADAFW::AnimationList::POSITION_Y: - modify_fcurve(curves, rna_path, 1 ); - break; - case COLLADAFW::AnimationList::POSITION_Z: - modify_fcurve(curves, rna_path, 2 ); - break; - case COLLADAFW::AnimationList::POSITION_XYZ: - modify_fcurve(curves, rna_path, -1 ); - break; - default: - unused_fcurve(curves); - fprintf(stderr, "AnimationClass %d is not supported for %s.\n", - binding->animationClass, loc ? "TRANSLATE" : "SCALE"); - } - break; + switch (binding->animationClass) { + case COLLADAFW::AnimationList::POSITION_X: + modify_fcurve(curves, rna_path, 0); + break; + case COLLADAFW::AnimationList::POSITION_Y: + modify_fcurve(curves, rna_path, 1); + break; + case COLLADAFW::AnimationList::POSITION_Z: + modify_fcurve(curves, rna_path, 2); + break; + case COLLADAFW::AnimationList::POSITION_XYZ: + modify_fcurve(curves, rna_path, -1); + break; + default: + unused_fcurve(curves); + fprintf(stderr, "AnimationClass %d is not supported for %s.\n", + binding->animationClass, loc ? "TRANSLATE" : "SCALE"); } + break; + } case COLLADAFW::Transformation::ROTATE: - { - if (is_joint) - BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path); - else - BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path)); - std::vector::iterator iter; - for (iter = curves->begin(); iter != curves->end(); iter++) { - FCurve* fcu = *iter; - - //if transform is rotation the fcurves values must be turned in to radian. - if (is_rotation) - fcurve_deg_to_rad(fcu); - } - COLLADAFW::Rotate* rot = (COLLADAFW::Rotate*)transform; - COLLADABU::Math::Vector3& axis = rot->getRotationAxis(); - - switch (binding->animationClass) { - case COLLADAFW::AnimationList::ANGLE: - if (COLLADABU::Math::Vector3::UNIT_X == axis) { - modify_fcurve(curves, rna_path, 0 ); - } - else if (COLLADABU::Math::Vector3::UNIT_Y == axis) { - modify_fcurve(curves, rna_path, 1 ); - } - else if (COLLADABU::Math::Vector3::UNIT_Z == axis) { - modify_fcurve(curves, rna_path, 2 ); - } + { + if (is_joint) + BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path); else - unused_fcurve(curves); - break; - case COLLADAFW::AnimationList::AXISANGLE: - // TODO convert axis-angle to quat? or XYZ? - default: - unused_fcurve(curves); - fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n", - binding->animationClass); - } - break; + BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path)); + std::vector::iterator iter; + for (iter = curves->begin(); iter != curves->end(); iter++) { + FCurve *fcu = *iter; + + //if transform is rotation the fcurves values must be turned in to radian. + if (is_rotation) + fcurve_deg_to_rad(fcu); } + COLLADAFW::Rotate *rot = (COLLADAFW::Rotate *)transform; + COLLADABU::Math::Vector3& axis = rot->getRotationAxis(); + + switch (binding->animationClass) { + case COLLADAFW::AnimationList::ANGLE: + if (COLLADABU::Math::Vector3::UNIT_X == axis) { + modify_fcurve(curves, rna_path, 0); + } + else if (COLLADABU::Math::Vector3::UNIT_Y == axis) { + modify_fcurve(curves, rna_path, 1); + } + else if (COLLADABU::Math::Vector3::UNIT_Z == axis) { + modify_fcurve(curves, rna_path, 2); + } + else + unused_fcurve(curves); + break; + case COLLADAFW::AnimationList::AXISANGLE: + // TODO convert axis-angle to quat? or XYZ? + default: + unused_fcurve(curves); + fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n", + binding->animationClass); + } + break; + } case COLLADAFW::Transformation::MATRIX: /*{ - COLLADAFW::Matrix* mat = (COLLADAFW::Matrix*)transform; - COLLADABU::Math::Matrix4 mat4 = mat->getMatrix(); - switch (binding->animationClass) { - case COLLADAFW::AnimationList::TRANSFORM: + COLLADAFW::Matrix* mat = (COLLADAFW::Matrix*)transform; + COLLADABU::Math::Matrix4 mat4 = mat->getMatrix(); + switch (binding->animationClass) { + case COLLADAFW::AnimationList::TRANSFORM: - } - }*/ + } + }*/ unused_fcurve(curves); break; case COLLADAFW::Transformation::SKEW: @@ -579,7 +580,7 @@ void AnimationImporter:: Assign_transform_animations(COLLADAFW::Transformation * } //creates the rna_paths and array indices of fcurves from animations using color and bound animation class of each animation. -void AnimationImporter:: Assign_color_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char * anim_type) +void AnimationImporter:: Assign_color_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char *anim_type) { char rna_path[100]; BLI_strncpy(rna_path, anim_type, sizeof(rna_path)); @@ -587,35 +588,35 @@ void AnimationImporter:: Assign_color_animations(const COLLADAFW::UniqueId& list const COLLADAFW::AnimationList *animlist = animlist_map[listid]; const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings(); //all the curves belonging to the current binding - std::vector animcurves; + std::vector animcurves; for (unsigned int j = 0; j < bindings.getCount(); j++) { animcurves = curve_map[bindings[j].animation]; switch (bindings[j].animationClass) { - case COLLADAFW::AnimationList::COLOR_R: - modify_fcurve(&animcurves, rna_path, 0 ); - break; - case COLLADAFW::AnimationList::COLOR_G: - modify_fcurve(&animcurves, rna_path, 1 ); - break; - case COLLADAFW::AnimationList::COLOR_B: - modify_fcurve(&animcurves, rna_path, 2 ); - break; - case COLLADAFW::AnimationList::COLOR_RGB: - case COLLADAFW::AnimationList::COLOR_RGBA: // to do-> set intensity - modify_fcurve(&animcurves, rna_path, -1 ); - break; + case COLLADAFW::AnimationList::COLOR_R: + modify_fcurve(&animcurves, rna_path, 0); + break; + case COLLADAFW::AnimationList::COLOR_G: + modify_fcurve(&animcurves, rna_path, 1); + break; + case COLLADAFW::AnimationList::COLOR_B: + modify_fcurve(&animcurves, rna_path, 2); + break; + case COLLADAFW::AnimationList::COLOR_RGB: + case COLLADAFW::AnimationList::COLOR_RGBA: // to do-> set intensity + modify_fcurve(&animcurves, rna_path, -1); + break; - default: - unused_fcurve(&animcurves); - fprintf(stderr, "AnimationClass %d is not supported for %s.\n", - bindings[j].animationClass, "COLOR" ); + default: + unused_fcurve(&animcurves); + fprintf(stderr, "AnimationClass %d is not supported for %s.\n", + bindings[j].animationClass, "COLOR"); } - std::vector::iterator iter; + std::vector::iterator iter; //Add the curves of the current animation to the object for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve * fcu = *iter; + FCurve *fcu = *iter; BLI_addtail(AnimCurves, fcu); } } @@ -623,7 +624,7 @@ void AnimationImporter:: Assign_color_animations(const COLLADAFW::UniqueId& list } -void AnimationImporter:: Assign_float_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char * anim_type) +void AnimationImporter:: Assign_float_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char *anim_type) { char rna_path[100]; if (animlist_map.find(listid) == animlist_map.end()) { @@ -634,16 +635,16 @@ void AnimationImporter:: Assign_float_animations(const COLLADAFW::UniqueId& list const COLLADAFW::AnimationList *animlist = animlist_map[listid]; const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings(); //all the curves belonging to the current binding - std::vector animcurves; + std::vector animcurves; for (unsigned int j = 0; j < bindings.getCount(); j++) { animcurves = curve_map[bindings[j].animation]; BLI_strncpy(rna_path, anim_type, sizeof(rna_path)); - modify_fcurve(&animcurves, rna_path, 0 ); - std::vector::iterator iter; + modify_fcurve(&animcurves, rna_path, 0); + std::vector::iterator iter; //Add the curves of the current animation to the object for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve * fcu = *iter; + FCurve *fcu = *iter; BLI_addtail(AnimCurves, fcu); } } @@ -651,13 +652,13 @@ void AnimationImporter:: Assign_float_animations(const COLLADAFW::UniqueId& list } -void AnimationImporter::apply_matrix_curves( Object * ob, std::vector& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node, - COLLADAFW::Transformation * tm ) +void AnimationImporter::apply_matrix_curves(Object *ob, std::vector& animcurves, COLLADAFW::Node *root, COLLADAFW::Node *node, + COLLADAFW::Transformation *tm) { bool is_joint = node->getType() == COLLADAFW::Node::JOINT; const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL; char joint_path[200]; - if ( is_joint ) + if (is_joint) armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path)); std::vector frames; @@ -670,7 +671,7 @@ void AnimationImporter::apply_matrix_curves( Object * ob, std::vector& get_joint_rest_mat(irest_dae, root, node); invert_m4(irest_dae); - Bone *bone = BKE_armature_find_bone_name((bArmature*)ob->data, bone_name); + Bone *bone = BKE_armature_find_bone_name((bArmature *)ob->data, bone_name); if (!bone) { fprintf(stderr, "cannot find bone \"%s\"\n", bone_name); return; @@ -751,13 +752,13 @@ void AnimationImporter::apply_matrix_curves( Object * ob, std::vector& copy_m4_m4(mat, matfra); } - float rot[4], loc[3], scale[3]; + float rot[4], loc[3], scale[3]; mat4_to_quat(rot, mat); /*for ( int i = 0 ; i < 4 ; i ++ ) - { - rot[i] = RAD2DEGF(rot[i]); - }*/ + { + rot[i] = RAD2DEGF(rot[i]); + }*/ copy_v3_v3(loc, mat[3]); mat4_to_size(scale, mat); @@ -771,12 +772,12 @@ void AnimationImporter::apply_matrix_curves( Object * ob, std::vector& add_bezt(newcu[i], fra, scale[i - 7]); } } - verify_adt_action((ID*)&ob->id, 1); + verify_adt_action((ID *)&ob->id, 1); ListBase *curves = &ob->adt->action->curves; // add curves - for (int i= 0; i < totcu; i++) { + for (int i = 0; i < totcu; i++) { if (is_joint) add_bone_fcurve(ob, node, newcu[i]); else @@ -795,12 +796,12 @@ void AnimationImporter::apply_matrix_curves( Object * ob, std::vector& } -void AnimationImporter::translate_Animations ( COLLADAFW::Node * node, - std::map& root_map, - std::multimap& object_map, - std::map FW_object_map) +void AnimationImporter::translate_Animations(COLLADAFW::Node *node, + std::map& root_map, + std::multimap& object_map, + std::map FW_object_map) { - AnimationImporter::AnimMix* animType = get_animation_type(node, FW_object_map ); + AnimationImporter::AnimMix *animType = get_animation_type(node, FW_object_map); bool is_joint = node->getType() == COLLADAFW::Node::JOINT; COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()]; @@ -810,17 +811,17 @@ void AnimationImporter::translate_Animations ( COLLADAFW::Node * node, return; } - bAction * act; + bAction *act; - if ( (animType->transform) != 0 ) { + if ( (animType->transform) != 0) { /* const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL; */ /* UNUSED */ char joint_path[200]; - if ( is_joint ) + if (is_joint) armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path)); - if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1); + if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID *)&ob->id, 1); else act = ob->adt->action; //Get the list of animation curves of the object @@ -847,11 +848,11 @@ void AnimationImporter::translate_Animations ( COLLADAFW::Node * node, const COLLADAFW::AnimationList *animlist = animlist_map[listid]; const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings(); //all the curves belonging to the current binding - std::vector animcurves; + std::vector animcurves; for (unsigned int j = 0; j < bindings.getCount(); j++) { animcurves = curve_map[bindings[j].animation]; - if ( is_matrix ) { - apply_matrix_curves(ob, animcurves, root, node, transform ); + if (is_matrix) { + apply_matrix_curves(ob, animcurves, root, node, transform); } else { @@ -861,12 +862,12 @@ void AnimationImporter::translate_Animations ( COLLADAFW::Node * node, } else { //calculate rnapaths and array index of fcurves according to transformation and animation class - Assign_transform_animations(transform, &bindings[j], &animcurves, is_joint, joint_path ); + Assign_transform_animations(transform, &bindings[j], &animcurves, is_joint, joint_path); - std::vector::iterator iter; + std::vector::iterator iter; //Add the curves of the current animation to the object for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve * fcu = *iter; + FCurve *fcu = *iter; BLI_addtail(AnimCurves, fcu); } @@ -882,9 +883,9 @@ void AnimationImporter::translate_Animations ( COLLADAFW::Node * node, } if ((animType->light) != 0) { - Lamp * lamp = (Lamp*) ob->data; + Lamp *lamp = (Lamp *) ob->data; - if (!lamp->adt || !lamp->adt->action) act = verify_adt_action((ID*)&lamp->id, 1); + if (!lamp->adt || !lamp->adt->action) act = verify_adt_action((ID *)&lamp->id, 1); else act = lamp->adt->action; ListBase *AnimCurves = &(act->curves); @@ -899,63 +900,63 @@ void AnimationImporter::translate_Animations ( COLLADAFW::Node * node, Assign_color_animations(listid, AnimCurves, "color"); } - if ((animType->light & LIGHT_FOA) != 0 ) { + if ((animType->light & LIGHT_FOA) != 0) { const COLLADAFW::AnimatableFloat *foa = &(light->getFallOffAngle()); const COLLADAFW::UniqueId& listid = foa->getAnimationList(); - Assign_float_animations( listid, AnimCurves, "spot_size"); + Assign_float_animations(listid, AnimCurves, "spot_size"); } - if ( (animType->light & LIGHT_FOE) != 0 ) { + if ( (animType->light & LIGHT_FOE) != 0) { const COLLADAFW::AnimatableFloat *foe = &(light->getFallOffExponent()); const COLLADAFW::UniqueId& listid = foe->getAnimationList(); - Assign_float_animations( listid, AnimCurves, "spot_blend"); + Assign_float_animations(listid, AnimCurves, "spot_blend"); } } } if ( (animType->camera) != 0) { - Camera * camera = (Camera*) ob->data; + Camera *camera = (Camera *) ob->data; - if (!camera->adt || !camera->adt->action) act = verify_adt_action((ID*)&camera->id, 1); + if (!camera->adt || !camera->adt->action) act = verify_adt_action((ID *)&camera->id, 1); else act = camera->adt->action; ListBase *AnimCurves = &(act->curves); - const COLLADAFW::InstanceCameraPointerArray& nodeCameras= node->getInstanceCameras(); + const COLLADAFW::InstanceCameraPointerArray& nodeCameras = node->getInstanceCameras(); for (unsigned int i = 0; i < nodeCameras.getCount(); i++) { const COLLADAFW::Camera *camera = (COLLADAFW::Camera *) FW_object_map[nodeCameras[i]->getInstanciatedObjectId()]; - if ((animType->camera & CAMERA_XFOV) != 0 ) { + if ((animType->camera & CAMERA_XFOV) != 0) { const COLLADAFW::AnimatableFloat *xfov = &(camera->getXFov()); const COLLADAFW::UniqueId& listid = xfov->getAnimationList(); - Assign_float_animations( listid, AnimCurves, "lens"); + Assign_float_animations(listid, AnimCurves, "lens"); } - else if ((animType->camera & CAMERA_XMAG) != 0 ) { + else if ((animType->camera & CAMERA_XMAG) != 0) { const COLLADAFW::AnimatableFloat *xmag = &(camera->getXMag()); const COLLADAFW::UniqueId& listid = xmag->getAnimationList(); - Assign_float_animations( listid, AnimCurves, "ortho_scale"); + Assign_float_animations(listid, AnimCurves, "ortho_scale"); } - if ((animType->camera & CAMERA_ZFAR) != 0 ) { + if ((animType->camera & CAMERA_ZFAR) != 0) { const COLLADAFW::AnimatableFloat *zfar = &(camera->getFarClippingPlane()); const COLLADAFW::UniqueId& listid = zfar->getAnimationList(); - Assign_float_animations( listid, AnimCurves, "clip_end"); + Assign_float_animations(listid, AnimCurves, "clip_end"); } - if ((animType->camera & CAMERA_ZNEAR) != 0 ) { + if ((animType->camera & CAMERA_ZNEAR) != 0) { const COLLADAFW::AnimatableFloat *znear = &(camera->getNearClippingPlane()); const COLLADAFW::UniqueId& listid = znear->getAnimationList(); - Assign_float_animations( listid, AnimCurves, "clip_start"); + Assign_float_animations(listid, AnimCurves, "clip_start"); } } } - if ( animType->material != 0) { + if (animType->material != 0) { Material *ma = give_current_material(ob, 1); - if (!ma->adt || !ma->adt->action) act = verify_adt_action((ID*)&ma->id, 1); + if (!ma->adt || !ma->adt->action) act = verify_adt_action((ID *)&ma->id, 1); else act = ma->adt->action; ListBase *AnimCurves = &(act->curves); @@ -972,25 +973,25 @@ void AnimationImporter::translate_Animations ( COLLADAFW::Node * node, if ((animType->material & MATERIAL_SHININESS) != 0) { const COLLADAFW::FloatOrParam *shin = &(efc->getShininess()); const COLLADAFW::UniqueId& listid = shin->getAnimationList(); - Assign_float_animations( listid, AnimCurves, "specular_hardness" ); + Assign_float_animations(listid, AnimCurves, "specular_hardness"); } if ((animType->material & MATERIAL_IOR) != 0) { const COLLADAFW::FloatOrParam *ior = &(efc->getIndexOfRefraction()); const COLLADAFW::UniqueId& listid = ior->getAnimationList(); - Assign_float_animations( listid, AnimCurves, "raytrace_transparency.ior" ); + Assign_float_animations(listid, AnimCurves, "raytrace_transparency.ior"); } if ((animType->material & MATERIAL_SPEC_COLOR) != 0) { const COLLADAFW::ColorOrTexture *cot = &(efc->getSpecular()); const COLLADAFW::UniqueId& listid = cot->getColor().getAnimationList(); - Assign_color_animations( listid, AnimCurves, "specular_color" ); + Assign_color_animations(listid, AnimCurves, "specular_color"); } if ((animType->material & MATERIAL_DIFF_COLOR) != 0) { const COLLADAFW::ColorOrTexture *cot = &(efc->getDiffuse()); const COLLADAFW::UniqueId& listid = cot->getColor().getAnimationList(); - Assign_color_animations( listid, AnimCurves, "diffuse_color" ); + Assign_color_animations(listid, AnimCurves, "diffuse_color"); } } } @@ -998,7 +999,7 @@ void AnimationImporter::translate_Animations ( COLLADAFW::Node * node, } } -void AnimationImporter::add_bone_animation_sampled(Object * ob, std::vector& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node, COLLADAFW::Transformation * tm) +void AnimationImporter::add_bone_animation_sampled(Object *ob, std::vector& animcurves, COLLADAFW::Node *root, COLLADAFW::Node *node, COLLADAFW::Transformation *tm) { const char *bone_name = bc_get_joint_name(node); char joint_path[200]; @@ -1010,9 +1011,9 @@ void AnimationImporter::add_bone_animation_sampled(Object * ob, std::vectorgetTransformationType() == COLLADAFW::Transformation::ROTATE) { - std::vector::iterator iter; + std::vector::iterator iter; for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve* fcu = *iter; + FCurve *fcu = *iter; fcurve_deg_to_rad(fcu); } @@ -1025,7 +1026,7 @@ void AnimationImporter::add_bone_animation_sampled(Object * ob, std::vectordata, bone_name); + Bone *bone = BKE_armature_find_bone_name((bArmature *)ob->data, bone_name); if (!bone) { fprintf(stderr, "cannot find bone \"%s\"\n", bone_name); return; @@ -1100,7 +1101,7 @@ void AnimationImporter::add_bone_animation_sampled(Object * ob, std::vectorid, 1); + verify_adt_action((ID *)&ob->id, 1); // add curves - for (int i= 0; i < totcu; i++) { + for (int i = 0; i < totcu; i++) { add_bone_fcurve(ob, node, newcu[i]); } @@ -1130,8 +1131,8 @@ void AnimationImporter::add_bone_animation_sampled(Object * ob, std::vector FW_object_map) +AnimationImporter::AnimMix *AnimationImporter::get_animation_type(const COLLADAFW::Node *node, + std::map FW_object_map) { AnimMix *types = new AnimMix(); @@ -1147,7 +1148,7 @@ AnimationImporter::AnimMix* AnimationImporter::get_animation_type ( const COLLAD continue; } else { - types->transform = types->transform|NODE_TRANSFORM; + types->transform = types->transform | NODE_TRANSFORM; break; } } @@ -1159,7 +1160,7 @@ AnimationImporter::AnimMix* AnimationImporter::get_animation_type ( const COLLAD types->light = setAnimType(&(light->getFallOffAngle()), (types->light), LIGHT_FOA); types->light = setAnimType(&(light->getFallOffExponent()), (types->light), LIGHT_FOE); - if ( types->light != 0) break; + if (types->light != 0) break; } @@ -1167,7 +1168,7 @@ AnimationImporter::AnimMix* AnimationImporter::get_animation_type ( const COLLAD for (unsigned int i = 0; i < nodeCameras.getCount(); i++) { const COLLADAFW::Camera *camera = (COLLADAFW::Camera *) FW_object_map[nodeCameras[i]->getInstanciatedObjectId()]; - if ( camera->getCameraType() == COLLADAFW::Camera::PERSPECTIVE ) { + if (camera->getCameraType() == COLLADAFW::Camera::PERSPECTIVE) { types->camera = setAnimType(&(camera->getXMag()), (types->camera), CAMERA_XFOV); } else { @@ -1176,7 +1177,7 @@ AnimationImporter::AnimMix* AnimationImporter::get_animation_type ( const COLLAD types->camera = setAnimType(&(camera->getFarClippingPlane()), (types->camera), CAMERA_ZFAR); types->camera = setAnimType(&(camera->getNearClippingPlane()), (types->camera), CAMERA_ZNEAR); - if ( types->camera != 0) break; + if (types->camera != 0) break; } @@ -1202,16 +1203,16 @@ AnimationImporter::AnimMix* AnimationImporter::get_animation_type ( const COLLAD return types; } -int AnimationImporter::setAnimType ( const COLLADAFW::Animatable * prop, int types, int addition) +int AnimationImporter::setAnimType(const COLLADAFW::Animatable *prop, int types, int addition) { const COLLADAFW::UniqueId& listid = prop->getAnimationList(); if (animlist_map.find(listid) != animlist_map.end()) - return types|addition; + return types | addition; else return types; } // Is not used anymore. -void AnimationImporter::find_frames_old(std::vector * frames, COLLADAFW::Node * node, COLLADAFW::Transformation::TransformationType tm_type) +void AnimationImporter::find_frames_old(std::vector *frames, COLLADAFW::Node *node, COLLADAFW::Transformation::TransformationType tm_type) { bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX; bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE; @@ -1237,11 +1238,11 @@ void AnimationImporter::find_frames_old(std::vector * frames, COLLADAFW:: if (bindings.getCount()) { //for each AnimationBinding get the fcurves which animate the transform for (unsigned int j = 0; j < bindings.getCount(); j++) { - std::vector& curves = curve_map[bindings[j].animation]; + std::vector& curves = curve_map[bindings[j].animation]; bool xyz = ((nodeTmType == COLLADAFW::Transformation::TRANSLATE || nodeTmType == COLLADAFW::Transformation::SCALE) && bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ); if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) { - std::vector::iterator iter; + std::vector::iterator iter; for (iter = curves.begin(); iter != curves.end(); iter++) { FCurve *fcu = *iter; @@ -1275,10 +1276,10 @@ void AnimationImporter::find_frames_old(std::vector * frames, COLLADAFW:: // animlist_map - map animlist id -> animlist // curve_map - map anim id -> curve(s) Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node, - std::map& object_map, - std::map& root_map, - COLLADAFW::Transformation::TransformationType tm_type, - Object *par_job) + std::map& object_map, + std::map& root_map, + COLLADAFW::Transformation::TransformationType tm_type, + Object *par_job) { bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE; @@ -1307,7 +1308,7 @@ Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node, get_joint_rest_mat(irest_dae, root, node); invert_m4(irest_dae); - Bone *bone = BKE_armature_find_bone_name((bArmature*)ob->data, bone_name); + Bone *bone = BKE_armature_find_bone_name((bArmature *)ob->data, bone_name); if (!bone) { fprintf(stderr, "cannot find bone \"%s\"\n", bone_name); return NULL; @@ -1332,19 +1333,19 @@ Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node, const char *tm_str = NULL; switch (tm_type) { - case COLLADAFW::Transformation::ROTATE: - tm_str = "rotation_quaternion"; - break; - case COLLADAFW::Transformation::SCALE: - tm_str = "scale"; - break; - case COLLADAFW::Transformation::TRANSLATE: - tm_str = "location"; - break; - case COLLADAFW::Transformation::MATRIX: - break; - default: - return job; + case COLLADAFW::Transformation::ROTATE: + tm_str = "rotation_quaternion"; + break; + case COLLADAFW::Transformation::SCALE: + tm_str = "scale"; + break; + case COLLADAFW::Transformation::TRANSLATE: + tm_str = "location"; + break; + case COLLADAFW::Transformation::MATRIX: + break; + default: + return job; } char rna_path[200]; @@ -1425,22 +1426,22 @@ Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node, float val[4], rot[4], loc[3], scale[3]; switch (tm_type) { - case COLLADAFW::Transformation::ROTATE: - mat4_to_quat(val, mat); - break; - case COLLADAFW::Transformation::SCALE: - mat4_to_size(val, mat); - break; - case COLLADAFW::Transformation::TRANSLATE: - copy_v3_v3(val, mat[3]); - break; - case COLLADAFW::Transformation::MATRIX: - mat4_to_quat(rot, mat); - copy_v3_v3(loc, mat[3]); - mat4_to_size(scale, mat); - break; - default: - break; + case COLLADAFW::Transformation::ROTATE: + mat4_to_quat(val, mat); + break; + case COLLADAFW::Transformation::SCALE: + mat4_to_size(val, mat); + break; + case COLLADAFW::Transformation::TRANSLATE: + copy_v3_v3(val, mat[3]); + break; + case COLLADAFW::Transformation::MATRIX: + mat4_to_quat(rot, mat); + copy_v3_v3(loc, mat[3]); + mat4_to_size(scale, mat); + break; + default: + break; } // add keys @@ -1461,22 +1462,22 @@ Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node, #ifdef ARMATURE_TEST if (is_joint) { switch (tm_type) { - case COLLADAFW::Transformation::ROTATE: - mat4_to_quat(val, matfra); - break; - case COLLADAFW::Transformation::SCALE: - mat4_to_size(val, matfra); - break; - case COLLADAFW::Transformation::TRANSLATE: - copy_v3_v3(val, matfra[3]); - break; - case MATRIX: - mat4_to_quat(rot, matfra); - copy_v3_v3(loc, matfra[3]); - mat4_to_size(scale, matfra); - break; - default: - break; + case COLLADAFW::Transformation::ROTATE: + mat4_to_quat(val, matfra); + break; + case COLLADAFW::Transformation::SCALE: + mat4_to_size(val, matfra); + break; + case COLLADAFW::Transformation::TRANSLATE: + copy_v3_v3(val, matfra[3]); + break; + case MATRIX: + mat4_to_quat(rot, matfra); + copy_v3_v3(loc, matfra[3]); + mat4_to_size(scale, matfra); + break; + default: + break; } for (i = 0; i < totcu; i++) { @@ -1496,7 +1497,7 @@ Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node, #endif } - verify_adt_action((ID*)&ob->id, 1); + verify_adt_action((ID *)&ob->id, 1); ListBase *curves = &ob->adt->action->curves; @@ -1545,20 +1546,20 @@ void AnimationImporter::evaluate_transform_at_frame(float mat[4][4], COLLADAFW:: std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId(); if (!evaluate_animation(tm, m, fra, nodename.c_str())) { switch (type) { - case COLLADAFW::Transformation::ROTATE: - dae_rotate_to_mat4(tm, m); - break; - case COLLADAFW::Transformation::TRANSLATE: - dae_translate_to_mat4(tm, m); - break; - case COLLADAFW::Transformation::SCALE: - dae_scale_to_mat4(tm, m); - break; - case COLLADAFW::Transformation::MATRIX: - dae_matrix_to_mat4(tm, m); - break; - default: - fprintf(stderr, "unsupported transformation type %d\n", type); + case COLLADAFW::Transformation::ROTATE: + dae_rotate_to_mat4(tm, m); + break; + case COLLADAFW::Transformation::TRANSLATE: + dae_translate_to_mat4(tm, m); + break; + case COLLADAFW::Transformation::SCALE: + dae_scale_to_mat4(tm, m); + break; + case COLLADAFW::Transformation::MATRIX: + dae_matrix_to_mat4(tm, m); + break; + default: + fprintf(stderr, "unsupported transformation type %d\n", type); } // dae_matrix_to_mat4(tm, m); @@ -1578,9 +1579,9 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); if (type != COLLADAFW::Transformation::ROTATE && - type != COLLADAFW::Transformation::SCALE && - type != COLLADAFW::Transformation::TRANSLATE && - type != COLLADAFW::Transformation::MATRIX) { + type != COLLADAFW::Transformation::SCALE && + type != COLLADAFW::Transformation::TRANSLATE && + type != COLLADAFW::Transformation::MATRIX) { fprintf(stderr, "animation of transformation %d is not supported yet\n", type); return false; } @@ -1604,25 +1605,25 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float for (unsigned int j = 0; j < bindings.getCount(); j++) { const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[j]; - std::vector& curves = curve_map[binding.animation]; + std::vector& curves = curve_map[binding.animation]; COLLADAFW::AnimationList::AnimationClass animclass = binding.animationClass; char path[100]; switch (type) { - case COLLADAFW::Transformation::ROTATE: - BLI_snprintf(path, sizeof(path), "%s.rotate (binding %u)", node_id, j); - break; - case COLLADAFW::Transformation::SCALE: - BLI_snprintf(path, sizeof(path), "%s.scale (binding %u)", node_id, j); - break; - case COLLADAFW::Transformation::TRANSLATE: - BLI_snprintf(path, sizeof(path), "%s.translate (binding %u)", node_id, j); - break; - case COLLADAFW::Transformation::MATRIX: - BLI_snprintf(path, sizeof(path), "%s.matrix (binding %u)", node_id, j); - break; - default: - break; + case COLLADAFW::Transformation::ROTATE: + BLI_snprintf(path, sizeof(path), "%s.rotate (binding %u)", node_id, j); + break; + case COLLADAFW::Transformation::SCALE: + BLI_snprintf(path, sizeof(path), "%s.scale (binding %u)", node_id, j); + break; + case COLLADAFW::Transformation::TRANSLATE: + BLI_snprintf(path, sizeof(path), "%s.translate (binding %u)", node_id, j); + break; + case COLLADAFW::Transformation::MATRIX: + BLI_snprintf(path, sizeof(path), "%s.matrix (binding %u)", node_id, j); + break; + default: + break; } if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) { @@ -1642,7 +1643,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float return false; } - COLLADABU::Math::Vector3& axis = ((COLLADAFW::Rotate*)tm)->getRotationAxis(); + COLLADABU::Math::Vector3& axis = ((COLLADAFW::Rotate *)tm)->getRotationAxis(); float ax[3] = {(float)axis[0], (float)axis[1], (float)axis[2]}; float angle = evaluate_fcurve(curves[0], fra); @@ -1662,23 +1663,23 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float } switch (animclass) { - case COLLADAFW::AnimationList::POSITION_X: - vec[0] = evaluate_fcurve(curves[0], fra); - break; - case COLLADAFW::AnimationList::POSITION_Y: - vec[1] = evaluate_fcurve(curves[0], fra); - break; - case COLLADAFW::AnimationList::POSITION_Z: - vec[2] = evaluate_fcurve(curves[0], fra); - break; - case COLLADAFW::AnimationList::POSITION_XYZ: - vec[0] = evaluate_fcurve(curves[0], fra); - vec[1] = evaluate_fcurve(curves[1], fra); - vec[2] = evaluate_fcurve(curves[2], fra); - break; - default: - fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass); - break; + case COLLADAFW::AnimationList::POSITION_X: + vec[0] = evaluate_fcurve(curves[0], fra); + break; + case COLLADAFW::AnimationList::POSITION_Y: + vec[1] = evaluate_fcurve(curves[0], fra); + break; + case COLLADAFW::AnimationList::POSITION_Z: + vec[2] = evaluate_fcurve(curves[0], fra); + break; + case COLLADAFW::AnimationList::POSITION_XYZ: + vec[0] = evaluate_fcurve(curves[0], fra); + vec[1] = evaluate_fcurve(curves[1], fra); + vec[2] = evaluate_fcurve(curves[2], fra); + break; + default: + fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass); + break; } } else if (type == COLLADAFW::Transformation::MATRIX) { @@ -1691,7 +1692,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float COLLADABU::Math::Matrix4 matrix; int i = 0, j = 0; - for (std::vector::iterator it = curves.begin(); it != curves.end(); it++) { + for (std::vector::iterator it = curves.begin(); it != curves.end(); it++) { matrix.setElement(i, j, evaluate_fcurve(*it, fra)); j++; if (j == 4) { @@ -1704,7 +1705,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float COLLADAFW::Matrix tm(matrix); dae_matrix_to_mat4(&tm, mat); - std::vector::iterator it; + std::vector::iterator it; return true; } @@ -1770,14 +1771,14 @@ bool AnimationImporter::calc_joint_parent_mat_rest(float mat[4][4], float par[4] Object *AnimationImporter::get_joint_object(COLLADAFW::Node *root, COLLADAFW::Node *node, Object *par_job) { if (joint_objects.find(node->getUniqueId()) == joint_objects.end()) { - Object *job = bc_add_object(scene, OB_EMPTY, (char*)get_joint_name(node)); + Object *job = bc_add_object(scene, OB_EMPTY, (char *)get_joint_name(node)); job->lay = BKE_scene_base_find(scene, job)->lay = 2; mul_v3_fl(job->size, 0.5f); job->recalc |= OB_RECALC_OB; - verify_adt_action((ID*)&job->id, 1); + verify_adt_action((ID *)&job->id, 1); job->rotmode = ROT_MODE_QUAT; @@ -1854,7 +1855,7 @@ void AnimationImporter::add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurv /* no matching groups, so add one */ if (grp == NULL) { /* Add a new group, and make it active */ - grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup"); + grp = (bActionGroup *)MEM_callocN(sizeof(bActionGroup), "bActionGroup"); grp->flag = AGRP_SELECTED; BLI_strncpy(grp->name, bone_name, sizeof(grp->name)); @@ -1874,7 +1875,7 @@ void AnimationImporter::add_bezt(FCurve *fcu, float fra, float value) memset(&bez, 0, sizeof(BezTriple)); bez.vec[1][0] = fra; bez.vec[1][1] = value; - bez.ipo = BEZT_IPO_LIN ;/* use default interpolation mode here... */ + bez.ipo = BEZT_IPO_LIN; /* use default interpolation mode here... */ bez.f1 = bez.f2 = bez.f3 = SELECT; bez.h1 = bez.h2 = HD_AUTO; insert_bezt_fcurve(fcu, &bez, 0); diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index e5548acadb5..98047df8aa4 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -58,16 +58,17 @@ extern "C" { // XXX exporter writes wrong data for shared armatures. A separate // controller should be written for each armature-mesh binding how do // we make controller ids then? -ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryControllers(sw), export_settings(export_settings) {} +ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryControllers(sw), export_settings(export_settings) { +} // write bone nodes -void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene* sce, - SceneExporter* se, - std::list& child_objects) +void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce, + SceneExporter *se, + std::list& child_objects) { // write bone nodes - bArmature *arm = (bArmature*)ob_arm->data; - for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) { + bArmature *arm = (bArmature *)ob_arm->data; + for (Bone *bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) { // start from root bones if (!bone->parent) add_bone_node(bone, ob_arm, sce, se, child_objects); @@ -82,7 +83,7 @@ bool ArmatureExporter::is_skinned_mesh(Object *ob) bool ArmatureExporter::add_instance_controller(Object *ob) { Object *ob_arm = bc_get_assigned_armature(ob); - bArmature *arm = (bArmature*)ob_arm->data; + bArmature *arm = (bArmature *)ob_arm->data; const std::string& controller_id = get_controller_id(ob_arm, ob); @@ -94,7 +95,7 @@ bool ArmatureExporter::add_instance_controller(Object *ob) // write root bone URLs Bone *bone; - for (bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) { + for (bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) { if (!bone->parent) ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm))); } @@ -140,7 +141,7 @@ void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vectorbase.first; + Base *base = (Base *) sce->base.first; while (base) { Object *ob = base->object; @@ -148,7 +149,7 @@ void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vectornext; + base = base->next; } } #endif @@ -159,9 +160,9 @@ std::string ArmatureExporter::get_joint_sid(Bone *bone, Object *ob_arm) } // parent_mat is armature-space -void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene* sce, - SceneExporter* se, - std::list& child_objects) +void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, + SceneExporter *se, + std::list& child_objects) { std::string node_id = get_joint_id(bone, ob_arm); std::string node_name = std::string(bone->name); @@ -175,14 +176,14 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene* sce, node.setNodeSid(node_sid); /*if ( bone->childbase.first == NULL || BLI_countlist(&(bone->childbase))>=2) - add_blender_leaf_bone( bone, ob_arm , node ); - else{*/ + add_blender_leaf_bone( bone, ob_arm , node ); + else{*/ node.start(); add_bone_transform(ob_arm, bone, node); // Write nodes of childobjects, remove written objects from list - std::list::iterator i = child_objects.begin(); + std::list::iterator i = child_objects.begin(); while (i != child_objects.end()) { if ((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name))) { @@ -219,29 +220,32 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene* sce, else i++; } - for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) { + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { add_bone_node(child, ob_arm, sce, se, child_objects); } node.end(); //} } -/*void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node) +#if 0 +void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node) { node.start(); add_bone_transform(ob_arm, bone, node); - node.addExtraTechniqueParameter("blender", "tip_x", bone->tail[0] ); - node.addExtraTechniqueParameter("blender", "tip_y", bone->tail[1] ); - node.addExtraTechniqueParameter("blender", "tip_z", bone->tail[2] ); + node.addExtraTechniqueParameter("blender", "tip_x", bone->tail[0]); + node.addExtraTechniqueParameter("blender", "tip_y", bone->tail[1]); + node.addExtraTechniqueParameter("blender", "tip_z", bone->tail[2]); - for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) { + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { add_bone_node(child, ob_arm, sce, se, child_objects); } node.end(); -}*/ +} +#endif + void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node) { bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name); @@ -292,7 +296,7 @@ std::string ArmatureExporter::get_controller_id(Object *ob_arm, Object *ob) // ob should be of type OB_MESH // both args are required -void ArmatureExporter::export_controller(Object* ob, Object *ob_arm) +void ArmatureExporter::export_controller(Object *ob, Object *ob_arm) { // joint names // joint inverse bind matrices @@ -302,29 +306,29 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm) // joint names: ob -> vertex group names // vertex group weights: me->dvert -> groups -> index, weight - /* - me->dvert: +#if 0 + me->dvert : typedef struct MDeformVert { struct MDeformWeight *dw; int totweight; - int flag; // flag only in use for weightpaint now + int flag; // flag only in use for weightpaint now } MDeformVert; typedef struct MDeformWeight { - int def_nr; - float weight; + int def_nr; + float weight; } MDeformWeight; - */ +#endif bool use_instantiation = this->export_settings->use_object_instantiation; Mesh *me; - if ( this->export_settings->apply_modifiers ) { + if (this->export_settings->apply_modifiers) { me = bc_to_mesh_apply_modifiers(scene, ob); } else { - me = (Mesh*)ob->data; + me = (Mesh *)ob->data; } BKE_mesh_tessface_ensure(me); @@ -352,7 +356,7 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm) std::vector joint_index_by_def_index; bDeformGroup *def; - for (def = (bDeformGroup*)ob->defbase.first, i = 0, j = 0; def; def = def->next, i++) { + for (def = (bDeformGroup *)ob->defbase.first, i = 0, j = 0; def; def = def->next, i++) { if (is_bone_defgroup(ob_arm, def)) joint_index_by_def_index.push_back(j++); else @@ -375,18 +379,20 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm) } if (sumw > 0.0f) { - float invsumw = 1.0f/sumw; + float invsumw = 1.0f / sumw; vcounts.push_back(jw.size()); for (std::map::iterator m = jw.begin(); m != jw.end(); ++m) { joints.push_back((*m).first); - weights.push_back(invsumw*(*m).second); + weights.push_back(invsumw * (*m).second); } } else { vcounts.push_back(0); - /*vcounts.push_back(1); +#if 0 + vcounts.push_back(1); joints.push_back(-1); - weights.push_back(1.0f);*/ + weights.push_back(1.0f); +#endif } } } @@ -404,15 +410,15 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm) } void ArmatureExporter::add_joints_element(ListBase *defbase, - const std::string& joints_source_id, const std::string& inv_bind_mat_source_id) + const std::string& joints_source_id, const std::string& inv_bind_mat_source_id) { COLLADASW::JointsElement joints(mSW); COLLADASW::InputList &input = joints.getInputList(); input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id))); + COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id))); input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::BINDMATRIX, - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id))); + COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id))); joints.add(); } @@ -431,7 +437,7 @@ std::string ArmatureExporter::add_joints_source(Object *ob_arm, ListBase *defbas int totjoint = 0; bDeformGroup *def; - for (def = (bDeformGroup*)defbase->first; def; def = def->next) { + for (def = (bDeformGroup *)defbase->first; def; def = def->next) { if (is_bone_defgroup(ob_arm, def)) totjoint++; } @@ -447,7 +453,7 @@ std::string ArmatureExporter::add_joints_source(Object *ob_arm, ListBase *defbas source.prepareToAppendValues(); - for (def = (bDeformGroup*)defbase->first; def; def = def->next) { + for (def = (bDeformGroup *)defbase->first; def; def = def->next) { Bone *bone = get_bone_from_defgroup(ob_arm, def); if (bone) source.appendValues(get_joint_sid(bone, ob_arm)); @@ -463,7 +469,7 @@ std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX; int totjoint = 0; - for (bDeformGroup *def = (bDeformGroup*)defbase->first; def; def = def->next) { + for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) { if (is_bone_defgroup(ob_arm, def)) totjoint++; } @@ -481,7 +487,7 @@ std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase source.prepareToAppendValues(); bPose *pose = ob_arm->pose; - bArmature *arm = (bArmature*)ob_arm->data; + bArmature *arm = (bArmature *)ob_arm->data; int flag = arm->flag; @@ -491,7 +497,7 @@ std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase BKE_pose_where_is(scene, ob_arm); } - for (bDeformGroup *def = (bDeformGroup*)defbase->first; def; def = def->next) { + for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) { if (is_bone_defgroup(ob_arm, def)) { bPoseChannel *pchan = BKE_pose_channel_find_name(pose, def->name); @@ -530,13 +536,13 @@ std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase return source_id; } -Bone *ArmatureExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup* def) +Bone *ArmatureExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def) { bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, def->name); return pchan ? pchan->bone : NULL; } -bool ArmatureExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup* def) +bool ArmatureExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup *def) { return get_bone_from_defgroup(ob_arm, def) != NULL; } @@ -566,17 +572,17 @@ std::string ArmatureExporter::add_weights_source(Mesh *me, const std::string& co } void ArmatureExporter::add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id, - const std::list& vcounts, - const std::list& joints) + const std::list& vcounts, + const std::list& joints) { COLLADASW::VertexWeightsElement weightselem(mSW); COLLADASW::InputList &input = weightselem.getInputList(); int offset = 0; input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id), offset++)); + COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id), offset++)); input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::WEIGHT, - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), offset++)); + COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), offset++)); weightselem.setCount(vcounts.size()); diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index f23b2bf4b02..c58b6f3101d 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -50,7 +50,8 @@ static const char *bc_get_joint_name(T *node) } ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce) : - TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh), anim_importer(anim) {} + TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh), anim_importer(anim) { +} ArmatureImporter::~ArmatureImporter() { @@ -68,7 +69,7 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node); if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) { fprintf(stderr, "Cannot find a joint index by joint id for %s.\n", - node->getOriginalId().c_str()); + node->getOriginalId().c_str()); return NULL; } @@ -77,12 +78,12 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node); return &joint_index_to_joint_info_map[joint_index]; } #endif -void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], Object * ob_arm) +void ArmatureImporter::create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild, + float parent_mat[][4], Object *ob_arm) { - std::vector::iterator it; + std::vector::iterator it; it = std::find(finished_joints.begin(), finished_joints.end(), node); - if ( it != finished_joints.end()) return; + if (it != finished_joints.end()) return; float mat[4][4]; float obmat[4][4]; @@ -90,7 +91,7 @@ void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *p // object-space get_node_mat(obmat, node, NULL, NULL); - EditBone *bone = ED_armature_edit_bone_add((bArmature*)ob_arm->data, (char*)bc_get_joint_name(node)); + EditBone *bone = ED_armature_edit_bone_add((bArmature *)ob_arm->data, (char *)bc_get_joint_name(node)); totbone++; if (parent) bone->parent = parent; @@ -107,9 +108,9 @@ void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *p } float loc[3], size[3], rot[3][3]; - mat4_to_loc_rot_size( loc, rot, size, obmat); - mat3_to_vec_roll(rot, NULL, &angle ); - bone->roll=angle; + mat4_to_loc_rot_size(loc, rot, size, obmat); + mat3_to_vec_roll(rot, NULL, &angle); + bone->roll = angle; // set head copy_v3_v3(bone->head, mat[3]); @@ -142,7 +143,7 @@ void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *p COLLADAFW::NodePointerArray& children = node->getChildNodes(); for (unsigned int i = 0; i < children.getCount(); i++) { - create_unskinned_bone( children[i], bone, children.getCount(), mat, ob_arm); + create_unskinned_bone(children[i], bone, children.getCount(), mat, ob_arm); } // in second case it's not a leaf bone, but we handle it the same way @@ -155,12 +156,12 @@ void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *p } void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], bArmature *arm) + float parent_mat[][4], bArmature *arm) { //Checking if bone is already made. - std::vector::iterator it; + std::vector::iterator it; it = std::find(finished_joints.begin(), finished_joints.end(), node); - if ( it != finished_joints.end()) return; + if (it != finished_joints.end()) return; float joint_inv_bind_mat[4][4]; @@ -169,7 +170,7 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo float mat[4][4]; // TODO rename from Node "name" attrs later - EditBone *bone = ED_armature_edit_bone_add(arm, (char*)bc_get_joint_name(node)); + EditBone *bone = ED_armature_edit_bone_add(arm, (char *)bc_get_joint_name(node)); totbone++; if (skin.get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) { @@ -190,9 +191,9 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo copy_m4_m4(mat, obmat); float loc[3], size[3], rot[3][3], angle; - mat4_to_loc_rot_size( loc, rot, size, obmat); - mat3_to_vec_roll(rot, NULL, &angle ); - bone->roll=angle; + mat4_to_loc_rot_size(loc, rot, size, obmat); + mat3_to_vec_roll(rot, NULL, &angle); + bone->roll = angle; } @@ -267,7 +268,7 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo finished_joints.push_back(node); } -void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node * node) +void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node *node) { LeafBone leaf; @@ -337,7 +338,7 @@ void ArmatureImporter::set_euler_rotmode() { // just set rotmode = ROT_MODE_EUL on pose channel for each joint - std::map::iterator it; + std::map::iterator it; for (it = joint_by_uid.begin(); it != joint_by_uid.end(); it++) { @@ -378,7 +379,7 @@ Object *ArmatureImporter::get_empty_for_leaves() #if 0 Object *ArmatureImporter::find_armature(COLLADAFW::Node *node) { - JointData* jd = get_joint_data(node); + JointData *jd = get_joint_data(node); if (jd) return jd->ob_arm; COLLADAFW::NodePointerArray& children = node->getChildNodes(); @@ -408,10 +409,10 @@ ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm) #endif void ArmatureImporter::create_armature_bones( ) { - std::vector::iterator ri; + std::vector::iterator ri; //if there is an armature created for root_joint next root_joint for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { - if ( get_armature_for_joint(*ri) != NULL ) continue; + if (get_armature_for_joint(*ri) != NULL) continue; //add armature object for current joint //Object *ob_arm = bc_add_object(scene, OB_ARMATURE, NULL); @@ -428,9 +429,9 @@ void ArmatureImporter::create_armature_bones( ) // create unskinned bones /* - TODO: - check if bones have already been created for a given joint - */ + * TODO: + * check if bones have already been created for a given joint + */ leaf_bone_length = FLT_MAX; create_unskinned_bone(*ri, NULL, (*ri)->getChildNodes().getCount(), NULL, ob_arm); @@ -442,10 +443,10 @@ void ArmatureImporter::create_armature_bones( ) ED_armature_from_edit(ob_arm); - set_pose(ob_arm, *ri, NULL, NULL ); + set_pose(ob_arm, *ri, NULL, NULL); ED_armature_edit_free(ob_arm); - DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA); + DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA); } @@ -496,7 +497,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) SkinInfo *a = &skin; Object *shared = NULL; - std::vector skin_root_joints; + std::vector skin_root_joints; std::map::iterator it; for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { @@ -508,7 +509,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) b->find_root_joints(root_joints, joint_by_uid, skin_root_joints); - std::vector::iterator ri; + std::vector::iterator ri; for (ri = skin_root_joints.begin(); ri != skin_root_joints.end(); ri++) { if (a->uses_joint_or_descendant(*ri)) { shared = b->BKE_armature_from_object(); @@ -523,7 +524,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) if (shared) ob_arm = skin.set_armature(shared); else - ob_arm = skin.create_armature(scene); //once for every armature + ob_arm = skin.create_armature(scene); //once for every armature // enter armature edit mode ED_armature_to_edit(ob_arm); @@ -538,9 +539,9 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) /* TODO: check if bones have already been created for a given joint - */ + */ - std::vector::iterator ri; + std::vector::iterator ri; for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { // for shared armature check if bone tree is already created if (shared && std::find(skin_root_joints.begin(), skin_root_joints.end(), *ri) != skin_root_joints.end()) @@ -548,7 +549,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) // since root_joints may contain joints for multiple controllers, we need to filter if (skin.uses_joint_or_descendant(*ri)) { - create_bone(skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature*)ob_arm->data); + create_bone(skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature *)ob_arm->data); if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent()) skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]); @@ -560,7 +561,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) // exit armature edit mode ED_armature_from_edit(ob_arm); ED_armature_edit_free(ob_arm); - DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA); + DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA); // set_leaf_bone_shapes(ob_arm); // set_euler_rotmode(); @@ -571,9 +572,9 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) // is a child of a node (not joint), root should be true since // this is where we build armature bones from -void ArmatureImporter::set_pose(Object * ob_arm, COLLADAFW::Node * root_node, const char *parentname, float parent_mat[][4]) +void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[][4]) { - char * bone_name = (char *) bc_get_joint_name ( root_node); + char *bone_name = (char *) bc_get_joint_name(root_node); float mat[4][4]; float obmat[4][4]; @@ -584,7 +585,7 @@ void ArmatureImporter::set_pose(Object * ob_arm, COLLADAFW::Node * root_node, c get_node_mat(obmat, root_node, NULL, NULL); //if (*edbone) - bPoseChannel * pchan = BKE_pose_channel_find_name(ob_arm -> pose, bone_name); + bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone_name); //else fprintf ( "", // get world-space @@ -592,7 +593,7 @@ void ArmatureImporter::set_pose(Object * ob_arm, COLLADAFW::Node * root_node, c mult_m4_m4m4(mat, parent_mat, obmat); bPoseChannel *parchan = BKE_pose_channel_find_name(ob_arm->pose, parentname); - mult_m4_m4m4(pchan->pose_mat, parchan->pose_mat, mat ); + mult_m4_m4m4(pchan->pose_mat, parchan->pose_mat, mat); } else { @@ -631,7 +632,7 @@ void ArmatureImporter::add_root_joint(COLLADAFW::Node *node) { // root_joints.push_back(node); Object *ob_arm = find_armature(node); - if (ob_arm) { + if (ob_arm) { get_armature_joints(ob_arm).root_joints.push_back(node); } #ifdef COLLADA_DEBUG @@ -694,7 +695,7 @@ void ArmatureImporter::link_armature(Object *ob_arm, const COLLADAFW::UniqueId& } #endif -bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControllerData* data) +bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControllerData *data) { // at this stage we get vertex influence info that should go into me->verts and ob->defbase // there's no info to which object this should be long so we associate it with skin controller data UID @@ -719,14 +720,14 @@ bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControlle return true; } -bool ArmatureImporter::write_controller(const COLLADAFW::Controller* controller) +bool ArmatureImporter::write_controller(const COLLADAFW::Controller *controller) { // - create and store armature object const COLLADAFW::UniqueId& skin_id = controller->getUniqueId(); if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) { - COLLADAFW::SkinController *co = (COLLADAFW::SkinController*)controller; + COLLADAFW::SkinController *co = (COLLADAFW::SkinController *)controller; // to be able to find geom id by controller id geom_uid_by_controller_uid[skin_id] = co->getSource(); @@ -766,7 +767,7 @@ Object *ArmatureImporter::get_armature_for_joint(COLLADAFW::Node *node) return skin.BKE_armature_from_object(); } - std::map::iterator arm; + std::map::iterator arm; for (arm = unskinned_armature_map.begin(); arm != unskinned_armature_map.end(); arm++) { if (arm->first == node->getUniqueId() ) return arm->second; @@ -799,6 +800,3 @@ bool ArmatureImporter::get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint) return found; } - - - diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp index 4e7f2f0434f..be424fbbb4d 100644 --- a/source/blender/collada/CameraExporter.cpp +++ b/source/blender/collada/CameraExporter.cpp @@ -37,13 +37,14 @@ extern "C" { #include "collada_internal.h" -CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): COLLADASW::LibraryCameras(sw), export_settings(export_settings) {} +CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryCameras(sw), export_settings(export_settings) { +} template void forEachCameraObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) { LinkNode *node; - for(node=export_set; node; node = node->next) { + for (node = export_set; node; node = node->next) { Object *ob = (Object *)node->link; if (ob->type == OB_CAMERA && ob->data) { @@ -63,32 +64,33 @@ void CamerasExporter::exportCameras(Scene *sce) void CamerasExporter::operator()(Object *ob, Scene *sce) { // TODO: shiftx, shifty, YF_dofdist - Camera *cam = (Camera*)ob->data; + Camera *cam = (Camera *)ob->data; std::string cam_id(get_camera_id(ob)); std::string cam_name(id_name(cam)); switch (cam->type) { - case CAM_PANO: - case CAM_PERSP: { - COLLADASW::PerspectiveOptic persp(mSW); - persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov"); - persp.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch), false, "aspect_ratio"); - persp.setZFar(cam->clipend, false, "zfar"); - persp.setZNear(cam->clipsta, false, "znear"); - COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name); - addCamera(ccam); - break; + case CAM_PANO: + case CAM_PERSP: { + COLLADASW::PerspectiveOptic persp(mSW); + persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov"); + persp.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio"); + persp.setZFar(cam->clipend, false, "zfar"); + persp.setZNear(cam->clipsta, false, "znear"); + COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name); + addCamera(ccam); + break; + } + case CAM_ORTHO: + default: + { + COLLADASW::OrthographicOptic ortho(mSW); + ortho.setXMag(cam->ortho_scale, "xmag"); + ortho.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio"); + ortho.setZFar(cam->clipend, false, "zfar"); + ortho.setZNear(cam->clipsta, false, "znear"); + COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name); + addCamera(ccam); + break; + } } - case CAM_ORTHO: - default: - { - COLLADASW::OrthographicOptic ortho(mSW); - ortho.setXMag(cam->ortho_scale, "xmag"); - ortho.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch), false, "aspect_ratio"); - ortho.setZFar(cam->clipend, false, "zfar"); - ortho.setZNear(cam->clipsta, false, "znear"); - COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name); - addCamera(ccam); - break; - }} } diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 4e84eba500c..c47798ee804 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -134,7 +134,7 @@ char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int int layer_index = CustomData_get_layer_index(data, type); if (layer_index < 0) return NULL; - return data->layers[layer_index+n].name; + return data->layers[layer_index + n].name; } char *bc_CustomData_get_active_layer_name(const CustomData *data, int type) @@ -146,7 +146,8 @@ char *bc_CustomData_get_active_layer_name(const CustomData *data, int type) return data->layers[layer_index].name; } -DocumentExporter::DocumentExporter(const ExportSettings *export_settings) : export_settings(export_settings) {} +DocumentExporter::DocumentExporter(const ExportSettings *export_settings) : export_settings(export_settings) { +} // TODO: it would be better to instantiate animations rather than create a new one per object // COLLADA allows this through multiple s in . @@ -160,7 +161,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce) clear_global_id_map(); COLLADABU::NativeString native_filename = - COLLADABU::NativeString(std::string(this->export_settings->filepath)); + COLLADABU::NativeString(std::string(this->export_settings->filepath)); COLLADASW::StreamWriter sw(native_filename); // open @@ -221,9 +222,9 @@ void DocumentExporter::exportCurrentScene(Scene *sce) } char version_buf[128]; #ifdef WITH_BUILDINFO - sprintf(version_buf, "Blender %d.%02d.%d r%s", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION, build_rev); + sprintf(version_buf, "Blender %d.%02d.%d r%s", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION, build_rev); #else - sprintf(version_buf, "Blender %d.%02d.%d", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION); + sprintf(version_buf, "Blender %d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION); #endif asset.getContributor().mAuthoringTool = version_buf; asset.add(); @@ -276,7 +277,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce) // std::string scene_name(translate_id(id_name(sce))); COLLADASW::Scene scene(&sw, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, - scene_name)); + scene_name)); scene.add(); // close @@ -284,14 +285,13 @@ void DocumentExporter::exportCurrentScene(Scene *sce) } -void DocumentExporter::exportScenes(const char* filename) +void DocumentExporter::exportScenes(const char *filename) { } /* - -NOTES: - -* AnimationExporter::sample_animation enables all curves on armature, this is undesirable for a user - + * NOTES: + * + * AnimationExporter::sample_animation enables all curves on armature, this is undesirable for a user + * */ diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index fa85e7527ff..6c9d277de54 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -88,8 +88,8 @@ extern "C" { /* - COLLADA Importer limitations: - - no multiple scene import, all objects are added to active scene + COLLADA Importer limitations: + - no multiple scene import, all objects are added to active scene */ // #define COLLADA_DEBUG @@ -103,13 +103,14 @@ DocumentImporter::DocumentImporter(bContext *C, const char *filename) : armature_importer(&unit_converter, &mesh_importer, &anim_importer, CTX_data_scene(C)), mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)), anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C)) -{} +{ +} DocumentImporter::~DocumentImporter() { TagsMap::iterator etit; etit = uid_tags_map.begin(); - while (etit!=uid_tags_map.end()) { + while (etit != uid_tags_map.end()) { delete etit->second; etit++; } @@ -171,11 +172,11 @@ void DocumentImporter::start() void DocumentImporter::finish() { - if (mImportStage!=General) + if (mImportStage != General) return; /** TODO Break up and put into 2-pass parsing of DAE */ - std::vector::iterator it; + std::vector::iterator it; for (it = vscenes.begin(); it != vscenes.end(); it++) { PointerRNA sceneptr, unit_settings; PropertyRNA *system, *scale; @@ -214,7 +215,7 @@ void DocumentImporter::finish() armature_importer.fix_animation(); #endif - for (std::vector::iterator it = vscenes.begin(); it != vscenes.end(); it++) { + for (std::vector::iterator it = vscenes.begin(); it != vscenes.end(); it++) { const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes(); for (unsigned int i = 0; i < roots.getCount(); i++) @@ -226,7 +227,7 @@ void DocumentImporter::finish() fprintf(stderr, "got %d library nodes to free\n", (int)libnode_ob.size()); // free all library_nodes - std::vector::iterator it; + std::vector::iterator it; for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) { Object *ob = *it; @@ -234,8 +235,8 @@ void DocumentImporter::finish() if (base) { BLI_remlink(&sce->base, base); BKE_libblock_free_us(&G.main->object, base->object); - if (sce->basact==base) - sce->basact= NULL; + if (sce->basact == base) + sce->basact = NULL; MEM_freeN(base); } } @@ -265,18 +266,20 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW root_map[node->getUniqueId()] = root_map[par->getUniqueId()]; } - /*COLLADAFW::Transformation::TransformationType types[] = { +#if 0 + COLLADAFW::Transformation::TransformationType types[] = { COLLADAFW::Transformation::ROTATE, COLLADAFW::Transformation::SCALE, COLLADAFW::Transformation::TRANSLATE, COLLADAFW::Transformation::MATRIX }; - Object *ob;*/ + Object *ob; +#endif unsigned int i; //for (i = 0; i < 4; i++) - //ob = + // ob = anim_importer.translate_Animations(node, root_map, object_map, FW_object_map); COLLADAFW::NodePointerArray &children = node->getChildNodes(); @@ -286,8 +289,8 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW } /** When this method is called, the writer must write the global document asset. - \return The writer should return true, if writing succeeded, false otherwise.*/ -bool DocumentImporter::writeGlobalAsset ( const COLLADAFW::FileInfo* asset ) + * \return The writer should return true, if writing succeeded, false otherwise.*/ +bool DocumentImporter::writeGlobalAsset(const COLLADAFW::FileInfo *asset) { unit_converter.read_asset(asset); @@ -295,13 +298,13 @@ bool DocumentImporter::writeGlobalAsset ( const COLLADAFW::FileInfo* asset ) } /** When this method is called, the writer must write the scene. - \return The writer should return true, if writing succeeded, false otherwise.*/ -bool DocumentImporter::writeScene ( const COLLADAFW::Scene* scene ) + * \return The writer should return true, if writing succeeded, false otherwise.*/ +bool DocumentImporter::writeScene(const COLLADAFW::Scene *scene) { // XXX could store the scene id, but do nothing for now return true; } -Object* DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce) +Object *DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce) { const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId(); if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) { @@ -311,7 +314,7 @@ Object* DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera Object *ob = bc_add_object(sce, OB_CAMERA, NULL); Camera *cam = uid_camera_map[cam_uid]; - Camera *old_cam = (Camera*)ob->data; + Camera *old_cam = (Camera *)ob->data; ob->data = cam; old_cam->id.us--; if (old_cam->id.us == 0) @@ -319,7 +322,7 @@ Object* DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera return ob; } -Object* DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Scene *sce) +Object *DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Scene *sce) { const COLLADAFW::UniqueId& lamp_uid = lamp->getInstanciatedObjectId(); if (uid_lamp_map.find(lamp_uid) == uid_lamp_map.end()) { @@ -329,7 +332,7 @@ Object* DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Sce Object *ob = bc_add_object(sce, OB_LAMP, NULL); Lamp *la = uid_lamp_map[lamp_uid]; - Lamp *old_lamp = (Lamp*)ob->data; + Lamp *old_lamp = (Lamp *)ob->data; ob->data = la; old_lamp->id.us--; if (old_lamp->id.us == 0) @@ -337,12 +340,12 @@ Object* DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Sce return ob; } -Object* DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, bool is_library_node) +Object *DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, bool is_library_node) { fprintf(stderr, "create under node id=%s from node id=%s\n", instance_node ? instance_node->getOriginalId().c_str() : NULL, source_node ? source_node->getOriginalId().c_str() : NULL); Object *obn = BKE_object_copy(source_ob); - obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; + obn->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; BKE_scene_base_add(sce, obn); if (instance_node) { @@ -399,21 +402,21 @@ Object* DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Nod return obn; } -void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node) +void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node) { Object *ob = NULL; bool is_joint = node->getType() == COLLADAFW::Node::JOINT; bool read_transform = true; - std::vector * objects_done = new std::vector(); + std::vector *objects_done = new std::vector(); if (is_joint) { - if ( par ) { - Object * empty = par; - par = bc_add_object(sce, OB_ARMATURE, NULL); - bc_set_parent(par, empty->parent, mContext); - //remove empty : todo - object_map.insert(std::make_pair(parent_node->getUniqueId(), par)); + if (par) { + Object *empty = par; + par = bc_add_object(sce, OB_ARMATURE, NULL); + bc_set_parent(par, empty->parent, mContext); + //remove empty : todo + object_map.insert(std::make_pair(parent_node->getUniqueId(), par)); } armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par, sce); } @@ -434,7 +437,7 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren // while (geom_done < geom.getCount()) { ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map, - material_texture_mapping_map); + material_texture_mapping_map); objects_done->push_back(ob); ++geom_done; } @@ -449,7 +452,7 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren ++lamp_done; } while (controller_done < controller.getCount()) { - COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry*)controller[controller_done]; + COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry *)controller[controller_done]; ob = mesh_importer.create_mesh_object(node, geom, true, uid_material_map, material_texture_mapping_map); objects_done->push_back(ob); ++controller_done; @@ -487,7 +490,7 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren for (std::vector::iterator it = objects_done->begin(); it != objects_done->end(); ++it) { ob = *it; std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId(); - rename_id(&ob->id, (char*)nodename.c_str()); + rename_id(&ob->id, (char *)nodename.c_str()); object_map.insert(std::make_pair(node->getUniqueId(), ob)); node_map[node->getUniqueId()] = node; @@ -498,10 +501,10 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren } for (std::vector::iterator it = objects_done->begin(); it != objects_done->end(); ++it) { - ob =*it; + ob = *it; if (read_transform) - anim_importer.read_node_transform(node, ob); // overwrites location set earlier + anim_importer.read_node_transform(node, ob); // overwrites location set earlier if (!is_joint) { // if par was given make this object child of the previous @@ -517,10 +520,10 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren } /** When this method is called, the writer must write the entire visual scene. - \return The writer should return true, if writing succeeded, false otherwise.*/ -bool DocumentImporter::writeVisualScene ( const COLLADAFW::VisualScene* visualScene ) + * \return The writer should return true, if writing succeeded, false otherwise.*/ +bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScene) { - if (mImportStage!=General) + if (mImportStage != General) return true; // this method called on post process after writeGeometry, writeMaterial, etc. @@ -539,11 +542,11 @@ bool DocumentImporter::writeVisualScene ( const COLLADAFW::VisualScene* visualSc } /** When this method is called, the writer must handle all nodes contained in the - library nodes. - \return The writer should return true, if writing succeeded, false otherwise.*/ -bool DocumentImporter::writeLibraryNodes ( const COLLADAFW::LibraryNodes* libraryNodes ) +* library nodes. +* \return The writer should return true, if writing succeeded, false otherwise.*/ +bool DocumentImporter::writeLibraryNodes(const COLLADAFW::LibraryNodes *libraryNodes) { - if (mImportStage!=General) + if (mImportStage != General) return true; Scene *sce = CTX_data_scene(mContext); @@ -558,24 +561,24 @@ bool DocumentImporter::writeLibraryNodes ( const COLLADAFW::LibraryNodes* librar } /** When this method is called, the writer must write the geometry. - \return The writer should return true, if writing succeeded, false otherwise.*/ -bool DocumentImporter::writeGeometry ( const COLLADAFW::Geometry* geom ) + * \return The writer should return true, if writing succeeded, false otherwise.*/ +bool DocumentImporter::writeGeometry(const COLLADAFW::Geometry *geom) { - if (mImportStage!=General) + if (mImportStage != General) return true; return mesh_importer.write_geometry(geom); } /** When this method is called, the writer must write the material. - \return The writer should return true, if writing succeeded, false otherwise.*/ -bool DocumentImporter::writeMaterial( const COLLADAFW::Material* cmat ) + * \return The writer should return true, if writing succeeded, false otherwise.*/ +bool DocumentImporter::writeMaterial(const COLLADAFW::Material *cmat) { - if (mImportStage!=General) + if (mImportStage != General) return true; const std::string& str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId(); - Material *ma = BKE_material_add((char*)str_mat_id.c_str()); + Material *ma = BKE_material_add((char *)str_mat_id.c_str()); this->uid_effect_map[cmat->getInstantiatedEffect()] = ma; this->uid_material_map[cmat->getUniqueId()] = ma; @@ -584,8 +587,8 @@ bool DocumentImporter::writeMaterial( const COLLADAFW::Material* cmat ) } // create mtex, create texture, set texture image -MTex* DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma, - int i, TexIndexTextureArrayMap &texindex_texarray_map) +MTex *DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma, + int i, TexIndexTextureArrayMap &texindex_texarray_map) { COLLADAFW::SamplerPointerArray& samp_array = ef->getSamplerPointerArray(); COLLADAFW::Sampler *sampler = samp_array[ctex.getSamplerId()]; @@ -735,32 +738,34 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia mtex->tex->imaflag |= TEX_USEALPHA; i++; ma->spectra = ma->alpha = 0; - ma->mode |= MA_ZTRANSP|MA_TRANSP; + ma->mode |= MA_ZTRANSP | MA_TRANSP; } } // TRANSPARENT // color -// if (ef->getOpacity().isColor()) { -// // XXX don't know what to do here -// } -// // texture -// else if (ef->getOpacity().isTexture()) { -// ctex = ef->getOpacity().getTexture(); -// if (mtex != NULL) mtex->mapto &= MAP_ALPHA; -// else { -// mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); -// if (mtex != NULL) mtex->mapto = MAP_ALPHA; -// } -// } +#if 0 + if (ef->getOpacity().isColor()) { + // XXX don't know what to do here + } + // texture + else if (ef->getOpacity().isTexture()) { + ctex = ef->getOpacity().getTexture(); + if (mtex != NULL) mtex->mapto &= MAP_ALPHA; + else { + mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); + if (mtex != NULL) mtex->mapto = MAP_ALPHA; + } + } +#endif material_texture_mapping_map[ma] = texindex_texarray_map; } /** When this method is called, the writer must write the effect. - \return The writer should return true, if writing succeeded, false otherwise.*/ + * \return The writer should return true, if writing succeeded, false otherwise.*/ -bool DocumentImporter::writeEffect( const COLLADAFW::Effect* effect ) +bool DocumentImporter::writeEffect(const COLLADAFW::Effect *effect) { - if (mImportStage!=General) + if (mImportStage != General) return true; const COLLADAFW::UniqueId& uid = effect->getUniqueId(); @@ -771,9 +776,9 @@ bool DocumentImporter::writeEffect( const COLLADAFW::Effect* effect ) } Material *ma = uid_effect_map[uid]; - std::map::iterator iter; - for (iter = uid_material_map.begin(); iter != uid_material_map.end() ; iter++ ) { - if ( iter->second == ma ) { + std::map::iterator iter; + for (iter = uid_material_map.begin(); iter != uid_material_map.end(); iter++) { + if (iter->second == ma) { this->FW_object_map[iter->first] = effect; break; } @@ -794,10 +799,10 @@ bool DocumentImporter::writeEffect( const COLLADAFW::Effect* effect ) /** When this method is called, the writer must write the camera. - \return The writer should return true, if writing succeeded, false otherwise.*/ -bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) + * \return The writer should return true, if writing succeeded, false otherwise.*/ +bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera) { - if (mImportStage!=General) + if (mImportStage != General) return true; Camera *cam = NULL; @@ -805,8 +810,8 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) cam_id = camera->getOriginalId(); cam_name = camera->getName(); - if (cam_name.size()) cam = (Camera *)BKE_camera_add((char*)cam_name.c_str()); - else cam = (Camera *)BKE_camera_add((char*)cam_id.c_str()); + if (cam_name.size()) cam = (Camera *)BKE_camera_add((char *)cam_name.c_str()); + else cam = (Camera *)BKE_camera_add((char *)cam_id.c_str()); if (!cam) { fprintf(stderr, "Cannot create camera.\n"); @@ -817,17 +822,17 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) COLLADAFW::Camera::CameraType type = camera->getCameraType(); switch (type) { - case COLLADAFW::Camera::ORTHOGRAPHIC: + case COLLADAFW::Camera::ORTHOGRAPHIC: { cam->type = CAM_ORTHO; } break; - case COLLADAFW::Camera::PERSPECTIVE: + case COLLADAFW::Camera::PERSPECTIVE: { cam->type = CAM_PERSP; } break; - case COLLADAFW::Camera::UNDEFINED_CAMERATYPE: + case COLLADAFW::Camera::UNDEFINED_CAMERATYPE: { fprintf(stderr, "Current camera type is not supported.\n"); cam->type = CAM_PERSP; @@ -836,35 +841,35 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) } switch (camera->getDescriptionType()) { - case COLLADAFW::Camera::ASPECTRATIO_AND_Y: + case COLLADAFW::Camera::ASPECTRATIO_AND_Y: { switch (cam->type) { case CAM_ORTHO: - { - double ymag = camera->getYMag().getValue(); - double aspect = camera->getAspectRatio().getValue(); - double xmag = aspect*ymag; - cam->ortho_scale = (float)xmag; - } - break; + { + double ymag = camera->getYMag().getValue(); + double aspect = camera->getAspectRatio().getValue(); + double xmag = aspect * ymag; + cam->ortho_scale = (float)xmag; + } + break; case CAM_PERSP: default: - { - double yfov = camera->getYFov().getValue(); - double aspect = camera->getAspectRatio().getValue(); - double xfov = aspect*yfov; - // xfov is in degrees, cam->lens is in millimiters - cam->lens = fov_to_focallength(DEG2RADF(xfov), cam->sensor_x); - } - break; + { + double yfov = camera->getYFov().getValue(); + double aspect = camera->getAspectRatio().getValue(); + double xfov = aspect * yfov; + // xfov is in degrees, cam->lens is in millimiters + cam->lens = fov_to_focallength(DEG2RADF(xfov), cam->sensor_x); + } + break; } } break; - /* XXX correct way to do following four is probably to get also render - size and determine proper settings from that somehow */ - case COLLADAFW::Camera::ASPECTRATIO_AND_X: - case COLLADAFW::Camera::SINGLE_X: - case COLLADAFW::Camera::X_AND_Y: + /* XXX correct way to do following four is probably to get also render + size and determine proper settings from that somehow */ + case COLLADAFW::Camera::ASPECTRATIO_AND_X: + case COLLADAFW::Camera::SINGLE_X: + case COLLADAFW::Camera::X_AND_Y: { switch (cam->type) { case CAM_ORTHO: @@ -872,16 +877,16 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) break; case CAM_PERSP: default: - { - double x = camera->getXFov().getValue(); - // x is in degrees, cam->lens is in millimiters - cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x); - } - break; + { + double x = camera->getXFov().getValue(); + // x is in degrees, cam->lens is in millimiters + cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x); + } + break; } } break; - case COLLADAFW::Camera::SINGLE_Y: + case COLLADAFW::Camera::SINGLE_Y: { switch (cam->type) { case CAM_ORTHO: @@ -889,18 +894,18 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) break; case CAM_PERSP: default: - { + { double yfov = camera->getYFov().getValue(); // yfov is in degrees, cam->lens is in millimiters cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x); - } - break; + } + break; } } break; - case COLLADAFW::Camera::UNDEFINED: - // read nothing, use blender defaults. - break; + case COLLADAFW::Camera::UNDEFINED: + // read nothing, use blender defaults. + break; } this->uid_camera_map[camera->getUniqueId()] = cam; @@ -910,15 +915,15 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) } /** When this method is called, the writer must write the image. - \return The writer should return true, if writing succeeded, false otherwise.*/ -bool DocumentImporter::writeImage( const COLLADAFW::Image* image ) + * \return The writer should return true, if writing succeeded, false otherwise.*/ +bool DocumentImporter::writeImage(const COLLADAFW::Image *image) { - if (mImportStage!=General) + if (mImportStage != General) return true; // XXX maybe it is necessary to check if the path is absolute or relative const std::string& filepath = image->getImageURI().toNativePath(); - const char *filename = (const char*)mFilename.c_str(); + const char *filename = (const char *)mFilename.c_str(); char dir[FILE_MAX]; char full_path[FILE_MAX]; @@ -935,10 +940,10 @@ bool DocumentImporter::writeImage( const COLLADAFW::Image* image ) } /** When this method is called, the writer must write the light. - \return The writer should return true, if writing succeeded, false otherwise.*/ -bool DocumentImporter::writeLight( const COLLADAFW::Light* light ) + * \return The writer should return true, if writing succeeded, false otherwise.*/ +bool DocumentImporter::writeLight(const COLLADAFW::Light *light) { - if (mImportStage!=General) + if (mImportStage != General) return true; Lamp *lamp = NULL; @@ -952,8 +957,8 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light ) la_id = light->getOriginalId(); la_name = light->getName(); - if (la_name.size()) lamp = (Lamp*)BKE_lamp_add((char*)la_name.c_str()); - else lamp = (Lamp*)BKE_lamp_add((char*)la_id.c_str()); + if (la_name.size()) lamp = (Lamp *)BKE_lamp_add((char *)la_name.c_str()); + else lamp = (Lamp *)BKE_lamp_add((char *)la_id.c_str()); if (!lamp) { fprintf(stderr, "Cannot create lamp.\n"); @@ -1036,12 +1041,12 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light ) if (IS_EQ(linatt, 0.0f) && quadatt > 0.0f) { att2 = quadatt; - d = sqrt(1.0f/quadatt); + d = sqrt(1.0f / quadatt); } // linear light else if (IS_EQ(quadatt, 0.0f) && linatt > 0.0f) { att1 = linatt; - d = (1.0f/linatt); + d = (1.0f / linatt); } else if (IS_EQ(constatt, 1.0f)) { att1 = 1.0f; @@ -1051,7 +1056,7 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light ) att1 = 1.0f; } - d *= ( 1.0f / unit_converter.getLinearMeter()); + d *= (1.0f / unit_converter.getLinearMeter()); lamp->energy = e; lamp->dist = d; @@ -1059,47 +1064,47 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light ) COLLADAFW::Light::LightType type = light->getLightType(); switch (type) { case COLLADAFW::Light::AMBIENT_LIGHT: - { - lamp->type = LA_HEMI; - } - break; + { + lamp->type = LA_HEMI; + } + break; case COLLADAFW::Light::SPOT_LIGHT: - { - lamp->type = LA_SPOT; - lamp->att1 = att1; - lamp->att2 = att2; - if (IS_EQ(att1, 0.0f) && att2 > 0) - lamp->falloff_type = LA_FALLOFF_INVSQUARE; - if (IS_EQ(att2, 0.0f) && att1 > 0) - lamp->falloff_type = LA_FALLOFF_INVLINEAR; - lamp->spotsize = light->getFallOffAngle().getValue(); - lamp->spotblend = light->getFallOffExponent().getValue(); - } - break; + { + lamp->type = LA_SPOT; + lamp->att1 = att1; + lamp->att2 = att2; + if (IS_EQ(att1, 0.0f) && att2 > 0) + lamp->falloff_type = LA_FALLOFF_INVSQUARE; + if (IS_EQ(att2, 0.0f) && att1 > 0) + lamp->falloff_type = LA_FALLOFF_INVLINEAR; + lamp->spotsize = light->getFallOffAngle().getValue(); + lamp->spotblend = light->getFallOffExponent().getValue(); + } + break; case COLLADAFW::Light::DIRECTIONAL_LIGHT: - { - /* our sun is very strong, so pick a smaller energy level */ - lamp->type = LA_SUN; - lamp->mode |= LA_NO_SPEC; - } - break; + { + /* our sun is very strong, so pick a smaller energy level */ + lamp->type = LA_SUN; + lamp->mode |= LA_NO_SPEC; + } + break; case COLLADAFW::Light::POINT_LIGHT: - { - lamp->type = LA_LOCAL; - lamp->att1 = att1; - lamp->att2 = att2; - if (IS_EQ(att1, 0.0f) && att2 > 0) - lamp->falloff_type = LA_FALLOFF_INVSQUARE; - if (IS_EQ(att2, 0.0f) && att1 > 0) - lamp->falloff_type = LA_FALLOFF_INVLINEAR; - } - break; + { + lamp->type = LA_LOCAL; + lamp->att1 = att1; + lamp->att2 = att2; + if (IS_EQ(att1, 0.0f) && att2 > 0) + lamp->falloff_type = LA_FALLOFF_INVSQUARE; + if (IS_EQ(att2, 0.0f) && att1 > 0) + lamp->falloff_type = LA_FALLOFF_INVLINEAR; + } + break; case COLLADAFW::Light::UNDEFINED: - { - fprintf(stderr, "Current lamp type is not supported.\n"); - lamp->type = LA_LOCAL; - } - break; + { + fprintf(stderr, "Current lamp type is not supported.\n"); + lamp->type = LA_LOCAL; + } + break; } } @@ -1109,9 +1114,9 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light ) } // this function is called only for animations that pass COLLADAFW::validate -bool DocumentImporter::writeAnimation( const COLLADAFW::Animation* anim ) +bool DocumentImporter::writeAnimation(const COLLADAFW::Animation *anim) { - if (mImportStage!=General) + if (mImportStage != General) return true; // return true; @@ -1119,9 +1124,9 @@ bool DocumentImporter::writeAnimation( const COLLADAFW::Animation* anim ) } // called on post-process stage after writeVisualScenes -bool DocumentImporter::writeAnimationList( const COLLADAFW::AnimationList* animationList ) +bool DocumentImporter::writeAnimationList(const COLLADAFW::AnimationList *animationList) { - if (mImportStage!=General) + if (mImportStage != General) return true; // return true; @@ -1129,40 +1134,40 @@ bool DocumentImporter::writeAnimationList( const COLLADAFW::AnimationList* anima } /** When this method is called, the writer must write the skin controller data. - \return The writer should return true, if writing succeeded, false otherwise.*/ -bool DocumentImporter::writeSkinControllerData( const COLLADAFW::SkinControllerData* skin ) + * \return The writer should return true, if writing succeeded, false otherwise.*/ +bool DocumentImporter::writeSkinControllerData(const COLLADAFW::SkinControllerData *skin) { return armature_importer.write_skin_controller_data(skin); } // this is called on postprocess, before writeVisualScenes -bool DocumentImporter::writeController( const COLLADAFW::Controller* controller ) +bool DocumentImporter::writeController(const COLLADAFW::Controller *controller) { - if (mImportStage!=General) + if (mImportStage != General) return true; return armature_importer.write_controller(controller); } -bool DocumentImporter::writeFormulas( const COLLADAFW::Formulas* formulas ) +bool DocumentImporter::writeFormulas(const COLLADAFW::Formulas *formulas) { return true; } -bool DocumentImporter::writeKinematicsScene( const COLLADAFW::KinematicsScene* kinematicsScene ) +bool DocumentImporter::writeKinematicsScene(const COLLADAFW::KinematicsScene *kinematicsScene) { return true; } -ExtraTags* DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid) +ExtraTags *DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid) { - if (uid_tags_map.find(uid.toAscii())==uid_tags_map.end()) { + if (uid_tags_map.find(uid.toAscii()) == uid_tags_map.end()) { return NULL; } return uid_tags_map[uid.toAscii()]; } -bool DocumentImporter::addExtraTags( const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags) +bool DocumentImporter::addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags) { uid_tags_map[uid.toAscii()] = extra_tags; return true; diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp index 644c350e8fe..3ed689628f7 100644 --- a/source/blender/collada/EffectExporter.cpp +++ b/source/blender/collada/EffectExporter.cpp @@ -46,7 +46,7 @@ // OB_MESH is assumed static std::string getActiveUVLayerName(Object *ob) { - Mesh *me = (Mesh*)ob->data; + Mesh *me = (Mesh *)ob->data; int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); if (num_layers) @@ -55,24 +55,25 @@ static std::string getActiveUVLayerName(Object *ob) return ""; } -EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryEffects(sw), export_settings(export_settings) {} +EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryEffects(sw), export_settings(export_settings) { +} bool EffectsExporter::hasEffects(Scene *sce) { Base *base = (Base *)sce->base.first; while (base) { - Object *ob= base->object; + Object *ob = base->object; int a; for (a = 0; a < ob->totcol; a++) { - Material *ma = give_current_material(ob, a+1); + Material *ma = give_current_material(ob, a + 1); // no material, but check all of the slots if (!ma) continue; return true; } - base= base->next; + base = base->next; } return false; } @@ -97,7 +98,7 @@ void EffectsExporter::writeBlinn(COLLADASW::EffectProfile &ep, Material *ma) ep.setShininess(ma->har, false, "shininess"); // specular cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f); - ep.setSpecular(cot, false, "specular" ); + ep.setSpecular(cot, false, "specular"); } void EffectsExporter::writeLambert(COLLADASW::EffectProfile &ep, Material *ma) @@ -111,10 +112,10 @@ void EffectsExporter::writePhong(COLLADASW::EffectProfile &ep, Material *ma) COLLADASW::ColorOrTexture cot; ep.setShaderType(COLLADASW::EffectProfile::PHONG); // shininess - ep.setShininess(ma->har, false, "shininess" ); + ep.setShininess(ma->har, false, "shininess"); // specular cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f); - ep.setSpecular(cot, false, "specular" ); + ep.setSpecular(cot, false, "specular"); } void EffectsExporter::operator()(Material *ma, Object *ob) @@ -129,7 +130,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob) ep.setProfileType(COLLADASW::EffectProfile::COMMON); ep.openProfile(); // set shader type - one of three blinn, phong or lambert - if (ma->spec>0.0f) { + if (ma->spec > 0.0f) { if (ma->spec_shader == MA_SPEC_BLINN) { writeBlinn(ep, ma); } @@ -144,8 +145,8 @@ void EffectsExporter::operator()(Material *ma, Object *ob) writeLambert(ep, ma); } else { - // \todo figure out handling of all spec+diff shader combos blender has, for now write phong - writePhong(ep, ma); + // \todo figure out handling of all spec+diff shader combos blender has, for now write phong + writePhong(ep, ma); } } @@ -168,7 +169,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob) } // emission - cot=getcol(ma->emit, ma->emit, ma->emit, 1.0f); + cot = getcol(ma->emit, ma->emit, ma->emit, 1.0f); ep.setEmission(cot, false, "emission"); // diffuse multiplied by diffuse intensity @@ -178,7 +179,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob) // ambient /* ma->ambX is calculated only on render, so lets do it here manually and not rely on ma->ambX. */ if (this->scene->world) - cot = getcol(this->scene->world->ambr*ma->amb, this->scene->world->ambg*ma->amb, this->scene->world->ambb*ma->amb, 1.0f); + cot = getcol(this->scene->world->ambr * ma->amb, this->scene->world->ambg * ma->amb, this->scene->world->ambb * ma->amb, 1.0f); else cot = getcol(ma->amb, ma->amb, ma->amb, 1.0f); @@ -191,9 +192,9 @@ void EffectsExporter::operator()(Material *ma, Object *ob) ep.setReflectivity(ma->ray_mirror); } // else { - // cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f); - // ep.setReflective(cot); - // ep.setReflectivity(ma->spec); + // cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f); + // ep.setReflective(cot); + // ep.setReflectivity(ma->spec); // } // specular @@ -229,7 +230,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob) if (im_samp_map.find(key) == im_samp_map.end()) { // // // COLLADASW::Surface surface(COLLADASW::Surface::SURFACE_TYPE_2D, - // key + COLLADASW::Surface::SURFACE_SID_SUFFIX); + // key + COLLADASW::Surface::SURFACE_SID_SUFFIX); // COLLADASW::SurfaceInitOption sio(COLLADASW::SurfaceInitOption::INIT_FROM); // sio.setImageReference(key); // surface.setInitOption(sio); @@ -239,8 +240,8 @@ void EffectsExporter::operator()(Material *ma, Object *ob) // COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, - key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, - key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); + key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, + key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); sampler.setImageId(key); // copy values to arrays since they will live longer samplers[a] = sampler; @@ -273,7 +274,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob) std::string key(id_name(ima)); key = translate_id(key); int i = im_samp_map[key]; - COLLADASW::Sampler *sampler = (COLLADASW::Sampler*)samp_surf[i][0]; + COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0]; //COLLADASW::Surface *surface = (COLLADASW::Surface*)samp_surf[i][1]; std::string uvname = strlen(t->uvname) ? t->uvname : active_uv; @@ -320,7 +321,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob) ep.addProfileElements(); bool twoSided = false; if (ob->type == OB_MESH && ob->data) { - Mesh *me = (Mesh*)ob->data; + Mesh *me = (Mesh *)ob->data; if (me->flag & ME_TWOSIDED) twoSided = true; } @@ -335,9 +336,9 @@ void EffectsExporter::operator()(Material *ma, Object *ob) } COLLADASW::ColorOrTexture EffectsExporter::createTexture(Image *ima, - std::string& uv_layer_name, - COLLADASW::Sampler *sampler - /*COLLADASW::Surface *surface*/) + std::string& uv_layer_name, + COLLADASW::Sampler *sampler + /*COLLADASW::Surface *surface*/) { COLLADASW::Texture texture(translate_id(id_name(ima))); diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp index 530158ed418..7ac138ac807 100644 --- a/source/blender/collada/ErrorHandler.cpp +++ b/source/blender/collada/ErrorHandler.cpp @@ -45,36 +45,36 @@ ErrorHandler::~ErrorHandler() } //-------------------------------------------------------------------- -bool ErrorHandler::handleError( const COLLADASaxFWL::IError* error ) +bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) { mError = true; - if ( error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER ) { - COLLADASaxFWL::SaxParserError* saxParserError = (COLLADASaxFWL::SaxParserError*) error; + if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER) { + COLLADASaxFWL::SaxParserError *saxParserError = (COLLADASaxFWL::SaxParserError *) error; const GeneratedSaxParser::ParserError& parserError = saxParserError->getError(); // Workaround to avoid wrong error - if ( parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_MIN_OCCURS_UNMATCHED) { - if ( strcmp(parserError.getElement(), "effect") == 0 ) { + if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_MIN_OCCURS_UNMATCHED) { + if (strcmp(parserError.getElement(), "effect") == 0) { mError = false; } } - if ( parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT) { - if ( !((strcmp(parserError.getElement(), "extra") == 0) && - (strcmp(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract") == 0))) + if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT) { + if (!((strcmp(parserError.getElement(), "extra") == 0) && + (strcmp(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract") == 0))) { mError = false; } } - if ( parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_COULD_NOT_OPEN_FILE) { + if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_COULD_NOT_OPEN_FILE) { std::cout << "Couldn't open file" << std::endl; } std::cout << "Schema validation error: " << parserError.getErrorMessage() << std::endl; } - else if ( error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXFWL ) { - COLLADASaxFWL::SaxFWLError* saxFWLError = (COLLADASaxFWL::SaxFWLError*) error; + else if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXFWL) { + COLLADASaxFWL::SaxFWLError *saxFWLError = (COLLADASaxFWL::SaxFWLError *) error; std::cout << "Sax FWL Error: " << saxFWLError->getErrorMessage() << std::endl; } else { diff --git a/source/blender/collada/ExtraHandler.cpp b/source/blender/collada/ExtraHandler.cpp index 6606fe1a27b..df49b4fe8b4 100644 --- a/source/blender/collada/ExtraHandler.cpp +++ b/source/blender/collada/ExtraHandler.cpp @@ -35,9 +35,10 @@ ExtraHandler::ExtraHandler(DocumentImporter *dimp, AnimationImporter *aimp) : cu this->aimp = aimp; } -ExtraHandler::~ExtraHandler() {} +ExtraHandler::~ExtraHandler() { +} -bool ExtraHandler::elementBegin( const char* elementName, const char** attributes) +bool ExtraHandler::elementBegin(const char *elementName, const char **attributes) { // \todo attribute handling for profile tags currentElement = std::string(elementName); @@ -45,37 +46,38 @@ bool ExtraHandler::elementBegin( const char* elementName, const char** attribute return true; } -bool ExtraHandler::elementEnd(const char* elementName ) +bool ExtraHandler::elementEnd(const char *elementName) { return true; } -bool ExtraHandler::textData(const char* text, size_t textLength) +bool ExtraHandler::textData(const char *text, size_t textLength) { char buf[1024]; if (currentElement.length() == 0 || currentExtraTags == 0) return false; - BLI_snprintf(buf, textLength+1, "%s", text); + BLI_snprintf(buf, textLength + 1, "%s", text); currentExtraTags->addTag(currentElement, std::string(buf)); return true; } -bool ExtraHandler::parseElement ( - const char* profileName, - const unsigned long& elementHash, - const COLLADAFW::UniqueId& uniqueId ) { - if (BLI_strcaseeq(profileName, "blender")) { - //printf("In parseElement for supported profile %s for id %s\n", profileName, uniqueId.toAscii().c_str()); - currentUid = uniqueId; - ExtraTags *et = dimp->getExtraTags(uniqueId); - if (!et) { - et = new ExtraTags(std::string(profileName)); - dimp->addExtraTags(uniqueId, et); - } - currentExtraTags = et; - return true; +bool ExtraHandler::parseElement( + const char *profileName, + const unsigned long& elementHash, + const COLLADAFW::UniqueId& uniqueId) +{ + if (BLI_strcaseeq(profileName, "blender")) { + //printf("In parseElement for supported profile %s for id %s\n", profileName, uniqueId.toAscii().c_str()); + currentUid = uniqueId; + ExtraTags *et = dimp->getExtraTags(uniqueId); + if (!et) { + et = new ExtraTags(std::string(profileName)); + dimp->addExtraTags(uniqueId, et); } - //printf("In parseElement for unsupported profile %s for id %s\n", profileName, uniqueId.toAscii().c_str()); - return false; + currentExtraTags = et; + return true; + } + //printf("In parseElement for unsupported profile %s for id %s\n", profileName, uniqueId.toAscii().c_str()); + return false; } diff --git a/source/blender/collada/ExtraTags.cpp b/source/blender/collada/ExtraTags.cpp index c5a126894cb..6af61432fda 100644 --- a/source/blender/collada/ExtraTags.cpp +++ b/source/blender/collada/ExtraTags.cpp @@ -32,7 +32,7 @@ #include "ExtraTags.h" -ExtraTags::ExtraTags( std::string profile) +ExtraTags::ExtraTags(std::string profile) { this->profile = profile; this->tags = std::map(); @@ -42,19 +42,19 @@ ExtraTags::~ExtraTags() { } -bool ExtraTags::isProfile( std::string profile) +bool ExtraTags::isProfile(std::string profile) { return this->profile == profile; } -bool ExtraTags::addTag( std::string tag, std::string data) +bool ExtraTags::addTag(std::string tag, std::string data) { tags[tag] = data; return true; } -int ExtraTags::asInt( std::string tag, bool *ok) +int ExtraTags::asInt(std::string tag, bool *ok) { if (tags.find(tag) == tags.end()) { *ok = false; @@ -64,7 +64,7 @@ int ExtraTags::asInt( std::string tag, bool *ok) return atoi(tags[tag].c_str()); } -float ExtraTags::asFloat( std::string tag, bool *ok) +float ExtraTags::asFloat(std::string tag, bool *ok) { if (tags.find(tag) == tags.end()) { *ok = false; @@ -74,7 +74,7 @@ float ExtraTags::asFloat( std::string tag, bool *ok) return (float)atof(tags[tag].c_str()); } -std::string ExtraTags::asString( std::string tag, bool *ok) +std::string ExtraTags::asString(std::string tag, bool *ok) { if (tags.find(tag) == tags.end()) { *ok = false; diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index bc06de4d56b..94b977ca01c 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -38,7 +38,7 @@ #include "DNA_meshdata_types.h" extern "C" { - #include "BKE_DerivedMesh.h" + #include "BKE_DerivedMesh.h" #include "BKE_main.h" #include "BKE_global.h" #include "BKE_library.h" @@ -52,7 +52,8 @@ extern "C" { #include "collada_utils.h" // TODO: optimize UV sets by making indexed list with duplicates removed -GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings) {} +GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings) { +} void GeometryExporter::exportGeom(Scene *sce) @@ -76,11 +77,11 @@ void GeometryExporter::operator()(Object *ob) bool use_instantiation = this->export_settings->use_object_instantiation; Mesh *me; - if ( this->export_settings->apply_modifiers ) { + if (this->export_settings->apply_modifiers) { me = bc_to_mesh_apply_modifiers(mScene, ob); } else { - me = (Mesh*)ob->data; + me = (Mesh *)ob->data; } BKE_mesh_tessface_ensure(me); @@ -90,8 +91,10 @@ void GeometryExporter::operator()(Object *ob) // Skip if linked geometry was already exported from another reference if (use_instantiation && - exportedGeometry.find(geom_id) != exportedGeometry.end()) + exportedGeometry.find(geom_id) != exportedGeometry.end()) + { return; + } std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob); @@ -132,7 +135,7 @@ void GeometryExporter::operator()(Object *ob) // XXX slow if (ob->totcol) { - for (int a = 0; a < ob->totcol; a++) { + for (int a = 0; a < ob->totcol; a++) { createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); } } @@ -161,9 +164,9 @@ void GeometryExporter::operator()(Object *ob) void GeometryExporter::createLooseEdgeList(Object *ob, - Mesh *me, - std::string& geom_id, - std::vector& norind) + Mesh *me, + std::string& geom_id, + std::vector& norind) { MEdge *medges = me->medge; @@ -204,8 +207,8 @@ void GeometryExporter::createLooseEdgeList(Object *ob, for (index = 0; index < edges_in_linelist; index++) { - lines.appendValues(edge_list[2*index+1]); - lines.appendValues(edge_list[2*index]); + lines.appendValues(edge_list[2 * index + 1]); + lines.appendValues(edge_list[2 * index]); } lines.finish(); } @@ -214,12 +217,12 @@ void GeometryExporter::createLooseEdgeList(Object *ob, // powerful because it handles both cases when there is material and when there's not void GeometryExporter::createPolylist(short material_index, - bool has_uvs, - bool has_color, - Object *ob, - Mesh *me, - std::string& geom_id, - std::vector& norind) + bool has_uvs, + bool has_color, + Object *ob, + Mesh *me, + std::string& geom_id, + std::vector& norind) { MFace *mfaces = me->mface; int totfaces = me->totface; @@ -280,10 +283,10 @@ void GeometryExporter::createPolylist(short material_index, for (i = 0; i < num_layers; i++) { // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD, - makeUrl(makeTexcoordSourceId(geom_id, i)), - 2, // offset always 2, this is only until we have optimized UV sets - i // set number equals UV map index - ); + makeUrl(makeTexcoordSourceId(geom_id, i)), + 2, // offset always 2, this is only until we have optimized UV sets + i // set number equals UV map index + ); til.push_back(input3); } @@ -342,7 +345,7 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) COLLADASW::FloatSourceF source(mSW); source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION)); source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION) + - ARRAY_ID_SUFFIX); + ARRAY_ID_SUFFIX); source.setAccessorCount(totverts); source.setAccessorStride(3); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); @@ -350,7 +353,7 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) param.push_back("Y"); param.push_back("Z"); /*main function, it creates , */ + count = ""> */ source.prepareToAppendValues(); //appends data to int i = 0; @@ -388,7 +391,7 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) int index = CustomData_get_active_layer_index(&me->fdata, CD_MCOL); - MCol *mcol = (MCol*)me->fdata.layers[index].data; + MCol *mcol = (MCol *)me->fdata.layers[index].data; MCol *c = mcol; for (i = 0, f = me->mface; i < me->totface; i++, c += 4, f++) @@ -422,10 +425,10 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) for (i = 0; i < totfaces; i++) { MFace *f = &mfaces[i]; if (f->v4 == 0) { - totuv+=3; + totuv += 3; } else { - totuv+=4; + totuv += 4; } } @@ -434,7 +437,7 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) // write for each layer // each will get id like meshName + "map-channel-1" for (int a = 0; a < num_layers; a++) { - MTFace *tface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); + MTFace *tface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a); COLLADASW::FloatSourceF source(mSW); @@ -455,7 +458,7 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { source.appendValues(tface[i].uv[j][0], - tface[i].uv[j][1]); + tface[i].uv[j][1]); } } @@ -475,7 +478,7 @@ void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::v COLLADASW::FloatSourceF source(mSW); source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL)); source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL) + - ARRAY_ID_SUFFIX); + ARRAY_ID_SUFFIX); source.setAccessorCount((unsigned long)nor.size()); source.setAccessorStride(3); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); @@ -563,8 +566,9 @@ COLLADASW::URI GeometryExporter::makeUrl(std::string id) return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id); } - -/* int GeometryExporter::getTriCount(MFace *faces, int totface) { +#if 0 +int GeometryExporter::getTriCount(MFace *faces, int totface) +{ int i; int tris = 0; for (i = 0; i < totface; i++) { @@ -576,4 +580,5 @@ COLLADASW::URI GeometryExporter::makeUrl(std::string id) } return tris; - }*/ +} +#endif diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp index 1999c68307e..105b895cf37 100644 --- a/source/blender/collada/ImageExporter.cpp +++ b/source/blender/collada/ImageExporter.cpp @@ -42,17 +42,19 @@ #include "BLI_string.h" ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryImages(sw), export_settings(export_settings) -{} +{ +} +/* TODO - shouldn't this use the objects LinkNode's ? */ bool ImagesExporter::hasImages(Scene *sce) { Base *base = (Base *)sce->base.first; while (base) { - Object *ob= base->object; + Object *ob = base->object; int a; for (a = 0; a < ob->totcol; a++) { - Material *ma = give_current_material(ob, a+1); + Material *ma = give_current_material(ob, a + 1); // no material, but check all of the slots if (!ma) continue; @@ -63,7 +65,7 @@ bool ImagesExporter::hasImages(Scene *sce) } } - base= base->next; + base = base->next; } return false; } diff --git a/source/blender/collada/InstanceWriter.cpp b/source/blender/collada/InstanceWriter.cpp index f83289ff5f5..788bd2a98b7 100644 --- a/source/blender/collada/InstanceWriter.cpp +++ b/source/blender/collada/InstanceWriter.cpp @@ -43,8 +43,8 @@ void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob) { - for (int a = 0; a < ob->totcol; a++) { - Material *ma = give_current_material(ob, a+1); + for (int a = 0; a < ob->totcol; a++) { + Material *ma = give_current_material(ob, a + 1); COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList(); @@ -56,7 +56,7 @@ void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_materia COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid)); // create for each uv map - Mesh *me = (Mesh*)ob->data; + Mesh *me = (Mesh *)ob->data; int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE); for (int b = 0; b < totlayer; b++) { diff --git a/source/blender/collada/LightExporter.cpp b/source/blender/collada/LightExporter.cpp index 44306616a85..af13d61a368 100644 --- a/source/blender/collada/LightExporter.cpp +++ b/source/blender/collada/LightExporter.cpp @@ -39,7 +39,7 @@ template void forEachLampObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) { LinkNode *node; - for (node=export_set; node; node = node->next) { + for (node = export_set; node; node = node->next) { Object *ob = (Object *)node->link; if (ob->type == OB_LAMP && ob->data) { @@ -48,7 +48,8 @@ void forEachLampObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) } } -LightsExporter::LightsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): COLLADASW::LibraryLights(sw), export_settings(export_settings) {} +LightsExporter::LightsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryLights(sw), export_settings(export_settings) { +} void LightsExporter::exportLights(Scene *sce) { @@ -61,7 +62,7 @@ void LightsExporter::exportLights(Scene *sce) void LightsExporter::operator()(Object *ob) { - Lamp *la = (Lamp*)ob->data; + Lamp *la = (Lamp *)ob->data; std::string la_id(get_light_id(ob)); std::string la_name(id_name(la)); COLLADASW::Color col(la->r * la->energy, la->g * la->energy, la->b * la->energy); @@ -71,7 +72,7 @@ void LightsExporter::operator()(Object *ob) constatt = 1.0f; - if (la->falloff_type==LA_FALLOFF_INVLINEAR) { + if (la->falloff_type == LA_FALLOFF_INVLINEAR) { linatt = 1.0f / d; quadatt = 0.0f; } diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp index ec075e7dcf8..106861c1916 100644 --- a/source/blender/collada/MaterialExporter.cpp +++ b/source/blender/collada/MaterialExporter.cpp @@ -31,7 +31,8 @@ #include "COLLADABUUtils.h" #include "collada_internal.h" -MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): COLLADASW::LibraryMaterials(sw), export_settings(export_settings) {} +MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryMaterials(sw), export_settings(export_settings) { +} void MaterialsExporter::exportMaterials(Scene *sce) { @@ -45,23 +46,23 @@ void MaterialsExporter::exportMaterials(Scene *sce) } } - +/* TODO - shouldn't this use the scenes object LinkNode's ? */ bool MaterialsExporter::hasMaterials(Scene *sce) { Base *base = (Base *)sce->base.first; while (base) { - Object *ob= base->object; + Object *ob = base->object; int a; for (a = 0; a < ob->totcol; a++) { - Material *ma = give_current_material(ob, a+1); + Material *ma = give_current_material(ob, a + 1); // no material, but check all of the slots if (!ma) continue; return true; } - base= base->next; + base = base->next; } return false; } diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index bcfec7a8056..59927e961bf 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -72,24 +72,24 @@ static const char *bc_get_dae_name(T *node) static const char *bc_primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type) { switch (type) { - case COLLADAFW::MeshPrimitive::LINES: - return "LINES"; - case COLLADAFW::MeshPrimitive::LINE_STRIPS: - return "LINESTRIPS"; - case COLLADAFW::MeshPrimitive::POLYGONS: - return "POLYGONS"; - case COLLADAFW::MeshPrimitive::POLYLIST: - return "POLYLIST"; - case COLLADAFW::MeshPrimitive::TRIANGLES: - return "TRIANGLES"; - case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: - return "TRIANGLE_FANS"; - case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: - return "TRIANGLE_FANS"; - case COLLADAFW::MeshPrimitive::POINTS: - return "POINTS"; - case COLLADAFW::MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE: - return "UNDEFINED_PRIMITIVE_TYPE"; + case COLLADAFW::MeshPrimitive::LINES: + return "LINES"; + case COLLADAFW::MeshPrimitive::LINE_STRIPS: + return "LINESTRIPS"; + case COLLADAFW::MeshPrimitive::POLYGONS: + return "POLYGONS"; + case COLLADAFW::MeshPrimitive::POLYLIST: + return "POLYLIST"; + case COLLADAFW::MeshPrimitive::TRIANGLES: + return "TRIANGLES"; + case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: + return "TRIANGLE_FANS"; + case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: + return "TRIANGLE_FANS"; + case COLLADAFW::MeshPrimitive::POINTS: + return "POINTS"; + case COLLADAFW::MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE: + return "UNDEFINED_PRIMITIVE_TYPE"; } return "UNKNOWN"; } @@ -97,43 +97,44 @@ static const char *bc_primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type static const char *bc_geomTypeToStr(COLLADAFW::Geometry::GeometryType type) { switch (type) { - case COLLADAFW::Geometry::GEO_TYPE_MESH: - return "MESH"; - case COLLADAFW::Geometry::GEO_TYPE_SPLINE: - return "SPLINE"; - case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH: - return "CONVEX_MESH"; - case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN: - default: - return "UNKNOWN"; + case COLLADAFW::Geometry::GEO_TYPE_MESH: + return "MESH"; + case COLLADAFW::Geometry::GEO_TYPE_SPLINE: + return "SPLINE"; + case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH: + return "CONVEX_MESH"; + case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN: + default: + return "UNKNOWN"; } } UVDataWrapper::UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata) -{} +{ +} #ifdef COLLADA_DEBUG void WVDataWrapper::print() { fprintf(stderr, "UVs:\n"); switch (mVData->getType()) { - case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: + case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: { - COLLADAFW::ArrayPrimitiveType* values = mVData->getFloatValues(); + COLLADAFW::ArrayPrimitiveType *values = mVData->getFloatValues(); if (values->getCount()) { for (int i = 0; i < values->getCount(); i += 2) { - fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i+1]); + fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i + 1]); } } } break; - case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: + case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: { - COLLADAFW::ArrayPrimitiveType* values = mVData->getDoubleValues(); + COLLADAFW::ArrayPrimitiveType *values = mVData->getDoubleValues(); if (values->getCount()) { for (int i = 0; i < values->getCount(); i += 2) { - fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i+1]); + fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i + 1]); } } } @@ -146,30 +147,30 @@ void WVDataWrapper::print() void UVDataWrapper::getUV(int uv_index, float *uv) { int stride = mVData->getStride(0); - if (stride==0) stride = 2; + if (stride == 0) stride = 2; switch (mVData->getType()) { - case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: + case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: { - COLLADAFW::ArrayPrimitiveType* values = mVData->getFloatValues(); + COLLADAFW::ArrayPrimitiveType *values = mVData->getFloatValues(); if (values->empty()) return; - uv[0] = (*values)[uv_index*stride]; - uv[1] = (*values)[uv_index*stride + 1]; + uv[0] = (*values)[uv_index * stride]; + uv[1] = (*values)[uv_index * stride + 1]; } break; - case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: + case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: { - COLLADAFW::ArrayPrimitiveType* values = mVData->getDoubleValues(); + COLLADAFW::ArrayPrimitiveType *values = mVData->getDoubleValues(); if (values->empty()) return; - uv[0] = (float)(*values)[uv_index*stride]; - uv[1] = (float)(*values)[uv_index*stride + 1]; + uv[0] = (float)(*values)[uv_index * stride]; + uv[1] = (float)(*values)[uv_index * stride + 1]; } break; - case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN: - default: - fprintf(stderr, "MeshImporter.getUV(): unknown data type\n"); + case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN: + default: + fprintf(stderr, "MeshImporter.getUV(): unknown data type\n"); } } @@ -198,7 +199,7 @@ void MeshImporter::rotate_face_indices(MFace *mface) #endif void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs, - COLLADAFW::IndexList& index_list, unsigned int *tris_indices) + COLLADAFW::IndexList& index_list, unsigned int *tris_indices) { // per face vertex indices, this means for quad we have 4 indices, not 8 COLLADAFW::UIntValuesArray& indices = index_list.getIndices(); @@ -209,7 +210,7 @@ void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs, } void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs, - COLLADAFW::IndexList& index_list, int index, bool quad) + COLLADAFW::IndexList& index_list, int index, bool quad) { // per face vertex indices, this means for quad we have 4 indices, not 8 COLLADAFW::UIntValuesArray& indices = index_list.getIndices(); @@ -223,31 +224,31 @@ void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs, #ifdef COLLADA_DEBUG if (quad) { fprintf(stderr, "face uv:\n" - "((%d, %d, %d, %d))\n" - "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", + "((%d, %d, %d, %d))\n" + "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", - indices[index + 0], - indices[index + 1], - indices[index + 2], - indices[index + 3], + indices[index + 0], + indices[index + 1], + indices[index + 2], + indices[index + 3], - mtface->uv[0][0], mtface->uv[0][1], - mtface->uv[1][0], mtface->uv[1][1], - mtface->uv[2][0], mtface->uv[2][1], - mtface->uv[3][0], mtface->uv[3][1]); + mtface->uv[0][0], mtface->uv[0][1], + mtface->uv[1][0], mtface->uv[1][1], + mtface->uv[2][0], mtface->uv[2][1], + mtface->uv[3][0], mtface->uv[3][1]); } else { fprintf(stderr, "face uv:\n" - "((%d, %d, %d))\n" - "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", + "((%d, %d, %d))\n" + "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", - indices[index + 0], - indices[index + 1], - indices[index + 2], + indices[index + 0], + indices[index + 1], + indices[index + 2], - mtface->uv[0][0], mtface->uv[0][1], - mtface->uv[1][0], mtface->uv[1][1], - mtface->uv[2][0], mtface->uv[2][1]); + mtface->uv[0][0], mtface->uv[0][1], + mtface->uv[1][0], mtface->uv[1][1], + mtface->uv[2][0], mtface->uv[2][1]); } #endif } @@ -263,7 +264,7 @@ void MeshImporter::print_index_list(COLLADAFW::IndexList& index_list) } #endif -bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has supported primitive types: lines, polylist, triangles, triangle_fans +bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has supported primitive types: lines, polylist, triangles, triangle_fans { COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); @@ -279,26 +280,26 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has sup // OpenCollada passes POLYGONS type for if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { - COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; + COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray(); for (unsigned int j = 0; j < vca.getCount(); j++) { int count = vca[j]; if (count < 3) { fprintf(stderr, "Primitive %s in %s has at least one face with vertex count < 3\n", - type_str, name); + type_str, name); return false; } } } - else if ( type == COLLADAFW::MeshPrimitive::LINES ) + else if (type == COLLADAFW::MeshPrimitive::LINES) { // TODO: Add Checker for line syntax here } - else if (type != COLLADAFW::MeshPrimitive::TRIANGLES && type!= COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { + else if (type != COLLADAFW::MeshPrimitive::TRIANGLES && type != COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { fprintf(stderr, "Primitive type %s is not supported.\n", type_str); return false; } @@ -317,10 +318,10 @@ void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me) // vertices COLLADAFW::MeshVertexData& pos = mesh->getPositions(); int stride = pos.getStride(0); - if (stride==0) stride = 3; + if (stride == 0) stride = 3; me->totvert = mesh->getPositions().getFloatValues()->getCount() / stride; - me->mvert = (MVert*)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); + me->mvert = (MVert *)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); MVert *mvert; int i; @@ -339,12 +340,12 @@ int MeshImporter::triangulate_poly(unsigned int *indices, int totvert, MVert *ve dispbase.first = dispbase.last = NULL; - dl = (DispList*)MEM_callocN(sizeof(DispList), "poly disp"); + dl = (DispList *)MEM_callocN(sizeof(DispList), "poly disp"); dl->nr = totvert; dl->type = DL_POLY; dl->parts = 1; - dl->verts = vert = (float*)MEM_callocN(totvert * 3 * sizeof(float), "poly verts"); - dl->index = (int*)MEM_callocN(sizeof(int) * 3 * totvert, "dl index"); + dl->verts = vert = (float *)MEM_callocN(totvert * 3 * sizeof(float), "poly verts"); + dl->index = (int *)MEM_callocN(sizeof(int) * 3 * totvert, "dl index"); BLI_addtail(&dispbase, dl); @@ -356,14 +357,14 @@ int MeshImporter::triangulate_poly(unsigned int *indices, int totvert, MVert *ve BKE_displist_fill(&dispbase, &dispbase, 0); int tottri = 0; - dl= (DispList*)dispbase.first; + dl = (DispList *)dispbase.first; if (dl->type == DL_INDEX3) { tottri = dl->parts; int *index = dl->index; - for (i= 0; i < tottri; i++) { - int t[3]= {*index, *(index + 1), *(index + 2)}; + for (i = 0; i < tottri; i++) { + int t[3] = {*index, *(index + 1), *(index + 2)}; std::sort(t, t + 3); @@ -394,9 +395,9 @@ int MeshImporter::count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me) unsigned int *indices = mp->getPositionIndices().getData(); if (type == COLLADAFW::MeshPrimitive::POLYLIST || - type == COLLADAFW::MeshPrimitive::POLYGONS) { - - COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; + type == COLLADAFW::MeshPrimitive::POLYGONS) + { + COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray(); for (unsigned int j = 0; j < prim_totface; j++) { @@ -433,8 +434,8 @@ bool MeshImporter::primitive_has_useable_normals(COLLADAFW::MeshPrimitive *mp) { has_useable_normals = true; else { fprintf(stderr, - "Warning: Number of normals %d is different from the number of vertices %d, skipping normals\n", - normals_count, index_count ); + "Warning: Number of normals %d is different from the number of vertices %d, skipping normals\n", + normals_count, index_count); } } @@ -496,7 +497,7 @@ void MeshImporter::allocate_face_data(COLLADAFW::Mesh *mesh, Mesh *me, int new_t // allocate space for faces if (total_facecount > 0) { me->totface = total_facecount + new_tris; - me->mface = (MFace*)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); + me->mface = (MFace *)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); } } @@ -566,7 +567,7 @@ void MeshImporter::mesh_add_edges(Mesh *mesh, int len) void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me) { unsigned int loose_edge_count = get_loose_edge_count(mesh); - if(loose_edge_count > 0) { + if (loose_edge_count > 0) { unsigned int face_edge_count = me->totedge; unsigned int total_edge_count = loose_edge_count + face_edge_count; @@ -587,11 +588,11 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me) unsigned int *indices = mp->getPositionIndices().getData(); for (int i = 0; i < edge_count; i++, med++) { - med->bweight= 0; - med->crease = 0; - med->flag = 0; - med->v1 = indices[ 2*i ]; - med->v2 = indices[ 2*i + 1]; + med->bweight = 0; + med->crease = 0; + med->flag = 0; + med->v1 = indices[2 * i]; + med->v2 = indices[2 * i + 1]; } } } @@ -630,7 +631,7 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //T } // activate the first uv map - if (totuvset) me->mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0); + if (totuvset) me->mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0); UVDataWrapper uvs(mesh->getUVCoords()); @@ -669,11 +670,11 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //T #ifdef COLLADA_DEBUG /* - fprintf(stderr, "Primitive %d:\n", i); - for (unsigned int j = 0; j < totuvset; j++) { - print_index_list(*index_list_array[j]); - } - */ + fprintf(stderr, "Primitive %d:\n", i); + for (unsigned int j = 0; j < totuvset; j++) { + print_index_list(*index_list_array[j]); + } + */ #endif if (type == COLLADAFW::MeshPrimitive::TRIANGLES) { @@ -686,14 +687,14 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //T for (unsigned int k = 0; k < totuvset; k++) { if (!index_list_array.empty() && index_list_array[k]) { // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, false); } } #else for (unsigned int k = 0; k < index_list_array.getCount(); k++) { // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, false); } #endif @@ -725,24 +726,24 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //T for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) { // For each triangle store indeces of its 3 vertices - unsigned int triangle_vertex_indices[3]={first_vertex, indices[1], indices[2]}; + unsigned int triangle_vertex_indices[3] = {first_vertex, indices[1], indices[2]}; set_face_indices(mface, triangle_vertex_indices, false); test_index_face(mface, &me->fdata, face_index, 3); if (mp_has_normals) { // vertex normals, same inplementation as for the triangles // the same for vertces normals - unsigned int vertex_normal_indices[3]={first_normal, nind[1], nind[2]}; + unsigned int vertex_normal_indices[3] = {first_normal, nind[1], nind[2]}; if (!flat_face(vertex_normal_indices, nor, 3)) mface->flag |= ME_SMOOTH; - nind++; - } - - mface++; // same inplementation as for the triangles - indices++; - face_index++; - prim.totface++; + nind++; } + mface++; // same inplementation as for the triangles + indices++; + face_index++; + prim.totface++; + } + // Moving cursor to the next triangle fan. if (mp_has_normals) nind += 2; @@ -751,7 +752,7 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //T } } else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { - COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; + COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray(); for (unsigned int j = 0; j < prim_totface; j++) { @@ -769,14 +770,14 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //T for (unsigned int k = 0; k < totuvset; k++) { if (!index_list_array.empty() && index_list_array[k]) { // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, mface->v4 != 0); } } #else for (unsigned int k = 0; k < index_list_array.getCount(); k++) { // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, vcount == 4); } #endif @@ -819,7 +820,7 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //T for (unsigned int l = 0; l < totuvset; l++) { if (!index_list_array.empty() && index_list_array[l]) { // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l); + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l); set_face_uv(&mtface[face_index], uvs, l, *index_list_array[l], uv_indices); } } @@ -828,7 +829,7 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //T int uvset_index = index_list_array[l]->getSetIndex(); // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index); + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index); set_face_uv(&mtface[face_index], uvs, *index_list_array[l], uv_indices); } #endif @@ -873,9 +874,9 @@ void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, i *= stride; switch (arr.getType()) { - case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: + case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: { - COLLADAFW::ArrayPrimitiveType* values = arr.getFloatValues(); + COLLADAFW::ArrayPrimitiveType *values = arr.getFloatValues(); if (values->empty()) return; v[0] = (*values)[i++]; @@ -884,9 +885,9 @@ void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, } break; - case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: + case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: { - COLLADAFW::ArrayPrimitiveType* values = arr.getDoubleValues(); + COLLADAFW::ArrayPrimitiveType *values = arr.getDoubleValues(); if (values->empty()) return; v[0] = (float)(*values)[i++]; @@ -894,8 +895,8 @@ void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, v[2] = (float)(*values)[i]; } break; - default: - break; + default: + break; } } @@ -921,12 +922,13 @@ bool MeshImporter::flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, return true; } -MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) {} +MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) { +} void MeshImporter::bmeshConversion() { - for (std::map::iterator m = uid_mesh_map.begin(); - m != uid_mesh_map.end(); ++m) + for (std::map::iterator m = uid_mesh_map.begin(); + m != uid_mesh_map.end(); ++m) { if ((*m).second) { Mesh *me = (*m).second; @@ -947,21 +949,21 @@ Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid } MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture, - Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map, - MTex *color_texture) + Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map, + MTex *color_texture) { const COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId(); size_t setindex = ctexture.getSetIndex(); std::string uvname = ctexture.getSemantic(); - if (setindex==-1) return NULL; + if (setindex == -1) return NULL; const CustomData *data = &me->fdata; int layer_index = CustomData_get_layer_index(data, CD_MTFACE); if (layer_index == -1) return NULL; - CustomDataLayer *cdl = &data->layers[layer_index+setindex]; + CustomDataLayer *cdl = &data->layers[layer_index + setindex]; /* set uvname to bind_vertex_input semantic */ BLI_strncpy(cdl->name, uvname.c_str(), sizeof(cdl->name)); @@ -972,9 +974,9 @@ MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBindi return color_texture; } - std::vector textures = texindex_texarray_map[texture_index]; + std::vector textures = texindex_texarray_map[texture_index]; - std::vector::iterator it; + std::vector::iterator it; for (it = textures.begin(); it != textures.end(); it++) { @@ -989,12 +991,12 @@ MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBindi } MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial, - std::map& uid_material_map, - Object *ob, const COLLADAFW::UniqueId *geom_uid, - MTex **color_texture, char *layername, MTFace *texture_face, - std::map& material_texture_mapping_map, short mat_index) + std::map& uid_material_map, + Object *ob, const COLLADAFW::UniqueId *geom_uid, + MTex **color_texture, char *layername, MTFace *texture_face, + std::map& material_texture_mapping_map, short mat_index) { - Mesh *me = (Mesh*)ob->data; + Mesh *me = (Mesh *)ob->data; const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial(); // do we know this material? @@ -1008,9 +1010,9 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri // again. Make sure we don't overwrite them on the next occurrences, so keep list of // what we already have handled. std::multimap::iterator it; - it=materials_mapped_to_geom.find(*geom_uid); - while (it!=materials_mapped_to_geom.end()) { - if (it->second == ma_uid && it->first == *geom_uid) return NULL; // do nothing if already found + it = materials_mapped_to_geom.find(*geom_uid); + while (it != materials_mapped_to_geom.end()) { + if (it->second == ma_uid && it->first == *geom_uid) return NULL; // do nothing if already found it++; } // first time we get geom_uid, ma_uid pair. Save for later check. @@ -1020,22 +1022,22 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri assign_material(ob, ma, ob->totcol + 1); COLLADAFW::TextureCoordinateBindingArray& tex_array = - cmaterial.getTextureCoordinateBindingArray(); + cmaterial.getTextureCoordinateBindingArray(); TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma]; unsigned int i; // loop through for (i = 0; i < tex_array.getCount(); i++) { *color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map, - *color_texture); + *color_texture); } // set texture face if (*color_texture && - strlen((*color_texture)->uvname) && - strcmp(layername, (*color_texture)->uvname) != 0) { - texture_face = (MTFace*)CustomData_get_layer_named(&me->fdata, CD_MTFACE, - (*color_texture)->uvname); + strlen((*color_texture)->uvname) && + strcmp(layername, (*color_texture)->uvname) != 0) { + texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE, + (*color_texture)->uvname); strcpy(layername, (*color_texture)->uvname); } @@ -1057,7 +1059,7 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri mface->mat_nr = mat_index; // bind texture images to faces if (texture_face && (*color_texture)) { - texture_face->tpage = (Image*)(*color_texture)->tex->ima; + texture_face->tpage = (Image *)(*color_texture)->tex->ima; texture_face++; } } @@ -1068,9 +1070,9 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri } Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom, - bool isController, - std::map& uid_material_map, - std::map& material_texture_mapping_map) + bool isController, + std::map& uid_material_map, + std::map& material_texture_mapping_map) { const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId(); @@ -1097,7 +1099,7 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta // name Object const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId(); - const char *name = (id.length())? id.c_str(): NULL; + const char *name = (id.length()) ? id.c_str() : NULL; // add object Object *ob = bc_add_object(scene, OB_MESH, name); @@ -1106,7 +1108,7 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta uid_object_map[*geom_uid] = ob; // replace ob->data freeing the old one - Mesh *old_mesh = (Mesh*)ob->data; + Mesh *old_mesh = (Mesh *)ob->data; set_mesh(ob, uid_mesh_map[*geom_uid]); @@ -1118,15 +1120,15 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta MTex *color_texture = NULL; COLLADAFW::MaterialBindingArray& mat_array = - geom->getMaterialBindings(); + geom->getMaterialBindings(); // loop through geom's materials - for (unsigned int i = 0; i < mat_array.getCount(); i++) { + for (unsigned int i = 0; i < mat_array.getCount(); i++) { if (mat_array[i].getReferencedMaterial().isValid()) { texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid, - &color_texture, layername, texture_face, - material_texture_mapping_map, i); + &color_texture, layername, texture_face, + material_texture_mapping_map, i); } else { fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str()); @@ -1137,7 +1139,7 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta } // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID -bool MeshImporter::write_geometry(const COLLADAFW::Geometry* geom) +bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom) { // TODO: import also uvs, normals // XXX what to do with normal indices? @@ -1150,7 +1152,7 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry* geom) return true; } - COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh*)geom; + COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh *)geom; if (!is_nice_mesh(mesh)) { fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh)); @@ -1158,7 +1160,7 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry* geom) } const std::string& str_geom_id = mesh->getName().size() ? mesh->getName() : mesh->getOriginalId(); - Mesh *me = BKE_mesh_add((char*)str_geom_id.c_str()); + Mesh *me = BKE_mesh_add((char *)str_geom_id.c_str()); me->id.us--; // is already 1 here, but will be set later in set_mesh // store the Mesh pointer to link it later with an Object diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp index 603a700c4a9..63bf94923d4 100644 --- a/source/blender/collada/SceneExporter.cpp +++ b/source/blender/collada/SceneExporter.cpp @@ -30,7 +30,8 @@ SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings) : COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings) -{} +{ +} void SceneExporter::exportScene(Scene *sce) { @@ -48,14 +49,14 @@ void SceneExporter::exportHierarchy(Scene *sce) std::vector base_objects; // Ensure all objects in the export_set are marked - for(node = this->export_settings->export_set; node; node = node->next) { - Object *ob = (Object*) node->link; + for (node = this->export_settings->export_set; node; node = node->next) { + Object *ob = (Object *) node->link; ob->id.flag |= LIB_DOIT; } // Now find all exportable base ojects (highest in export hierarchy) - for(node = this->export_settings->export_set; node; node = node->next) { - Object *ob = (Object*) node->link; + for (node = this->export_settings->export_set; node; node = node->next) { + Object *ob = (Object *) node->link; if (bc_is_base_node(this->export_settings->export_set, ob)) { switch (ob->type) { @@ -71,7 +72,7 @@ void SceneExporter::exportHierarchy(Scene *sce) } // And now export the base objects: - for(int index=0; index < base_objects.size(); index++) { + for (int index = 0; index < base_objects.size(); index++) { Object *ob = base_objects[index]; if (bc_is_marked(ob)) { bc_remove_mark(ob); @@ -84,7 +85,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) { // Add associated armature first if available Object *ob_arm = bc_get_assigned_armature(ob); - if(ob_arm != NULL && bc_is_marked(ob_arm)) { + if (ob_arm != NULL && bc_is_marked(ob_arm)) { bc_remove_mark(ob_arm); writeNodes(ob_arm, sce); } @@ -97,10 +98,10 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) colladaNode.start(); bool is_skinned_mesh = arm_exporter->is_skinned_mesh(ob); - std::list child_objects; + std::list child_objects; // list child objects - LinkNode *node = this->export_settings->export_set ; + LinkNode *node = this->export_settings->export_set; while (node) { // cob - child object Object *cob = (Object *)node->link; @@ -132,7 +133,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) if (this->export_settings->include_armatures && is_skinned_mesh) { instance_controller_created = arm_exporter->add_instance_controller(ob); } - if (!instance_controller_created){ + if (!instance_controller_created) { COLLADASW::InstanceGeometry instGeom(mSW); instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation))); @@ -165,7 +166,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) GroupObject *go = NULL; Group *gr = ob->dup_group; /* printf("group detected '%s'\n", gr->id.name+2); */ - for (go = (GroupObject*)(gr->gobject.first); go; go=go->next) { + for (go = (GroupObject *)(gr->gobject.first); go; go = go->next) { printf("\t%s\n", go->ob->id.name); } } @@ -175,8 +176,8 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) colladaNode.end(); } - for (std::list::iterator i= child_objects.begin(); i != child_objects.end(); ++i) { - if(bc_is_marked(*i)) { + for (std::list::iterator i = child_objects.begin(); i != child_objects.end(); ++i) { + if (bc_is_marked(*i)) { bc_remove_mark(*i); writeNodes(*i, sce); } diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index edc8981deab..0116f89361b 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -57,14 +57,15 @@ static const char *bc_get_joint_name(T *node) // This is used to store data passed in write_controller_data. // Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members // so that arrays don't get freed until we free them explicitly. -SkinInfo::SkinInfo() {} +SkinInfo::SkinInfo() { +} SkinInfo::SkinInfo(const SkinInfo& skin) : weights(skin.weights), - joint_data(skin.joint_data), - unit_converter(skin.unit_converter), - ob_arm(skin.ob_arm), - controller_uid(skin.controller_uid), - parent(skin.parent) + joint_data(skin.joint_data), + unit_converter(skin.unit_converter), + ob_arm(skin.ob_arm), + controller_uid(skin.controller_uid), + parent(skin.parent) { copy_m4_m4(bind_shape_matrix, (float (*)[4])skin.bind_shape_matrix); @@ -73,7 +74,8 @@ SkinInfo::SkinInfo(const SkinInfo& skin) : weights(skin.weights), transfer_int_array_data_const(skin.joint_indices, joint_indices); } -SkinInfo::SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL), parent(NULL) {} +SkinInfo::SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL), parent(NULL) { +} // nobody owns the data after this, so it should be freed manually with releaseMemory template @@ -87,21 +89,21 @@ void SkinInfo::transfer_array_data(T& src, T& dest) // when src is const we cannot src.yieldOwnerShip, this is used by copy constructor void SkinInfo::transfer_int_array_data_const(const COLLADAFW::IntValuesArray& src, COLLADAFW::IntValuesArray& dest) { - dest.setData((int*)src.getData(), src.getCount()); + dest.setData((int *)src.getData(), src.getCount()); dest.yieldOwnerShip(); } void SkinInfo::transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray& src, COLLADAFW::UIntValuesArray& dest) { - dest.setData((unsigned int*)src.getData(), src.getCount()); + dest.setData((unsigned int *)src.getData(), src.getCount()); dest.yieldOwnerShip(); } -void SkinInfo::borrow_skin_controller_data(const COLLADAFW::SkinControllerData* skin) +void SkinInfo::borrow_skin_controller_data(const COLLADAFW::SkinControllerData *skin) { - transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getJointsPerVertex(), joints_per_vertex); - transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getWeightIndices(), weight_indices); - transfer_array_data((COLLADAFW::IntValuesArray&)skin->getJointIndices(), joint_indices); + transfer_array_data((COLLADAFW::UIntValuesArray &)skin->getJointsPerVertex(), joints_per_vertex); + transfer_array_data((COLLADAFW::UIntValuesArray &)skin->getWeightIndices(), weight_indices); + transfer_array_data((COLLADAFW::IntValuesArray &)skin->getJointIndices(), joint_indices); // transfer_array_data(skin->getWeights(), weights); // cannot transfer data for FloatOrDoubleArray, copy values manually @@ -130,7 +132,7 @@ void SkinInfo::add_joint(const COLLADABU::Math::Matrix4& matrix) joint_data.push_back(jd); } -void SkinInfo::set_controller(const COLLADAFW::SkinController* co) +void SkinInfo::set_controller(const COLLADAFW::SkinController *co) { controller_uid = co->getUniqueId(); @@ -155,7 +157,7 @@ Object *SkinInfo::create_armature(Scene *scene) return ob_arm; } -Object* SkinInfo::set_armature(Object *ob_arm) +Object *SkinInfo::set_armature(Object *ob_arm) { if (this->ob_arm) return this->ob_arm; @@ -211,8 +213,8 @@ bool SkinInfo::uses_joint_or_descendant(COLLADAFW::Node *node) return false; } -void SkinInfo::link_armature(bContext *C, Object *ob, std::map& joint_by_uid, - TransformReader *tm) +void SkinInfo::link_armature(bContext *C, Object *ob, std::map& joint_by_uid, + TransformReader *tm) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -233,11 +235,11 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::mapparentinv, workob.obmat); - ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA; + ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA; DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); #endif amd->deformflag = ARM_DEF_VGROUP; @@ -257,7 +259,7 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map - number of joints per vertex - joints_per_vertex @@ -274,12 +276,12 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::mapdefbase, joint); + bDeformGroup *def = (bDeformGroup *)BLI_findlink(&ob->defbase, joint); ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE); } @@ -297,16 +299,16 @@ void SkinInfo::set_parent(Object *_parent) parent = _parent; } -Object* SkinInfo::get_parent() +Object *SkinInfo::get_parent() { return parent; } -void SkinInfo::find_root_joints(const std::vector &root_joints, - std::map& joint_by_uid, - std::vector& result) +void SkinInfo::find_root_joints(const std::vector &root_joints, + std::map& joint_by_uid, + std::vector& result) { - std::vector::const_iterator it; + std::vector::const_iterator it; // for each root_joint for (it = root_joints.begin(); it != root_joints.end(); it++) { COLLADAFW::Node *root = *it; diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp index 4c7fde8ef17..be615f83787 100644 --- a/source/blender/collada/TransformReader.cpp +++ b/source/blender/collada/TransformReader.cpp @@ -29,7 +29,8 @@ #include "TransformReader.h" -TransformReader::TransformReader(UnitConverter* conv) : unit_converter(conv) {} +TransformReader::TransformReader(UnitConverter *conv) : unit_converter(conv) { +} void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map *animation_map, Object *ob) { @@ -43,7 +44,7 @@ void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::m COLLADAFW::Transformation *tm = node->getTransformations()[i]; COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); - switch (type) { + switch (type) { case COLLADAFW::Transformation::TRANSLATE: dae_translate_to_mat4(tm, cur); break; @@ -60,7 +61,7 @@ void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::m case COLLADAFW::Transformation::SKEW: fprintf(stderr, "LOOKAT and SKEW transformations are not supported yet.\n"); break; - } + } copy_m4_m4(copy, mat); mult_m4_m4m4(mat, copy, cur); @@ -78,7 +79,7 @@ void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::m void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) { - COLLADAFW::Rotate *ro = (COLLADAFW::Rotate*)tm; + COLLADAFW::Rotate *ro = (COLLADAFW::Rotate *)tm; COLLADABU::Math::Vector3& axis = ro->getRotationAxis(); const float angle = (float)DEG2RAD(ro->getRotationAngle()); const float ax[] = {axis[0], axis[1], axis[2]}; @@ -90,7 +91,7 @@ void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[ void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) { - COLLADAFW::Translate *tra = (COLLADAFW::Translate*)tm; + COLLADAFW::Translate *tra = (COLLADAFW::Translate *)tm; COLLADABU::Math::Vector3& t = tra->getTranslation(); unit_m4(m); @@ -102,24 +103,24 @@ void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) { - COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale*)tm)->getScale(); + COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale *)tm)->getScale(); float size[3] = {(float)s[0], (float)s[1], (float)s[2]}; size_to_mat4(m, size); } void TransformReader::dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) { - unit_converter->dae_matrix_to_mat4_(m, ((COLLADAFW::Matrix*)tm)->getMatrix()); + unit_converter->dae_matrix_to_mat4_(m, ((COLLADAFW::Matrix *)tm)->getMatrix()); } void TransformReader::dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3]) { - dae_vector3_to_v3(((COLLADAFW::Translate*)tm)->getTranslation(), v); + dae_vector3_to_v3(((COLLADAFW::Translate *)tm)->getTranslation(), v); } void TransformReader::dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3]) { - dae_vector3_to_v3(((COLLADAFW::Scale*)tm)->getScale(), v); + dae_vector3_to_v3(((COLLADAFW::Scale *)tm)->getScale(), v); } void TransformReader::dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]) diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp index fbd36cd6613..0d6e3831637 100644 --- a/source/blender/collada/TransformWriter.cpp +++ b/source/blender/collada/TransformWriter.cpp @@ -47,11 +47,11 @@ void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[][4], } double dmat[4][4]; - UnitConverter* converter = new UnitConverter(); + UnitConverter *converter = new UnitConverter(); converter->mat4_to_dae_double(dmat, local); TransformBase::decompose(local, loc, rot, NULL, scale); - if ( node.getType() == COLLADASW::Node::JOINT) + if (node.getType() == COLLADASW::Node::JOINT) node.addMatrix("transform", dmat); else add_transform(node, loc, rot, scale); @@ -59,7 +59,7 @@ void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[][4], void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob) { - /* +#if 0 float rot[3], loc[3], scale[3]; if (ob->parent) { @@ -92,7 +92,7 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob) } add_transform(node, loc, rot, scale); - */ +#endif /* Using parentinv should allow use of existing curves */ if (ob->parent) { @@ -124,9 +124,11 @@ void TransformWriter::add_node_transform_identity(COLLADASW::Node& node) void TransformWriter::add_transform(COLLADASW::Node& node, float loc[3], float rot[3], float scale[3]) { node.addTranslate("location", loc[0], loc[1], loc[2]); - /*node.addRotateZ("rotationZ", COLLADABU::Math::Utils::radToDegF(rot[2])); +#if 0 + node.addRotateZ("rotationZ", COLLADABU::Math::Utils::radToDegF(rot[2])); node.addRotateY("rotationY", COLLADABU::Math::Utils::radToDegF(rot[1])); - node.addRotateX("rotationX", COLLADABU::Math::Utils::radToDegF(rot[0]));*/ + node.addRotateX("rotationX", COLLADABU::Math::Utils::radToDegF(rot[0])); +#endif node.addRotateZ("rotationZ", RAD2DEGF(rot[2])); node.addRotateY("rotationY", RAD2DEGF(rot[1])); node.addRotateX("rotationX", RAD2DEGF(rot[0])); diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index b852190dd4c..bc03bdc970c 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -41,58 +41,60 @@ extern "C" #include "BLI_fileops.h" #include "BLI_path_util.h" - int collada_import(bContext *C, const char *filepath) - { - DocumentImporter imp (C, filepath); - if (imp.import()) return 1; +int collada_import(bContext *C, const char *filepath) +{ + DocumentImporter imp(C, filepath); + if (imp.import()) return 1; - return 0; - } - - int collada_export( - Scene *sce, - const char *filepath, - int selected, - int apply_modifiers, - - int include_armatures, - int include_children, - - int use_object_instantiation, - int second_life ) - { - ExportSettings export_settings; - - /* annoying, collada crashes if file cant be created! [#27162] */ - if (!BLI_exists(filepath)) { - BLI_make_existing_file(filepath); /* makes the dir if its not there */ - if (BLI_file_touch(filepath) == 0) { - return 0; - } - } - /* end! */ - - - export_settings.selected = selected != 0; - export_settings.apply_modifiers = apply_modifiers != 0; - export_settings.include_armatures = include_armatures != 0; - export_settings.include_children = include_children != 0; - export_settings.second_life = second_life != 0; - export_settings.use_object_instantiation = use_object_instantiation != 0; - export_settings.filepath = (char *)filepath; - - int includeFilter = OB_REL_NONE; - if (export_settings.include_armatures) includeFilter |= OB_REL_MOD_ARMATURE; - if (export_settings.include_children) includeFilter |= OB_REL_CHILDREN_RECURSIVE; - - eObjectSet objectSet = (export_settings.selected) ? OB_SET_SELECTED : OB_SET_ALL; - export_settings.export_set = BKE_object_relational_superset(sce, objectSet, (eObRelationTypes)includeFilter); - - DocumentExporter exporter(&export_settings); - exporter.exportCurrentScene(sce); - - BLI_linklist_free(export_settings.export_set, NULL); - - return 1; - } + return 0; +} + +int collada_export( + Scene *sce, + const char *filepath, + int selected, + int apply_modifiers, + + int include_armatures, + int include_children, + + int use_object_instantiation, + int second_life) +{ + ExportSettings export_settings; + + /* annoying, collada crashes if file cant be created! [#27162] */ + if (!BLI_exists(filepath)) { + BLI_make_existing_file(filepath); /* makes the dir if its not there */ + if (BLI_file_touch(filepath) == 0) { + return 0; + } + } + /* end! */ + + + export_settings.selected = selected != 0; + export_settings.apply_modifiers = apply_modifiers != 0; + export_settings.include_armatures = include_armatures != 0; + export_settings.include_children = include_children != 0; + export_settings.second_life = second_life != 0; + export_settings.use_object_instantiation = use_object_instantiation != 0; + export_settings.filepath = (char *)filepath; + + int includeFilter = OB_REL_NONE; + if (export_settings.include_armatures) includeFilter |= OB_REL_MOD_ARMATURE; + if (export_settings.include_children) includeFilter |= OB_REL_CHILDREN_RECURSIVE; + + eObjectSet objectSet = (export_settings.selected) ? OB_SET_SELECTED : OB_SET_ALL; + export_settings.export_set = BKE_object_relational_superset(sce, objectSet, (eObRelationTypes)includeFilter); + + DocumentExporter exporter(&export_settings); + exporter.exportCurrentScene(sce); + + BLI_linklist_free(export_settings.export_set, NULL); + + return 1; +} + +/* end extern C */ } diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index 06e688a93ac..0ee8419eda7 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -31,9 +31,10 @@ #include "BLI_linklist.h" -UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) {} +UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) { +} -void UnitConverter::read_asset(const COLLADAFW::FileInfo* asset) +void UnitConverter::read_asset(const COLLADAFW::FileInfo *asset) { unit = asset->getUnit(); up_axis = asset->getUpAxisType(); @@ -121,72 +122,74 @@ void TransformBase::decompose(float mat[][4], float *loc, float eul[3], float qu * must obviously be removed too, otherwise they would be heavily misinterpreted. */ const unsigned char translate_start_name_map[256] = { -95, 95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -65, 66, 67, 68, 69, 70, 71, 72, -73, 74, 75, 76, 77, 78, 79, 80, -81, 82, 83, 84, 85, 86, 87, 88, -89, 90, 95, 95, 95, 95, 95, 95, -97, 98, 99, 100, 101, 102, 103, 104, -105, 106, 107, 108, 109, 110, 111, 112, -113, 114, 115, 116, 117, 118, 119, 120, -121, 122, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 192, -193, 194, 195, 196, 197, 198, 199, 200, -201, 202, 203, 204, 205, 206, 207, 208, -209, 210, 211, 212, 213, 214, 95, 216, -217, 218, 219, 220, 221, 222, 223, 224, -225, 226, 227, 228, 229, 230, 231, 232, -233, 234, 235, 236, 237, 238, 239, 240, -241, 242, 243, 244, 245, 246, 95, 248, -249, 250, 251, 252, 253, 254, 255}; + 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 95, 95, 95, 95, 95, 95, + 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 192, + 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 95, 216, + 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 95, 248, + 249, 250, 251, 252, 253, 254, 255 +}; const unsigned char translate_name_map[256] = { -95, 95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 45, 95, 95, 48, -49, 50, 51, 52, 53, 54, 55, 56, -57, 95, 95, 95, 95, 95, 95, 95, -65, 66, 67, 68, 69, 70, 71, 72, -73, 74, 75, 76, 77, 78, 79, 80, -81, 82, 83, 84, 85, 86, 87, 88, -89, 90, 95, 95, 95, 95, 95, 95, -97, 98, 99, 100, 101, 102, 103, 104, -105, 106, 107, 108, 109, 110, 111, 112, -113, 114, 115, 116, 117, 118, 119, 120, -121, 122, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 183, 95, -95, 95, 95, 95, 95, 95, 95, 192, -193, 194, 195, 196, 197, 198, 199, 200, -201, 202, 203, 204, 205, 206, 207, 208, -209, 210, 211, 212, 213, 214, 95, 216, -217, 218, 219, 220, 221, 222, 223, 224, -225, 226, 227, 228, 229, 230, 231, 232, -233, 234, 235, 236, 237, 238, 239, 240, -241, 242, 243, 244, 245, 246, 95, 248, -249, 250, 251, 252, 253, 254, 255}; + 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 45, 95, 95, 48, + 49, 50, 51, 52, 53, 54, 55, 56, + 57, 95, 95, 95, 95, 95, 95, 95, + 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 95, 95, 95, 95, 95, 95, + 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 183, 95, + 95, 95, 95, 95, 95, 95, 95, 192, + 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 95, 216, + 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 95, 248, + 249, 250, 251, 252, 253, 254, 255 +}; typedef std::map< std::string, std::vector > map_string_list; map_string_list global_id_map; @@ -205,7 +208,7 @@ std::string translate_id(const std::string &id) std::string id_translated = id; id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]]; - for (unsigned int i=1; i < id_translated.size(); i++) { + for (unsigned int i = 1; i < id_translated.size(); i++) { id_translated[i] = translate_name_map[(unsigned int)id_translated[i]]; } // It's so much workload now, the if () should speed up things. @@ -215,7 +218,7 @@ std::string translate_id(const std::string &id) if (iter != global_id_map.end()) { unsigned int i = 0; bool found = false; - for (i=0; i < iter->second.size(); i++) { + for (i = 0; i < iter->second.size(); i++) { if (id == iter->second[i]) { found = true; break; @@ -223,9 +226,9 @@ std::string translate_id(const std::string &id) } bool convert = false; if (found) { - if (i > 0) { - convert = true; - } + if (i > 0) { + convert = true; + } } else { convert = true; @@ -244,7 +247,7 @@ std::string translate_id(const std::string &id) std::string id_name(void *id) { - return ((ID*)id)->name + 2; + return ((ID *)id)->name + 2; } std::string get_geometry_id(Object *ob) diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index c92131d5359..f481de994a3 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -117,7 +117,7 @@ int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space) DAG_scene_sort(bmain, sce); DAG_ids_flush_update(bmain, 0); - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return true; } @@ -126,9 +126,9 @@ Object *bc_add_object(Scene *scene, int type, const char *name) { Object *ob = BKE_object_add_only_object(type, name); - ob->data= BKE_object_obdata_add_from_type(type); - ob->lay= scene->lay; - ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; + ob->data = BKE_object_obdata_add_from_type(type); + ob->lay = scene->lay; + ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; BKE_scene_base_select(scene, BKE_scene_base_add(scene, ob)); @@ -154,13 +154,11 @@ Object *bc_get_assigned_armature(Object *ob) ob_arm = ob->parent; } else { - ModifierData *mod = (ModifierData*)ob->modifiers.first; - while (mod) { + ModifierData *mod; + for (mod = (ModifierData *)ob->modifiers.first; mod; mod = mod->next) { if (mod->type == eModifierType_Armature) { - ob_arm = ((ArmatureModifierData*)mod)->object; + ob_arm = ((ArmatureModifierData *)mod)->object; } - - mod = mod->next; } } diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 8d18f9dd1c2..76fe5a656b6 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -87,17 +87,17 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name static void rna_Scene_collada_export( Scene *scene, - const char *filepath, - int selected, - int apply_modifiers, - int include_armatures, - int include_children, - int use_object_instantiation, - int second_life) + const char *filepath, + int selected, + int apply_modifiers, + int include_armatures, + int include_children, + int use_object_instantiation, + int second_life) { collada_export(scene, filepath, selected, apply_modifiers, - include_armatures, include_children, - use_object_instantiation, second_life); + include_armatures, include_children, + use_object_instantiation, second_life); } #endif diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5f4a536d18f..b4e055e23c0 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -591,7 +591,7 @@ void WM_operator_properties_alloc(PointerRNA **ptr, IDProperty **properties, con void WM_operator_properties_sanitize(PointerRNA *ptr, const short no_context) { - RNA_STRUCT_BEGIN (ptr, prop) + RNA_STRUCT_BEGIN(ptr, prop) { switch (RNA_property_type(prop)) { case PROP_ENUM: @@ -625,7 +625,7 @@ void WM_operator_properties_reset(wmOperator *op) PropertyRNA *iterprop; iterprop = RNA_struct_iterator_property(op->type->srna); - RNA_PROP_BEGIN (op->ptr, itemptr, iterprop) + RNA_PROP_BEGIN(op->ptr, itemptr, iterprop) { PropertyRNA *prop = itemptr.data; @@ -1809,7 +1809,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag); } else { - RNA_BEGIN (op->ptr, itemptr, "files") + RNA_BEGIN(op->ptr, itemptr, "files") { RNA_string_get(&itemptr, "name", name); BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag); @@ -2163,10 +2163,10 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) { char filename[FILE_MAX]; int selected, second_life, - include_armatures, - apply_modifiers, - include_children, - use_object_instantiation; + int include_armatures, + int apply_modifiers, + int include_children, + int use_object_instantiation; if (!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); @@ -2187,14 +2187,14 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) ED_object_exit_editmode(C, 0); /* 0 = does not exit editmode */ if (collada_export( - CTX_data_scene(C), - filename, - selected, - apply_modifiers, - include_armatures, - include_children, - use_object_instantiation, - second_life)) { + CTX_data_scene(C), + filename, + selected, + apply_modifiers, + include_armatures, + include_children, + use_object_instantiation, + second_life)) { return OPERATOR_FINISHED; } else { @@ -2229,7 +2229,7 @@ static void WM_OT_collada_export(wmOperatorType *ot) "Include all children even if not selected"); RNA_def_boolean(ot->srna, "use_object_instantiation", 1, "Use Object Instantiation", - "Instantiate multiple Objects from same Data"); + "Instantiate multiple Objects from same Data"); RNA_def_boolean(ot->srna, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life"); @@ -2315,7 +2315,7 @@ static void WM_OT_console_toggle(wmOperatorType *ot) { /* XXX Have to mark these for xgettext, as under linux they do not exists... * And even worth, have to give the context as text, as xgettext doesn't expand macros. :( */ - ot->name = CTX_N_("Operator"/* BLF_I18NCONTEXT_OPERATOR_DEFAULT */, "Toggle System Console"); + ot->name = CTX_N_("Operator" /* BLF_I18NCONTEXT_OPERATOR_DEFAULT */, "Toggle System Console"); ot->idname = "WM_OT_console_toggle"; ot->description = N_("Toggle System Console"); @@ -2869,7 +2869,7 @@ int (*WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *m static int gesture_lasso_exec(bContext *C, wmOperator *op) { - RNA_BEGIN (op->ptr, itemptr, "path") + RNA_BEGIN(op->ptr, itemptr, "path") { float loc[2]; @@ -3825,7 +3825,8 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf) {GESTURE_MODAL_DESELECT, "DESELECT", 0, "DeSelect", ""}, {GESTURE_MODAL_NOP, "NOP", 0, "No Operation", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Gesture Circle"); @@ -3873,7 +3874,8 @@ static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf) {GESTURE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, {GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""}, {GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Straight Line"); @@ -3902,7 +3904,8 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) {GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""}, {GESTURE_MODAL_DESELECT, "DESELECT", 0, "DeSelect", ""}, {GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Border"); @@ -3962,7 +3965,8 @@ static void gesture_zoom_border_modal_keymap(wmKeyConfig *keyconf) {GESTURE_MODAL_IN, "IN", 0, "In", ""}, {GESTURE_MODAL_OUT, "OUT", 0, "Out", ""}, {GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Zoom Border"); From c7cca0c842e05a4fc2f5946844d212a365c5ab47 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Tue, 12 Jun 2012 23:01:43 +0000 Subject: [PATCH 255/360] fix code style cleanup --- source/blender/windowmanager/intern/wm_operators.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b4e055e23c0..cd6ef646e6b 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2162,10 +2162,10 @@ static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED static int wm_collada_export_exec(bContext *C, wmOperator *op) { char filename[FILE_MAX]; - int selected, second_life, - int include_armatures, - int apply_modifiers, - int include_children, + int selected, second_life; + int include_armatures; + int apply_modifiers; + int include_children; int use_object_instantiation; if (!RNA_struct_property_is_set(op->ptr, "filepath")) { From b0038ae4996993f1dd808babe402e2e390933330 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Tue, 12 Jun 2012 23:19:34 +0000 Subject: [PATCH 256/360] Collada: fixed a few loops to only loop over the list of exported objects, instead of the current scene. --- source/blender/collada/AnimationExporter.cpp | 8 +++----- source/blender/collada/ImageExporter.cpp | 8 +++----- source/blender/collada/MaterialExporter.cpp | 9 +++------ 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index cb675618ea5..9582da4fe5c 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -1110,13 +1110,12 @@ void AnimationExporter::enable_fcurves(bAction *act, char *bone_name) } } -/* TODO - only check NodeLink objects that are exported */ bool AnimationExporter::hasAnimations(Scene *sce) { - Base *base = (Base *) sce->base.first; + LinkNode *node; - while (base) { - Object *ob = base->object; + for(node=this->export_settings->export_set; node; node=node->next) { + Object *ob = (Object *)node->link; FCurve *fcu = 0; //Check for object transform animations @@ -1140,7 +1139,6 @@ bool AnimationExporter::hasAnimations(Scene *sce) if (fcu) return true; - base = base->next; } return false; } diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp index 105b895cf37..c777a7d1fab 100644 --- a/source/blender/collada/ImageExporter.cpp +++ b/source/blender/collada/ImageExporter.cpp @@ -45,13 +45,12 @@ ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings { } -/* TODO - shouldn't this use the objects LinkNode's ? */ bool ImagesExporter::hasImages(Scene *sce) { - Base *base = (Base *)sce->base.first; + LinkNode *node; - while (base) { - Object *ob = base->object; + for (node=this->export_settings->export_set; node; node=node->next) { + Object *ob = (Object *)node->link; int a; for (a = 0; a < ob->totcol; a++) { Material *ma = give_current_material(ob, a + 1); @@ -65,7 +64,6 @@ bool ImagesExporter::hasImages(Scene *sce) } } - base = base->next; } return false; } diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp index 106861c1916..ef22a76d28e 100644 --- a/source/blender/collada/MaterialExporter.cpp +++ b/source/blender/collada/MaterialExporter.cpp @@ -46,13 +46,11 @@ void MaterialsExporter::exportMaterials(Scene *sce) } } -/* TODO - shouldn't this use the scenes object LinkNode's ? */ bool MaterialsExporter::hasMaterials(Scene *sce) { - Base *base = (Base *)sce->base.first; - - while (base) { - Object *ob = base->object; + LinkNode *node; + for(node=this->export_settings->export_set; node; node = node->next) { + Object *ob = (Object *)node->link; int a; for (a = 0; a < ob->totcol; a++) { Material *ma = give_current_material(ob, a + 1); @@ -62,7 +60,6 @@ bool MaterialsExporter::hasMaterials(Scene *sce) return true; } - base = base->next; } return false; } From 1a625d1416e5caaaa21a2dcc1fb00e66a1911758 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 12 Jun 2012 23:19:52 +0000 Subject: [PATCH 257/360] code cleanup: use const float's where possible and specify vector size. --- source/blender/blenkernel/BKE_node.h | 2 +- source/blender/blenkernel/BKE_shrinkwrap.h | 4 +- source/blender/blenkernel/intern/node.c | 2 +- source/blender/editors/mesh/editmesh_bvh.c | 4 +- source/blender/editors/mesh/editmesh_bvh.h | 4 +- source/blender/editors/mesh/meshtools.c | 3 +- .../editors/transform/transform_manipulator.c | 2 +- .../editors/uvedit/uvedit_parametrizer.c | 4 +- .../modifiers/intern/MOD_simpledeform.c | 76 +++++++++---------- .../blender/render/intern/source/occlusion.c | 13 ++-- 10 files changed, 58 insertions(+), 56 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index ef664f8fc4f..e8f863fbbfd 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -339,7 +339,7 @@ struct bNodeSocket *nodeInsertSocket(struct bNodeTree *ntree, struct bNode *node void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock); void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node); -void nodeAddToPreview(struct bNode *, float *, int, int, int); +void nodeAddToPreview(struct bNode *node, float col[4], int x, int y, int do_manage); struct bNode *nodeAddNode(struct bNodeTree *ntree, struct bNodeTemplate *ntemp); void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node); diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index 5b09f8fdf3d..a7b03cef933 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -72,8 +72,8 @@ typedef struct SpaceTransform { } SpaceTransform; void space_transform_from_matrixs(struct SpaceTransform *data, float local[4][4], float target[4][4]); -void space_transform_apply(const struct SpaceTransform *data, float *co); -void space_transform_invert(const struct SpaceTransform *data, float *co); +void space_transform_apply(const struct SpaceTransform *data, float co[3]); +void space_transform_invert(const struct SpaceTransform *data, float co[3]); #define space_transform_setup(data, local, target) space_transform_from_matrixs(data, (local)->obmat, (target)->obmat) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 924e6a354ef..c48c0231aa0 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -802,7 +802,7 @@ void ntreeClearPreview(bNodeTree *ntree) /* hack warning! this function is only used for shader previews, and * since it gets called multiple times per pixel for Ztransp we only * add the color once. Preview gets cleared before it starts render though */ -void nodeAddToPreview(bNode *node, float *col, int x, int y, int do_manage) +void nodeAddToPreview(bNode *node, float col[4], int x, int y, int do_manage) { bNodePreview *preview= node->preview; if (preview) { diff --git a/source/blender/editors/mesh/editmesh_bvh.c b/source/blender/editors/mesh/editmesh_bvh.c index c5f8494836b..2cb03104874 100644 --- a/source/blender/editors/mesh/editmesh_bvh.c +++ b/source/blender/editors/mesh/editmesh_bvh.c @@ -308,7 +308,7 @@ static void vertsearchcallback(void *userdata, int index, const float *UNUSED(co } } -BMVert *BMBVH_FindClosestVert(BMBVHTree *tree, float *co, float maxdist) +BMVert *BMBVH_FindClosestVert(BMBVHTree *tree, const float co[3], float maxdist) { BVHTreeNearest hit; @@ -370,7 +370,7 @@ int BMBVH_VertVisible(BMBVHTree *tree, BMEdge *e, RegionView3D *r3d) } #endif -static BMFace *edge_ray_cast(BMBVHTree *tree, float *co, float *dir, float *hitout, BMEdge *e) +static BMFace *edge_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], float *hitout, BMEdge *e) { BMFace *f = BMBVH_RayCast(tree, co, dir, hitout, NULL); diff --git a/source/blender/editors/mesh/editmesh_bvh.h b/source/blender/editors/mesh/editmesh_bvh.h index 6512f054c1b..53d1c36119e 100644 --- a/source/blender/editors/mesh/editmesh_bvh.h +++ b/source/blender/editors/mesh/editmesh_bvh.h @@ -57,8 +57,8 @@ int BMBVH_EdgeVisible(struct BMBVHTree *tree, struct BMEdge *e, struct ARegion *ar, struct View3D *v3d, struct Object *obedit); /*find a vert closest to co in a sphere of radius maxdist*/ -struct BMVert *BMBVH_FindClosestVert(struct BMBVHTree *tree, float *co, float maxdist); - +struct BMVert *BMBVH_FindClosestVert(struct BMBVHTree *tree, const float co[3], const float maxdist); + /* BMBVH_NewBVH flag parameter */ enum { BMBVH_USE_CAGE = 1, /* project geometry onto modifier cage */ diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 989f1a36f99..59a0475ebb5 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -690,7 +690,8 @@ static void mesh_octree_free_node(MocNode **bt) /* temporal define, just to make nicer code below */ #define MOC_INDEX(vx, vy, vz) (((vx) * MOC_RES * MOC_RES) + (vy) * MOC_RES + (vz)) -static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, float *div, intptr_t index) +static void mesh_octree_add_nodes(MocNode **basetable, const float co[3], const float offs[3], + const float div[3], intptr_t index) { float fx, fy, fz; int vx, vy, vz; diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index e02ad00ac7f..b3ccf004810 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -108,7 +108,7 @@ #define MAN_MOVECOL 2 /* transform widget center calc helper for below */ -static void calc_tw_center(Scene *scene, float *co) +static void calc_tw_center(Scene *scene, const float co[3]) { float *twcent = scene->twcent; float *min = scene->twmin; diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 16cd95a2f70..87ff36ebf27 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -706,7 +706,7 @@ static void p_face_restore_uvs(PFace *f) /* Construction (use only during construction, relies on u.key being set */ -static PVert *p_vert_add(PHandle *handle, PHashKey key, float *co, PEdge *e) +static PVert *p_vert_add(PHandle *handle, PHashKey key, const float co[3], PEdge *e) { PVert *v = (PVert *)BLI_memarena_alloc(handle->arena, sizeof *v); copy_v3_v3(v->co, co); @@ -719,7 +719,7 @@ static PVert *p_vert_add(PHandle *handle, PHashKey key, float *co, PEdge *e) return v; } -static PVert *p_vert_lookup(PHandle *handle, PHashKey key, float *co, PEdge *e) +static PVert *p_vert_lookup(PHandle *handle, PHashKey key, const float co[3], PEdge *e) { PVert *v = (PVert *)phash_lookup(handle->hash_verts, key); diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 36c052440b6..14735810cad 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -51,8 +51,6 @@ #include "MOD_util.h" - - /* Clamps/Limits the given coordinate to: limits[0] <= co[axis] <= limits[1] * The amount of clamp is saved on dcut */ static void axis_limit(int axis, const float limits[2], float co[3], float dcut[3]) @@ -65,79 +63,79 @@ static void axis_limit(int axis, const float limits[2], float co[3], float dcut[ co[axis] = val; } -static void simpleDeform_taper(const float factor, const float dcut[3], float *co) +static void simpleDeform_taper(const float factor, const float dcut[3], float r_co[3]) { - float x = co[0], y = co[1], z = co[2]; + float x = r_co[0], y = r_co[1], z = r_co[2]; float scale = z * factor; - co[0] = x + x * scale; - co[1] = y + y * scale; - co[2] = z; + r_co[0] = x + x * scale; + r_co[1] = y + y * scale; + r_co[2] = z; if (dcut) { - co[0] += dcut[0]; - co[1] += dcut[1]; - co[2] += dcut[2]; + r_co[0] += dcut[0]; + r_co[1] += dcut[1]; + r_co[2] += dcut[2]; } } -static void simpleDeform_stretch(const float factor, const float dcut[3], float *co) +static void simpleDeform_stretch(const float factor, const float dcut[3], float r_co[3]) { - float x = co[0], y = co[1], z = co[2]; + float x = r_co[0], y = r_co[1], z = r_co[2]; float scale; scale = (z * z * factor - factor + 1.0f); - co[0] = x * scale; - co[1] = y * scale; - co[2] = z * (1.0f + factor); + r_co[0] = x * scale; + r_co[1] = y * scale; + r_co[2] = z * (1.0f + factor); if (dcut) { - co[0] += dcut[0]; - co[1] += dcut[1]; - co[2] += dcut[2]; + r_co[0] += dcut[0]; + r_co[1] += dcut[1]; + r_co[2] += dcut[2]; } } -static void simpleDeform_twist(const float factor, const float *dcut, float *co) +static void simpleDeform_twist(const float factor, const float *dcut, float r_co[3]) { - float x = co[0], y = co[1], z = co[2]; + float x = r_co[0], y = r_co[1], z = r_co[2]; float theta, sint, cost; theta = z * factor; - sint = sin(theta); - cost = cos(theta); + sint = sinf(theta); + cost = cosf(theta); - co[0] = x * cost - y * sint; - co[1] = x * sint + y * cost; - co[2] = z; + r_co[0] = x * cost - y * sint; + r_co[1] = x * sint + y * cost; + r_co[2] = z; if (dcut) { - co[0] += dcut[0]; - co[1] += dcut[1]; - co[2] += dcut[2]; + r_co[0] += dcut[0]; + r_co[1] += dcut[1]; + r_co[2] += dcut[2]; } } -static void simpleDeform_bend(const float factor, const float dcut[3], float *co) +static void simpleDeform_bend(const float factor, const float dcut[3], float r_co[3]) { - float x = co[0], y = co[1], z = co[2]; + float x = r_co[0], y = r_co[1], z = r_co[2]; float theta, sint, cost; theta = x * factor; - sint = sin(theta); - cost = cos(theta); + sint = sinf(theta); + cost = cosf(theta); if (fabsf(factor) > 1e-7f) { - co[0] = -(y - 1.0f / factor) * sint; - co[1] = (y - 1.0f / factor) * cost + 1.0f / factor; - co[2] = z; + r_co[0] = -(y - 1.0f / factor) * sint; + r_co[1] = (y - 1.0f / factor) * cost + 1.0f / factor; + r_co[2] = z; } if (dcut) { - co[0] += cost * dcut[0]; - co[1] += sint * dcut[0]; - co[2] += dcut[2]; + r_co[0] += cost * dcut[0]; + r_co[1] += sint * dcut[0]; + r_co[2] += dcut[2]; } } @@ -153,7 +151,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object int limit_axis = 0; float smd_limit[2], smd_factor; SpaceTransform *transf = NULL, tmp_transf; - void (*simpleDeform_callback)(const float factor, const float dcut[3], float *co) = NULL; /* Mode callback */ + void (*simpleDeform_callback)(const float factor, const float dcut[3], float co[3]) = NULL; /* Mode callback */ int vgroup; MDeformVert *dvert; diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index 21e4e216063..b3eb8c0fd5c 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -1197,7 +1197,8 @@ static float occ_form_factor(OccFace *face, float *p, float *n) return contrib; } -static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float *pp, float *pn, float *occ, float rad[3], float bentn[3]) +static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, + const float pp[3], const float pn[3], float *occ, float rad[3], float bentn[3]) { OccNode *node, **stack; OccFace *face; @@ -1391,7 +1392,9 @@ static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass) MEM_freeN(occ); } -static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, float *co, float *n, int thread, int onlyshadow, float *ao, float *env, float *indirect) +static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, + const float co[3], const float n[3], int thread, int onlyshadow, + float *ao, float *env, float *indirect) { float nn[3], bn[3], fac, occ, occlusion, correction, rad[3]; int envcolor; @@ -1415,9 +1418,9 @@ static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, f /* sky shading using bent normal */ if (ELEM(envcolor, WO_AOSKYCOL, WO_AOSKYTEX)) { fac= 0.5f * (1.0f + dot_v3v3(bn, re->grvec)); - env[0]= (1.0f-fac)*re->wrld.horr + fac*re->wrld.zenr; - env[1]= (1.0f-fac)*re->wrld.horg + fac*re->wrld.zeng; - env[2]= (1.0f-fac)*re->wrld.horb + fac*re->wrld.zenb; + env[0] = (1.0f - fac) * re->wrld.horr + fac * re->wrld.zenr; + env[1] = (1.0f - fac) * re->wrld.horg + fac * re->wrld.zeng; + env[2] = (1.0f - fac) * re->wrld.horb + fac * re->wrld.zenb; mul_v3_fl(env, occlusion); } From f73d5f2c446083928553dd6d16b2104657917a88 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 13 Jun 2012 08:10:59 +0000 Subject: [PATCH 258/360] Fix #31780, cycles nested group rendering broken. Was using the dupli object 'index' member to identify dupli objects, but this is not unique and in fact just 0 in most cases. Needs to use a simple dupli list counter instead. --- intern/cycles/blender/blender_object.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index c4b58d6fa76..9c98cacc9b8 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -317,14 +317,18 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) object_create_duplilist(*b_ob, b_scene); BL::Object::dupli_list_iterator b_dup; + int b_index = 0; + for(b_ob->dupli_list.begin(b_dup); b_dup != b_ob->dupli_list.end(); ++b_dup) { Transform tfm = get_transform(b_dup->matrix()); BL::Object b_dup_ob = b_dup->object(); bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render(); if(!(b_dup->hide() || dup_hide)) { - sync_object(*b_ob, b_dup->index(), b_dup_ob, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset); + sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset); } + + ++b_index; } object_free_duplilist(*b_ob); From 4cf66322f32aedcdb5c916452c95da559dfa83ca Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 08:20:43 +0000 Subject: [PATCH 259/360] tint non-active mask layers grey --- source/blender/editors/mask/mask_draw.c | 45 ++++++++++++++++++----- source/blender/makesrna/intern/rna_mask.c | 1 + 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index e1efb6d841b..678186f0e8c 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -233,11 +233,26 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline) /* #define USE_XOR */ +static void mask_color_active_tint(unsigned char r_rgb[4], const unsigned char rgb[4], const short is_active) +{ + if (!is_active) { + r_rgb[0] = (unsigned char)((((int)(rgb[0])) + 128) / 2); + r_rgb[1] = (unsigned char)((((int)(rgb[1])) + 128) / 2); + r_rgb[2] = (unsigned char)((((int)(rgb[2])) + 128) / 2); + r_rgb[3] = rgb[3]; + } + else { + *(unsigned int *)r_rgb = *(const unsigned int *)rgb; + } +} + static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot_point, - const short is_feather, const short is_smooth, + const short is_feather, const short is_smooth, const short is_active, const unsigned char rgb_spline[4], const char draw_type) { const int draw_method = (spline->flag & MASK_SPLINE_CYCLIC) ? GL_LINE_LOOP : GL_LINE_STRIP; + const unsigned char rgb_black[4] = {0x00, 0x00, 0x00, 0xff}; +// const unsigned char rgb_white[4] = {0xff, 0xff, 0xff, 0xff}; unsigned char rgb_tmp[4]; glEnableClientState(GL_VERTEX_ARRAY); @@ -247,12 +262,15 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot case MASK_DT_OUTLINE: glLineWidth(3); - cpack(0x0); + + mask_color_active_tint(rgb_tmp, rgb_black, is_active); + glColor4ubv(rgb_tmp); glDrawArrays(draw_method, 0, tot_point); glLineWidth(1); - glColor4ubv(rgb_spline); + mask_color_active_tint(rgb_tmp, rgb_spline, is_active); + glColor4ubv(rgb_tmp); glDrawArrays(draw_method, 0, tot_point); break; @@ -265,7 +283,8 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot glEnable(GL_COLOR_LOGIC_OP); glLogicOp(GL_OR); #endif - glColor4ubv(rgb_spline); + mask_color_active_tint(rgb_tmp, rgb_spline, is_active); + glColor4ubv(rgb_tmp); glLineStipple(3, 0xaaaa); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, points); @@ -274,7 +293,8 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot #ifdef USE_XOR glDisable(GL_COLOR_LOGIC_OP); #endif - glColor4ub(0, 0, 0, 255); + mask_color_active_tint(rgb_tmp, rgb_black, is_active); + glColor4ubv(rgb_tmp); glLineStipple(3, 0x5555); glDrawArrays(draw_method, 0, tot_point); @@ -301,7 +321,9 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } + mask_color_active_tint(rgb_tmp, rgb_tmp, is_active); glColor4ubv(rgb_tmp); + glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(draw_method, 0, tot_point); @@ -321,6 +343,7 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, const char draw_flag, const char draw_type, + const short is_active, int width, int height) { unsigned char rgb_tmp[4]; @@ -350,14 +373,14 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, /* draw feather */ mask_spline_feather_color_get(masklay, spline, is_spline_sel, rgb_tmp); mask_draw_curve_type(spline, feather_points, tot_feather_point, - TRUE, is_smooth, + TRUE, is_smooth, is_active, rgb_tmp, draw_type); MEM_freeN(feather_points); /* draw main curve */ mask_spline_color_get(masklay, spline, is_spline_sel, rgb_tmp); mask_draw_curve_type(spline, diff_points, tot_diff_point, - FALSE, is_smooth, + FALSE, is_smooth, is_active, rgb_tmp, draw_type); MEM_freeN(diff_points); @@ -373,9 +396,11 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type int width, int height) { MaskLayer *masklay; + int i; - for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + for (masklay = mask->masklayers.first, i = 0; masklay; masklay = masklay->next, i++) { MaskSpline *spline; + const short is_active = (i == mask->masklay_act); if (masklay->restrictflag & MASK_RESTRICT_VIEW) { continue; @@ -384,7 +409,7 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type for (spline = masklay->splines.first; spline; spline = spline->next) { /* draw curve itself first... */ - draw_spline_curve(masklay, spline, draw_flag, draw_type, width, height); + draw_spline_curve(masklay, spline, draw_flag, draw_type, is_active, width, height); // draw_spline_parents(masklay, spline); @@ -398,7 +423,7 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type void *back = spline->points_deform; spline->points_deform = NULL; - draw_spline_curve(masklay, spline, draw_flag, draw_type, width, height); + draw_spline_curve(masklay, spline, draw_flag, draw_type, is_active, width, height); // draw_spline_parents(masklay, spline); draw_spline_points(masklay, spline); spline->points_deform = back; diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 64f1663a524..dfcbbe0653b 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -665,6 +665,7 @@ static void rna_def_mask(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_funcs(prop, "rna_Mask_layer_active_index_get", "rna_Mask_layer_active_index_set", "rna_Mask_layer_active_index_range"); RNA_def_property_ui_text(prop, "Active Shape Index", "Index of active layer in list of all mask's layers"); + RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL); /* frame range */ prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME); From c83d37ccc07c40813e44658857fc79886099b485 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 08:35:50 +0000 Subject: [PATCH 260/360] mango request - highlight active mask layers. - remove keyframes when all layer data is removed. --- source/blender/blenkernel/BKE_mask.h | 1 + source/blender/blenkernel/intern/mask.c | 29 ++++++++++++++++--------- source/blender/editors/mask/mask_ops.c | 6 +++++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 345a2190e89..dd2c7cb3a18 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -48,6 +48,7 @@ struct MaskLayer *BKE_mask_layer_active(struct Mask *mask); void BKE_mask_layer_active_set(struct Mask *mask, struct MaskLayer *masklay); void BKE_mask_layer_remove(struct Mask *mask, struct MaskLayer *masklay); +void BKE_mask_layer_free_shapes(struct MaskLayer *masklay); void BKE_mask_layer_free(struct MaskLayer *masklay); void BKE_mask_spline_free(struct MaskSpline *spline); struct MaskSpline *BKE_mask_spline_copy(struct MaskSpline *spline); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index a28ff3a175d..012ce97b4d7 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1029,10 +1029,27 @@ void BKE_mask_layer_shape_free(MaskLayerShape *masklay_shape) MEM_freeN(masklay_shape); } +/** \brief Free all animation keys for a mask layer + */ +void BKE_mask_layer_free_shapes(MaskLayer *masklay) +{ + MaskLayerShape *masklay_shape; + + /* free animation data */ + masklay_shape = masklay->splines_shapes.first; + while (masklay_shape) { + MaskLayerShape *next_masklay_shape = masklay_shape->next; + + BLI_remlink(&masklay->splines_shapes, masklay_shape); + BKE_mask_layer_shape_free(masklay_shape); + + masklay_shape = next_masklay_shape; + } +} + void BKE_mask_layer_free(MaskLayer *masklay) { MaskSpline *spline; - MaskLayerShape *masklay_shape; /* free splines */ spline = masklay->splines.first; @@ -1046,15 +1063,7 @@ void BKE_mask_layer_free(MaskLayer *masklay) } /* free animation data */ - masklay_shape = masklay->splines_shapes.first; - while (masklay_shape) { - MaskLayerShape *next_masklay_shape = masklay_shape->next; - - BLI_remlink(&masklay->splines_shapes, masklay_shape); - BKE_mask_layer_shape_free(masklay_shape); - - masklay_shape = next_masklay_shape; - } + BKE_mask_layer_free_shapes(masklay); MEM_freeN(masklay); } diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 7c94b79010c..315e40380f9 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -957,6 +957,12 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) spline = next_spline; } + + /* not essential but confuses users when there are keys with no data! + * assume if they delete all data from the layer they also dont care about keys */ + if (masklay->splines.first == NULL) { + BKE_mask_layer_free_shapes(masklay); + } } /* TODO: only update edited splines */ From 6fa1af2a216cf4c4c944818bc0b9f68b4cc7ff6b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 10:03:39 +0000 Subject: [PATCH 261/360] style cleanup: scale node --- .../compositor/nodes/COM_ScaleNode.cpp | 84 +++++++++---------- .../operations/COM_ScaleOperation.cpp | 72 ++++++++-------- .../operations/COM_ScaleOperation.h | 12 +-- 3 files changed, 84 insertions(+), 84 deletions(-) diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp index d709781299f..fd4e4331fca 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.cpp +++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp @@ -31,7 +31,7 @@ ScaleNode::ScaleNode(bNode *editorNode) : Node(editorNode) { } -void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *inputSocket = this->getInputSocket(0); InputSocket *inputXSocket = this->getInputSocket(1); @@ -39,50 +39,50 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext * OutputSocket *outputSocket = this->getOutputSocket(0); bNode *bnode = this->getbNode(); switch (bnode->custom1) { - case CMP_SCALE_RELATIVE: { - ScaleOperation *operation = new ScaleOperation(); - - inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); - inputXSocket->relinkConnections(operation->getInputSocket(1), 1, graph); - inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph); - outputSocket->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - } + case CMP_SCALE_RELATIVE: { + ScaleOperation *operation = new ScaleOperation(); + + inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); + inputXSocket->relinkConnections(operation->getInputSocket(1), 1, graph); + inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph); + outputSocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + } break; - case CMP_SCALE_SCENEPERCENT: { - SetValueOperation * scaleFactorOperation = new SetValueOperation(); - scaleFactorOperation->setValue(context->getScene()->r.size/100.0f); - ScaleOperation * operation = new ScaleOperation(); - inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); - addLink(graph, scaleFactorOperation->getOutputSocket(), operation->getInputSocket(1)); - addLink(graph, scaleFactorOperation->getOutputSocket(), operation->getInputSocket(2)); - outputSocket->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(scaleFactorOperation); - graph->addOperation(operation); - } + case CMP_SCALE_SCENEPERCENT: { + SetValueOperation *scaleFactorOperation = new SetValueOperation(); + scaleFactorOperation->setValue(context->getScene()->r.size / 100.0f); + ScaleOperation *operation = new ScaleOperation(); + inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); + addLink(graph, scaleFactorOperation->getOutputSocket(), operation->getInputSocket(1)); + addLink(graph, scaleFactorOperation->getOutputSocket(), operation->getInputSocket(2)); + outputSocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(scaleFactorOperation); + graph->addOperation(operation); + } break; - - case CMP_SCALE_RENDERPERCENT: { - const RenderData *data = &context->getScene()->r; - ScaleFixedSizeOperation * operation = new ScaleFixedSizeOperation(); - operation->setNewWidth(data->xsch*data->size/100.0f); - operation->setNewHeight(data->ysch*data->size/100.0f); - inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); - outputSocket->relinkConnections(operation->getOutputSocket(0)); - operation->getInputSocket(0)->getConnection()->setIgnoreResizeCheck(true); - graph->addOperation(operation); - } + + case CMP_SCALE_RENDERPERCENT: { + const RenderData *data = &context->getScene()->r; + ScaleFixedSizeOperation *operation = new ScaleFixedSizeOperation(); + operation->setNewWidth(data->xsch * data->size / 100.0f); + operation->setNewHeight(data->ysch * data->size / 100.0f); + inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); + outputSocket->relinkConnections(operation->getOutputSocket(0)); + operation->getInputSocket(0)->getConnection()->setIgnoreResizeCheck(true); + graph->addOperation(operation); + } break; - - case CMP_SCALE_ABSOLUTE: { - ScaleAbsoluteOperation *operation = new ScaleAbsoluteOperation(); // TODO: what is the use of this one.... perhaps some issues when the ui was updated.... - - inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); - inputXSocket->relinkConnections(operation->getInputSocket(1), 1, graph); - inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph); - outputSocket->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - } + + case CMP_SCALE_ABSOLUTE: { + ScaleAbsoluteOperation *operation = new ScaleAbsoluteOperation(); // TODO: what is the use of this one.... perhaps some issues when the ui was updated.... + + inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); + inputXSocket->relinkConnections(operation->getInputSocket(1), 1, graph); + inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph); + outputSocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + } break; } } diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp index ca2095c3170..ef1199cfa32 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cpp +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ @@ -38,8 +38,8 @@ void ScaleOperation::initExecution() this->inputOperation = this->getInputSocketReader(0); this->inputXOperation = this->getInputSocketReader(1); this->inputYOperation = this->getInputSocketReader(2); - this->centerX = this->getWidth()/2.0; - this->centerY = this->getHeight()/2.0; + this->centerX = this->getWidth() / 2.0; + this->centerY = this->getHeight() / 2.0; } void ScaleOperation::deinitExecution() @@ -50,7 +50,7 @@ void ScaleOperation::deinitExecution() } -void ScaleOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void ScaleOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { float scaleX[4]; float scaleY[4]; @@ -61,8 +61,8 @@ void ScaleOperation::executePixel(float *color,float x, float y, PixelSampler sa const float scx = scaleX[0]; const float scy = scaleY[0]; - float nx = this->centerX+ (x - this->centerX) / scx; - float ny = this->centerY+ (y - this->centerY) / scy; + float nx = this->centerX + (x - this->centerX) / scx; + float ny = this->centerY + (y - this->centerY) / scy; this->inputOperation->read(color, nx, ny, sampler, inputBuffers); } @@ -71,18 +71,18 @@ bool ScaleOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOpe rcti newInput; float scaleX[4]; float scaleY[4]; - + this->inputXOperation->read(scaleX, 0, 0, COM_PS_NEAREST, NULL); this->inputYOperation->read(scaleY, 0, 0, COM_PS_NEAREST, NULL); - + const float scx = scaleX[0]; const float scy = scaleY[0]; - - newInput.xmax = this->centerX+ (input->xmax - this->centerX) / scx; - newInput.xmin = this->centerX+ (input->xmin - this->centerX) / scx; - newInput.ymax = this->centerY+ (input->ymax - this->centerY) / scy; - newInput.ymin = this->centerY+ (input->ymin - this->centerY) / scy; - + + newInput.xmax = this->centerX + (input->xmax - this->centerX) / scx; + newInput.xmin = this->centerX + (input->xmin - this->centerX) / scx; + newInput.ymax = this->centerY + (input->ymax - this->centerY) / scy; + newInput.ymin = this->centerY + (input->ymin - this->centerY) / scy; + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } @@ -92,7 +92,7 @@ ScaleAbsoluteOperation::ScaleAbsoluteOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); - this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_COLOR); this->setResolutionInputSocketIndex(0); this->inputOperation = NULL; @@ -104,8 +104,8 @@ void ScaleAbsoluteOperation::initExecution() this->inputOperation = this->getInputSocketReader(0); this->inputXOperation = this->getInputSocketReader(1); this->inputYOperation = this->getInputSocketReader(2); - this->centerX = this->getWidth()/2.0; - this->centerY = this->getHeight()/2.0; + this->centerX = this->getWidth() / 2.0; + this->centerY = this->getHeight() / 2.0; } void ScaleAbsoluteOperation::deinitExecution() @@ -116,7 +116,7 @@ void ScaleAbsoluteOperation::deinitExecution() } -void ScaleAbsoluteOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void ScaleAbsoluteOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { float scaleX[4]; float scaleY[4]; @@ -129,11 +129,11 @@ void ScaleAbsoluteOperation::executePixel(float *color,float x, float y, PixelSa const float width = this->getWidth(); const float height = this->getHeight(); //div - float relativeXScale = scx/width; - float relativeYScale = scy/height; + float relativeXScale = scx / width; + float relativeYScale = scy / height; - float nx = this->centerX+ (x - this->centerX) / relativeXScale; - float ny = this->centerY+ (y - this->centerY) / relativeYScale; + float nx = this->centerX + (x - this->centerX) / relativeXScale; + float ny = this->centerY + (y - this->centerY) / relativeYScale; this->inputOperation->read(color, nx, ny, sampler, inputBuffers); } @@ -151,13 +151,13 @@ bool ScaleAbsoluteOperation::determineDependingAreaOfInterest(rcti *input, ReadB const float width = this->getWidth(); const float height = this->getHeight(); //div - float relateveXScale = scx/width; - float relateveYScale = scy/height; + float relateveXScale = scx / width; + float relateveYScale = scy / height; - newInput.xmax = this->centerX+ (input->xmax - this->centerX) / relateveXScale; - newInput.xmin = this->centerX+ (input->xmin - this->centerX) / relateveXScale; - newInput.ymax = this->centerY+ (input->ymax - this->centerY) / relateveYScale; - newInput.ymin = this->centerY+ (input->ymin - this->centerY) / relateveYScale; + newInput.xmax = this->centerX + (input->xmax - this->centerX) / relateveXScale; + newInput.xmin = this->centerX + (input->xmin - this->centerX) / relateveXScale; + newInput.ymax = this->centerY + (input->ymax - this->centerY) / relateveYScale; + newInput.ymin = this->centerY + (input->ymin - this->centerY) / relateveYScale; return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } @@ -184,19 +184,19 @@ void ScaleFixedSizeOperation::deinitExecution() } -void ScaleFixedSizeOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void ScaleFixedSizeOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { - this->inputOperation->read(color, x*relX, y*relY, sampler, inputBuffers); + this->inputOperation->read(color, x * relX, y * relY, sampler, inputBuffers); } bool ScaleFixedSizeOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { rcti newInput; - - newInput.xmax = input->xmax *relX; - newInput.xmin = input->xmin *relX; - newInput.ymax = input->ymax *relY; - newInput.ymin = input->ymin *relY; + + newInput.xmax = input->xmax * relX; + newInput.xmin = input->xmin * relX; + newInput.ymax = input->ymax * relY; + newInput.ymin = input->ymin * relY; return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h index 3e075249fa1..2c99cb63978 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -25,7 +25,7 @@ #include "COM_NodeOperation.h" -class ScaleOperation: public NodeOperation { +class ScaleOperation : public NodeOperation { private: SocketReader *inputOperation; SocketReader *inputXOperation; @@ -35,13 +35,13 @@ private: public: ScaleOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); }; -class ScaleAbsoluteOperation: public NodeOperation { +class ScaleAbsoluteOperation : public NodeOperation { SocketReader *inputOperation; SocketReader *inputXOperation; SocketReader *inputYOperation; @@ -50,13 +50,13 @@ class ScaleAbsoluteOperation: public NodeOperation { public: ScaleAbsoluteOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); }; -class ScaleFixedSizeOperation: public NodeOperation { +class ScaleFixedSizeOperation : public NodeOperation { SocketReader *inputOperation; int newWidth; int newHeight; @@ -66,7 +66,7 @@ public: ScaleFixedSizeOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); From 902014555a401f770ec17ffeb77e65dc8615c30c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 10:35:41 +0000 Subject: [PATCH 262/360] always use bicubic sampler for the scale node with the new compositor since it worked like this in the old compositor. this ignores the sampler passed and could be done in a nicer way so left this as an ifdef so it can be easily redone. --- .../compositor/operations/COM_ScaleOperation.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp index ef1199cfa32..341bcdd1b62 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cpp +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -22,6 +22,10 @@ #include "COM_ScaleOperation.h" +#define USE_FORCE_BICUBIC +/* XXX - ignore input and use default from old compositor, + * could become an option like the transform node - campbell */ + ScaleOperation::ScaleOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); @@ -52,6 +56,10 @@ void ScaleOperation::deinitExecution() void ScaleOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { +#ifdef USE_FORCE_BICUBIC + sampler = COM_PS_BICUBIC; +#endif + float scaleX[4]; float scaleY[4]; @@ -118,6 +126,10 @@ void ScaleAbsoluteOperation::deinitExecution() void ScaleAbsoluteOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { +#ifdef USE_FORCE_BICUBIC + sampler = COM_PS_BICUBIC; +#endif + float scaleX[4]; float scaleY[4]; @@ -186,6 +198,10 @@ void ScaleFixedSizeOperation::deinitExecution() void ScaleFixedSizeOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { +#ifdef USE_FORCE_BICUBIC + sampler = COM_PS_BICUBIC; +#endif + this->inputOperation->read(color, x * relX, y * relY, sampler, inputBuffers); } From 5e2a9a261bbffdb01bd8fffbc41c02163b97596e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 13 Jun 2012 11:25:22 +0000 Subject: [PATCH 263/360] Fix cycles object_flag array being allocated too big. --- intern/cycles/render/object.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 376a7911fc9..6de7eaea343 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -147,7 +147,7 @@ ObjectManager::~ObjectManager() void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) { float4 *objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size()); - uint *object_flag = dscene->object_flag.resize(OBJECT_SIZE*scene->objects.size()); + uint *object_flag = dscene->object_flag.resize(scene->objects.size()); int i = 0; map surface_area_map; Scene::MotionType need_motion = scene->need_motion(); From 74a85df0c1fa9b564f128b71898777c9b826c0fd Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 13 Jun 2012 11:25:36 +0000 Subject: [PATCH 264/360] Fix cycles crash when viewport camera border goes out of view. --- intern/cycles/blender/blender_camera.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index 122d0bd7c17..46d5fefd4dc 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -485,10 +485,10 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp bcam->border_top = tmp_bottom + bcam->border_top*(tmp_top - tmp_bottom); /* clamp */ - bcam->border_left = max(bcam->border_left, 0.0f); - bcam->border_right = min(bcam->border_right, 1.0f); - bcam->border_bottom = max(bcam->border_bottom, 0.0f); - bcam->border_top = min(bcam->border_top, 1.0f); + bcam->border_left = clamp(bcam->border_left, 0.0f, 1.0f); + bcam->border_right = clamp(bcam->border_right, 0.0f, 1.0f); + bcam->border_bottom = clamp(bcam->border_bottom, 0.0f, 1.0f); + bcam->border_top = clamp(bcam->border_top, 0.0f, 1.0f); } void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) @@ -514,6 +514,10 @@ BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, Camera *cam, int params.full_y = cam->border_bottom*height; params.width = (int)(cam->border_right*width) - params.full_x; params.height = (int)(cam->border_top*height) - params.full_y; + + /* survive in case border goes out of view or becomes too small */ + params.width = max(params.width, 1); + params.height = max(params.height, 1); } else { params.width = width; From dcda234a3d93ed44189fac3716a694f4f75f366e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 11:40:49 +0000 Subject: [PATCH 265/360] update themes for new colors, patch by Brendon Murphy --- .../presets/interface_theme/back_to_black.xml | 31 ++++++++++++++++--- .../presets/interface_theme/blender_24x.xml | 31 ++++++++++++++++--- .../presets/interface_theme/elsyiun.xml | 31 ++++++++++++++++--- .../presets/interface_theme/hexagon.xml | 31 ++++++++++++++++--- .../interface_theme/ubuntu_ambiance.xml | 31 ++++++++++++++++--- 5 files changed, 130 insertions(+), 25 deletions(-) diff --git a/release/scripts/presets/interface_theme/back_to_black.xml b/release/scripts/presets/interface_theme/back_to_black.xml index 66a2ae54ade..866c4ab412d 100644 --- a/release/scripts/presets/interface_theme/back_to_black.xml +++ b/release/scripts/presets/interface_theme/back_to_black.xml @@ -42,6 +42,7 @@ object_selected="#f15800" outline_width="1" panel="#a5a5a57f" + skin_root="#000000" speaker="#535353" transform="#ffffff" handle_vect="#409030" @@ -80,7 +81,9 @@ marker_outline="#0094af" path_after="#0000ff" path_before="#ff0000" - selected_marker="#ffff00"> + selected_marker="#ffff00" + strips="#0c0a0a" + strips_selected="#ff8c00"> + + + + @@ -130,6 +140,7 @@ grid="#212121" long_key="#0c0a0a" long_key_selected="#ff8c00" + summary="#00000000" value_sliders="#000000" view_sliders="#969696"> @@ -304,12 +315,20 @@ - - + selected_marker="#ffff00" + strips="#0c0a0a" + strips_selected="#ff8c00"> + + + + @@ -130,6 +140,7 @@ grid="#858585" long_key="#0c0a0a" long_key_selected="#ff8c00" + summary="#00000000" value_sliders="#000000" view_sliders="#969696"> @@ -304,12 +315,20 @@ - - + selected_marker="#ffff00" + strips="#0c0a0a" + strips_selected="#ff8c00"> + + + + @@ -130,6 +140,7 @@ grid="#585858" long_key="#0c0a0a" long_key_selected="#ff8c00" + summary="#00000000" value_sliders="#000000" view_sliders="#969696"> @@ -304,12 +315,20 @@ - - + selected_marker="#ffff00" + strips="#0c0a0a" + strips_selected="#ff8c00"> + + + + @@ -130,6 +140,7 @@ grid="#58587c" long_key="#0c0a0a" long_key_selected="#ff8c00" + summary="#00000000" value_sliders="#000000" view_sliders="#969696"> @@ -304,12 +315,20 @@ - - + selected_marker="#d5ff00" + strips="#0c0a0a" + strips_selected="#ff8c00"> + + + + @@ -130,6 +140,7 @@ grid="#525252" long_key="#0c0a0a" long_key_selected="#f47421" + summary="#00000000" value_sliders="#000000" view_sliders="#969696"> @@ -304,12 +315,20 @@ - - Date: Wed, 13 Jun 2012 11:44:48 +0000 Subject: [PATCH 266/360] Cycles: first step for implementation of non-progressive sampler that handles direct and indirect lighting differently. Rather than picking one light for each point on the path, it now loops over all lights for direct lighting. For indirect lighting it still picks a random light each time. It gives control over the number of AA samples, and the number of Diffuse, Glossy, Transmission, AO, Mesh Light, Background and Lamp samples for each AA sample. This helps tuning render performance/noise and tends to give less noise for renders dominated by direct lighting. This sampling mode only works on the CPU, and still needs proper tile rendering to show progress (will follow tommorrow or so), because each AA sample can be quite slow now and so the delay between each update wil be too long. --- intern/cycles/blender/addon/properties.py | 61 +++ intern/cycles/blender/addon/ui.py | 74 +++- intern/cycles/blender/blender_object.cpp | 2 + intern/cycles/blender/blender_sync.cpp | 31 +- intern/cycles/kernel/kernel_emission.h | 2 +- intern/cycles/kernel/kernel_light.h | 6 + intern/cycles/kernel/kernel_path.h | 482 +++++++++++++++++++++- intern/cycles/kernel/kernel_shader.h | 48 +++ intern/cycles/kernel/kernel_types.h | 11 +- intern/cycles/render/integrator.cpp | 38 +- intern/cycles/render/integrator.h | 10 +- intern/cycles/render/light.cpp | 67 ++- intern/cycles/render/light.h | 1 + intern/cycles/render/scene.cpp | 2 +- 14 files changed, 745 insertions(+), 90 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 3ade04c4658..7ce3b949bb1 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -57,6 +57,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default='GPU_COMPATIBLE', ) + cls.progressive = BoolProperty( + name="Progressive", + description="Use progressive sampling of lighting", + default=True, + ) + cls.samples = IntProperty( name="Samples", description="Number of samples to render for each pixel", @@ -80,6 +86,49 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default=False, ) + cls.aa_samples = IntProperty( + name="AA Samples", + description="Number of antialiasing samples to render for each pixel", + min=1, max=10000, + default=4, + ) + cls.preview_aa_samples = IntProperty( + name="AA Samples", + description="Number of antialiasing samples to in viewport, unlimited if 0", + min=1, max=10000, + default=4, + ) + cls.diffuse_samples = IntProperty( + name="Diffuse Samples", + description="Number of diffuse bounce samples to render for each AA sample", + min=1, max=10000, + default=1, + ) + cls.glossy_samples = IntProperty( + name="Glossy Samples", + description="Number of glossy bounce samples to render for each AA sample", + min=1, max=10000, + default=1, + ) + cls.transmission_samples = IntProperty( + name="Transmission Samples", + description="Number of transmission bounce samples to render for each AA sample", + min=1, max=10000, + default=1, + ) + cls.ao_samples = IntProperty( + name="Ambient Occlusion Samples", + description="Number of ambient occlusion samples to render for each AA sample", + min=1, max=10000, + default=1, + ) + cls.mesh_light_samples = IntProperty( + name="Mesh Light Samples", + description="Number of mesh emission light samples to render for each AA sample", + min=1, max=10000, + default=1, + ) + cls.no_caustics = BoolProperty( name="No Caustics", description="Leave out caustics, resulting in a darker image with less noise", @@ -340,6 +389,12 @@ class CyclesLampSettings(bpy.types.PropertyGroup): description="Lamp casts shadows", default=True, ) + cls.samples = IntProperty( + name="Samples", + description="Number of light samples to render for each AA sample", + min=1, max=10000, + default=1, + ) @classmethod def unregister(cls): @@ -365,6 +420,12 @@ class CyclesWorldSettings(bpy.types.PropertyGroup): min=4, max=8096, default=256, ) + cls.samples = IntProperty( + name="Samples", + description="Number of light samples to render for each AA sample", + min=1, max=10000, + default=4, + ) @classmethod def unregister(cls): diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 3b906bb4bdf..6f2b33b2815 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -44,8 +44,48 @@ class CyclesButtonsPanel(): return rd.engine == 'CYCLES' -class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel): - bl_label = "Integrator" +class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel): + bl_label = "Sampling" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + + scene = context.scene + cscene = scene.cycles + + split = layout.split() + + col = split.column() + sub = col.column(align=True) + sub.active = cscene.device == 'CPU' + sub.prop(cscene, "progressive") + + sub = col.column(align=True) + sub.prop(cscene, "seed") + sub.prop(cscene, "sample_clamp") + + if cscene.progressive or cscene.device != 'CPU': + col = split.column(align=True) + col.label(text="Samples:") + col.prop(cscene, "samples", text="Render") + col.prop(cscene, "preview_samples", text="Preview") + else: + sub = col.column(align=True) + sub.label(text="AA Samples:") + sub.prop(cscene, "aa_samples", text="Render") + sub.prop(cscene, "preview_aa_samples", text="Preview") + + col = split.column(align=True) + col.label(text="Samples:") + col.prop(cscene, "diffuse_samples", text="Diffuse") + col.prop(cscene, "glossy_samples", text="Glossy") + col.prop(cscene, "transmission_samples", text="Transmission") + col.prop(cscene, "ao_samples", text="AO") + col.prop(cscene, "mesh_light_samples", text="Mesh Light") + +class CyclesRender_PT_light_paths(CyclesButtonsPanel, Panel): + bl_label = "Light Paths" bl_options = {'DEFAULT_CLOSED'} def draw(self, context): @@ -62,12 +102,6 @@ class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel): split = layout.split() col = split.column() - sub = col.column(align=True) - sub.label(text="Samples:") - sub.prop(cscene, "samples", text="Render") - sub.prop(cscene, "preview_samples", text="Preview") - sub.prop(cscene, "seed") - sub.prop(cscene, "sample_clamp") sub = col.column(align=True) sub.label("Transparency:") @@ -75,6 +109,11 @@ class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel): sub.prop(cscene, "transparent_min_bounces", text="Min") sub.prop(cscene, "use_transparent_shadows", text="Shadows") + col.separator() + + col.prop(cscene, "no_caustics") + col.prop(cscene, "blur_glossy") + col = split.column() sub = col.column(align=True) @@ -83,16 +122,10 @@ class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel): sub.prop(cscene, "min_bounces", text="Min") sub = col.column(align=True) - sub.label(text="Light Paths:") sub.prop(cscene, "diffuse_bounces", text="Diffuse") sub.prop(cscene, "glossy_bounces", text="Glossy") sub.prop(cscene, "transmission_bounces", text="Transmission") - col.separator() - - col.prop(cscene, "no_caustics") - col.prop(cscene, "blur_glossy") - class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel): bl_label = "Motion Blur" @@ -467,6 +500,7 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel): lamp = context.lamp clamp = lamp.cycles + cscene = context.scene.cycles layout.prop(lamp, "type", expand=True) @@ -485,6 +519,9 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel): sub.prop(lamp, "size", text="Size X") sub.prop(lamp, "size_y", text="Size Y") + if not cscene.progressive and cscene.device == 'CPU': + col.prop(clamp, "samples") + col = split.column() col.prop(clamp, "cast_shadow") @@ -604,13 +641,16 @@ class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel): world = context.world cworld = world.cycles + cscene = context.scene.cycles col = layout.column() col.prop(cworld, "sample_as_light") - row = col.row() - row.active = cworld.sample_as_light - row.prop(cworld, "sample_map_resolution") + sub = col.row(align=True) + sub.active = cworld.sample_as_light + sub.prop(cworld, "sample_map_resolution") + if not cscene.progressive and cscene.device == 'CPU': + sub.prop(cworld, "samples") class CyclesMaterial_PT_surface(CyclesButtonsPanel, Panel): diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 9c98cacc9b8..d5b884cfccd 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -154,6 +154,7 @@ void BlenderSync::sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, /* shadow */ PointerRNA clamp = RNA_pointer_get(&b_lamp.ptr, "cycles"); light->cast_shadow = get_boolean(clamp, "cast_shadow"); + light->samples = get_int(clamp, "samples"); /* tag */ light->tag_update(scene); @@ -178,6 +179,7 @@ void BlenderSync::sync_background_light() { light->type = LIGHT_BACKGROUND; light->map_resolution = get_int(cworld, "sample_map_resolution"); + light->samples = get_int(cworld, "samples"); light->shader = scene->default_background; light->tag_update(scene); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 13040e551bd..5640a411fd7 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -168,6 +168,13 @@ void BlenderSync::sync_integrator() integrator->motion_blur = (!preview && r.use_motion_blur()); #endif + integrator->diffuse_samples = get_int(cscene, "diffuse_samples"); + integrator->glossy_samples = get_int(cscene, "glossy_samples"); + integrator->transmission_samples = get_int(cscene, "transmission_samples"); + integrator->ao_samples = get_int(cscene, "ao_samples"); + integrator->mesh_light_samples = get_int(cscene, "mesh_light_samples"); + integrator->progressive = get_boolean(cscene, "progressive"); + if(integrator->modified(previntegrator)) integrator->tag_update(scene); } @@ -308,15 +315,27 @@ SessionParams BlenderSync::get_session_params(BL::UserPreferences b_userpref, BL /* Background */ params.background = background; - + /* samples */ - if(background) { - params.samples = get_int(cscene, "samples"); + if(get_boolean(cscene, "progressive")) { + if(background) { + params.samples = get_int(cscene, "samples"); + } + else { + params.samples = get_int(cscene, "preview_samples"); + if(params.samples == 0) + params.samples = INT_MAX; + } } else { - params.samples = get_int(cscene, "preview_samples"); - if(params.samples == 0) - params.samples = INT_MAX; + if(background) { + params.samples = get_int(cscene, "aa_samples"); + } + else { + params.samples = get_int(cscene, "preview_aa_samples"); + if(params.samples == 0) + params.samples = INT_MAX; + } } /* other parameters */ diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index f582ace69f0..53d53b4bedd 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -67,7 +67,7 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, float pdf = -1.0f; -#ifdef __MULTI_LIGHT__ +#ifdef __NON_PROGRESSIVE__ if(lindex != -1) { /* sample position on a specified light */ light_select(kg, lindex, randu, randv, sd->P, &ls, &pdf); diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index edc302cd6e3..1084415d0cf 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -388,6 +388,12 @@ __device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, fl return pdf; } +__device int light_select_num_samples(KernelGlobals *kg, int index) +{ + float4 data3 = kernel_tex_fetch(__light_data, index*LIGHT_SIZE + 3); + return __float_as_int(data3.x); +} + __device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf) { regular_light_sample(kg, index, randu, randv, P, ls, pdf); diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 8dbf66c108c..80d66532506 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -218,7 +218,7 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra return result; } -__device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer) +__device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer) { /* initialize */ PathRadiance L; @@ -366,26 +366,15 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R light_ray.time = sd.time; #endif -#ifdef __MULTI_LIGHT__ - /* index -1 means randomly sample from distribution */ - int i = (kernel_data.integrator.num_all_lights)? 0: -1; + if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; - for(; i < kernel_data.integrator.num_all_lights; i++) { -#else - const int i = -1; -#endif - if(direct_emission(kg, &sd, i, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) { - /* trace shadow ray */ - float3 shadow; - - if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { - /* accumulate */ - path_radiance_accum_light(&L, throughput, &L_light, shadow, state.bounce, is_lamp); - } + if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(&L, throughput, &L_light, shadow, state.bounce, is_lamp); } -#ifdef __MULTI_LIGHT__ } -#endif } } #endif @@ -444,6 +433,451 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent); } +#ifdef __NON_PROGRESSIVE__ + +__device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer, + float3 throughput, float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L) +{ + /* path iteration */ + for(;; rng_offset += PRNG_BOUNCE_NUM) { + /* intersect scene */ + Intersection isect; + uint visibility = path_state_ray_visibility(kg, &state); + + if(!scene_intersect(kg, &ray, visibility, &isect)) { +#ifdef __BACKGROUND__ + /* sample background shader */ + float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf); + path_radiance_accum_background(L, throughput, L_background, state.bounce); +#endif + + break; + } + + /* setup shading */ + ShaderData sd; + shader_setup_from_ray(kg, &sd, &isect, &ray); + float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF); + shader_eval_surface(kg, &sd, rbsdf, state.flag); + shader_merge_closures(kg, &sd); + + /* blurring of bsdf after bounces, for rays that have a small likelihood + * of following this particular path (diffuse, rough glossy) */ + if(kernel_data.integrator.filter_glossy != FLT_MAX) { + float blur_pdf = kernel_data.integrator.filter_glossy*min_ray_pdf; + + if(blur_pdf < 1.0f) { + float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f; + shader_bsdf_blur(kg, &sd, blur_roughness); + } + } + +#ifdef __EMISSION__ + /* emission */ + if(sd.flag & SD_EMISSION) { + float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf); + path_radiance_accum_emission(L, throughput, emission, state.bounce); + } +#endif + + /* path termination. this is a strange place to put the termination, it's + * mainly due to the mixed in MIS that we use. gives too many unneeded + * shader evaluations, only need emission if we are going to terminate */ + float probability = path_state_terminate_probability(kg, &state, throughput); + float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE); + + if(terminate >= probability) + break; + + throughput /= probability; + +#ifdef __AO__ + /* ambient occlusion */ + if(kernel_data.integrator.use_ambient_occlusion) { + /* todo: solve correlation */ + float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U); + float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V); + + float3 ao_D; + float ao_pdf; + + sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); + + if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { + Ray light_ray; + float3 ao_shadow; + + light_ray.P = ray_offset(sd.P, sd.Ng); + light_ray.D = ao_D; + light_ray.t = kernel_data.background.ao_distance; +#ifdef __MOTION__ + light_ray.time = sd.time; +#endif + + if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) { + float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor; + path_radiance_accum_ao(L, throughput, ao_bsdf, ao_shadow, state.bounce); + } + } + } +#endif + +#ifdef __EMISSION__ + if(kernel_data.integrator.use_direct_light) { + /* sample illumination from lights to find path contribution */ + if(sd.flag & SD_BSDF_HAS_EVAL) { + float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT); + float light_o = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_F); + float light_u = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_U); + float light_v = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_V); + + Ray light_ray; + BsdfEval L_light; + bool is_lamp; + +#ifdef __MOTION__ + light_ray.time = sd.time; +#endif + + /* sample random light */ + if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; + + if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(L, throughput, &L_light, shadow, state.bounce, is_lamp); + } + } + } + } +#endif + + /* no BSDF? we can stop here */ + if(!(sd.flag & SD_BSDF)) + break; + + /* sample BSDF */ + float bsdf_pdf; + BsdfEval bsdf_eval; + float3 bsdf_omega_in; + differential3 bsdf_domega_in; + float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U); + float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V); + int label; + + label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval, + &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf); + + shader_release(kg, &sd); + + if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) + break; + + /* modify throughput */ + path_radiance_bsdf_bounce(L, &throughput, &bsdf_eval, bsdf_pdf, state.bounce, label); + + /* set labels */ + if(!(label & LABEL_TRANSPARENT)) { + ray_pdf = bsdf_pdf; + min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); + } + + /* update path state */ + path_state_next(kg, &state, label); + + /* setup ray */ + ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng); + ray.D = bsdf_omega_in; + ray.t = FLT_MAX; +#ifdef __RAY_DIFFERENTIALS__ + ray.dP = sd.dP; + ray.dD = bsdf_domega_in; +#endif + } +} + +__device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer) +{ + /* initialize */ + PathRadiance L; + float3 throughput = make_float3(1.0f, 1.0f, 1.0f); + float L_transparent = 0.0f; + + path_radiance_init(&L, kernel_data.film.use_light_pass); + + float ray_pdf = 0.0f; + PathState state; + int rng_offset = PRNG_BASE_NUM; + + path_state_init(&state); + + for(;; rng_offset += PRNG_BOUNCE_NUM) { + /* intersect scene */ + Intersection isect; + uint visibility = path_state_ray_visibility(kg, &state); + + if(!scene_intersect(kg, &ray, visibility, &isect)) { + /* eval background shader if nothing hit */ + if(kernel_data.background.transparent) { + L_transparent += average(throughput); + +#ifdef __PASSES__ + if(!(kernel_data.film.pass_flag & PASS_BACKGROUND)) +#endif + break; + } + +#ifdef __BACKGROUND__ + /* sample background shader */ + float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf); + path_radiance_accum_background(&L, throughput, L_background, state.bounce); +#endif + + break; + } + + /* setup shading */ + ShaderData sd; + shader_setup_from_ray(kg, &sd, &isect, &ray); + float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF); + shader_eval_surface(kg, &sd, rbsdf, state.flag); + shader_merge_closures(kg, &sd); + + kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput); + + /* holdout */ +#ifdef __HOLDOUT__ + if((sd.flag & (SD_HOLDOUT|SD_HOLDOUT_MASK))) { + if(kernel_data.background.transparent) { + float3 holdout_weight; + + if(sd.flag & SD_HOLDOUT_MASK) + holdout_weight = make_float3(1.0f, 1.0f, 1.0f); + else + shader_holdout_eval(kg, &sd); + + /* any throughput is ok, should all be identical here */ + L_transparent += average(holdout_weight*throughput); + } + + if(sd.flag & SD_HOLDOUT_MASK) + break; + } +#endif + +#ifdef __EMISSION__ + /* emission */ + if(sd.flag & SD_EMISSION) { + float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf); + path_radiance_accum_emission(&L, throughput, emission, state.bounce); + } +#endif + + /* transparency termination */ + if(state.flag & PATH_RAY_TRANSPARENT) { + /* path termination. this is a strange place to put the termination, it's + * mainly due to the mixed in MIS that we use. gives too many unneeded + * shader evaluations, only need emission if we are going to terminate */ + float probability = path_state_terminate_probability(kg, &state, throughput); + float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE); + + if(terminate >= probability) + break; + + throughput /= probability; + } + +#ifdef __AO__ + /* ambient occlusion */ + if(kernel_data.integrator.use_ambient_occlusion) { + int num_samples = kernel_data.integrator.ao_samples; + float ao_factor = kernel_data.background.ao_factor/num_samples; + + for(int j = 0; j < num_samples; j++) { + /* todo: solve correlation */ + float bsdf_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_BSDF_U); + float bsdf_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_BSDF_V); + + float3 ao_D; + float ao_pdf; + + sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); + + if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { + Ray light_ray; + float3 ao_shadow; + + light_ray.P = ray_offset(sd.P, sd.Ng); + light_ray.D = ao_D; + light_ray.t = kernel_data.background.ao_distance; +#ifdef __MOTION__ + light_ray.time = sd.time; +#endif + + if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) { + float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*ao_factor; + path_radiance_accum_ao(&L, throughput, ao_bsdf, ao_shadow, state.bounce); + } + } + } + } +#endif + +#ifdef __EMISSION__ + /* sample illumination from lights to find path contribution */ + if(sd.flag & SD_BSDF_HAS_EVAL) { + Ray light_ray; + BsdfEval L_light; + bool is_lamp; + +#ifdef __MOTION__ + light_ray.time = sd.time; +#endif + + /* lamp sampling */ + for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) { + int num_samples = light_select_num_samples(kg, i); + float num_samples_inv = 1.0f/(num_samples*kernel_data.integrator.num_all_lights); + + if(kernel_data.integrator.pdf_triangles != 0.0f) + num_samples_inv *= 0.5f; + + for(int j = 0; j < num_samples; j++) { + float light_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_U); + float light_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_V); + + if(direct_emission(kg, &sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; + + if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp); + } + } + } + } + + /* mesh light sampling */ + if(kernel_data.integrator.pdf_triangles != 0.0f) { + int num_samples = kernel_data.integrator.mesh_light_samples; + float num_samples_inv = 1.0f/num_samples; + + if(kernel_data.integrator.num_all_lights) + num_samples_inv *= 0.5f; + + for(int j = 0; j < num_samples; j++) { + float light_t = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT); + float light_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_U); + float light_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_V); + + /* only sample triangle lights */ + if(kernel_data.integrator.num_all_lights) + light_t = 0.5f*light_t; + + if(direct_emission(kg, &sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; + + if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp); + } + } + } + } + } +#endif + + for(int i = 0; i< sd.num_closure; i++) { + const ShaderClosure *sc = &sd.closure[i]; + + if(!CLOSURE_IS_BSDF(sc->type)) + continue; + /* transparency is not handled here, but in outer loop */ + if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) + continue; + + int num_samples; + + if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) + num_samples = kernel_data.integrator.diffuse_samples; + else if(CLOSURE_IS_BSDF_GLOSSY(sc->type)) + num_samples = kernel_data.integrator.glossy_samples; + else + num_samples = kernel_data.integrator.transmission_samples; + + float num_samples_inv = 1.0f/num_samples; + + for(int j = 0; j < num_samples; j++) { + /* sample BSDF */ + float bsdf_pdf; + BsdfEval bsdf_eval; + float3 bsdf_omega_in; + differential3 bsdf_domega_in; + float bsdf_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_BSDF_U); + float bsdf_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_BSDF_V); + int label; + + label = shader_bsdf_sample_closure(kg, &sd, sc, bsdf_u, bsdf_v, &bsdf_eval, + &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf); + + if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) + continue; + + /* modify throughput */ + float3 tp = throughput; + path_radiance_bsdf_bounce(&L, &tp, &bsdf_eval, bsdf_pdf, state.bounce, label); + + /* set labels */ + float min_ray_pdf = FLT_MAX; + + if(!(label & LABEL_TRANSPARENT)) + min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); + + /* modify path state */ + PathState ps = state; + path_state_next(kg, &ps, label); + + /* setup ray */ + ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng); + ray.D = bsdf_omega_in; + ray.t = FLT_MAX; +#ifdef __RAY_DIFFERENTIALS__ + ray.dP = sd.dP; + ray.dD = bsdf_domega_in; +#endif + + kernel_path_indirect(kg, rng, sample*num_samples, ray, buffer, + tp*num_samples_inv, min_ray_pdf, ray_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L); + } + } + + /* continue in case of transparency */ + throughput *= shader_bsdf_transparency(kg, &sd); + shader_release(kg, &sd); + + if(is_zero(throughput)) + break; + + path_state_next(kg, &state, LABEL_TRANSPARENT); + ray.P = ray_offset(sd.P, -sd.Ng); + } + + float3 L_sum = path_radiance_sum(kg, &L); + +#ifdef __CLAMP_SAMPLE__ + path_radiance_clamp(&L, &L_sum, kernel_data.integrator.sample_clamp); +#endif + + kernel_write_light_passes(kg, buffer, &L, sample); + + return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent); +} + +#endif + __device void kernel_path_trace(KernelGlobals *kg, __global float *buffer, __global uint *rng_state, int sample, int x, int y, int offset, int stride) @@ -480,8 +914,16 @@ __device void kernel_path_trace(KernelGlobals *kg, /* integrate */ float4 L; - if (ray.t != 0.f) - L = kernel_path_integrate(kg, &rng, sample, ray, buffer); + if (ray.t != 0.0f) { +#ifdef __NON_PROGRESSIVE__ + if(kernel_data.integrator.progressive) +#endif + L = kernel_path_progressive(kg, &rng, sample, ray, buffer); +#ifdef __NON_PROGRESSIVE__ + else + L = kernel_path_non_progressive(kg, &rng, sample, ray, buffer); +#endif + } else L = make_float4(0.f, 0.f, 0.f, 0.f); diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 53a41d58e20..bc873f4e112 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -407,6 +407,25 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd, #endif } +__device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd, + const ShaderClosure *sc, float randu, float randv, BsdfEval *bsdf_eval, + float3 *omega_in, differential3 *domega_in, float *pdf) +{ + int label; + float3 eval; + + *pdf = 0.0f; +#ifdef __OSL__ + label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf); +#else + label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); +#endif + if(*pdf != 0.0f) + bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass); + + return label; +} + __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness) { #ifndef __OSL__ @@ -679,6 +698,35 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect) } #endif +/* Merging */ + +#ifdef __NON_PROGRESSIVE__ +__device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd) +{ +#ifndef __OSL__ + /* merge identical closures, better when we sample a single closure at a time */ + for(int i = 0; i < sd->num_closure; i++) { + ShaderClosure *sci = &sd->closure[i]; + + for(int j = i + 1; j < sd->num_closure; j++) { + ShaderClosure *scj = &sd->closure[j]; + + if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) { + sci->weight += scj->weight; + sci->sample_weight += scj->sample_weight; + + int size = sd->num_closure - (j+1); + if(size > 0) + memmove(scj, scj+1, size*sizeof(ShaderClosure)); + + sd->num_closure--; + } + } + } +#endif +} +#endif + /* Free ShaderData */ __device void shader_release(KernelGlobals *kg, ShaderData *sd) diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 77a800b0e67..d204b114b8e 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -43,6 +43,7 @@ CCL_NAMESPACE_BEGIN #ifdef WITH_OSL #define __OSL__ #endif +#define __NON_PROGRESSIVE__ #endif #ifdef __KERNEL_CUDA__ @@ -110,7 +111,6 @@ CCL_NAMESPACE_BEGIN //#define __MOTION__ #endif -//#define __MULTI_LIGHT__ //#define __SOBOL_FULL_SCREEN__ //#define __QBVH__ @@ -627,6 +627,15 @@ typedef struct KernelIntegrator { /* clamp */ float sample_clamp; + + /* non-progressive */ + int progressive; + int diffuse_samples; + int glossy_samples; + int transmission_samples; + int ao_samples; + int mesh_light_samples; + int pad1, pad2; } KernelIntegrator; typedef struct KernelBVH { diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index b26ebfd91e1..da563c9c4ec 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -18,9 +18,11 @@ #include "device.h" #include "integrator.h" +#include "light.h" #include "scene.h" #include "sobol.h" +#include "util_foreach.h" #include "util_hash.h" CCL_NAMESPACE_BEGIN @@ -47,6 +49,13 @@ Integrator::Integrator() sample_clamp = 0.0f; motion_blur = false; + diffuse_samples = 1; + glossy_samples = 1; + transmission_samples = 1; + ao_samples = 1; + mesh_light_samples = 1; + progressive = true; + need_update = true; } @@ -54,7 +63,7 @@ Integrator::~Integrator() { } -void Integrator::device_update(Device *device, DeviceScene *dscene) +void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene) { if(!need_update) return; @@ -93,8 +102,27 @@ void Integrator::device_update(Device *device, DeviceScene *dscene) kintegrator->sample_clamp = (sample_clamp == 0.0f)? FLT_MAX: sample_clamp*3.0f; + kintegrator->progressive = progressive; + kintegrator->diffuse_samples = diffuse_samples; + kintegrator->glossy_samples = glossy_samples; + kintegrator->transmission_samples = transmission_samples; + kintegrator->ao_samples = ao_samples; + kintegrator->mesh_light_samples = mesh_light_samples; + /* sobol directions table */ - int dimensions = PRNG_BASE_NUM + (max_bounce + transparent_max_bounce + 2)*PRNG_BOUNCE_NUM; + int max_samples = 1; + + if(!progressive) { + foreach(Light *light, scene->lights) + max_samples = max(max_samples, light->samples); + + max_samples = max(max_samples, max(diffuse_samples, max(glossy_samples, transmission_samples))); + max_samples = max(max_samples, max(ao_samples, mesh_light_samples)); + } + + max_samples *= (max_bounce + transparent_max_bounce + 2); + + int dimensions = PRNG_BASE_NUM + max_samples*PRNG_BOUNCE_NUM; uint *directions = dscene->sobol_directions.resize(SOBOL_BITS*dimensions); sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions); @@ -127,6 +155,12 @@ bool Integrator::modified(const Integrator& integrator) layer_flag == integrator.layer_flag && seed == integrator.seed && sample_clamp == integrator.sample_clamp && + progressive == integrator.progressive && + diffuse_samples == integrator.diffuse_samples && + glossy_samples == integrator.glossy_samples && + transmission_samples == integrator.transmission_samples && + ao_samples == integrator.ao_samples && + mesh_light_samples == integrator.mesh_light_samples && motion_blur == integrator.motion_blur); } diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h index afda41a857d..8fb341182b7 100644 --- a/intern/cycles/render/integrator.h +++ b/intern/cycles/render/integrator.h @@ -49,12 +49,20 @@ public: float sample_clamp; bool motion_blur; + int diffuse_samples; + int glossy_samples; + int transmission_samples; + int ao_samples; + int mesh_light_samples; + + bool progressive; + bool need_update; Integrator(); ~Integrator(); - void device_update(Device *device, DeviceScene *dscene); + void device_update(Device *device, DeviceScene *dscene, Scene *scene); void device_free(Device *device, DeviceScene *dscene); bool modified(const Integrator& integrator); diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index e918de990c2..6c03d0859a7 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -17,6 +17,7 @@ */ #include "device.h" +#include "integrator.h" #include "light.h" #include "mesh.h" #include "object.h" @@ -114,6 +115,7 @@ Light::Light() cast_shadow = true; shader = 0; + samples = 1; } void Light::tag_update(Scene *scene) @@ -136,9 +138,6 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen { progress.set_status("Updating Lights", "Computing distribution"); - /* option to always sample all point lights */ - bool multi_light = false; - /* count */ size_t num_lights = scene->lights.size(); size_t num_triangles = 0; @@ -169,9 +168,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen } size_t num_distribution = num_triangles; - - if(!multi_light) - num_distribution += num_lights; + num_distribution += num_lights; /* emission area */ float4 *distribution = dscene->light_distribution.resize(num_distribution + 1); @@ -231,16 +228,14 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen float trianglearea = totarea; /* point lights */ - if(!multi_light) { - float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f; + float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f; - for(int i = 0; i < scene->lights.size(); i++, offset++) { - distribution[offset].x = totarea; - distribution[offset].y = __int_as_float(~(int)i); - distribution[offset].z = 1.0f; - distribution[offset].w = scene->lights[i]->size; - totarea += lightarea; - } + for(int i = 0; i < scene->lights.size(); i++, offset++) { + distribution[offset].x = totarea; + distribution[offset].y = __int_as_float(~(int)i); + distribution[offset].z = 1.0f; + distribution[offset].w = scene->lights[i]->size; + totarea += lightarea; } /* normalize cumulative distribution functions */ @@ -259,7 +254,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen /* update device */ KernelIntegrator *kintegrator = &dscene->data.integrator; - kintegrator->use_direct_light = (totarea > 0.0f) || (multi_light && num_lights); + kintegrator->use_direct_light = (totarea > 0.0f); if(kintegrator->use_direct_light) { /* number of emissives */ @@ -269,30 +264,19 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen kintegrator->pdf_triangles = 0.0f; kintegrator->pdf_lights = 0.0f; - if(multi_light) { - /* sample one of all triangles and all lights */ - kintegrator->num_all_lights = num_lights; + /* sample one, with 0.5 probability of light or triangle */ + kintegrator->num_all_lights = num_lights; - if(trianglearea > 0.0f) - kintegrator->pdf_triangles = 1.0f/trianglearea; + if(trianglearea > 0.0f) { + kintegrator->pdf_triangles = 1.0f/trianglearea; if(num_lights) - kintegrator->pdf_lights = 1.0f; + kintegrator->pdf_triangles *= 0.5f; } - else { - /* sample one, with 0.5 probability of light or triangle */ - kintegrator->num_all_lights = 0; - if(trianglearea > 0.0f) { - kintegrator->pdf_triangles = 1.0f/trianglearea; - if(num_lights) - kintegrator->pdf_triangles *= 0.5f; - } - - if(num_lights) { - kintegrator->pdf_lights = 1.0f/num_lights; - if(trianglearea > 0.0f) - kintegrator->pdf_lights *= 0.5f; - } + if(num_lights) { + kintegrator->pdf_lights = 1.0f/num_lights; + if(trianglearea > 0.0f) + kintegrator->pdf_lights *= 0.5f; } /* CDF */ @@ -417,6 +401,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce float3 co = light->co; float3 dir = normalize(light->dir); int shader_id = scene->shader_manager->get_shader_id(scene->lights[i]->shader); + float samples = __int_as_float(light->samples); if(!light->cast_shadow) shader_id &= ~SHADER_CAST_SHADOW; @@ -427,7 +412,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z); light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); } else if(light->type == LIGHT_DISTANT) { shader_id &= ~SHADER_AREA_LIGHT; @@ -435,7 +420,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), dir.x, dir.y, dir.z); light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); } else if(light->type == LIGHT_BACKGROUND) { shader_id &= ~SHADER_AREA_LIGHT; @@ -443,7 +428,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), 0.0f, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); } else if(light->type == LIGHT_AREA) { float3 axisu = light->axisu*(light->sizeu*light->size); @@ -452,7 +437,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z); light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z); light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z); - light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, dir.x, dir.y, dir.z); + light_data[i*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z); } else if(light->type == LIGHT_SPOT) { shader_id &= ~SHADER_AREA_LIGHT; @@ -463,7 +448,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z); light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y); light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f); - light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); } } diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h index fb8684fa59b..3cedde2596e 100644 --- a/intern/cycles/render/light.h +++ b/intern/cycles/render/light.h @@ -54,6 +54,7 @@ public: bool cast_shadow; int shader; + int samples; void tag_update(Scene *scene); }; diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index a5f90bfe34b..45c8a05c27d 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -160,7 +160,7 @@ void Scene::device_update(Device *device_, Progress& progress) if(progress.get_cancel()) return; progress.set_status("Updating Integrator"); - integrator->device_update(device, &dscene); + integrator->device_update(device, &dscene, this); if(progress.get_cancel()) return; From be1b5f82cee09041fdee355697841ee92b31ef70 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Wed, 13 Jun 2012 12:34:56 +0000 Subject: [PATCH 267/360] * optimized threading * break out with glare node * Added OpenCL kernels compatible with AMD still need some testing. --- source/blender/compositor/CMakeLists.txt | 3 + .../compositor/intern/COM_ExecutionGroup.cpp | 31 ++++++-- .../compositor/intern/COM_ExecutionGroup.h | 22 ++---- .../compositor/intern/COM_ExecutionSystem.cpp | 4 +- .../intern/COM_ExecutionSystemHelper.cpp | 2 +- .../compositor/intern/COM_NodeOperation.cpp | 21 +++++- .../compositor/intern/COM_NodeOperation.h | 22 ++++-- .../COM_SingleThreadedNodeOperation.cpp | 60 ++++++++++++++++ .../intern/COM_SingleThreadedNodeOperation.h | 60 ++++++++++++++++ .../compositor/intern/COM_compositor.cpp | 1 - .../compositor/nodes/COM_DilateErodeNode.cpp | 2 +- .../blender/compositor/nodes/COM_MuteNode.cpp | 3 +- .../operations/COM_AntiAliasOperation.cpp | 6 +- .../operations/COM_CalculateMeanOperation.cpp | 4 +- ...OM_CalculateStandardDeviationOperation.cpp | 4 +- .../operations/COM_CompositorOperation.cpp | 4 +- .../operations/COM_CompositorOperation.h | 6 -- .../operations/COM_DilateErodeOperation.cpp | 64 ++++++++++++++--- .../operations/COM_DilateErodeOperation.h | 16 ++++- .../COM_DoubleEdgeMaskOperation.cpp | 9 +-- .../COM_FastGaussianBlurOperation.cpp | 4 +- .../operations/COM_GlareBaseOperation.cpp | 47 +++++-------- .../operations/COM_GlareBaseOperation.h | 18 ++--- .../operations/COM_GlareGhostOperation.cpp | 25 ++++--- .../COM_GlareSimpleStarOperation.cpp | 14 ++-- .../operations/COM_GlareStreaksOperation.cpp | 11 +-- .../operations/COM_MaskOperation.cpp | 5 +- .../COM_MovieDistortionOperation.cpp | 2 +- .../COM_MultilayerImageOperation.cpp | 6 +- .../operations/COM_NormalizeOperation.cpp | 5 +- .../operations/COM_OpenCLKernels.cl | 66 ++++++++++++++++- .../operations/COM_OpenCLKernels.cl.h | 70 +++++++++++++++++-- .../operations/COM_OutputFileOperation.cpp | 8 +-- .../operations/COM_PreviewOperation.h | 2 - .../operations/COM_TonemapOperation.cpp | 4 +- .../operations/COM_VectorBlurOperation.cpp | 4 +- .../operations/COM_ViewerBaseOperation.h | 2 - .../operations/COM_ViewerOperation.cpp | 2 +- .../operations/COM_WriteBufferOperation.cpp | 5 +- .../operations/COM_WriteBufferOperation.h | 2 - 40 files changed, 483 insertions(+), 163 deletions(-) create mode 100644 source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp create mode 100644 source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 22f72270734..bc2aeaefc83 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -97,6 +97,9 @@ set(SRC intern/COM_CompositorContext.h intern/COM_ChannelInfo.cpp intern/COM_ChannelInfo.h + intern/COM_SingleThreadedNodeOperation.cpp + intern/COM_SingleThreadedNodeOperation.h + operations/COM_QualityStepHelper.h operations/COM_QualityStepHelper.cpp diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index e46b4934217..7a53af7f58c 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -54,6 +54,7 @@ ExecutionGroup::ExecutionGroup() this->numberOfChunks = 0; this->initialized = false; this->openCL = false; + this->singleThreaded = false; this->chunksFinished = 0; } @@ -100,6 +101,7 @@ void ExecutionGroup::addOperation(ExecutionSystem *system, NodeOperation *operat if (!operation->isBufferOperation()) { this->complex = operation->isComplex(); this->openCL = operation->isOpenCL(); + this->singleThreaded = operation->isSingleThreaded(); this->initialized = true; } this->operations.push_back(operation); @@ -191,10 +193,17 @@ void ExecutionGroup::determineResolution(unsigned int resolution[]) void ExecutionGroup::determineNumberOfChunks() { - const float chunkSizef = this->chunkSize; - this->numberOfXChunks = ceil(this->width / chunkSizef); - this->numberOfYChunks = ceil(this->height / chunkSizef); - this->numberOfChunks = this->numberOfXChunks * this->numberOfYChunks; + if (singleThreaded) { + this->numberOfXChunks = 1; + this->numberOfYChunks = 1; + this->numberOfChunks = 1; + } + else { + const float chunkSizef = this->chunkSize; + this->numberOfXChunks = ceil(this->width / chunkSizef); + this->numberOfYChunks = ceil(this->height / chunkSizef); + this->numberOfChunks = this->numberOfXChunks * this->numberOfYChunks; + } } /** @@ -435,9 +444,14 @@ void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer** memo inline void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk ) const { - const unsigned int minx = xChunk * chunkSize; - const unsigned int miny = yChunk * chunkSize; - BLI_init_rcti(rect, minx, min(minx + this->chunkSize, this->width), miny, min(miny + this->chunkSize, this->height)); + if (singleThreaded) { + BLI_init_rcti(rect, 0, this->width, 0, this->height); + } + else { + const unsigned int minx = xChunk * chunkSize; + const unsigned int miny = yChunk * chunkSize; + BLI_init_rcti(rect, minx, min(minx + this->chunkSize, this->width), miny, min(miny + this->chunkSize, this->height)); + } } void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int chunkNumber) const @@ -462,6 +476,9 @@ MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int chunkNumber, rcti *rect) bool ExecutionGroup::scheduleAreaWhenPossible(ExecutionSystem * graph, rcti *area) { + if (singleThreaded) { + return scheduleChunkWhenPossible(graph, 0, 0); + } // find all chunks inside the rect // determine minxchunk, minychunk, maxxchunk, maxychunk where x and y are chunknumbers diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index 416a78eb8b8..1698890cc34 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -63,10 +63,6 @@ class Device; class ExecutionGroup { private: // fields - /** - * @brief unique identifier of this node. - */ - string id; /** * @brief list of operations in this ExecutionGroup @@ -120,6 +116,11 @@ private: */ bool openCL; + /** + * @brief Is this Execution group SingleThreaded + */ + bool singleThreaded; + /** * @brief what is the maximum number field of all ReadBufferOperation in this ExecutionGroup. * @note this is used to construct the MemoryBuffers that will be passed during execution. @@ -233,18 +234,7 @@ private: public: // constructors ExecutionGroup(); - - /** - * @brief set the id of this ExecutionGroup - * @param id - */ - void setId(string id) {this->id = id;} - - /** - * @brief return the id of this ExecutionGroup - */ - const string getId() const {return this->id;} - + // methods /** * @brief check to see if a NodeOperation is already inside this execution group diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 1056c6d3f65..9681996c74d 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -124,6 +124,7 @@ void ExecutionSystem::execute() for (index = 0 ; index < this->operations.size() ; index ++) { NodeOperation * operation = this->operations[index]; + operation->setbNodeTree(this->context.getbNodeTree()); operation->initExecution(); } for (index = 0 ; index < this->groups.size() ; index ++) { @@ -153,7 +154,7 @@ void ExecutionSystem::execute() void ExecutionSystem::executeGroups(CompositorPriority priority) { - int index; + unsigned int index; vector executionGroups; this->findOutputExecutionGroup(&executionGroups, priority); @@ -166,6 +167,7 @@ void ExecutionSystem::executeGroups(CompositorPriority priority) void ExecutionSystem::addOperation(NodeOperation *operation) { ExecutionSystemHelper::addOperation(this->operations, operation); +// operation->setBTree } void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp index 75be8df74de..d5ca2ec619a 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp @@ -65,7 +65,7 @@ Node *ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_sta } /* Expand group nodes */ - for (int i=nodes_start; i < nodes.size(); ++i) { + for (unsigned int i=nodes_start; i < nodes.size(); ++i) { Node *execnode = nodes[i]; if (execnode->isGroupNode()) { GroupNode * groupNode = (GroupNode*)execnode; diff --git a/source/blender/compositor/intern/COM_NodeOperation.cpp b/source/blender/compositor/intern/COM_NodeOperation.cpp index 650e4af5ae0..148ad48ba3a 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.cpp +++ b/source/blender/compositor/intern/COM_NodeOperation.cpp @@ -34,6 +34,7 @@ NodeOperation::NodeOperation() this->width = 0; this->height = 0; this->openCL = false; + this->btree = NULL; } void NodeOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) @@ -74,10 +75,22 @@ void NodeOperation::initMutex() { BLI_mutex_init(&mutex); } + +void NodeOperation::lockMutex() +{ + BLI_mutex_lock(&mutex); +} + +void NodeOperation::unlockMutex() +{ + BLI_mutex_unlock(&mutex); +} + void NodeOperation::deinitMutex() { BLI_mutex_end(&mutex); } + void NodeOperation::deinitExecution() { } @@ -196,14 +209,15 @@ void NodeOperation::COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, size_t size[2]; cl_int2 offset; - for (offsety = 0 ; offsety < height; offsety+=localSize) { + bool breaked = false; + for (offsety = 0 ; offsety < height && (!breaked); offsety+=localSize) { offset[1] = offsety; if (offsety+localSize < height) { size[1] = localSize; } else { size[1] = height - offsety; } - for (offsetx = 0 ; offsetx < width ; offsetx+=localSize) { + for (offsetx = 0 ; offsetx < width && (!breaked) ; offsetx+=localSize) { if (offsetx+localSize < width) { size[0] = localSize; } else { @@ -216,6 +230,9 @@ void NodeOperation::COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, error = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, size, 0, 0, 0, NULL); if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } clFlush(queue); + if (isBreaked()) { + breaked = false; + } } } } diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index 3f536fb3f2d..e56ac7bd51f 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -77,6 +77,11 @@ private: * @see NodeOperation.getMutex retrieve a pointer to this mutex. */ ThreadMutex mutex; + + /** + * @brief reference to the editing bNodeTree only used for break callback + */ + const bNodeTree *btree; public: /** @@ -119,9 +124,10 @@ public: * for all other operations this will result in false. */ virtual int isBufferOperation() {return false;} + virtual int isSingleThreaded() {return false;} + void setbNodeTree(const bNodeTree * tree) {this->btree = tree;} virtual void initExecution(); - void initMutex(); /** * @brief when a chunk is executed by a CPUDevice, this method is called @@ -161,7 +167,6 @@ public: */ virtual void executeOpenCL(cl_context context,cl_program program, cl_command_queue queue, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer** inputMemoryBuffers, list *clMemToCleanUp, list *clKernelsToCleanUp) {} virtual void deinitExecution(); - void deinitMutex(); bool isResolutionSet() { return this->width != 0 && height != 0; @@ -236,6 +241,11 @@ public: virtual bool isViewerOperation() {return false;} virtual bool isPreviewOperation() {return false;} + + inline bool isBreaked() { + return btree->test_break(btree->tbh); + } + protected: NodeOperation(); @@ -244,7 +254,11 @@ protected: SocketReader *getInputSocketReader(unsigned int inputSocketindex); NodeOperation *getInputOperation(unsigned int inputSocketindex); - inline ThreadMutex *getMutex() {return &this->mutex;} + void deinitMutex(); + void initMutex(); + void lockMutex(); + void unlockMutex(); + /** * @brief set whether this operation is complex @@ -264,7 +278,7 @@ protected: static void COM_clAttachOutputMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, cl_mem clOutputMemoryBuffer); void COM_clAttachSizeToKernelParameter(cl_kernel kernel, int offsetIndex); static void COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer* outputMemoryBuffer); - static void COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer *outputMemoryBuffer, int offsetIndex); + void COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer *outputMemoryBuffer, int offsetIndex); cl_kernel COM_clCreateKernel(cl_program program, const char* kernelname, list *clKernelsToCleanUp); }; diff --git a/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp b/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp new file mode 100644 index 00000000000..9ea90809de4 --- /dev/null +++ b/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2011, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_SingleThreadedNodeOperation.h" + +SingleThreadedNodeOperation::SingleThreadedNodeOperation(): NodeOperation() +{ + this->cachedInstance = NULL; + setComplex(true); +} + +void SingleThreadedNodeOperation::initExecution() +{ + initMutex(); +} + +void SingleThreadedNodeOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + this->cachedInstance->read(color, x, y); +} + +void SingleThreadedNodeOperation::deinitExecution() +{ + deinitMutex(); + if (this->cachedInstance) { + delete cachedInstance; + this->cachedInstance = NULL; + } +} +void *SingleThreadedNodeOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + if (this->cachedInstance) return this->cachedInstance; + + lockMutex(); + if (this->cachedInstance == NULL) { + // + this->cachedInstance = createMemoryBuffer(rect, memoryBuffers); + } + unlockMutex(); + return this->cachedInstance; +} diff --git a/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h b/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h new file mode 100644 index 00000000000..ace48365752 --- /dev/null +++ b/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h @@ -0,0 +1,60 @@ +/* + * Copyright 2011, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_SingleThreadedNodeOperation_h +#define _COM_SingleThreadedNodeOperation_h +#include "COM_NodeOperation.h" + +class SingleThreadedNodeOperation : public NodeOperation { +private: + MemoryBuffer *cachedInstance; + +protected: + inline bool isCached() { + return cachedInstance != NULL; + } + +public: + SingleThreadedNodeOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + virtual MemoryBuffer* createMemoryBuffer(rcti *rect, MemoryBuffer **memoryBuffers) = 0; + + int isSingleThreaded() {return true;} +}; +#endif diff --git a/source/blender/compositor/intern/COM_compositor.cpp b/source/blender/compositor/intern/COM_compositor.cpp index e27bff4401e..2bbfd18e7c5 100644 --- a/source/blender/compositor/intern/COM_compositor.cpp +++ b/source/blender/compositor/intern/COM_compositor.cpp @@ -51,7 +51,6 @@ void COM_execute(bNodeTree *editingtree, int rendering) /* set progress bar to 0% and status to init compositing*/ editingtree->progress(editingtree->prh, 0.0); - editingtree->stats_draw(editingtree->sdh, (char*)"Compositing"); /* initialize execution system */ ExecutionSystem *system = new ExecutionSystem(editingtree, rendering); diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp index 47791956865..0619bb5133e 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp @@ -36,7 +36,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont bNode *editorNode = this->getbNode(); if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE_THRESH) { - DilateErodeDistanceOperation *operation = new DilateErodeDistanceOperation(); + DilateErodeThresholdOperation *operation = new DilateErodeThresholdOperation(); operation->setDistance(editorNode->custom2); operation->setInset(editorNode->custom3); diff --git a/source/blender/compositor/nodes/COM_MuteNode.cpp b/source/blender/compositor/nodes/COM_MuteNode.cpp index d02eb2a0b98..93e352cfede 100644 --- a/source/blender/compositor/nodes/COM_MuteNode.cpp +++ b/source/blender/compositor/nodes/COM_MuteNode.cpp @@ -44,7 +44,7 @@ void MuteNode::reconnect(ExecutionSystem * graph, OutputSocket * output) } } - NodeOperation *operation; + NodeOperation *operation = NULL; switch (output->getDataType()) { case COM_DT_VALUE: { @@ -74,7 +74,6 @@ void MuteNode::reconnect(ExecutionSystem * graph, OutputSocket * output) } /* quiet warnings */ case COM_DT_UNKNOWN: - operation = NULL; break; } diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp index 62639eeb24a..4cd9552b108 100644 --- a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp @@ -44,7 +44,7 @@ void AntiAliasOperation::initExecution() void AntiAliasOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data) { - if (y < 0 || y >= this->height || x < 0 || x >= this->width) { + if (y < 0 || (unsigned int)y >= this->height || x < 0 || (unsigned int)x >= this->width) { color[0] = 0.0f; } else { @@ -85,7 +85,7 @@ bool AntiAliasOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe void *AntiAliasOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { if (this->buffer) {return buffer;} - BLI_mutex_lock(getMutex()); + lockMutex(); if (this->buffer == NULL) { MemoryBuffer *tile = (MemoryBuffer*)valueReader->initializeTileData(rect, memoryBuffers); int size = tile->getHeight()*tile->getWidth(); @@ -100,6 +100,6 @@ void *AntiAliasOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBu antialias_tagbuf(tile->getWidth(), tile->getHeight(), valuebuffer); this->buffer = valuebuffer; } - BLI_mutex_unlock(getMutex()); + unlockMutex(); return this->buffer; } diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp index a3438cea27b..077d8473f0b 100644 --- a/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp +++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp @@ -72,13 +72,13 @@ bool CalculateMeanOperation::determineDependingAreaOfInterest(rcti *input, ReadB void *CalculateMeanOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { - BLI_mutex_lock(getMutex()); + lockMutex(); if (!this->iscalculated) { MemoryBuffer *tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); calculateMean(tile); this->iscalculated = true; } - BLI_mutex_unlock(getMutex()); + unlockMutex(); return NULL; } diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp index 651c6674fdb..dfe1b6aa329 100644 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp @@ -37,7 +37,7 @@ void CalculateStandardDeviationOperation::executePixel(float *color, int x, int void *CalculateStandardDeviationOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { - BLI_mutex_lock(getMutex()); + lockMutex(); if (!this->iscalculated) { MemoryBuffer *tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); CalculateMeanOperation::calculateMean(tile); @@ -92,6 +92,6 @@ void *CalculateStandardDeviationOperation::initializeTileData(rcti *rect, Memory this->standardDeviation = sqrt(sum / (float)(pixels-1)); this->iscalculated = true; } - BLI_mutex_unlock(getMutex()); + unlockMutex(); return NULL; } diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index c6e8faaa638..4ce7ffac9ef 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -59,7 +59,7 @@ void CompositorOperation::initExecution() void CompositorOperation::deinitExecution() { - if (tree->test_break && !tree->test_break(tree->tbh)) { + if (isBreaked()) { const Scene * scene = this->scene; Render *re = RE_GetRender(scene->id.name); RenderResult *rr = RE_AcquireResultWrite(re); @@ -118,7 +118,7 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber, Mem buffer[offset+2] = color[2]; buffer[offset+3] = color[3]; offset +=COM_NUMBER_OF_CHANNELS; - if (tree->test_break && tree->test_break(tree->tbh)) { + if (isBreaked()) { breaked = true; } } diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h index 13cb4f28324..36099b3eb91 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.h +++ b/source/blender/compositor/operations/COM_CompositorOperation.h @@ -36,11 +36,6 @@ private: */ const Scene *scene; - /** - * @brief local reference to the node tree - */ - const bNodeTree *tree; - /** * @brief reference to the output float buffer */ @@ -59,7 +54,6 @@ public: CompositorOperation(); void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); void setScene(const Scene *scene) {this->scene = scene;} - void setbNodeTree(const bNodeTree *tree) {this->tree = tree;} bool isOutputOperation(bool rendering) const {return true;} void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp index 7bc49fa695c..bdd7362952a 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp @@ -24,7 +24,7 @@ #include "BLI_math.h" // DilateErode Distance Threshold -DilateErodeDistanceOperation::DilateErodeDistanceOperation(): NodeOperation() +DilateErodeThresholdOperation::DilateErodeThresholdOperation(): NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -34,7 +34,7 @@ DilateErodeDistanceOperation::DilateErodeDistanceOperation(): NodeOperation() this->_switch = 0.5f; this->distance = 0.0f; } -void DilateErodeDistanceOperation::initExecution() +void DilateErodeThresholdOperation::initExecution() { this->inputProgram = this->getInputSocketReader(0); if (this->distance < 0.0f) { @@ -53,13 +53,13 @@ void DilateErodeDistanceOperation::initExecution() } } -void *DilateErodeDistanceOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +void *DilateErodeThresholdOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { void *buffer = inputProgram->initializeTileData(NULL, memoryBuffers); return buffer; } -void DilateErodeDistanceOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +void DilateErodeThresholdOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { float inputValue[4]; const float sw = this->_switch; @@ -142,12 +142,12 @@ void DilateErodeDistanceOperation::executePixel(float *color, int x, int y, Memo } } -void DilateErodeDistanceOperation::deinitExecution() +void DilateErodeThresholdOperation::deinitExecution() { this->inputProgram = NULL; } -bool DilateErodeDistanceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool DilateErodeThresholdOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { rcti newInput; @@ -167,6 +167,7 @@ DilateDistanceOperation::DilateDistanceOperation(): NodeOperation() this->setComplex(true); this->inputProgram = NULL; this->distance = 0.0f; + this->setOpenCL(true); } void DilateDistanceOperation::initExecution() { @@ -231,6 +232,28 @@ bool DilateDistanceOperation::determineDependingAreaOfInterest(rcti *input, Read return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } + +static cl_kernel dilateKernel = 0; +void DilateDistanceOperation::executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, + list *clKernelsToCleanUp) +{ + if (!dilateKernel) { + dilateKernel = COM_clCreateKernel(program, "dilateKernel", NULL); + } + cl_int distanceSquared = this->distance*this->distance; + cl_int scope = this->scope; + + COM_clAttachMemoryBufferToKernelParameter(context, dilateKernel, 0, 2, clMemToCleanUp, inputMemoryBuffers, this->inputProgram); + COM_clAttachOutputMemoryBufferToKernelParameter(dilateKernel, 1, clOutputBuffer); + COM_clAttachMemoryBufferOffsetToKernelParameter(dilateKernel, 3, outputMemoryBuffer); + clSetKernelArg(dilateKernel, 4, sizeof(cl_int), &scope); + clSetKernelArg(dilateKernel, 5, sizeof(cl_int), &distanceSquared); + COM_clAttachSizeToKernelParameter(dilateKernel, 6); + COM_clEnqueueRange(queue, dilateKernel, outputMemoryBuffer, 7); +} + // Erode Distance ErodeDistanceOperation::ErodeDistanceOperation() : DilateDistanceOperation() { @@ -268,6 +291,27 @@ void ErodeDistanceOperation::executePixel(float *color, int x, int y, MemoryBuff color[0] = value; } +static cl_kernel erodeKernel = 0; +void ErodeDistanceOperation::executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, + list *clKernelsToCleanUp) +{ + if (!erodeKernel) { + erodeKernel = COM_clCreateKernel(program, "erodeKernel", NULL); + } + cl_int distanceSquared = this->distance*this->distance; + cl_int scope = this->scope; + + COM_clAttachMemoryBufferToKernelParameter(context, erodeKernel, 0, 2, clMemToCleanUp, inputMemoryBuffers, this->inputProgram); + COM_clAttachOutputMemoryBufferToKernelParameter(erodeKernel, 1, clOutputBuffer); + COM_clAttachMemoryBufferOffsetToKernelParameter(erodeKernel, 3, outputMemoryBuffer); + clSetKernelArg(erodeKernel, 4, sizeof(cl_int), &scope); + clSetKernelArg(erodeKernel, 5, sizeof(cl_int), &distanceSquared); + COM_clAttachSizeToKernelParameter(erodeKernel, 6); + COM_clEnqueueRange(queue, erodeKernel, outputMemoryBuffer, 7); +} + // Dilate step DilateStepOperation::DilateStepOperation(): NodeOperation() { @@ -288,7 +332,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryB if (this->cached_buffer != NULL) { return this->cached_buffer; } - BLI_mutex_lock(getMutex()); + lockMutex(); if (this->cached_buffer == NULL) { MemoryBuffer *buffer = (MemoryBuffer*)inputProgram->initializeTileData(NULL, memoryBuffers); float *rectf = buffer->convertToValueBuffer(); @@ -327,7 +371,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryB } this->cached_buffer = rectf; } - BLI_mutex_unlock(getMutex()); + unlockMutex(); return this->cached_buffer; } @@ -374,7 +418,7 @@ void *ErodeStepOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBu if (this->cached_buffer != NULL) { return this->cached_buffer; } - BLI_mutex_lock(getMutex()); + lockMutex(); if (this->cached_buffer == NULL) { MemoryBuffer *buffer = (MemoryBuffer*)inputProgram->initializeTileData(NULL, memoryBuffers); float *rectf = buffer->convertToValueBuffer(); @@ -413,6 +457,6 @@ void *ErodeStepOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBu } this->cached_buffer = rectf; } - BLI_mutex_unlock(getMutex()); + unlockMutex(); return this->cached_buffer; } diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h index 71bbab74a4b..63cee4c333a 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.h +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.h @@ -25,7 +25,7 @@ #include "COM_NodeOperation.h" -class DilateErodeDistanceOperation : public NodeOperation { +class DilateErodeThresholdOperation : public NodeOperation { private: /** * Cached reference to the inputProgram @@ -42,7 +42,7 @@ private: */ int scope; public: - DilateErodeDistanceOperation(); + DilateErodeThresholdOperation(); /** * the inner loop of this program @@ -70,11 +70,11 @@ public: class DilateDistanceOperation : public NodeOperation { private: +protected: /** * Cached reference to the inputProgram */ SocketReader * inputProgram; -protected: float distance; int scope; public: @@ -98,6 +98,11 @@ public: void setDistance(float distance) {this->distance = distance;} bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, + list *clKernelsToCleanUp); }; class ErodeDistanceOperation : public DilateDistanceOperation { public: @@ -107,6 +112,11 @@ public: * the inner loop of this program */ void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + + void executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, + list *clKernelsToCleanUp); }; class DilateStepOperation : public NodeOperation { diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp index 40f492b0f10..df04b889200 100644 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp @@ -23,6 +23,7 @@ #include "COM_DoubleEdgeMaskOperation.h" #include "BLI_math.h" #include "DNA_node_types.h" +#include "MEM_guardedalloc.h" // this part has been copied from the double edge mask // Contributor(s): Peter Larabell. @@ -1215,12 +1216,12 @@ void DoubleEdgeMaskOperation::doDoubleEdgeMask(float *imask, float *omask, float gsz=rsize[2]; // by the do_*EdgeDetection() function. fsz=gsz+isz+osz; // calculate size of pixel index buffer needed - gbuf = new unsigned short[fsz*2]; // allocate edge/gradient pixel index buffer + gbuf = (unsigned short*)MEM_callocN(sizeof (unsigned short)*fsz*2, "DEM"); // allocate edge/gradient pixel index buffer do_createEdgeLocationBuffer(t,rw,lres,res,gbuf,&innerEdgeOffset,&outerEdgeOffset,isz,gsz); do_fillGradientBuffer(rw,res,gbuf,isz,osz,gsz,innerEdgeOffset,outerEdgeOffset); - delete [] gbuf; // free the gradient index buffer + MEM_freeN(gbuf); // free the gradient index buffer } } @@ -1263,7 +1264,7 @@ void *DoubleEdgeMaskOperation::initializeTileData(rcti *rect, MemoryBuffer **mem { if (this->cachedInstance) return this->cachedInstance; - BLI_mutex_lock(getMutex()); + lockMutex(); if (this->cachedInstance == NULL) { MemoryBuffer *innerMask = (MemoryBuffer*)inputInnerMask->initializeTileData(rect, memoryBuffers); MemoryBuffer *outerMask = (MemoryBuffer*)inputOuterMask->initializeTileData(rect, memoryBuffers); @@ -1275,7 +1276,7 @@ void *DoubleEdgeMaskOperation::initializeTileData(rcti *rect, MemoryBuffer **mem delete omask; this->cachedInstance = data; } - BLI_mutex_unlock(getMutex()); + unlockMutex(); return this->cachedInstance; } void DoubleEdgeMaskOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index ad58631f2c1..92e1aace9e2 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -79,7 +79,7 @@ void FastGaussianBlurOperation::deinitExecution() void *FastGaussianBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { - BLI_mutex_lock(this->getMutex()); + lockMutex(); if (!iirgaus) { MemoryBuffer *newBuf = (MemoryBuffer*)this->inputProgram->initializeTileData(rect, memoryBuffers); MemoryBuffer *copy = newBuf->duplicate(); @@ -105,7 +105,7 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **m } this->iirgaus = copy; } - BLI_mutex_unlock(this->getMutex()); + unlockMutex(); return iirgaus; } diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp index fdfd19a10ae..83132963f0b 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp @@ -23,56 +23,41 @@ #include "COM_GlareBaseOperation.h" #include "BLI_math.h" -GlareBaseOperation::GlareBaseOperation(): NodeOperation() +GlareBaseOperation::GlareBaseOperation(): SingleThreadedNodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); this->settings = NULL; - this->cachedInstance = NULL; - setComplex(true); } void GlareBaseOperation::initExecution() { - initMutex(); + SingleThreadedNodeOperation::initExecution(); this->inputProgram = getInputSocketReader(0); - this->cachedInstance = NULL; -} - -void GlareBaseOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data)\ -{ - float *buffer = (float*) data; - int index = (y*this->getWidth() + x) * COM_NUMBER_OF_CHANNELS; - color[0] = buffer[index]; - color[1] = buffer[index+1]; - color[2] = buffer[index+2]; - color[3] = buffer[index+3]; } void GlareBaseOperation::deinitExecution() { - deinitMutex(); this->inputProgram = NULL; - if (this->cachedInstance) { - delete cachedInstance; - this->cachedInstance = NULL; - } + SingleThreadedNodeOperation::deinitExecution(); } -void *GlareBaseOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) + +MemoryBuffer *GlareBaseOperation::createMemoryBuffer(rcti *rect2, MemoryBuffer **memoryBuffers) { - BLI_mutex_lock(getMutex()); - if (this->cachedInstance == NULL) { - MemoryBuffer *tile = (MemoryBuffer*)inputProgram->initializeTileData(rect, memoryBuffers); - float *data = new float[this->getWidth()*this->getHeight()*COM_NUMBER_OF_CHANNELS]; - this->generateGlare(data, tile, this->settings); - this->cachedInstance = data; - } - BLI_mutex_unlock(getMutex()); - return this->cachedInstance; + MemoryBuffer *tile = (MemoryBuffer*)inputProgram->initializeTileData(rect2, memoryBuffers); + rcti rect; + rect.xmin = 0; + rect.ymin = 0; + rect.xmax = getWidth(); + rect.ymax = getHeight(); + MemoryBuffer *result = new MemoryBuffer(NULL, &rect); + float *data = result->getBuffer(); + this->generateGlare(data, tile, this->settings); + return result; } bool GlareBaseOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { - if (this->cachedInstance != NULL) { + if (isCached()) { return false; } else { diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h index 2fa8afc9c4c..d79f449f426 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.h +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.h @@ -22,7 +22,8 @@ #ifndef _COM_GlareBaseOperation_h #define _COM_GlareBaseOperation_h -#include "COM_NodeOperation.h" + +#include "COM_SingleThreadedNodeOperation.h" #include "DNA_node_types.h" @@ -55,7 +56,7 @@ typedef float fRGB[4]; } (void)0 -class GlareBaseOperation : public NodeOperation { +class GlareBaseOperation : public SingleThreadedNodeOperation { private: /** * @brief Cached reference to the inputProgram @@ -66,16 +67,7 @@ private: * @brief settings of the glare node. */ NodeGlare * settings; - - float *cachedInstance; - public: - - /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); - /** * Initialize the execution */ @@ -86,15 +78,15 @@ public: */ void deinitExecution(); - void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); - void setGlareSettings(NodeGlare * settings) {this->settings = settings;} bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + protected: GlareBaseOperation(); virtual void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) = 0; + MemoryBuffer *createMemoryBuffer(rcti *rect, MemoryBuffer **memoryBuffers); }; #endif diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp index c5b1d6caa89..383a13c54de 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp @@ -45,15 +45,21 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No MemoryBuffer *gbuf = inputTile->duplicate(); MemoryBuffer *tbuf1 = inputTile->duplicate(); + bool breaked = false; + FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 0, 3); - FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 1, 3); - FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 2, 3); + if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 1, 3); + if (isBreaked()) breaked = true; + if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 2, 3); MemoryBuffer *tbuf2 = tbuf1->duplicate(); - FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 0, 3); - FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 1, 3); - FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 2, 3); + if (isBreaked()) breaked = true; + if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 0, 3); + if (isBreaked()) breaked = true; + if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 1, 3); + if (isBreaked()) breaked = true; + if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 2, 3); if (settings->iter & 1) ofs = 0.5f; else ofs = 0.f; for (x=0; x<(settings->iter*4); x++) { @@ -68,7 +74,7 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No sc = 2.13; isc = -0.97; - for (y=0; ygetHeight(); y++) { + for (y=0; ygetHeight() &(!breaked); y++) { v = (float)(y+0.5f) / (float)gbuf->getHeight(); for (x=0; xgetWidth(); x++) { u = (float)(x+0.5f) / (float)gbuf->getWidth(); @@ -83,11 +89,13 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No gbuf->writePixel(x, y, c); } + if (isBreaked()) breaked = true; + } memset(tbuf1->getBuffer(), 0, tbuf1->getWidth()*tbuf1->getHeight()*COM_NUMBER_OF_CHANNELS*sizeof(float)); - for (n=1; niter; n++) { - for (y=0; ygetHeight(); y++) { + for (n=1; niter &(!breaked); n++) { + for (y=0; ygetHeight()&(!breaked); y++) { v = (float)(y+0.5f) / (float)gbuf->getHeight(); for (x=0; xgetWidth(); x++) { u = (float)(x+0.5f) / (float)gbuf->getWidth(); @@ -103,6 +111,7 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No } tbuf1->writePixel(x, y, tc); } + if (isBreaked()) breaked = true; } memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth()*tbuf1->getHeight()*COM_NUMBER_OF_CHANNELS*sizeof(float)); } diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp index fba3eca4af9..4a393a33073 100644 --- a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp @@ -32,10 +32,11 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTil MemoryBuffer *tbuf1 = inputTile->duplicate(); MemoryBuffer *tbuf2 = inputTile->duplicate(); - for (i=0; iiter; i++) { + bool breaked = false; + for (i=0; iiter && (!breaked); i++) { // // (x || x-1, y-1) to (x || x+1, y+1) // // F - for (y=0; ygetHeight(); y++) { + for (y=0; ygetHeight() && (!breaked); y++) { ym = y - i; yp = y + i; for (x=0; xgetWidth(); x++) { @@ -58,11 +59,13 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTil madd_v3_v3fl(c, tc, f2); c[3] = 1.0f; tbuf2->writePixel(x, y, c); - + } + if (isBreaked()) { + breaked = true; } } // // B - for (y=tbuf1->getHeight()-1; y>=0; y--) { + for (y=tbuf1->getHeight()-1 && (!breaked); y>=0; y--) { ym = y - i; yp = y + i; for (x=tbuf1->getWidth()-1; x>=0; x--) { @@ -86,6 +89,9 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTil c[3] = 1.0f; tbuf2->writePixel(x, y, c); } + if (isBreaked()) { + breaked = true; + } } } diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp index 42b6a2b5e50..e735893ed6d 100644 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp @@ -33,22 +33,23 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile, int size = inputTile->getWidth()*inputTile->getHeight(); int size4 = size*4; + bool breaked = false; MemoryBuffer *tsrc = inputTile->duplicate(); MemoryBuffer *tdst = new MemoryBuffer(NULL, inputTile->getRect()); tdst->clear(); memset(data, 0, size4*sizeof(float)); - for (a=0.f; aangle_ofs; const float vx = cos((double)an), vy = sin((double)an); - for (n=0; niter; ++n) { + for (n=0; niter && (!breaked); ++n) { const float p4 = pow(4.0, (double)n); const float vxp = vx*p4, vyp = vy*p4; const float wt = pow((double)settings->fade, (double)p4); const float cmo = 1.f - (float)pow((double)settings->colmod, (double)n+1); // colormodulation amount relative to current pass float *tdstcol = tdst->getBuffer(); - for (y=0; ygetHeight(); ++y) { + for (y=0; ygetHeight() && (!breaked); ++y) { for (x=0; xgetWidth(); ++x, tdstcol+=4) { // first pass no offset, always same for every pass, exact copy, // otherwise results in uneven brightness, only need once @@ -71,11 +72,13 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile, tdstcol[2] = 0.5f*(tdstcol[2] + c1[2] + wt*(c2[2] + wt*(c3[2] + wt*c4[2]))); tdstcol[3] = 1.0f; } + if (isBreaked()) { + breaked = true; + } } memcpy(tsrc->getBuffer(), tdst->getBuffer(), sizeof(float)*size4); } -// addImage(sbuf, tsrc, 1.f/(float)(6 - ndg->iter)); // add result to data @todo float *sourcebuffer = tsrc->getBuffer(); float factor = 1.f/(float)(6 - settings->iter); for (int i = 0 ; i < size4; i ++) { diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index 35174349a63..bfbf2b42e82 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -67,7 +67,7 @@ void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers if (!this->mask) return NULL; - BLI_mutex_lock(getMutex()); + lockMutex(); if (this->rasterizedMask == NULL) { int width = this->getWidth(); int height = this->getHeight(); @@ -78,8 +78,7 @@ void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers this->rasterizedMask = buffer; } - BLI_mutex_unlock(getMutex()); - + unlockMutex(); return this->rasterizedMask; } diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp index ebea9e8b4a2..d9e8977871f 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp @@ -52,7 +52,7 @@ void MovieDistortionOperation::initExecution() BKE_movieclip_user_set_frame(&clipUser, this->framenumber); BKE_movieclip_get_size(this->movieClip, &clipUser, &calibration_width, &calibration_height); - for (int i = 0 ; i < s_cache.size() ; i ++) { + for (unsigned int i = 0 ; i < s_cache.size() ; i ++) { DistortionCache *c = (DistortionCache*)s_cache[i]; if (c->isCacheFor(this->movieClip, this->width, this->height, calibration_width, calibration_height, this->distortion)) diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp index f95dd12a81a..5e81cd639dd 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp @@ -47,7 +47,7 @@ void MultilayerColorOperation::executePixel(float *color, float x, float y, Pixe { int yi = y; int xi = x; - if (this->imageBuffer == NULL || xi < 0 || yi < 0 || xi >= this->getWidth() || yi >= this->getHeight() ) { + if (this->imageBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) { color[0] = 0.0f; color[1] = 0.0f; color[2] = 0.0f; @@ -80,7 +80,7 @@ void MultilayerValueOperation::executePixel(float *color, float x, float y, Pixe { int yi = y; int xi = x; - if (this->imageBuffer == NULL || xi < 0 || yi < 0 || xi >= this->getWidth() || yi >= this->getHeight() ) { + if (this->imageBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) { color[0] = 0.0f; } else { @@ -93,7 +93,7 @@ void MultilayerVectorOperation::executePixel(float *color, float x, float y, Pix { int yi = y; int xi = x; - if (this->imageBuffer == NULL || xi < 0 || yi < 0 || xi >= this->getWidth() || yi >= this->getHeight() ) { + if (this->imageBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) { color[0] = 0.0f; } else { diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cpp b/source/blender/compositor/operations/COM_NormalizeOperation.cpp index d144739f845..4dd94943f4e 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.cpp +++ b/source/blender/compositor/operations/COM_NormalizeOperation.cpp @@ -76,8 +76,7 @@ bool NormalizeOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe void *NormalizeOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { - BLI_mutex_lock(getMutex()); - + lockMutex(); if (this->cachedInstance == NULL) { MemoryBuffer *tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); /* using generic two floats struct to store x: min y: mult */ @@ -105,7 +104,7 @@ void *NormalizeOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBu this->cachedInstance = minmult; } - BLI_mutex_unlock(getMutex()); + unlockMutex(); return this->cachedInstance; } diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl index aeccfcab8b5..e1f175b318a 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl @@ -6,8 +6,8 @@ const sampler_t SAMPLER_NEAREST = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS __constant const int2 zero = {0,0}; // KERNEL --- BOKEH BLUR --- -__kernel void bokehBlurKernel(__global __read_only image2d_t boundingBox, __global __read_only image2d_t inputImage, - __global __read_only image2d_t bokehImage, __global __write_only image2d_t output, +__kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only image2d_t inputImage, + __read_only image2d_t bokehImage, __write_only image2d_t output, int2 offsetInput, int2 offsetOutput, int radius, int step, int2 dimension, int2 offset) { int2 coords = {get_global_id(0), get_global_id(1)}; @@ -50,3 +50,65 @@ __kernel void bokehBlurKernel(__global __read_only image2d_t boundingBox, __glob write_imagef(output, coords, color); } + +// KERNEL --- DILATE --- +__kernel void dilateKernel(__read_only image2d_t inputImage, __write_only image2d_t output, + int2 offsetInput, int2 offsetOutput, int scope, int distanceSquared, int2 dimension, + int2 offset) +{ + int2 coords = {get_global_id(0), get_global_id(1)}; + coords += offset; + const int2 realCoordinate = coords + offsetOutput; + + const int2 minXY = max(realCoordinate - scope, zero); + const int2 maxXY = min(realCoordinate + scope, dimension); + + float value = 0.0f; + int nx, ny; + int2 inputXy; + + for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny ++, inputXy.y++) { + for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx ++, inputXy.x++) { + const float deltaX = (realCoordinate.x - nx); + const float deltaY = (realCoordinate.y - ny); + const float measuredDistance = deltaX*deltaX+deltaY*deltaY; + if (measuredDistance <= distanceSquared) { + value = max(value, read_imagef(inputImage, SAMPLER_NEAREST, inputXy).s0); + } + } + } + + float4 color = {value,0.0f,0.0f,0.0f}; + write_imagef(output, coords, color); +} + +// KERNEL --- DILATE --- +__kernel void erodeKernel(__read_only image2d_t inputImage, __write_only image2d_t output, + int2 offsetInput, int2 offsetOutput, int scope, int distanceSquared, int2 dimension, + int2 offset) +{ + int2 coords = {get_global_id(0), get_global_id(1)}; + coords += offset; + const int2 realCoordinate = coords + offsetOutput; + + const int2 minXY = max(realCoordinate - scope, zero); + const int2 maxXY = min(realCoordinate + scope, dimension); + + float value = 1.0f; + int nx, ny; + int2 inputXy; + + for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny ++, inputXy.y++) { + for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx ++, inputXy.x++) { + const float deltaX = (realCoordinate.x - nx); + const float deltaY = (realCoordinate.y - ny); + const float measuredDistance = deltaX*deltaX+deltaY*deltaY; + if (measuredDistance <= distanceSquared) { + value = min(value, read_imagef(inputImage, SAMPLER_NEAREST, inputXy).s0); + } + } + } + + float4 color = {value,0.0f,0.0f,0.0f}; + write_imagef(output, coords, color); +} diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl.h b/source/blender/compositor/operations/COM_OpenCLKernels.cl.h index 3cf33c75272..ef8668f6f21 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl.h +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl.h @@ -8,8 +8,8 @@ const char * clkernelstoh_COM_OpenCLKernels_cl = "/// This file contains all ope "__constant const int2 zero = {0,0};\n" \ "\n" \ "// KERNEL --- BOKEH BLUR ---\n" \ -"__kernel void bokehBlurKernel(__global __read_only image2d_t boundingBox, __global __read_only image2d_t inputImage,\n" \ -" __global __read_only image2d_t bokehImage, __global __write_only image2d_t output,\n" \ +"__kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only image2d_t inputImage,\n" \ +" __read_only image2d_t bokehImage, __write_only image2d_t output,\n" \ " int2 offsetInput, int2 offsetOutput, int radius, int step, int2 dimension, int2 offset)\n" \ "{\n" \ " int2 coords = {get_global_id(0), get_global_id(1)};\n" \ @@ -26,8 +26,8 @@ const char * clkernelstoh_COM_OpenCLKernels_cl = "/// This file contains all ope " if (tempBoundingBox > 0.0f) {\n" \ " const int2 bokehImageDim = get_image_dim(bokehImage);\n" \ " const int2 bokehImageCenter = bokehImageDim/2;\n" \ -" const int2 minXY = max(realCoordinate - radius, zero);;\n" \ -" const int2 maxXY = min(realCoordinate + radius, dimension);;\n" \ +" const int2 minXY = max(realCoordinate - radius, zero);\n" \ +" const int2 maxXY = min(realCoordinate + radius, dimension);\n" \ " int nx, ny;\n" \ "\n" \ " float2 uv;\n" \ @@ -52,4 +52,66 @@ const char * clkernelstoh_COM_OpenCLKernels_cl = "/// This file contains all ope "\n" \ " write_imagef(output, coords, color);\n" \ "}\n" \ +"\n" \ +"// KERNEL --- DILATE ---\n" \ +"__kernel void dilateKernel(__read_only image2d_t inputImage, __write_only image2d_t output,\n" \ +" int2 offsetInput, int2 offsetOutput, int scope, int distanceSquared, int2 dimension,\n" \ +" int2 offset)\n" \ +"{\n" \ +" int2 coords = {get_global_id(0), get_global_id(1)};\n" \ +" coords += offset;\n" \ +" const int2 realCoordinate = coords + offsetOutput;\n" \ +"\n" \ +" const int2 minXY = max(realCoordinate - scope, zero);\n" \ +" const int2 maxXY = min(realCoordinate + scope, dimension);\n" \ +"\n" \ +" float value = 0.0f;\n" \ +" int nx, ny;\n" \ +" int2 inputXy;\n" \ +"\n" \ +" for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny ++, inputXy.y++) {\n" \ +" for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx ++, inputXy.x++) {\n" \ +" const float deltaX = (realCoordinate.x - nx);\n" \ +" const float deltaY = (realCoordinate.y - ny);\n" \ +" const float measuredDistance = deltaX*deltaX+deltaY*deltaY;\n" \ +" if (measuredDistance <= distanceSquared) {\n" \ +" value = max(value, read_imagef(inputImage, SAMPLER_NEAREST, inputXy).s0);\n" \ +" }\n" \ +" }\n" \ +" }\n" \ +"\n" \ +" float4 color = {value,0.0f,0.0f,0.0f};\n" \ +" write_imagef(output, coords, color);\n" \ +"}\n" \ +"\n" \ +"// KERNEL --- DILATE ---\n" \ +"__kernel void erodeKernel(__read_only image2d_t inputImage, __write_only image2d_t output,\n" \ +" int2 offsetInput, int2 offsetOutput, int scope, int distanceSquared, int2 dimension,\n" \ +" int2 offset)\n" \ +"{\n" \ +" int2 coords = {get_global_id(0), get_global_id(1)};\n" \ +" coords += offset;\n" \ +" const int2 realCoordinate = coords + offsetOutput;\n" \ +"\n" \ +" const int2 minXY = max(realCoordinate - scope, zero);\n" \ +" const int2 maxXY = min(realCoordinate + scope, dimension);\n" \ +"\n" \ +" float value = 1.0f;\n" \ +" int nx, ny;\n" \ +" int2 inputXy;\n" \ +"\n" \ +" for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny ++, inputXy.y++) {\n" \ +" for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx ++, inputXy.x++) {\n" \ +" const float deltaX = (realCoordinate.x - nx);\n" \ +" const float deltaY = (realCoordinate.y - ny);\n" \ +" const float measuredDistance = deltaX*deltaX+deltaY*deltaY;\n" \ +" if (measuredDistance <= distanceSquared) {\n" \ +" value = min(value, read_imagef(inputImage, SAMPLER_NEAREST, inputXy).s0);\n" \ +" }\n" \ +" }\n" \ +" }\n" \ +"\n" \ +" float4 color = {value,0.0f,0.0f,0.0f};\n" \ +" write_imagef(output, coords, color);\n" \ +"}\n" \ "\0"; diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp index 8d39e987bd4..1438116f313 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -177,7 +177,7 @@ void OutputOpenExrMultiLayerOperation::add_layer(const char *name, DataType data void OutputOpenExrMultiLayerOperation::initExecution() { - for (int i=0; i < layers.size(); ++i) { + for (unsigned int i=0; i < layers.size(); ++i) { layers[i].imageInput = getInputSocketReader(i); layers[i].outputBuffer = init_buffer(this->getWidth(), this->getHeight(), layers[i].datatype); } @@ -185,7 +185,7 @@ void OutputOpenExrMultiLayerOperation::initExecution() void OutputOpenExrMultiLayerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) { - for (int i=0; i < layers.size(); ++i) { + for (unsigned int i=0; i < layers.size(); ++i) { write_buffer_rect(rect, memoryBuffers, this->tree, layers[i].imageInput, layers[i].outputBuffer, this->getWidth(), layers[i].datatype); } } @@ -203,7 +203,7 @@ void OutputOpenExrMultiLayerOperation::deinitExecution() (this->scene->r.scemode & R_EXTENSION), true); BLI_make_existing_file(filename); - for (int i=0; i < layers.size(); ++i) { + for (unsigned int i=0; i < layers.size(); ++i) { char channelname[EXR_TOT_MAXNAME]; BLI_strncpy(channelname, layers[i].name, sizeof(channelname)-2); char *channelname_ext = channelname + strlen(channelname); @@ -251,7 +251,7 @@ void OutputOpenExrMultiLayerOperation::deinitExecution() } IMB_exr_close(exrhandle); - for (int i=0; i < layers.size(); ++i) { + for (unsigned int i=0; i < layers.size(); ++i) { if (layers[i].outputBuffer) { MEM_freeN(layers[i].outputBuffer); layers[i].outputBuffer = NULL; diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h index 2b81b914746..32c0b6ecc77 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.h +++ b/source/blender/compositor/operations/COM_PreviewOperation.h @@ -34,7 +34,6 @@ protected: * @brief holds reference to the SDNA bNode, where this nodes will render the preview image for */ bNode *node; - const bNodeTree *tree; SocketReader *input; float divider; @@ -48,7 +47,6 @@ public: void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers); void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); void setbNode(bNode *node) { this->node = node;} - void setbNodeTree(const bNodeTree *tree) { this->tree = tree;} bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); bool isPreviewOperation() {return true;} diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cpp b/source/blender/compositor/operations/COM_TonemapOperation.cpp index 75adcf524c4..9a02d6a58ca 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.cpp +++ b/source/blender/compositor/operations/COM_TonemapOperation.cpp @@ -118,7 +118,7 @@ bool TonemapOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferO void *TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { - BLI_mutex_lock(getMutex()); + lockMutex(); if (this->cachedInstance == NULL) { MemoryBuffer *tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); AvgLogLum *data = new AvgLogLum(); @@ -150,7 +150,7 @@ void *TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuff data->igm = (this->data->gamma==0.f) ? 1 : (1.f / this->data->gamma); this->cachedInstance = data; } - BLI_mutex_unlock(getMutex()); + unlockMutex(); return this->cachedInstance; } diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp index e6305dc26a2..3dac3547b8a 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp @@ -77,7 +77,7 @@ void *VectorBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryB { if (this->cachedInstance) return this->cachedInstance; - BLI_mutex_lock(getMutex()); + lockMutex(); if (this->cachedInstance == NULL) { MemoryBuffer *tile = (MemoryBuffer*)inputImageProgram->initializeTileData(rect, memoryBuffers); MemoryBuffer *speed = (MemoryBuffer*)inputSpeedProgram->initializeTileData(rect, memoryBuffers); @@ -87,7 +87,7 @@ void *VectorBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryB this->generateVectorBlur(data, tile, speed, z); this->cachedInstance = data; } - BLI_mutex_unlock(getMutex()); + unlockMutex(); return this->cachedInstance; } diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.h b/source/blender/compositor/operations/COM_ViewerBaseOperation.h index 51fa8cecc0d..8864894f0ed 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.h +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.h @@ -34,7 +34,6 @@ protected: ImageUser * imageUser; void *lock; bool active; - const bNodeTree *tree; float centerX; float centerY; OrderOfChunks chunkOrder; @@ -49,7 +48,6 @@ public: void setImageUser(ImageUser *imageUser) {this->imageUser = imageUser;} const bool isActiveViewerOutput() const {return active;} void setActive(bool active) {this->active = active;} - void setbNodeTree(const bNodeTree *tree) {this->tree = tree;} void setCenterX(float centerX) {this->centerX = centerX;} void setCenterY(float centerY) {this->centerY = centerY;} void setChunkOrder(OrderOfChunks tileOrder) {this->chunkOrder = tileOrder;} diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp index 22e6511fbe7..3bec1ef48f5 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp @@ -104,7 +104,7 @@ void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryB offset +=4; } - if (tree->test_break && tree->test_break(tree->tbh)) { + if (isBreaked()) { breaked = true; } diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index 8888d30ba2f..087ab50cf47 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -30,7 +30,6 @@ WriteBufferOperation::WriteBufferOperation() :NodeOperation() this->memoryProxy = new MemoryProxy(); this->memoryProxy->setWriteBufferOperation(this); this->memoryProxy->setExecutor(NULL); - this->tree = NULL; } WriteBufferOperation::~WriteBufferOperation() { @@ -78,7 +77,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me offset4 +=COM_NUMBER_OF_CHANNELS; } - if (tree->test_break && tree->test_break(tree->tbh)) { + if (isBreaked()) { breaked = true; } @@ -103,7 +102,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me input->read(&(buffer[offset4]), x, y, COM_PS_NEAREST, memoryBuffers); offset4 +=COM_NUMBER_OF_CHANNELS; } - if (tree->test_break && tree->test_break(tree->tbh)) { + if (isBreaked()) { breaked = true; } } diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h index 068adc03293..fff3212b410 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.h +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h @@ -33,7 +33,6 @@ class WriteBufferOperation: public NodeOperation { MemoryProxy *memoryProxy; NodeOperation *input; - const bNodeTree * tree; public: WriteBufferOperation(); ~WriteBufferOperation(); @@ -45,7 +44,6 @@ public: void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); void initExecution(); void deinitExecution(); - void setbNodeTree(const bNodeTree *tree) {this->tree = tree;} void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers, MemoryBuffer* outputBuffer); void readResolutionFromInputSocket(); From 91781c76c4b1bb3eecd31a2b482a4c87754cd2a7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 12:58:01 +0000 Subject: [PATCH 268/360] framing options for camera background image: stretch/fit/crop --- release/scripts/startup/bl_ui/space_view3d.py | 9 ++++- .../editors/space_view3d/view3d_draw.c | 40 +++++++++++++++++++ source/blender/makesdna/DNA_view3d_types.h | 18 ++++++--- source/blender/makesrna/intern/rna_space.c | 27 +++++++++++++ 4 files changed, 88 insertions(+), 6 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 397bdc0d74e..eb2f14fa3a8 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2575,8 +2575,15 @@ class VIEW3D_PT_background_image(Panel): if has_bg: col = box.column() - col.prop(bg, "show_on_foreground") col.prop(bg, "opacity", slider=True) + + rowsub = col.row() + rowsub.prop(bg, "draw_depth", expand=True) + + if bg.view_axis in {'CAMERA', 'ALL'}: + rowsub = col.row() + rowsub.prop(bg, "frame_method", expand=True) + if bg.view_axis != 'CAMERA': col.prop(bg, "size") row = col.row(align=True) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 6d9507ebff1..6ef5d538b24 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1547,6 +1547,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, (bgpic->view & (1 << rv3d->view)) || /* check agaist flags */ (rv3d->persp == RV3D_CAMOB && bgpic->view == (1 << RV3D_VIEW_CAMERA))) { + float image_aspect[2]; + /* disable individual images */ if ((bgpic->flag & V3D_BGPIC_DISABLED)) continue; @@ -1558,6 +1560,9 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, continue; BKE_image_user_frame_calc(&bgpic->iuser, CFRA, 0); ibuf = BKE_image_get_ibuf(ima, &bgpic->iuser); + + image_aspect[0] = ima->aspx; + image_aspect[1] = ima->aspx; } else if (bgpic->source == V3D_BGPIC_MOVIE) { clip = NULL; @@ -1574,6 +1579,9 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, BKE_movieclip_user_set_frame(&bgpic->cuser, CFRA); ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser); + image_aspect[0] = clip->aspx; + image_aspect[1] = clip->aspx; + /* working with ibuf from image and clip has got different workflow now. * ibuf acquired from clip is referenced by cache system and should * be dereferenced after usage. */ @@ -1609,6 +1617,38 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, x2 = ar->winrct.xmax; y2 = ar->winrct.ymax; } + + /* aspect correction */ + if (bgpic->flag & V3D_BGPIC_CAMERA_ASPECT) + { + /* apply aspect from clip */ + const float w_src = ibuf->x * image_aspect[0]; + const float h_src = ibuf->y * image_aspect[1]; + + /* destination aspect is already applied from the camera frame */ + const float w_dst = x1 - x2; + const float h_dst = y1 - y2; + + const float asp_src = w_src / h_src; + const float asp_dst = w_dst / h_dst; + + if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) { + if ((asp_src > asp_dst) == ((bgpic->flag & V3D_BGPIC_CAMERA_CROP) != 0)) { + /* fit X */ + const float div = asp_src / asp_dst; + const float cent = (x1 + x2) / 2.0f; + x1 = ((x1 - cent) * div) + cent; + x2 = ((x2 - cent) * div) + cent; + } + else { + /* fit Y */ + const float div = asp_dst / asp_src; + const float cent = (y1 + y2) / 2.0f; + y1 = ((y1 - cent) * div) + cent; + y2 = ((y2 - cent) * div) + cent; + } + } + } } else { float sco[2]; diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index e89cc751a69..487c0d97e5e 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -311,11 +311,19 @@ typedef struct View3D { /* #define V3D_CALC_MANIPULATOR 4 */ /*UNUSED*/ /* BGPic->flag */ -/* may want to use 1 for select ?*/ -#define V3D_BGPIC_EXPANDED 2 -#define V3D_BGPIC_CAMERACLIP 4 -#define V3D_BGPIC_DISABLED 8 -#define V3D_BGPIC_FOREGROUND 16 +/* may want to use 1 for select ? */ +enum { + V3D_BGPIC_EXPANDED = (1 << 1), + V3D_BGPIC_CAMERACLIP = (1 << 2), + V3D_BGPIC_DISABLED = (1 << 3), + V3D_BGPIC_FOREGROUND = (1 << 4), + + /* Camera framing options */ + V3D_BGPIC_CAMERA_ASPECT = (1 << 5), /* don't stretch to fit the camera view */ + V3D_BGPIC_CAMERA_CROP = (1 << 6) /* crop out the image */ +}; + +#define V3D_BGPIC_EXPANDED (V3D_BGPIC_EXPANDED | V3D_BGPIC_CAMERACLIP) /* BGPic->source */ /* may want to use 1 for select ?*/ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 50a682f56bd..30b06017568 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1297,6 +1297,19 @@ static void rna_def_background_image(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static const EnumPropertyItem bgpic_camera_frame_items[] = { + {0, "STRETCH", 0, "Stretch", ""}, + {V3D_BGPIC_CAMERA_ASPECT, "FIT", 0, "Fit", ""}, + {V3D_BGPIC_CAMERA_ASPECT | V3D_BGPIC_CAMERA_CROP, "CROP", 0, "Crop", ""}, + {0, NULL, 0, NULL, NULL} + }; + + static const EnumPropertyItem bgpic_draw_depth_items[] = { + {0, "BACK", 0, "Back", ""}, + {V3D_BGPIC_FOREGROUND, "FRONT", 0, "Front", ""}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "BackgroundImage", NULL); RNA_def_struct_sdna(srna, "BGpic"); RNA_def_struct_ui_text(srna, "Background Image", "Image and settings for display in the 3d View background"); @@ -1381,6 +1394,20 @@ static void rna_def_background_image(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_BGPIC_FOREGROUND); RNA_def_property_ui_text(prop, "Show On Foreground", "Show this image in front of objects in viewport"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + /* expose 1 flag as a enum of 2 items */ + prop = RNA_def_property(srna, "draw_depth", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, bgpic_draw_depth_items); + RNA_def_property_ui_text(prop, "Depth", "Draw under or over everything"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + /* expose 2 flags as a enum of 3 items */ + prop = RNA_def_property(srna, "frame_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, bgpic_camera_frame_items); + RNA_def_property_ui_text(prop, "Frame Method", "How the image fits in the camera frame"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); } static void rna_def_backgroundImages(BlenderRNA *brna, PropertyRNA *cprop) From 2e72720718d80d3659a4f84143905b0e69724186 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 13:23:48 +0000 Subject: [PATCH 269/360] apply offset to the camera view - this works exactly like camera shift (transforms X/Y in the same space). --- release/scripts/startup/bl_ui/space_view3d.py | 7 ++++--- source/blender/editors/space_view3d/view3d_draw.c | 13 +++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index eb2f14fa3a8..d7fe7ebbbf7 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2586,9 +2586,10 @@ class VIEW3D_PT_background_image(Panel): if bg.view_axis != 'CAMERA': col.prop(bg, "size") - row = col.row(align=True) - row.prop(bg, "offset_x", text="X") - row.prop(bg, "offset_y", text="Y") + + row = col.row(align=True) + row.prop(bg, "offset_x", text="X") + row.prop(bg, "offset_y", text="Y") class VIEW3D_PT_transform_orientations(Panel): diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 6ef5d538b24..5073eca96ad 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1618,6 +1618,19 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, y2 = ar->winrct.ymax; } + /* apply offset last - camera offset is different to offset in blender units */ + /* so this has some sane way of working - this matches camera's shift _exactly_ */ + { + const float max_dim = maxf(x2 - x1, y2 - y1); + const float xof_scale = bgpic->xof * max_dim; + const float yof_scale = bgpic->yof * max_dim; + + x1 += xof_scale; + y1 += yof_scale; + x2 += xof_scale; + y2 += yof_scale; + } + /* aspect correction */ if (bgpic->flag & V3D_BGPIC_CAMERA_ASPECT) { From 29165fc373aace1cef7b070112ebfc4301ef8f95 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 13:59:46 +0000 Subject: [PATCH 270/360] style cleanup --- .../operations/COM_GlareGhostOperation.cpp | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp index 383a13c54de..defbd76fa51 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp @@ -27,8 +27,8 @@ static float smoothMask(float x, float y) { float t; - x = 2.f*x - 1.f, y = 2.f*y - 1.f; - if ((t = 1.f - sqrtf(x*x + y*y)) <= 0.f) return 0.f; + x = 2.f * x - 1.f, y = 2.f * y - 1.f; + if ((t = 1.f - sqrtf(x * x + y * y)) <= 0.f) return 0.f; return t; } @@ -36,7 +36,7 @@ static float smoothMask(float x, float y) void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) { const int qt = 1 << settings->quality; - const float s1 = 4.f/(float)qt, s2 = 2.f*s1; + const float s1 = 4.f / (float)qt, s2 = 2.f * s1; int x, y, n, p, np; fRGB c, tc, cm[64]; float sc, isc, u, v, sm, s, t, ofs, scalef[64]; @@ -46,77 +46,77 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No MemoryBuffer *tbuf1 = inputTile->duplicate(); bool breaked = false; - + FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 0, 3); if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 1, 3); if (isBreaked()) breaked = true; if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 2, 3); - + MemoryBuffer *tbuf2 = tbuf1->duplicate(); - + if (isBreaked()) breaked = true; if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 0, 3); if (isBreaked()) breaked = true; if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 1, 3); if (isBreaked()) breaked = true; if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 2, 3); - + if (settings->iter & 1) ofs = 0.5f; else ofs = 0.f; - for (x=0; x<(settings->iter*4); x++) { + for (x = 0; x < (settings->iter * 4); x++) { y = x & 3; cm[x][0] = cm[x][1] = cm[x][2] = 1; - if (y==1) fRGB_rgbmult(cm[x], 1.f, cmo, cmo); - if (y==2) fRGB_rgbmult(cm[x], cmo, cmo, 1.f); - if (y==3) fRGB_rgbmult(cm[x], cmo, 1.f, cmo); - scalef[x] = 2.1f*(1.f-(x+ofs)/(float)(settings->iter*4)); - if (x & 1) scalef[x] = -0.99f/scalef[x]; + if (y == 1) fRGB_rgbmult(cm[x], 1.f, cmo, cmo); + if (y == 2) fRGB_rgbmult(cm[x], cmo, cmo, 1.f); + if (y == 3) fRGB_rgbmult(cm[x], cmo, 1.f, cmo); + scalef[x] = 2.1f * (1.f - (x + ofs) / (float)(settings->iter * 4)); + if (x & 1) scalef[x] = -0.99f / scalef[x]; } sc = 2.13; isc = -0.97; - for (y=0; ygetHeight() &(!breaked); y++) { - v = (float)(y+0.5f) / (float)gbuf->getHeight(); - for (x=0; xgetWidth(); x++) { - u = (float)(x+0.5f) / (float)gbuf->getWidth(); - s = (u-0.5f)*sc + 0.5f, t = (v-0.5f)*sc + 0.5f; - tbuf1->read(c, s*gbuf->getWidth(), t*gbuf->getHeight()); + for (y = 0; y < gbuf->getHeight() & (!breaked); y++) { + v = (float)(y + 0.5f) / (float)gbuf->getHeight(); + for (x = 0; x < gbuf->getWidth(); x++) { + u = (float)(x + 0.5f) / (float)gbuf->getWidth(); + s = (u - 0.5f) * sc + 0.5f, t = (v - 0.5f) * sc + 0.5f; + tbuf1->read(c, s * gbuf->getWidth(), t * gbuf->getHeight()); sm = smoothMask(s, t); fRGB_mult(c, sm); - s = (u-0.5f)*isc + 0.5f, t = (v-0.5f)*isc + 0.5f; - tbuf2->read(tc, s*gbuf->getWidth()-0.5f, t*gbuf->getHeight()-0.5f); + s = (u - 0.5f) * isc + 0.5f, t = (v - 0.5f) * isc + 0.5f; + tbuf2->read(tc, s * gbuf->getWidth() - 0.5f, t * gbuf->getHeight() - 0.5f); sm = smoothMask(s, t); fRGB_madd(c, tc, sm); - + gbuf->writePixel(x, y, c); } if (isBreaked()) breaked = true; - + } - memset(tbuf1->getBuffer(), 0, tbuf1->getWidth()*tbuf1->getHeight()*COM_NUMBER_OF_CHANNELS*sizeof(float)); - for (n=1; niter &(!breaked); n++) { - for (y=0; ygetHeight()&(!breaked); y++) { - v = (float)(y+0.5f) / (float)gbuf->getHeight(); - for (x=0; xgetWidth(); x++) { - u = (float)(x+0.5f) / (float)gbuf->getWidth(); + memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); + for (n = 1; n < settings->iter & (!breaked); n++) { + for (y = 0; y < gbuf->getHeight() & (!breaked); y++) { + v = (float)(y + 0.5f) / (float)gbuf->getHeight(); + for (x = 0; x < gbuf->getWidth(); x++) { + u = (float)(x + 0.5f) / (float)gbuf->getWidth(); tc[0] = tc[1] = tc[2] = 0.f; - for (p=0;p<4;p++) { - np = (n<<2) + p; - s = (u-0.5f)*scalef[np] + 0.5f; - t = (v-0.5f)*scalef[np] + 0.5f; - gbuf->read(c, s*gbuf->getWidth() - 0.5f, t*gbuf->getHeight() - 0.5f); + for (p = 0; p < 4; p++) { + np = (n << 2) + p; + s = (u - 0.5f) * scalef[np] + 0.5f; + t = (v - 0.5f) * scalef[np] + 0.5f; + gbuf->read(c, s * gbuf->getWidth() - 0.5f, t * gbuf->getHeight() - 0.5f); fRGB_colormult(c, cm[np]); - sm = smoothMask(s, t)*0.25f; + sm = smoothMask(s, t) * 0.25f; fRGB_madd(tc, c, sm); } tbuf1->writePixel(x, y, tc); } if (isBreaked()) breaked = true; } - memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth()*tbuf1->getHeight()*COM_NUMBER_OF_CHANNELS*sizeof(float)); + memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); } - memcpy(data, gbuf->getBuffer(), gbuf->getWidth()*gbuf->getHeight()*COM_NUMBER_OF_CHANNELS*sizeof(float)); - + memcpy(data, gbuf->getBuffer(), gbuf->getWidth() * gbuf->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); + delete gbuf; delete tbuf1; delete tbuf2; From 3dd02efe2c1ae76c9d69f10352585dfdaf40afc8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 14:01:28 +0000 Subject: [PATCH 271/360] fix for incorrectly checking for break in r47826 --- .../compositor/operations/COM_GlareGhostOperation.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp index defbd76fa51..d3ecee2a508 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp @@ -74,7 +74,7 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No sc = 2.13; isc = -0.97; - for (y = 0; y < gbuf->getHeight() & (!breaked); y++) { + for (y = 0; y < gbuf->getHeight() && (!breaked); y++) { v = (float)(y + 0.5f) / (float)gbuf->getHeight(); for (x = 0; x < gbuf->getWidth(); x++) { u = (float)(x + 0.5f) / (float)gbuf->getWidth(); @@ -94,8 +94,8 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No } memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); - for (n = 1; n < settings->iter & (!breaked); n++) { - for (y = 0; y < gbuf->getHeight() & (!breaked); y++) { + for (n = 1; n < settings->iter && (!breaked); n++) { + for (y = 0; y < gbuf->getHeight() && (!breaked); y++) { v = (float)(y + 0.5f) / (float)gbuf->getHeight(); for (x = 0; x < gbuf->getWidth(); x++) { u = (float)(x + 0.5f) / (float)gbuf->getWidth(); From 99f7c06d7e59de0bb07ade589190db52b75e47e5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 14:09:20 +0000 Subject: [PATCH 272/360] added mask tool to recalculate handles (Ctrl+N) --- release/scripts/startup/bl_ui/space_clip.py | 1 + source/blender/editors/mask/mask_edit.c | 2 + source/blender/editors/mask/mask_intern.h | 1 + source/blender/editors/mask/mask_ops.c | 76 +++++++++++++++++++++ 4 files changed, 80 insertions(+) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 55922da3892..a77302ff4ae 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -1269,6 +1269,7 @@ class CLIP_MT_mask(Menu): layout.separator() layout.operator("mask.cyclic_toggle") layout.operator("mask.switch_direction") + layout.operator("mask.normals_make_consistent") layout.operator("mask.feather_weight_clear") # TODO, better place? layout.separator() diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c index 24f55f66bb8..52711c8da55 100644 --- a/source/blender/editors/mask/mask_edit.c +++ b/source/blender/editors/mask/mask_edit.c @@ -207,6 +207,7 @@ void ED_operatortypes_mask(void) /* geometry */ WM_operatortype_append(MASK_OT_switch_direction); + WM_operatortype_append(MASK_OT_normals_make_consistent); WM_operatortype_append(MASK_OT_delete); /* select */ @@ -307,6 +308,7 @@ void ED_keymap_mask(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MASK_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MASK_OT_slide_point", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MASK_OT_handle_type_set", VKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_normals_make_consistent", NKEY, KM_PRESS, KM_CTRL, 0); // WM_keymap_add_item(keymap, "MASK_OT_feather_weight_clear", SKEY, KM_PRESS, KM_ALT, 0); /* ... matches curve editmode */ RNA_enum_set(WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", TFM_MASK_SHRINKFATTEN); diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index fc6089238a1..c34558d2a01 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -56,6 +56,7 @@ void MASK_OT_hide_view_clear(struct wmOperatorType *ot); void MASK_OT_hide_view_set(struct wmOperatorType *ot); void MASK_OT_feather_weight_clear(struct wmOperatorType *ot); void MASK_OT_switch_direction(struct wmOperatorType *ot); +void MASK_OT_normals_make_consistent(struct wmOperatorType *ot); void MASK_OT_handle_type_set(struct wmOperatorType *ot); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 315e40380f9..b770e5e9dba 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -992,6 +992,7 @@ void MASK_OT_delete(wmOperatorType *ot) /* *** switch direction *** */ static int mask_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) { + Scene *scene = CTX_data_scene(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; @@ -1000,6 +1001,7 @@ static int mask_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) /* do actual selection */ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; + int change_layer = FALSE; if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; @@ -1009,6 +1011,13 @@ static int mask_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) if (ED_mask_spline_select_check(spline)) { BKE_mask_spline_direction_switch(masklay, spline); change = TRUE; + change_layer = TRUE; + } + } + + if (change_layer) { + if (IS_AUTOKEY_ON(scene)) { + ED_mask_layer_shape_auto_key(masklay, CFRA); } } } @@ -1041,6 +1050,73 @@ void MASK_OT_switch_direction(wmOperatorType *ot) } +/* *** recalc normals *** */ +static int mask_normals_make_consistent_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int i; + + int change = FALSE; + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + int change_layer = FALSE; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + BKE_mask_calc_handle_point_auto(spline, point, FALSE); + change = TRUE; + change_layer = TRUE; + } + } + } + + if (change_layer) { + if (IS_AUTOKEY_ON(scene)) { + ED_mask_layer_shape_auto_key(masklay, CFRA); + } + } + } + + if (change) { + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +/* named to match mesh recalc normals */ +void MASK_OT_normals_make_consistent(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Recalc Normals"; + ot->description = "Re-calculate the direction of selected handles"; + ot->idname = "MASK_OT_normals_make_consistent"; + + /* api callbacks */ + ot->exec = mask_normals_make_consistent_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + /******************** set handle type *********************/ static int set_handle_type_exec(bContext *C, wmOperator *op) From 342fb0a19ef267de288086f3d0bb3c330a76d855 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 13 Jun 2012 14:18:42 +0000 Subject: [PATCH 273/360] Cycles: * UI Tooltip fix. --- intern/cycles/blender/addon/properties.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 7ce3b949bb1..e3f286de83d 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -94,7 +94,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): ) cls.preview_aa_samples = IntProperty( name="AA Samples", - description="Number of antialiasing samples to in viewport, unlimited if 0", + description="Number of antialiasing samples to render in the viewport, unlimited if 0", min=1, max=10000, default=4, ) From e22aa7bc38c5d38a0714bed8a2a1869383cd5e5a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 14:33:50 +0000 Subject: [PATCH 274/360] style cleanup --- .../operations/COM_GlareBaseOperation.cpp | 4 +- .../operations/COM_GlareBaseOperation.h | 40 ++++++------ .../operations/COM_GlareGhostOperation.cpp | 16 +++-- .../operations/COM_GlareGhostOperation.h | 7 ++- .../COM_GlareSimpleStarOperation.cpp | 22 +++---- .../operations/COM_GlareSimpleStarOperation.h | 7 ++- .../operations/COM_GlareStreaksOperation.cpp | 62 +++++++++---------- .../operations/COM_GlareStreaksOperation.h | 7 ++- .../COM_GlareThresholdOperation.cpp | 18 +++--- .../operations/COM_GlareThresholdOperation.h | 38 ++++++------ 10 files changed, 117 insertions(+), 104 deletions(-) diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp index 83132963f0b..90bdd705a7c 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp @@ -23,7 +23,7 @@ #include "COM_GlareBaseOperation.h" #include "BLI_math.h" -GlareBaseOperation::GlareBaseOperation(): SingleThreadedNodeOperation() +GlareBaseOperation::GlareBaseOperation() : SingleThreadedNodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); @@ -43,7 +43,7 @@ void GlareBaseOperation::deinitExecution() MemoryBuffer *GlareBaseOperation::createMemoryBuffer(rcti *rect2, MemoryBuffer **memoryBuffers) { - MemoryBuffer *tile = (MemoryBuffer*)inputProgram->initializeTileData(rect2, memoryBuffers); + MemoryBuffer *tile = (MemoryBuffer *)inputProgram->initializeTileData(rect2, memoryBuffers); rcti rect; rect.xmin = 0; rect.ymin = 0; diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h index d79f449f426..0d20dd363c7 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.h +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.h @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ @@ -59,34 +59,36 @@ typedef float fRGB[4]; class GlareBaseOperation : public SingleThreadedNodeOperation { private: /** - * @brief Cached reference to the inputProgram - */ - SocketReader * inputProgram; - + * @brief Cached reference to the inputProgram + */ + SocketReader *inputProgram; + /** - * @brief settings of the glare node. - */ - NodeGlare * settings; + * @brief settings of the glare node. + */ + NodeGlare *settings; public: /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); - + /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setGlareSettings(NodeGlare * settings) {this->settings = settings;} + void setGlareSettings(NodeGlare *settings) { + this->settings = settings; + } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - + protected: GlareBaseOperation(); - + virtual void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) = 0; - + MemoryBuffer *createMemoryBuffer(rcti *rect, MemoryBuffer **memoryBuffers); - + }; #endif diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp index d3ecee2a508..9bf39db2727 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ @@ -27,12 +27,16 @@ static float smoothMask(float x, float y) { float t; - x = 2.f * x - 1.f, y = 2.f * y - 1.f; - if ((t = 1.f - sqrtf(x * x + y * y)) <= 0.f) return 0.f; - return t; + x = 2.0f * x - 1.0f; + y = 2.0f * y - 1.0f; + if ((t = 1.0f - sqrtf(x * x + y * y)) > 0.0f) { + return t; + } + else { + return 0.0f; + } } - void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) { const int qt = 1 << settings->quality; diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.h b/source/blender/compositor/operations/COM_GlareGhostOperation.h index 48b5e8986a9..2ee85cc4543 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.h +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.h @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ @@ -28,7 +28,8 @@ class GlareGhostOperation : public GlareBaseOperation { public: - GlareGhostOperation() : GlareBaseOperation() {} + GlareGhostOperation() : GlareBaseOperation() { + } protected: void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings); }; diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp index 4a393a33073..957ac5af748 100644 --- a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ @@ -25,21 +25,21 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) { int i, x, y, ym, yp, xm, xp; - float c[4] = {0,0,0,0}, tc[4] = {0,0,0,0}; - const float f1 = 1.f - settings->fade, f2 = (1.f - f1)*0.5f; - + float c[4] = {0, 0, 0, 0}, tc[4] = {0, 0, 0, 0}; + const float f1 = 1.0f - settings->fade; + const float f2 = (1.0f - f1) * 0.5f; MemoryBuffer *tbuf1 = inputTile->duplicate(); MemoryBuffer *tbuf2 = inputTile->duplicate(); bool breaked = false; - for (i=0; iiter && (!breaked); i++) { + for (i = 0; i < settings->iter && (!breaked); i++) { // // (x || x-1, y-1) to (x || x+1, y+1) // // F - for (y=0; ygetHeight() && (!breaked); y++) { + for (y = 0; y < this->getHeight() && (!breaked); y++) { ym = y - i; yp = y + i; - for (x=0; xgetWidth(); x++) { + for (x = 0; x < this->getWidth(); x++) { xm = x - i; xp = x + i; tbuf1->read(c, x, y); @@ -65,10 +65,10 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTil } } // // B - for (y=tbuf1->getHeight()-1 && (!breaked); y>=0; y--) { + for (y = tbuf1->getHeight() - 1 && (!breaked); y >= 0; y--) { ym = y - i; yp = y + i; - for (x=tbuf1->getWidth()-1; x>=0; x--) { + for (x = tbuf1->getWidth() - 1; x >= 0; x--) { xm = x - i; xp = x + i; tbuf1->read(c, x, y); @@ -95,7 +95,7 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTil } } - for (i = 0 ; i < this->getWidth()*this->getHeight()*4 ; i++) { + for (i = 0; i < this->getWidth() * this->getHeight() * 4; i++) { data[i] = tbuf1->getBuffer()[i] + tbuf2->getBuffer()[i]; } diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h index 22040da9bc5..a12d1191a1a 100644 --- a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h +++ b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ @@ -28,7 +28,8 @@ class GlareSimpleStarOperation : public GlareBaseOperation { public: - GlareSimpleStarOperation() : GlareBaseOperation() {} + GlareSimpleStarOperation() : GlareBaseOperation() { + } protected: void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings); }; diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp index e735893ed6d..9125783c222 100644 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ @@ -26,73 +26,73 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) { int x, y, n; - unsigned int nump=0; + unsigned int nump = 0; float c1[4], c2[4], c3[4], c4[4]; - float a, ang = DEG2RADF(360.0f)/(float)settings->angle; - - int size = inputTile->getWidth()*inputTile->getHeight(); - int size4 = size*4; + float a, ang = DEG2RADF(360.0f) / (float)settings->angle; + + int size = inputTile->getWidth() * inputTile->getHeight(); + int size4 = size * 4; bool breaked = false; - + MemoryBuffer *tsrc = inputTile->duplicate(); MemoryBuffer *tdst = new MemoryBuffer(NULL, inputTile->getRect()); tdst->clear(); - memset(data, 0, size4*sizeof(float)); - - for (a=0.f; aangle_ofs; const float vx = cos((double)an), vy = sin((double)an); - for (n=0; niter && (!breaked); ++n) { + for (n = 0; n < settings->iter && (!breaked); ++n) { const float p4 = pow(4.0, (double)n); - const float vxp = vx*p4, vyp = vy*p4; + const float vxp = vx * p4, vyp = vy * p4; const float wt = pow((double)settings->fade, (double)p4); - const float cmo = 1.f - (float)pow((double)settings->colmod, (double)n+1); // colormodulation amount relative to current pass + const float cmo = 1.f - (float)pow((double)settings->colmod, (double)n + 1); // colormodulation amount relative to current pass float *tdstcol = tdst->getBuffer(); - for (y=0; ygetHeight() && (!breaked); ++y) { - for (x=0; xgetWidth(); ++x, tdstcol+=4) { + for (y = 0; y < tsrc->getHeight() && (!breaked); ++y) { + for (x = 0; x < tsrc->getWidth(); ++x, tdstcol += 4) { // first pass no offset, always same for every pass, exact copy, // otherwise results in uneven brightness, only need once - if (n==0) tsrc->read(c1, x, y); else c1[0]=c1[1]=c1[2]=0; + if (n == 0) tsrc->read(c1, x, y); else c1[0] = c1[1] = c1[2] = 0; tsrc->readCubic(c2, x + vxp, y + vyp); - tsrc->readCubic(c3, x + vxp*2.f, y + vyp*2.f); - tsrc->readCubic(c4, x + vxp*3.f, y + vyp*3.f); + tsrc->readCubic(c3, x + vxp * 2.f, y + vyp * 2.f); + tsrc->readCubic(c4, x + vxp * 3.f, y + vyp * 3.f); // modulate color to look vaguely similar to a color spectrum c2[1] *= cmo; c2[2] *= cmo; c3[0] *= cmo; c3[1] *= cmo; - + c4[0] *= cmo; c4[2] *= cmo; - tdstcol[0] = 0.5f*(tdstcol[0] + c1[0] + wt*(c2[0] + wt*(c3[0] + wt*c4[0]))); - tdstcol[1] = 0.5f*(tdstcol[1] + c1[1] + wt*(c2[1] + wt*(c3[1] + wt*c4[1]))); - tdstcol[2] = 0.5f*(tdstcol[2] + c1[2] + wt*(c2[2] + wt*(c3[2] + wt*c4[2]))); + tdstcol[0] = 0.5f * (tdstcol[0] + c1[0] + wt * (c2[0] + wt * (c3[0] + wt * c4[0]))); + tdstcol[1] = 0.5f * (tdstcol[1] + c1[1] + wt * (c2[1] + wt * (c3[1] + wt * c4[1]))); + tdstcol[2] = 0.5f * (tdstcol[2] + c1[2] + wt * (c2[2] + wt * (c3[2] + wt * c4[2]))); tdstcol[3] = 1.0f; } if (isBreaked()) { breaked = true; } } - memcpy(tsrc->getBuffer(), tdst->getBuffer(), sizeof(float)*size4); + memcpy(tsrc->getBuffer(), tdst->getBuffer(), sizeof(float) * size4); } float *sourcebuffer = tsrc->getBuffer(); - float factor = 1.f/(float)(6 - settings->iter); - for (int i = 0 ; i < size4; i ++) { + float factor = 1.f / (float)(6 - settings->iter); + for (int i = 0; i < size4; i++) { data[i] += sourcebuffer[i] * factor; } - for (int i = 0 ; i < size; i ++) { - data[i*4+3] = 1.0f; + for (int i = 0; i < size; i++) { + data[i * 4 + 3] = 1.0f; } - + tdst->clear(); - memcpy(tsrc->getBuffer(), inputTile->getBuffer(), sizeof(float)*size4); + memcpy(tsrc->getBuffer(), inputTile->getBuffer(), sizeof(float) * size4); nump++; } - + delete tsrc; delete tdst; } diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.h b/source/blender/compositor/operations/COM_GlareStreaksOperation.h index 07155a4713a..6520a05b44f 100644 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.h +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.h @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ @@ -28,7 +28,8 @@ class GlareStreaksOperation : public GlareBaseOperation { public: - GlareStreaksOperation() : GlareBaseOperation() {} + GlareStreaksOperation() : GlareBaseOperation() { + } protected: void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings); }; diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp index e8def72b7da..4ca5f575cfe 100644 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp @@ -15,15 +15,15 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ #include "COM_GlareThresholdOperation.h" #include "BLI_math.h" -GlareThresholdOperation::GlareThresholdOperation(): NodeOperation() +GlareThresholdOperation::GlareThresholdOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); @@ -37,13 +37,15 @@ void GlareThresholdOperation::initExecution() void GlareThresholdOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { this->inputProgram->read(color, x, y, sampler, inputBuffers); - if ((0.212671f*color[0] + 0.71516f*color[1] + 0.072169f*color[2]) >= threshold) { + if ((0.212671f * color[0] + 0.71516f * color[1] + 0.072169f * color[2]) >= threshold) { color[0] -= threshold, color[1] -= threshold, color[2] -= threshold; - color[0] = MAX2(color[0], 0.f); - color[1] = MAX2(color[1], 0.f); - color[2] = MAX2(color[2], 0.f); + color[0] = MAX2(color[0], 0.0f); + color[1] = MAX2(color[1], 0.0f); + color[2] = MAX2(color[2], 0.0f); + } + else { + zero_v3(color); } - else color[0] = color[1] = color[2] = 0.f; } void GlareThresholdOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.h b/source/blender/compositor/operations/COM_GlareThresholdOperation.h index 3dfa2f44339..d5ec8ba93a6 100644 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.h +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.h @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ @@ -28,30 +28,32 @@ class GlareThresholdOperation : public NodeOperation { private: /** - * @brief Cached reference to the inputProgram - */ - SocketReader * inputProgram; - + * @brief Cached reference to the inputProgram + */ + SocketReader *inputProgram; + float threshold; public: GlareThresholdOperation(); - + /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); - + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); + /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); - + /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - - void setThreshold(float threshold) {this->threshold = threshold;} + + void setThreshold(float threshold) { + this->threshold = threshold; + } }; #endif From 1dec23d33a86c0412852ef510fc5b5b619284697 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 15:05:42 +0000 Subject: [PATCH 275/360] add rgb_to_luma_y(), was being done inline in many places. --- source/blender/blenlib/BLI_math_color.h | 2 ++ source/blender/blenlib/intern/math_color.c | 17 ++++++++++++++--- .../operations/COM_ColorCorrectionOperation.cpp | 7 ++++--- .../operations/COM_GlareThresholdOperation.cpp | 2 +- .../operations/COM_TonemapOperation.cpp | 4 ++-- .../composite/nodes/node_composite_glare.c | 2 +- .../composite/nodes/node_composite_tonemap.c | 4 ++-- .../blender/render/intern/source/volumetric.c | 16 +++++----------- 8 files changed, 31 insertions(+), 23 deletions(-) diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h index 44f54c41129..24c237f1130 100644 --- a/source/blender/blenlib/BLI_math_color.h +++ b/source/blender/blenlib/BLI_math_color.h @@ -78,6 +78,8 @@ float rgb_to_grayscale(const float rgb[3]); unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3]); float rgb_to_luma(const float rgb[3]); unsigned char rgb_to_luma_byte(const unsigned char rgb[3]); +float rgb_to_luma_y(const float rgb[3]); +float rgb_to_luma_rec709_byte(const unsigned char rgb[3]); /**************** Profile Transformations *****************/ diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 5b034bd2872..f1529671492 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -516,6 +516,17 @@ unsigned char rgb_to_luma_byte(const unsigned char rgb[3]) return (76 * (unsigned short) rgb[0] + 150 * (unsigned short) rgb[1] + 29 * (unsigned short) rgb[2]) / 255; } +/* gamma-corrected RGB --> CIE XYZ + * for this function we only get the Y component + * see: http://software.intel.com/sites/products/documentation/hpc/ipp/ippi/ippi_ch6/ch6_color_models.html + * + * also known as: + * luminance rec. 709 */ +float rgb_to_luma_y(const float rgb[3]) +{ + return 0.212671f * rgb[0] + 0.71516f * rgb[1] + 0.072169f * rgb[2]; +} + /* ********************************* lift/gamma/gain / ASC-CDL conversion ********************************* */ void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power) @@ -648,9 +659,9 @@ void rgb_to_xyz(float r, float g, float b, float *x, float *y, float *z) g = inverse_srgb_companding(g) * 100.0f; b = inverse_srgb_companding(b) * 100.0f; - *x = r * 0.4124 + g * 0.3576 + b * 0.1805; - *y = r * 0.2126 + g * 0.7152 + b * 0.0722; - *z = r * 0.0193 + g * 0.1192 + b * 0.9505; + *x = r * 0.412453f + g * 0.357580f + b * 0.180423f; + *y = r * 0.212671f + g * 0.715160f + b * 0.072169f; + *z = r * 0.019334f + g * 0.119193f + b * 0.950227f; } static float xyz_to_lab_component(float v) diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp index 82a71f6a7a8..8ff58be7980 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp @@ -89,12 +89,13 @@ void ColorCorrectionOperation::executePixel(float *output, float x, float y, Pix gain *= (levelShadows*this->data->shadows.gain)+(levelMidtones*this->data->midtones.gain)+(levelHighlights*this->data->highlights.gain); lift += (levelShadows*this->data->shadows.lift)+(levelMidtones*this->data->midtones.lift)+(levelHighlights*this->data->highlights.lift); + float invgamma = 1.0f / gamma; + float luma = rgb_to_luma_y(inputImageColor); + r = inputImageColor[0]; g = inputImageColor[1]; b = inputImageColor[2]; - - float invgamma = 1.0f / gamma; - float luma = 0.2126f * r + 0.7152f * g + 0.0722f * b; + r = (luma + saturation * (r - luma)); g = (luma + saturation * (g - luma)); b = (luma + saturation * (b - luma)); diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp index 4ca5f575cfe..ea76e7551ad 100644 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp @@ -37,7 +37,7 @@ void GlareThresholdOperation::initExecution() void GlareThresholdOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { this->inputProgram->read(color, x, y, sampler, inputBuffers); - if ((0.212671f * color[0] + 0.71516f * color[1] + 0.072169f * color[2]) >= threshold) { + if (rgb_to_luma_y(color) >= threshold) { color[0] -= threshold, color[1] -= threshold, color[2] -= threshold; color[0] = MAX2(color[0], 0.0f); color[1] = MAX2(color[1], 0.0f); diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cpp b/source/blender/compositor/operations/COM_TonemapOperation.cpp index 9a02d6a58ca..b281fb938fd 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.cpp +++ b/source/blender/compositor/operations/COM_TonemapOperation.cpp @@ -75,7 +75,7 @@ void PhotoreceptorTonemapOperation::executePixel(float *color, int x, int y, Mem float output[4]; this->imageReader->read(output, x, y, inputBuffers, NULL); - const float L = 0.212671f * output[0] + 0.71516f * output[1] + 0.072169f * output[2]; + const float L = rgb_to_luma_y(output); float I_l = output[0] + ic * (L - output[0]); float I_g = avg->cav[0] + ic * (avg->lav - avg->cav[0]); float I_a = I_l + ia * (I_g - I_l); @@ -133,7 +133,7 @@ void *TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuff float Lav = 0.f; float cav[4] = {0.0f,0.0f,0.0f,0.0f}; while (p--) { - float L = 0.212671f * bc[0] + 0.71516f * bc[1] + 0.072169f * bc[2]; + float L = rgb_to_luma_y(bc); Lav += L; add_v3_v3(cav, bc); lsum += logf(MAX2(L, 0.0f) + 1e-5f); diff --git a/source/blender/nodes/composite/nodes/node_composite_glare.c b/source/blender/nodes/composite/nodes/node_composite_glare.c index 1e32d6f0461..9b1505e9333 100644 --- a/source/blender/nodes/composite/nodes/node_composite_glare.c +++ b/source/blender/nodes/composite/nodes/node_composite_glare.c @@ -107,7 +107,7 @@ static CompBuf* BTP(CompBuf* src, float threshold, int scaledown) float* cr = bsrc->rect; for (y=0; yy; ++y) for (x=0; xx; ++x, cr+=4) { - if ((0.212671f*cr[0] + 0.71516f*cr[1] + 0.072169f*cr[2]) >= threshold) { + if (rgb_to_luma_y(cr) >= threshold) { cr[0] -= threshold, cr[1] -= threshold, cr[2] -= threshold; cr[0] = MAX2(cr[0], 0.f); cr[1] = MAX2(cr[1], 0.f); diff --git a/source/blender/nodes/composite/nodes/node_composite_tonemap.c b/source/blender/nodes/composite/nodes/node_composite_tonemap.c index a9d071ececc..6196825c9b3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_tonemap.c +++ b/source/blender/nodes/composite/nodes/node_composite_tonemap.c @@ -51,7 +51,7 @@ static float avgLogLum(CompBuf *src, float* auto_key, float* Lav, float* Cav) const float sc = 1.f/(src->x*src->y); *Lav = 0.f; while (p--) { - float L = 0.212671f*bc[0][0] + 0.71516f*bc[0][1] + 0.072169f*bc[0][2]; + float L = rgb_to_luma_y(bc[0]); *Lav += L; fRGB_add(Cav, bc[0]); lsum += (float)log((double)MAX2(L, 0.0) + 1e-5); @@ -86,7 +86,7 @@ static void tonemap(NodeTonemap* ntm, CompBuf* dst, CompBuf* src) fRGB* sp = (fRGB*)&src->rect[y*src->x*src->type]; fRGB* dp = (fRGB*)&dst->rect[y*src->x*src->type]; for (x=0; xx; ++x) { - const float L = 0.212671f*sp[x][0] + 0.71516f*sp[x][1] + 0.072169f*sp[x][2]; + const float L = rgb_to_luma_y(sp[x]); float I_l = sp[x][0] + ic*(L - sp[x][0]); float I_g = Cav[0] + ic*(Lav - Cav[0]); float I_a = I_l + ia*(I_g - I_l); diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 75748696a72..e4c4e905aa6 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -68,12 +68,6 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* luminance rec. 709 */ -BLI_INLINE float luminance(const float col[3]) -{ - return (0.212671f * col[0] + 0.71516f * col[1] + 0.072169f * col[2]); -} - /* tracing */ static float vol_get_shadow(ShadeInput *shi, LampRen *lar, const float co[3]) { @@ -502,7 +496,7 @@ static void vol_shade_one_lamp(struct ShadeInput *shi, const float co[3], const if (shi->mat->vol.shadeflag & MA_VOL_RECV_EXT_SHADOW) { mul_v3_fl(lacol, vol_get_shadow(shi, lar, co)); - if (luminance(lacol) < 0.001f) return; + if (rgb_to_luma_y(lacol) < 0.001f) return; } /* find minimum of volume bounds, or lamp coord */ @@ -536,7 +530,7 @@ static void vol_shade_one_lamp(struct ShadeInput *shi, const float co[3], const } } - if (luminance(lacol) < 0.001f) return; + if (rgb_to_luma_y(lacol) < 0.001f) return; normalize_v3(lv); p = vol_get_phasefunc(shi, shi->mat->vol.asymmetry, view, lv); @@ -618,7 +612,7 @@ static void volumeintegrate(struct ShadeInput *shi, float col[4], const float co if (t0 > t1 * 0.25f) { /* only use depth cutoff after we've traced a little way into the volume */ - if (luminance(tr) < shi->mat->vol.depth_cutoff) break; + if (rgb_to_luma_y(tr) < shi->mat->vol.depth_cutoff) break; } vol_get_emission(shi, emit_col, p); @@ -647,7 +641,7 @@ static void volumeintegrate(struct ShadeInput *shi, float col[4], const float co add_v3_v3(col, radiance); /* alpha <-- transmission luminance */ - col[3] = 1.0f - luminance(tr); + col[3] = 1.0f - rgb_to_luma_y(tr); } /* the main entry point for volume shading */ @@ -787,7 +781,7 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct copy_v3_v3(shr->combined, tr); - shr->combined[3] = 1.0f - luminance(tr); + shr->combined[3] = 1.0f - rgb_to_luma_y(tr); shr->alpha = shr->combined[3]; } From 0bed750c3a4f7b368c06d40847356451f51eced6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 15:13:19 +0000 Subject: [PATCH 276/360] move one line color conversion functions to be inline. --- source/blender/blenlib/BLI_math_color.h | 7 +--- source/blender/blenlib/intern/math_color.c | 31 ----------------- .../blenlib/intern/math_color_inline.c | 33 +++++++++++++++++++ 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h index 24c237f1130..7520f09fe95 100644 --- a/source/blender/blenlib/BLI_math_color.h +++ b/source/blender/blenlib/BLI_math_color.h @@ -74,12 +74,7 @@ void rgb_to_xyz(float r, float g, float b, float *x, float *y, float *z); unsigned int rgb_to_cpack(float r, float g, float b); unsigned int hsv_to_cpack(float h, float s, float v); -float rgb_to_grayscale(const float rgb[3]); -unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3]); -float rgb_to_luma(const float rgb[3]); -unsigned char rgb_to_luma_byte(const unsigned char rgb[3]); -float rgb_to_luma_y(const float rgb[3]); -float rgb_to_luma_rec709_byte(const unsigned char rgb[3]); +/* rgb_to_grayscale & rgb_to_luma functions moved to math_color_inline.c */ /**************** Profile Transformations *****************/ diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index f1529671492..c32f981396d 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -496,37 +496,6 @@ int constrain_rgb(float *r, float *g, float *b) return 0; /* Color within RGB gamut */ } -float rgb_to_grayscale(const float rgb[3]) -{ - return 0.3f * rgb[0] + 0.58f * rgb[1] + 0.12f * rgb[2]; -} - -unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3]) -{ - return (76 * (unsigned short) rgb[0] + 148 * (unsigned short) rgb[1] + 31 * (unsigned short) rgb[2]) / 255; -} - -float rgb_to_luma(const float rgb[3]) -{ - return 0.299f * rgb[0] + 0.587f * rgb[1] + 0.114f * rgb[2]; -} - -unsigned char rgb_to_luma_byte(const unsigned char rgb[3]) -{ - return (76 * (unsigned short) rgb[0] + 150 * (unsigned short) rgb[1] + 29 * (unsigned short) rgb[2]) / 255; -} - -/* gamma-corrected RGB --> CIE XYZ - * for this function we only get the Y component - * see: http://software.intel.com/sites/products/documentation/hpc/ipp/ippi/ippi_ch6/ch6_color_models.html - * - * also known as: - * luminance rec. 709 */ -float rgb_to_luma_y(const float rgb[3]) -{ - return 0.212671f * rgb[0] + 0.71516f * rgb[1] + 0.072169f * rgb[2]; -} - /* ********************************* lift/gamma/gain / ASC-CDL conversion ********************************* */ void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power) diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c index b2a87a91433..417c557af8a 100644 --- a/source/blender/blenlib/intern/math_color_inline.c +++ b/source/blender/blenlib/intern/math_color_inline.c @@ -222,4 +222,37 @@ MINLINE void cpack_cpy_3ub(unsigned char r_col[3], const unsigned int pack) r_col[2] = ((pack) >> 16) & 0xFF; } + +MINLINE float rgb_to_grayscale(const float rgb[3]) +{ + return 0.3f * rgb[0] + 0.58f * rgb[1] + 0.12f * rgb[2]; +} + +MINLINE unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3]) +{ + return (76 * (unsigned short) rgb[0] + 148 * (unsigned short) rgb[1] + 31 * (unsigned short) rgb[2]) / 255; +} + +MINLINE float rgb_to_luma(const float rgb[3]) +{ + return 0.299f * rgb[0] + 0.587f * rgb[1] + 0.114f * rgb[2]; +} + +MINLINE unsigned char rgb_to_luma_byte(const unsigned char rgb[3]) +{ + return (76 * (unsigned short) rgb[0] + 150 * (unsigned short) rgb[1] + 29 * (unsigned short) rgb[2]) / 255; +} + +/* gamma-corrected RGB --> CIE XYZ + * for this function we only get the Y component + * see: http://software.intel.com/sites/products/documentation/hpc/ipp/ippi/ippi_ch6/ch6_color_models.html + * + * also known as: + * luminance rec. 709 */ +MINLINE float rgb_to_luma_y(const float rgb[3]) +{ + return 0.212671f * rgb[0] + 0.71516f * rgb[1] + 0.072169f * rgb[2]; +} + + #endif /* __MATH_COLOR_INLINE_C__ */ From 01b036f5c623ff022d09f9209d16d69fbf6df3b7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 13 Jun 2012 15:33:59 +0000 Subject: [PATCH 277/360] Fix #31754: strand width fade value 2.0 gives wrong result, should fade out strand entirely. Fix based on patch by Philipp Oeser. --- source/blender/render/intern/source/convertblender.c | 2 +- source/blender/render/intern/source/strand.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index a48a6b75049..4eebc967823 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1729,7 +1729,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem strandbuf->minwidth= ma->strand_min; if (ma->strand_widthfade == 0.0f) - strandbuf->widthfade= 0.0f; + strandbuf->widthfade= -1.0f; else if (ma->strand_widthfade >= 1.0f) strandbuf->widthfade= 2.0f - ma->strand_widthfade; else diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 7e0744096b3..0e7c8a13043 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -400,7 +400,7 @@ void strand_shade_segment(Render *re, StrandShadeCache *cache, StrandSegment *ss interpolate_shade_result(&shr1, &shr2, t, ssamp->shr, addpassflag); /* apply alpha along width */ - if (sseg->buffer->widthfade != 0.0f) { + if (sseg->buffer->widthfade != -1.0f) { s = 1.0f - powf(fabsf(s), sseg->buffer->widthfade); strand_apply_shaderesult_alpha(ssamp->shr, s); From 0a2da1ee45776d5f5b99708fff6169d6ca4df256 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 16:06:13 +0000 Subject: [PATCH 278/360] patch [#31574] Screw seams to not work from Benoit Donat-Bouillud (ladeheria) from tracker - When using a screw axis (reference edge for screw), the operation always give the same result (as if the orientation of the reference edge was not take into account). --- source/blender/bmesh/operators/bmo_dupe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index ae001b2baf6..6e6037239b9 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -504,7 +504,9 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op) BMO_op_finish(bm, &extop); } - if (usedvec) + if (usedvec) { + mul_m3_v3(rmat, dvec); BMO_op_callf(bm, "translate vec=%v verts=%s", dvec, op, "lastout"); + } } } From 7818b94016040a3eca2b5e329600fd39d80befff Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 13 Jun 2012 16:15:42 +0000 Subject: [PATCH 279/360] Cycles: * "preview_aa_samples" minimum should be 0, not 1. --- intern/cycles/blender/addon/properties.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index e3f286de83d..b4673ec6206 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -95,7 +95,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): cls.preview_aa_samples = IntProperty( name="AA Samples", description="Number of antialiasing samples to render in the viewport, unlimited if 0", - min=1, max=10000, + min=0, max=10000, default=4, ) cls.diffuse_samples = IntProperty( From 50493317558eac2f4d15e5f5cbf86bb48f957b17 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 17:23:44 +0000 Subject: [PATCH 280/360] style cleanup --- source/blender/blenlib/intern/math_color.c | 12 +- .../blender/render/intern/source/pipeline.c | 914 +++++++++--------- .../render/intern/source/render_result.c | 606 ++++++------ 3 files changed, 763 insertions(+), 769 deletions(-) diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index c32f981396d..b93597bf107 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -381,15 +381,9 @@ unsigned int rgb_to_cpack(float r, float g, float b) void cpack_to_rgb(unsigned int col, float *r, float *g, float *b) { - - *r = (float)((col) & 0xFF); - *r /= 255.0f; - - *g = (float)(((col) >> 8) & 0xFF); - *g /= 255.0f; - - *b = (float)(((col) >> 16) & 0xFF); - *b /= 255.0f; + *r = ((float)(((col) ) & 0xFF)) * (1.0f / 255.0f); + *g = ((float)(((col) >> 8) & 0xFF)) * (1.0f / 255.0f); + *b = ((float)(((col) >> 16) & 0xFF)) * (1.0f / 255.0f); } void rgb_uchar_to_float(float col_r[3], const unsigned char col_ub[3]) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 8f5230e4b2b..eab152262f8 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -45,7 +45,7 @@ #include "MEM_guardedalloc.h" -#include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */ +#include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */ #include "BKE_camera.h" #include "BKE_global.h" #include "BKE_image.h" @@ -56,7 +56,7 @@ #include "BKE_scene.h" #include "BKE_sequencer.h" #include "BKE_utildefines.h" -#include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */ +#include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */ #include "BLI_math.h" #include "BLI_listbase.h" @@ -127,7 +127,7 @@ Render R; static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const char *name_override); -static volatile int g_break= 0; +static volatile int g_break = 0; static int thread_break(void *UNUSED(arg)) { return g_break; @@ -145,13 +145,13 @@ static void stats_background(void *UNUSED(arg), RenderStats *rs) uintptr_t mem_in_use, mmap_in_use, peak_memory; float megs_used_memory, mmap_used_memory, megs_peak_memory; - mem_in_use= MEM_get_memory_in_use(); - mmap_in_use= MEM_get_mapped_memory_in_use(); + mem_in_use = MEM_get_memory_in_use(); + mmap_in_use = MEM_get_mapped_memory_in_use(); peak_memory = MEM_get_peak_memory(); - megs_used_memory= (mem_in_use-mmap_in_use)/(1024.0*1024.0); - mmap_used_memory= (mmap_in_use)/(1024.0*1024.0); - megs_peak_memory = (peak_memory)/(1024.0*1024.0); + megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0); + mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0); + megs_peak_memory = (peak_memory) / (1024.0 * 1024.0); fprintf(stdout, "Fra:%d Mem:%.2fM (%.2fM, peak %.2fM) ", rs->cfra, megs_used_memory, mmap_used_memory, megs_peak_memory); @@ -186,8 +186,8 @@ float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype) { RenderPass *rpass; - for (rpass=rl->passes.first; rpass; rpass= rpass->next) - if (rpass->passtype== passtype) + for (rpass = rl->passes.first; rpass; rpass = rpass->next) + if (rpass->passtype == passtype) return rpass->rect; return NULL; } @@ -196,10 +196,10 @@ RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name) { RenderLayer *rl; - if (rr==NULL) return NULL; + if (rr == NULL) return NULL; - for (rl= rr->layers.first; rl; rl= rl->next) - if (strncmp(rl->name, name, RE_MAXNAME)==0) + for (rl = rr->layers.first; rl; rl = rl->next) + if (strncmp(rl->name, name, RE_MAXNAME) == 0) return rl; return NULL; } @@ -211,7 +211,7 @@ RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty) RenderLayer *render_get_active_layer(Render *re, RenderResult *rr) { - RenderLayer *rl= BLI_findlink(&rr->layers, re->r.actlay); + RenderLayer *rl = BLI_findlink(&rr->layers, re->r.actlay); if (rl) return rl; @@ -223,7 +223,7 @@ static int render_scene_needs_vector(Render *re) { SceneRenderLayer *srl; - for (srl= re->scene->r.layers.first; srl; srl= srl->next) + for (srl = re->scene->r.layers.first; srl; srl = srl->next) if (!(srl->layflag & SCE_LAY_DISABLE)) if (srl->passflag & SCE_PASS_VECTOR) return 1; @@ -238,8 +238,8 @@ Render *RE_GetRender(const char *name) Render *re; /* search for existing renders */ - for (re= RenderGlobal.renderlist.first; re; re= re->next) - if (strncmp(re->name, name, RE_MAXNAME)==0) + for (re = RenderGlobal.renderlist.first; re; re = re->next) + if (strncmp(re->name, name, RE_MAXNAME) == 0) break; return re; @@ -270,7 +270,7 @@ void RE_SwapResult(Render *re, RenderResult **rr) { /* for keeping render buffers */ if (re) { - SWAP(RenderResult*, re->result, *rr); + SWAP(RenderResult *, re->result, *rr); } } @@ -300,25 +300,25 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr) if (re->result) { RenderLayer *rl; - rr->rectx= re->result->rectx; - rr->recty= re->result->recty; + rr->rectx = re->result->rectx; + rr->recty = re->result->recty; - rr->rectf= re->result->rectf; - rr->rectz= re->result->rectz; - rr->rect32= re->result->rect32; + rr->rectf = re->result->rectf; + rr->rectz = re->result->rectz; + rr->rect32 = re->result->rect32; /* active layer */ - rl= render_get_active_layer(re, re->result); + rl = render_get_active_layer(re, re->result); if (rl) { - if (rr->rectf==NULL) - rr->rectf= rl->rectf; - if (rr->rectz==NULL) - rr->rectz= RE_RenderLayerGetPass(rl, SCE_PASS_Z); + if (rr->rectf == NULL) + rr->rectf = rl->rectf; + if (rr->rectz == NULL) + rr->rectz = RE_RenderLayerGetPass(rl, SCE_PASS_Z); } - rr->have_combined= (re->result->rectf != NULL); - rr->layers= re->result->layers; + rr->have_combined = (re->result->rectf != NULL); + rr->layers = re->result->layers; } } } @@ -349,11 +349,11 @@ Render *RE_NewRender(const char *name) Render *re; /* only one render per name exists */ - re= RE_GetRender(name); - if (re==NULL) { + re = RE_GetRender(name); + if (re == NULL) { /* new render data struct */ - re= MEM_callocN(sizeof(Render), "new render"); + re = MEM_callocN(sizeof(Render), "new render"); BLI_addtail(&RenderGlobal.renderlist, re); BLI_strncpy(re->name, name, RE_MAXNAME); BLI_rw_mutex_init(&re->resultmutex); @@ -362,7 +362,7 @@ Render *RE_NewRender(const char *name) RE_InitRenderCB(re); /* init some variables */ - re->ycor= 1.0f; + re->ycor = 1.0f; return re; } @@ -372,17 +372,17 @@ Render *RE_NewRender(const char *name) void RE_InitRenderCB(Render *re) { /* set default empty callbacks */ - re->display_init= result_nothing; - re->display_clear= result_nothing; - re->display_draw= result_rcti_nothing; - re->progress= float_nothing; - re->test_break= default_break; + re->display_init = result_nothing; + re->display_clear = result_nothing; + re->display_draw = result_rcti_nothing; + re->progress = float_nothing; + re->test_break = default_break; if (G.background) - re->stats_draw= stats_background; + re->stats_draw = stats_background; else - re->stats_draw= stats_nothing; + re->stats_draw = stats_nothing; /* clear callback handles */ - re->dih= re->dch= re->ddh= re->sdh= re->prh= re->tbh= NULL; + re->dih = re->dch = re->ddh = re->sdh = re->prh = re->tbh = NULL; } /* only call this while you know it will remove the link too */ @@ -429,66 +429,66 @@ void RE_FreeAllRenderResults(void) /* disprect is optional, if NULL it assumes full window render */ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *srl, int winx, int winy, rcti *disprect) { - re->ok= TRUE; /* maybe flag */ + re->ok = TRUE; /* maybe flag */ - re->i.starttime= PIL_check_seconds_timer(); - re->r= *rd; /* hardcopy */ + re->i.starttime = PIL_check_seconds_timer(); + re->r = *rd; /* hardcopy */ - re->winx= winx; - re->winy= winy; + re->winx = winx; + re->winy = winy; if (disprect) { - re->disprect= *disprect; - re->rectx= disprect->xmax-disprect->xmin; - re->recty= disprect->ymax-disprect->ymin; + re->disprect = *disprect; + re->rectx = disprect->xmax - disprect->xmin; + re->recty = disprect->ymax - disprect->ymin; } else { re->disprect.xmin = re->disprect.ymin = 0; re->disprect.xmax = winx; re->disprect.ymax = winy; - re->rectx= winx; - re->recty= winy; + re->rectx = winx; + re->recty = winy; } if (re->rectx < 2 || re->recty < 2 || (BKE_imtype_is_movie(rd->im_format.imtype) && (re->rectx < 16 || re->recty < 16) )) { BKE_report(re->reports, RPT_ERROR, "Image too small"); - re->ok= 0; + re->ok = 0; return; } - if ((re->r.mode & (R_OSA))==0) + if ((re->r.mode & (R_OSA)) == 0) re->r.scemode &= ~R_FULL_SAMPLE; #ifdef WITH_OPENEXR if (re->r.scemode & R_FULL_SAMPLE) - re->r.scemode |= R_EXR_TILE_FILE; /* enable automatic */ + re->r.scemode |= R_EXR_TILE_FILE; /* enable automatic */ /* Until use_border is made compatible with save_buffers/full_sample, render without the later instead of not rendering at all.*/ if (re->r.mode & R_BORDER) { - re->r.scemode &= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE); + re->r.scemode &= ~(R_EXR_TILE_FILE | R_FULL_SAMPLE); } #else /* can't do this without openexr support */ - re->r.scemode &= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE); + re->r.scemode &= ~(R_EXR_TILE_FILE | R_FULL_SAMPLE); #endif /* fullsample wants uniform osa levels */ if (source && (re->r.scemode & R_FULL_SAMPLE)) { /* but, if source has no full sample we disable it */ - if ((source->r.scemode & R_FULL_SAMPLE)==0) + if ((source->r.scemode & R_FULL_SAMPLE) == 0) re->r.scemode &= ~R_FULL_SAMPLE; else - re->r.osa= re->osa= source->osa; + re->r.osa = re->osa = source->osa; } else { /* check state variables, osa? */ if (re->r.mode & (R_OSA)) { - re->osa= re->r.osa; - if (re->osa>16) re->osa= 16; + re->osa = re->r.osa; + if (re->osa > 16) re->osa = 16; } - else re->osa= 0; + else re->osa = 0; } if (srl) { @@ -506,25 +506,25 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer * BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if (re->r.scemode & R_PREVIEWBUTS) { - if (re->result && re->result->rectx==re->rectx && re->result->recty==re->recty); + if (re->result && re->result->rectx == re->rectx && re->result->recty == re->recty) ; else { render_result_free(re->result); - re->result= NULL; + re->result = NULL; } } else { /* make empty render result, so display callbacks can initialize */ render_result_free(re->result); - re->result= MEM_callocN(sizeof(RenderResult), "new render result"); - re->result->rectx= re->rectx; - re->result->recty= re->recty; + re->result = MEM_callocN(sizeof(RenderResult), "new render result"); + re->result->rectx = re->rectx; + re->result->recty = re->recty; } BLI_rw_mutex_unlock(&re->resultmutex); /* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */ - re->clipcrop= 1.0f + 2.0f/(float)(re->winx>re->winy?re->winy:re->winx); + re->clipcrop = 1.0f + 2.0f / (float)(re->winx > re->winy ? re->winy : re->winx); re->mblur_offs = re->field_offs = 0.f; @@ -535,9 +535,9 @@ void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend) { /* re->ok flag? */ - re->viewplane= *viewplane; - re->clipsta= clipsta; - re->clipend= clipend; + re->viewplane = *viewplane; + re->clipsta = clipsta; + re->clipend = clipend; re->r.mode &= ~R_ORTHO; perspective_m4(re->winmat, @@ -550,9 +550,9 @@ void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend) { /* re->ok flag? */ - re->viewplane= *viewplane; - re->clipsta= clipsta; - re->clipend= clipend; + re->viewplane = *viewplane; + re->clipsta = clipsta; + re->clipend = clipend; re->r.mode |= R_ORTHO; orthographic_m4(re->winmat, @@ -570,40 +570,40 @@ void RE_SetView(Render *re, float mat[][4]) /* image and movie output has to move to either imbuf or kernel */ void RE_display_init_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr)) { - re->display_init= f; - re->dih= handle; + re->display_init = f; + re->dih = handle; } void RE_display_clear_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr)) { - re->display_clear= f; - re->dch= handle; + re->display_clear = f; + re->dch = handle; } void RE_display_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr, volatile rcti *rect)) { - re->display_draw= f; - re->ddh= handle; + re->display_draw = f; + re->ddh = handle; } void RE_stats_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderStats *rs)) { - re->stats_draw= f; - re->sdh= handle; + re->stats_draw = f; + re->sdh = handle; } void RE_progress_cb(Render *re, void *handle, void (*f)(void *handle, float)) { - re->progress= f; - re->prh= handle; + re->progress = f; + re->prh = handle; } void RE_draw_lock_cb(Render *re, void *handle, void (*f)(void *handle, int i)) { - re->draw_lock= f; - re->tbh= handle; + re->draw_lock = f; + re->tbh = handle; } void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle)) { - re->test_break= f; - re->tbh= handle; + re->test_break = f; + re->tbh = handle; } @@ -632,15 +632,15 @@ static int render_display_draw_enabled(Render *re) /* the main thread call, renders an entire part */ static void *do_part_thread(void *pa_v) { - RenderPart *pa= pa_v; + RenderPart *pa = pa_v; /* need to return nicely all parts on esc */ - if (R.test_break(R.tbh)==0) { + if (R.test_break(R.tbh) == 0) { if (!R.sss_points && (R.r.scemode & R_FULL_SAMPLE)) - pa->result= render_result_new_full_sample(&R, &pa->fullresult, &pa->disprect, pa->crop, RR_USE_MEM); + pa->result = render_result_new_full_sample(&R, &pa->fullresult, &pa->disprect, pa->crop, RR_USE_MEM); else - pa->result= render_result_new(&R, &pa->disprect, pa->crop, RR_USE_MEM); + pa->result = render_result_new(&R, &pa->disprect, pa->crop, RR_USE_MEM); if (R.sss_points) zbufshade_sss_tile(pa); @@ -655,12 +655,12 @@ static void *do_part_thread(void *pa_v) } else if (render_display_draw_enabled(&R)) { /* on break, don't merge in result for preview renders, looks nicer */ - if (R.test_break(R.tbh) && (R.r.scemode & R_PREVIEWBUTS)); + if (R.test_break(R.tbh) && (R.r.scemode & R_PREVIEWBUTS)) ; else render_result_merge(R.result, pa->result); } } - pa->ready= 1; + pa->ready = 1; return NULL; } @@ -671,21 +671,21 @@ static void *do_part_thread(void *pa_v) float panorama_pixel_rot(Render *re) { float psize, phi, xfac; - float borderfac= (float)(re->disprect.xmax - re->disprect.xmin) / (float)re->winx; + float borderfac = (float)(re->disprect.xmax - re->disprect.xmin) / (float)re->winx; /* size of 1 pixel mapped to viewplane coords */ - psize= (re->viewplane.xmax-re->viewplane.xmin)/(float)(re->winx); + psize = (re->viewplane.xmax - re->viewplane.xmin) / (float)(re->winx); /* angle of a pixel */ - phi= atan(psize/re->clipsta); + phi = atan(psize / re->clipsta); /* correction factor for viewplane shifting, first calculate how much the viewplane angle is */ - xfac= borderfac*((re->viewplane.xmax-re->viewplane.xmin))/(float)re->xparts; - xfac= atan(0.5f*xfac/re->clipsta); + xfac = borderfac * ((re->viewplane.xmax - re->viewplane.xmin)) / (float)re->xparts; + xfac = atan(0.5f * xfac / re->clipsta); /* and how much the same viewplane angle is wrapped */ - psize= 0.5f*phi*((float)re->partx); + psize = 0.5f * phi * ((float)re->partx); /* the ratio applied to final per-pixel angle */ - phi*= xfac/psize; + phi *= xfac / psize; return phi; } @@ -694,25 +694,25 @@ float panorama_pixel_rot(Render *re) /* if slice found, it rotates the dbase */ static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane) { - RenderPart *pa, *best= NULL; + RenderPart *pa, *best = NULL; - *minx= re->winx; + *minx = re->winx; /* most left part of the non-rendering parts */ - for (pa= re->parts.first; pa; pa= pa->next) { - if (pa->ready==0 && pa->nr==0) { + for (pa = re->parts.first; pa; pa = pa->next) { + if (pa->ready == 0 && pa->nr == 0) { if (pa->disprect.xmin < *minx) { - best= pa; - *minx= pa->disprect.xmin; + best = pa; + *minx = pa->disprect.xmin; } } } if (best) { - float phi= panorama_pixel_rot(re); + float phi = panorama_pixel_rot(re); - R.panodxp= (re->winx - (best->disprect.xmin + best->disprect.xmax) )/2; - R.panodxv= ((viewplane->xmax-viewplane->xmin)*R.panodxp)/(float)(re->winx); + R.panodxp = (re->winx - (best->disprect.xmin + best->disprect.xmax) ) / 2; + R.panodxv = ((viewplane->xmax - viewplane->xmin) * R.panodxp) / (float)(re->winx); /* shift viewplane */ R.viewplane.xmin = viewplane->xmin + R.panodxv; @@ -721,48 +721,48 @@ static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane) copy_m4_m4(R.winmat, re->winmat); /* rotate database according to part coordinates */ - project_renderdata(re, projectverto, 1, -R.panodxp*phi, 1); - R.panosi= sin(R.panodxp*phi); - R.panoco= cos(R.panodxp*phi); + project_renderdata(re, projectverto, 1, -R.panodxp * phi, 1); + R.panosi = sin(R.panodxp * phi); + R.panoco = cos(R.panodxp * phi); } return best; } static RenderPart *find_next_part(Render *re, int minx) { - RenderPart *pa, *best= NULL; + RenderPart *pa, *best = NULL; /* long long int's needed because of overflow [#24414] */ - long long int centx=re->winx/2, centy=re->winy/2, tot=1; - long long int mindist= (long long int)re->winx * (long long int)re->winy; + long long int centx = re->winx / 2, centy = re->winy / 2, tot = 1; + long long int mindist = (long long int)re->winx * (long long int)re->winy; /* find center of rendered parts, image center counts for 1 too */ - for (pa= re->parts.first; pa; pa= pa->next) { + for (pa = re->parts.first; pa; pa = pa->next) { if (pa->ready) { - centx+= (pa->disprect.xmin+pa->disprect.xmax)/2; - centy+= (pa->disprect.ymin+pa->disprect.ymax)/2; + centx += (pa->disprect.xmin + pa->disprect.xmax) / 2; + centy += (pa->disprect.ymin + pa->disprect.ymax) / 2; tot++; } } - centx/=tot; - centy/=tot; + centx /= tot; + centy /= tot; /* closest of the non-rendering parts */ - for (pa= re->parts.first; pa; pa= pa->next) { - if (pa->ready==0 && pa->nr==0) { - long long int distx= centx - (pa->disprect.xmin+pa->disprect.xmax)/2; - long long int disty= centy - (pa->disprect.ymin+pa->disprect.ymax)/2; - distx= (long long int)sqrt(distx*distx + disty*disty); - if (distxparts.first; pa; pa = pa->next) { + if (pa->ready == 0 && pa->nr == 0) { + long long int distx = centx - (pa->disprect.xmin + pa->disprect.xmax) / 2; + long long int disty = centy - (pa->disprect.ymin + pa->disprect.ymax) / 2; + distx = (long long int)sqrt(distx * distx + disty * disty); + if (distx < mindist) { if (re->r.mode & R_PANORAMA) { - if (pa->disprect.xmin==minx) { - best= pa; - mindist= distx; + if (pa->disprect.xmin == minx) { + best = pa; + mindist = distx; } } else { - best= pa; - mindist= distx; + best = pa; + mindist = distx; } } } @@ -774,37 +774,37 @@ static void print_part_stats(Render *re, RenderPart *pa) { char str[64]; - BLI_snprintf(str, sizeof(str), "%s, Part %d-%d", re->scene->id.name+2, pa->nr, re->i.totpart); - re->i.infostr= str; + BLI_snprintf(str, sizeof(str), "%s, Part %d-%d", re->scene->id.name + 2, pa->nr, re->i.totpart); + re->i.infostr = str; re->stats_draw(re->sdh, &re->i); - re->i.infostr= NULL; + re->i.infostr = NULL; } static void threaded_tile_processor(Render *re) { ListBase threads; RenderPart *pa, *nextpa; - rctf viewplane= re->viewplane; - int rendering=1, counter= 1, drawtimer=0, hasdrawn, minx=0; + rctf viewplane = re->viewplane; + int rendering = 1, counter = 1, drawtimer = 0, hasdrawn, minx = 0; BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); /* first step; free the entire render result, make new, and/or prepare exr buffer saving */ - if (re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) { + if (re->result == NULL || !(re->r.scemode & R_PREVIEWBUTS)) { render_result_free(re->result); if (re->sss_points && render_display_draw_enabled(re)) - re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); + re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM); else if (re->r.scemode & R_FULL_SAMPLE) - re->result= render_result_new_full_sample(re, &re->fullresult, &re->disprect, 0, RR_USE_EXR); + re->result = render_result_new_full_sample(re, &re->fullresult, &re->disprect, 0, RR_USE_EXR); else - re->result= render_result_new(re, &re->disprect, 0, - (re->r.scemode & R_EXR_TILE_FILE)? RR_USE_EXR: RR_USE_MEM); + re->result = render_result_new(re, &re->disprect, 0, + (re->r.scemode & R_EXR_TILE_FILE) ? RR_USE_EXR : RR_USE_MEM); } BLI_rw_mutex_unlock(&re->resultmutex); - if (re->result==NULL) + if (re->result == NULL) return; /* warning; no return here without closing exr file */ @@ -817,32 +817,32 @@ static void threaded_tile_processor(Render *re) BLI_init_threads(&threads, do_part_thread, re->r.threads); /* assuming no new data gets added to dbase... */ - R= *re; + R = *re; /* set threadsafe break */ - R.test_break= thread_break; + R.test_break = thread_break; /* timer loop demands to sleep when no parts are left, so we enter loop with a part */ if (re->r.mode & R_PANORAMA) - nextpa= find_next_pano_slice(re, &minx, &viewplane); + nextpa = find_next_pano_slice(re, &minx, &viewplane); else - nextpa= find_next_part(re, 0); + nextpa = find_next_part(re, 0); while (rendering) { if (re->test_break(re->tbh)) PIL_sleep_ms(50); else if (nextpa && BLI_available_threads(&threads)) { - drawtimer= 0; - nextpa->nr= counter++; /* for nicest part, and for stats */ - nextpa->thread= BLI_available_thread_index(&threads); /* sample index */ + drawtimer = 0; + nextpa->nr = counter++; /* for nicest part, and for stats */ + nextpa->thread = BLI_available_thread_index(&threads); /* sample index */ BLI_insert_thread(&threads, nextpa); - nextpa= find_next_part(re, minx); + nextpa = find_next_part(re, minx); } else if (re->r.mode & R_PANORAMA) { - if (nextpa==NULL && BLI_available_threads(&threads)==re->r.threads) - nextpa= find_next_pano_slice(re, &minx, &viewplane); + if (nextpa == NULL && BLI_available_threads(&threads) == re->r.threads) + nextpa = find_next_pano_slice(re, &minx, &viewplane); else { PIL_sleep_ms(50); drawtimer++; @@ -854,9 +854,9 @@ static void threaded_tile_processor(Render *re) } /* check for ready ones to display, and if we need to continue */ - rendering= 0; - hasdrawn= 0; - for (pa= re->parts.first; pa; pa= pa->next) { + rendering = 0; + hasdrawn = 0; + for (pa = re->parts.first; pa; pa = pa->next) { if (pa->ready) { BLI_remove_thread(&threads, pa); @@ -867,27 +867,27 @@ static void threaded_tile_processor(Render *re) print_part_stats(re, pa); render_result_free_list(&pa->fullresult, pa->result); - pa->result= NULL; + pa->result = NULL; re->i.partsdone++; re->progress(re->prh, re->i.partsdone / (float)re->i.totpart); - hasdrawn= 1; + hasdrawn = 1; } } else { - rendering= 1; - if (pa->nr && pa->result && drawtimer>20) { + rendering = 1; + if (pa->nr && pa->result && drawtimer > 20) { if (render_display_draw_enabled(re)) re->display_draw(re->ddh, pa->result, &pa->result->renrect); - hasdrawn= 1; + hasdrawn = 1; } } } if (hasdrawn) - drawtimer= 0; + drawtimer = 0; /* on break, wait for all slots to get freed */ - if ( (g_break=re->test_break(re->tbh)) && BLI_available_threads(&threads)==re->r.threads) - rendering= 0; + if ( (g_break = re->test_break(re->tbh)) && BLI_available_threads(&threads) == re->r.threads) + rendering = 0; } @@ -898,11 +898,11 @@ static void threaded_tile_processor(Render *re) } /* unset threadsafety */ - g_break= 0; + g_break = 0; BLI_end_threads(&threads); freeparts(re); - re->viewplane= viewplane; /* restore viewplane, modified by pano render */ + re->viewplane = viewplane; /* restore viewplane, modified by pano render */ } /* currently only called by preview renders and envmap */ @@ -954,59 +954,59 @@ static void do_render_3d(Render *re) /* called by blur loop, accumulate RGBA key alpha */ static void addblur_rect_key(RenderResult *rr, float *rectf, float *rectf1, float blurfac) { - float mfac= 1.0f - blurfac; - int a, b, stride= 4*rr->rectx; - int len= stride*sizeof(float); + float mfac = 1.0f - blurfac; + int a, b, stride = 4 * rr->rectx; + int len = stride * sizeof(float); - for (a=0; arecty; a++) { - if (blurfac==1.0f) { + for (a = 0; a < rr->recty; a++) { + if (blurfac == 1.0f) { memcpy(rectf, rectf1, len); } else { - float *rf= rectf, *rf1= rectf1; + float *rf = rectf, *rf1 = rectf1; - for ( b= rr->rectx; b>0; b--, rf+=4, rf1+=4) { - if (rf1[3]<0.01f) - rf[3]= mfac*rf[3]; - else if (rf[3]<0.01f) { - rf[0]= rf1[0]; - rf[1]= rf1[1]; - rf[2]= rf1[2]; - rf[3]= blurfac*rf1[3]; + for (b = rr->rectx; b > 0; b--, rf += 4, rf1 += 4) { + if (rf1[3] < 0.01f) + rf[3] = mfac * rf[3]; + else if (rf[3] < 0.01f) { + rf[0] = rf1[0]; + rf[1] = rf1[1]; + rf[2] = rf1[2]; + rf[3] = blurfac * rf1[3]; } else { - rf[0]= mfac*rf[0] + blurfac*rf1[0]; - rf[1]= mfac*rf[1] + blurfac*rf1[1]; - rf[2]= mfac*rf[2] + blurfac*rf1[2]; - rf[3]= mfac*rf[3] + blurfac*rf1[3]; + rf[0] = mfac * rf[0] + blurfac * rf1[0]; + rf[1] = mfac * rf[1] + blurfac * rf1[1]; + rf[2] = mfac * rf[2] + blurfac * rf1[2]; + rf[3] = mfac * rf[3] + blurfac * rf1[3]; } } } - rectf+= stride; - rectf1+= stride; + rectf += stride; + rectf1 += stride; } } /* called by blur loop, accumulate renderlayers */ static void addblur_rect(RenderResult *rr, float *rectf, float *rectf1, float blurfac, int channels) { - float mfac= 1.0f - blurfac; - int a, b, stride= channels*rr->rectx; - int len= stride*sizeof(float); + float mfac = 1.0f - blurfac; + int a, b, stride = channels * rr->rectx; + int len = stride * sizeof(float); - for (a=0; arecty; a++) { - if (blurfac==1.0f) { + for (a = 0; a < rr->recty; a++) { + if (blurfac == 1.0f) { memcpy(rectf, rectf1, len); } else { - float *rf= rectf, *rf1= rectf1; + float *rf = rectf, *rf1 = rectf1; - for ( b= rr->rectx*channels; b>0; b--, rf++, rf1++) { - rf[0]= mfac*rf[0] + blurfac*rf1[0]; + for (b = rr->rectx * channels; b > 0; b--, rf++, rf1++) { + rf[0] = mfac * rf[0] + blurfac * rf1[0]; } } - rectf+= stride; - rectf1+= stride; + rectf += stride; + rectf1 += stride; } } @@ -1017,8 +1017,8 @@ static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float b RenderLayer *rl, *rl1; RenderPass *rpass, *rpass1; - rl1= brr->layers.first; - for (rl= rr->layers.first; rl && rl1; rl= rl->next, rl1= rl1->next) { + rl1 = brr->layers.first; + for (rl = rr->layers.first; rl && rl1; rl = rl->next, rl1 = rl1->next) { /* combined */ if (rl->rectf && rl1->rectf) { @@ -1029,8 +1029,8 @@ static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float b } /* passes are allocated in sync */ - rpass1= rl1->passes.first; - for (rpass= rl->passes.first; rpass && rpass1; rpass= rpass->next, rpass1= rpass1->next) { + rpass1 = rl1->passes.first; + for (rpass = rl->passes.first; rpass && rpass1; rpass = rpass->next, rpass1 = rpass1->next) { addblur_rect(rr, rpass->rect, rpass1->rect, blurfac, rpass->channels); } } @@ -1041,20 +1041,20 @@ static void do_render_blur_3d(Render *re) { RenderResult *rres; float blurfac; - int blur= re->r.mblur_samples; + int blur = re->r.mblur_samples; /* create accumulation render result */ - rres= render_result_new(re, &re->disprect, 0, RR_USE_MEM); + rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM); /* do the blur steps */ while (blur--) { - re->mblur_offs = re->r.blurfac*((float)(re->r.mblur_samples-blur))/(float)re->r.mblur_samples; + re->mblur_offs = re->r.blurfac * ((float)(re->r.mblur_samples - blur)) / (float)re->r.mblur_samples; - re->i.curblur= re->r.mblur_samples-blur; /* stats */ + re->i.curblur = re->r.mblur_samples - blur; /* stats */ do_render_3d(re); - blurfac= 1.0f/(float)(re->r.mblur_samples-blur); + blurfac = 1.0f / (float)(re->r.mblur_samples - blur); merge_renderresult_blur(rres, re->result, blurfac, re->r.alphamode & R_ALPHAKEY); if (re->test_break(re->tbh)) break; @@ -1063,14 +1063,14 @@ static void do_render_blur_3d(Render *re) /* swap results */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); render_result_free(re->result); - re->result= rres; + re->result = rres; BLI_rw_mutex_unlock(&re->resultmutex); re->mblur_offs = 0.0f; - re->i.curblur= 0; /* stats */ + re->i.curblur = 0; /* stats */ /* weak... the display callback wants an active renderlayer pointer... */ - re->result->renlay= render_get_active_layer(re, re->result); + re->result->renlay = render_get_active_layer(re, re->result); re->display_draw(re->ddh, re->result, NULL); } @@ -1078,16 +1078,16 @@ static void do_render_blur_3d(Render *re) /* function assumes rectf1 and rectf2 to be half size of rectf */ static void interleave_rect(RenderResult *rr, float *rectf, float *rectf1, float *rectf2, int channels) { - int a, stride= channels*rr->rectx; - int len= stride*sizeof(float); + int a, stride = channels * rr->rectx; + int len = stride * sizeof(float); - for (a=0; arecty; a+=2) { + for (a = 0; a < rr->recty; a += 2) { memcpy(rectf, rectf1, len); - rectf+= stride; - rectf1+= stride; + rectf += stride; + rectf1 += stride; memcpy(rectf, rectf2, len); - rectf+= stride; - rectf2+= stride; + rectf += stride; + rectf2 += stride; } } @@ -1097,18 +1097,18 @@ static void merge_renderresult_fields(RenderResult *rr, RenderResult *rr1, Rende RenderLayer *rl, *rl1, *rl2; RenderPass *rpass, *rpass1, *rpass2; - rl1= rr1->layers.first; - rl2= rr2->layers.first; - for (rl= rr->layers.first; rl && rl1 && rl2; rl= rl->next, rl1= rl1->next, rl2= rl2->next) { + rl1 = rr1->layers.first; + rl2 = rr2->layers.first; + for (rl = rr->layers.first; rl && rl1 && rl2; rl = rl->next, rl1 = rl1->next, rl2 = rl2->next) { /* combined */ if (rl->rectf && rl1->rectf && rl2->rectf) interleave_rect(rr, rl->rectf, rl1->rectf, rl2->rectf, 4); /* passes are allocated in sync */ - rpass1= rl1->passes.first; - rpass2= rl2->passes.first; - for (rpass= rl->passes.first; rpass && rpass1 && rpass2; rpass= rpass->next, rpass1= rpass1->next, rpass2= rpass2->next) { + rpass1 = rl1->passes.first; + rpass2 = rl2->passes.first; + for (rpass = rl->passes.first; rpass && rpass1 && rpass2; rpass = rpass->next, rpass1 = rpass1->next, rpass2 = rpass2->next) { interleave_rect(rr, rpass->rect, rpass1->rect, rpass2->rect, rpass->channels); } } @@ -1118,8 +1118,8 @@ static void merge_renderresult_fields(RenderResult *rr, RenderResult *rr1, Rende /* interleaves 2 frames */ static void do_render_fields_3d(Render *re) { - Object *camera= RE_GetCamera(re); - RenderResult *rr1, *rr2= NULL; + Object *camera = RE_GetCamera(re); + RenderResult *rr1, *rr2 = NULL; /* no render result was created, we can safely halve render y */ re->winy /= 2; @@ -1127,31 +1127,31 @@ static void do_render_fields_3d(Render *re) re->disprect.ymin /= 2; re->disprect.ymax /= 2; - re->i.curfield= 1; /* stats */ + re->i.curfield = 1; /* stats */ /* first field, we have to call camera routine for correct aspect and subpixel offset */ RE_SetCamera(re, camera); - if (re->r.mode & R_MBLUR && (re->r.scemode & R_FULL_SAMPLE)==0) + if (re->r.mode & R_MBLUR && (re->r.scemode & R_FULL_SAMPLE) == 0) do_render_blur_3d(re); else do_render_3d(re); BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - rr1= re->result; - re->result= NULL; + rr1 = re->result; + re->result = NULL; BLI_rw_mutex_unlock(&re->resultmutex); /* second field */ if (!re->test_break(re->tbh)) { - re->i.curfield= 2; /* stats */ + re->i.curfield = 2; /* stats */ re->flag |= R_SEC_FIELD; - if ((re->r.mode & R_FIELDSTILL)==0) { + if ((re->r.mode & R_FIELDSTILL) == 0) { re->field_offs = 0.5f; } RE_SetCamera(re, camera); - if (re->r.mode & R_MBLUR && (re->r.scemode & R_FULL_SAMPLE)==0) + if (re->r.mode & R_MBLUR && (re->r.scemode & R_FULL_SAMPLE) == 0) do_render_blur_3d(re); else do_render_3d(re); @@ -1159,7 +1159,7 @@ static void do_render_fields_3d(Render *re) re->field_offs = 0.0f; - rr2= re->result; + rr2 = re->result; } /* allocate original height new buffers */ @@ -1169,7 +1169,7 @@ static void do_render_fields_3d(Render *re) re->disprect.ymax *= 2; BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); + re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM); if (rr2) { if (re->r.mode & R_ODDFIELD) @@ -1182,10 +1182,10 @@ static void do_render_fields_3d(Render *re) render_result_free(rr1); - re->i.curfield= 0; /* stats */ + re->i.curfield = 0; /* stats */ /* weak... the display callback wants an active renderlayer pointer... */ - re->result->renlay= render_get_active_layer(re, re->result); + re->result->renlay = render_get_active_layer(re, re->result); BLI_rw_mutex_unlock(&re->resultmutex); @@ -1195,11 +1195,11 @@ static void do_render_fields_3d(Render *re) /* main render routine, no compositing */ static void do_render_fields_blur_3d(Render *re) { - Object *camera= RE_GetCamera(re); + Object *camera = RE_GetCamera(re); /* also check for camera here */ if (camera == NULL) { printf("ERROR: Cannot render, no camera\n"); - G.afbreek= 1; + G.afbreek = 1; return; } @@ -1208,7 +1208,7 @@ static void do_render_fields_blur_3d(Render *re) if (re->r.mode & R_FIELDS) do_render_fields_3d(re); - else if (re->r.mode & R_MBLUR && (re->r.scemode & R_FULL_SAMPLE)==0) + else if (re->r.mode & R_MBLUR && (re->r.scemode & R_FULL_SAMPLE) == 0) do_render_blur_3d(re); else do_render_3d(re); @@ -1216,30 +1216,30 @@ static void do_render_fields_blur_3d(Render *re) /* when border render, check if we have to insert it in black */ if (re->result) { if (re->r.mode & R_BORDER) { - if ((re->r.mode & R_CROP)==0) { + if ((re->r.mode & R_CROP) == 0) { RenderResult *rres; BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); /* sub-rect for merge call later on */ - re->result->tilerect= re->disprect; + re->result->tilerect = re->disprect; /* this copying sequence could become function? */ /* weak is: it chances disprect from border */ re->disprect.xmin = re->disprect.ymin = 0; re->disprect.xmax = re->winx; re->disprect.ymax = re->winy; - re->rectx= re->winx; - re->recty= re->winy; + re->rectx = re->winx; + re->recty = re->winy; - rres= render_result_new(re, &re->disprect, 0, RR_USE_MEM); + rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM); render_result_merge(rres, re->result); render_result_free(re->result); - re->result= rres; + re->result = rres; /* weak... the display callback wants an active renderlayer pointer... */ - re->result->renlay= render_get_active_layer(re, re->result); + re->result->renlay = render_get_active_layer(re, re->result); BLI_rw_mutex_unlock(&re->resultmutex); @@ -1248,8 +1248,8 @@ static void do_render_fields_blur_3d(Render *re) } else { /* set offset (again) for use in compositor, disprect was manipulated. */ - re->result->xof= 0; - re->result->yof= 0; + re->result->xof = 0; + re->result->yof = 0; } } } @@ -1261,37 +1261,37 @@ static void do_render_fields_blur_3d(Render *re) */ static void render_scene(Render *re, Scene *sce, int cfra) { - Render *resc= RE_NewRender(sce->id.name); - int winx= re->winx, winy= re->winy; + Render *resc = RE_NewRender(sce->id.name); + int winx = re->winx, winy = re->winy; - sce->r.cfra= cfra; + sce->r.cfra = cfra; BKE_scene_camera_switch_update(sce); /* exception: scene uses own size (unfinished code) */ if (0) { - winx= (sce->r.size*sce->r.xsch)/100; - winy= (sce->r.size*sce->r.ysch)/100; + winx = (sce->r.size * sce->r.xsch) / 100; + winy = (sce->r.size * sce->r.ysch) / 100; } /* initial setup */ RE_InitState(resc, re, &sce->r, NULL, winx, winy, &re->disprect); /* still unsure entity this... */ - resc->main= re->main; - resc->scene= sce; - resc->lay= sce->lay; + resc->main = re->main; + resc->scene = sce; + resc->lay = sce->lay; /* ensure scene has depsgraph, base flags etc OK */ BKE_scene_set_background(re->main, sce); /* copy callbacks */ - resc->display_draw= re->display_draw; - resc->ddh= re->ddh; - resc->test_break= re->test_break; - resc->tbh= re->tbh; - resc->stats_draw= re->stats_draw; - resc->sdh= re->sdh; + resc->display_draw = re->display_draw; + resc->ddh = re->ddh; + resc->test_break = re->test_break; + resc->tbh = re->tbh; + resc->stats_draw = re->stats_draw; + resc->sdh = re->sdh; do_render_fields_blur_3d(resc); } @@ -1299,16 +1299,16 @@ static void render_scene(Render *re, Scene *sce, int cfra) /* helper call to detect if this scene needs a render, or if there's a any render layer to render */ static int composite_needs_render(Scene *sce, int this_scene) { - bNodeTree *ntree= sce->nodetree; + bNodeTree *ntree = sce->nodetree; bNode *node; - if (ntree==NULL) return 1; + if (ntree == NULL) return 1; if (sce->use_nodes == FALSE) return 1; - if ((sce->r.scemode & R_DOCOMP)==0) return 1; + if ((sce->r.scemode & R_DOCOMP) == 0) return 1; - for (node= ntree->nodes.first; node; node= node->next) { - if (node->type==CMP_NODE_R_LAYERS) - if (this_scene==0 || node->id==NULL || node->id==&sce->id) + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_R_LAYERS) + if (this_scene == 0 || node->id == NULL || node->id == &sce->id) return 1; } return 0; @@ -1319,17 +1319,17 @@ static void tag_scenes_for_render(Render *re) bNode *node; Scene *sce; - for (sce= re->main->scene.first; sce; sce= sce->id.next) + for (sce = re->main->scene.first; sce; sce = sce->id.next) sce->id.flag &= ~LIB_DOIT; if (RE_GetCamera(re) && composite_needs_render(re->scene, 1)) re->scene->id.flag |= LIB_DOIT; - if (re->scene->nodetree==NULL) return; + if (re->scene->nodetree == NULL) return; /* check for render-layers nodes using other scenes, we tag them LIB_DOIT */ - for (node= re->scene->nodetree->nodes.first; node; node= node->next) { - if (node->type==CMP_NODE_R_LAYERS) { + for (node = re->scene->nodetree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_R_LAYERS) { if (node->id) { if (node->id != (ID *)re->scene) node->id->flag |= LIB_DOIT; @@ -1342,23 +1342,23 @@ static void tag_scenes_for_render(Render *re) static void ntree_render_scenes(Render *re) { bNode *node; - int cfra= re->scene->r.cfra; - int restore_scene= 0; + int cfra = re->scene->r.cfra; + int restore_scene = 0; - if (re->scene->nodetree==NULL) return; + if (re->scene->nodetree == NULL) return; tag_scenes_for_render(re); /* now foreach render-result node tagged we do a full render */ /* results are stored in a way compisitor will find it */ - for (node= re->scene->nodetree->nodes.first; node; node= node->next) { - if (node->type==CMP_NODE_R_LAYERS) { + for (node = re->scene->nodetree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_R_LAYERS) { if (node->id && node->id != (ID *)re->scene) { if (node->id->flag & LIB_DOIT) { - Scene *scene = (Scene*)node->id; + Scene *scene = (Scene *)node->id; render_scene(re, scene, cfra); - restore_scene= (scene != re->scene); + restore_scene = (scene != re->scene); node->id->flag &= ~LIB_DOIT; nodeUpdate(re->scene->nodetree, node); @@ -1375,9 +1375,9 @@ static void ntree_render_scenes(Render *re) /* bad call... need to think over proper method still */ static void render_composit_stats(void *UNUSED(arg), char *str) { - R.i.infostr= str; + R.i.infostr = str; R.stats_draw(R.sdh, &R.i); - R.i.infostr= NULL; + R.i.infostr = NULL; } @@ -1389,33 +1389,33 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) /* interaction callbacks */ if (ntree) { - ntree->stats_draw= render_composit_stats; - ntree->test_break= re->test_break; - ntree->progress= re->progress; - ntree->sdh= re->sdh; - ntree->tbh= re->tbh; - ntree->prh= re->prh; + ntree->stats_draw = render_composit_stats; + ntree->test_break = re->test_break; + ntree->progress = re->progress; + ntree->sdh = re->sdh; + ntree->tbh = re->tbh; + ntree->prh = re->prh; } /* filtmask needs it */ - R= *re; + R = *re; /* we accumulate in here */ - rectf= MEM_mapallocN(re->rectx*re->recty*sizeof(float)*4, "fullsample rgba"); + rectf = MEM_mapallocN(re->rectx * re->recty * sizeof(float) * 4, "fullsample rgba"); - for (sample=0; sampler.osa; sample++) { + for (sample = 0; sample < re->r.osa; sample++) { Render *re1; RenderResult rres; int x, y, mask; /* enable full sample print */ - R.i.curfsa= sample+1; + R.i.curfsa = sample + 1; /* set all involved renders on the samplebuffers (first was done by render itself, but needs tagged) */ /* also function below assumes this */ tag_scenes_for_render(re); - for (re1= RenderGlobal.renderlist.first; re1; re1= re1->next) { + for (re1 = RenderGlobal.renderlist.first; re1; re1 = re1->next) { if (re1->scene->id.flag & LIB_DOIT) { if (re1->r.scemode & R_FULL_SAMPLE) { if (sample) { @@ -1433,25 +1433,25 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) ntreeCompositTagRender(re->scene); ntreeCompositTagAnimated(ntree); - ntreeCompositExecTree(ntree, &re->r, 1, G.background==0); + ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0); } /* ensure we get either composited result or the active layer */ RE_AcquireResultImage(re, &rres); /* accumulate with filter, and clip */ - mask= (1<recty; y++) { - float *rf= rectf + 4*y*re->rectx; - float *col= rres.rectf + 4*y*re->rectx; + for (y = 0; y < re->recty; y++) { + float *rf = rectf + 4 * y * re->rectx; + float *col = rres.rectf + 4 * y * re->rectx; - for (x=0; xrectx; x++, rf+=4, col+=4) { + for (x = 0; x < re->rectx; x++, rf += 4, col += 4) { /* clamping to 1.0 is needed for correct AA */ - if (col[0]<0.0f) col[0]=0.0f; else if (col[0] > 1.0f) col[0]= 1.0f; - if (col[1]<0.0f) col[1]=0.0f; else if (col[1] > 1.0f) col[1]= 1.0f; - if (col[2]<0.0f) col[2]=0.0f; else if (col[2] > 1.0f) col[2]= 1.0f; + if (col[0] < 0.0f) col[0] = 0.0f; else if (col[0] > 1.0f) col[0] = 1.0f; + if (col[1] < 0.0f) col[1] = 0.0f; else if (col[1] > 1.0f) col[1] = 1.0f; + if (col[2] < 0.0f) col[2] = 0.0f; else if (col[2] > 1.0f) col[2] = 1.0f; add_filt_fmask_coord(filt, col, rf, re->rectx, re->recty, x, y); } @@ -1460,9 +1460,9 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) RE_ReleaseResultImage(re); /* show stuff */ - if (sample!=re->osa-1) { + if (sample != re->osa - 1) { /* weak... the display callback wants an active renderlayer pointer... */ - re->result->renlay= render_get_active_layer(re, re->result); + re->result->renlay = render_get_active_layer(re, re->result); re->display_draw(re->ddh, re->result, NULL); } @@ -1472,19 +1472,19 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) /* clear interaction callbacks */ if (ntree) { - ntree->stats_draw= NULL; - ntree->test_break= NULL; - ntree->progress= NULL; - ntree->tbh= ntree->sdh= ntree->prh= NULL; + ntree->stats_draw = NULL; + ntree->test_break = NULL; + ntree->progress = NULL; + ntree->tbh = ntree->sdh = ntree->prh = NULL; } /* disable full sample print */ - R.i.curfsa= 0; + R.i.curfsa = 0; BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if (re->result->rectf) MEM_freeN(re->result->rectf); - re->result->rectf= rectf; + re->result->rectf = rectf; BLI_rw_mutex_unlock(&re->resultmutex); } @@ -1495,24 +1495,24 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) bNode *node; /* default start situation */ - G.afbreek= 0; + G.afbreek = 0; - re->main= bmain; - re->scene= sce; + re->main = bmain; + re->scene = sce; /* first call RE_ReadRenderResult on every renderlayer scene. this creates Render structs */ /* tag scenes unread */ - for (scene= re->main->scene.first; scene; scene= scene->id.next) + for (scene = re->main->scene.first; scene; scene = scene->id.next) scene->id.flag |= LIB_DOIT; - for (node= ntree->nodes.first; node; node= node->next) { - if (node->type==CMP_NODE_R_LAYERS) { - Scene *nodescene= (Scene *)node->id; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_R_LAYERS) { + Scene *nodescene = (Scene *)node->id; - if (nodescene==NULL) nodescene= sce; + if (nodescene == NULL) nodescene = sce; if (nodescene->id.flag & LIB_DOIT) { - nodescene->r.mode |= R_OSA; /* render struct needs tables */ + nodescene->r.mode |= R_OSA; /* render struct needs tables */ RE_ReadRenderResult(sce, nodescene); nodescene->id.flag &= ~LIB_DOIT; } @@ -1535,8 +1535,8 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) /* returns fully composited render-result on given time step (in RenderData) */ static void do_render_composite_fields_blur_3d(Render *re) { - bNodeTree *ntree= re->scene->nodetree; - int update_newframe=0; + bNodeTree *ntree = re->scene->nodetree; + int update_newframe = 0; /* INIT seeding, compositor can use random texture */ BLI_srandom(re->r.cfra); @@ -1552,7 +1552,7 @@ static void do_render_composite_fields_blur_3d(Render *re) BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); render_result_free(re->result); - re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); + re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM); BLI_rw_mutex_unlock(&re->resultmutex); @@ -1576,20 +1576,20 @@ static void do_render_composite_fields_blur_3d(Render *re) if (ntree && re->scene->use_nodes && re->r.scemode & R_DOCOMP) { /* checks if there are render-result nodes that need scene */ - if ((re->r.scemode & R_SINGLE_LAYER)==0) + if ((re->r.scemode & R_SINGLE_LAYER) == 0) ntree_render_scenes(re); if (!re->test_break(re->tbh)) { - ntree->stats_draw= render_composit_stats; - ntree->test_break= re->test_break; - ntree->progress= re->progress; - ntree->sdh= re->sdh; - ntree->tbh= re->tbh; - ntree->prh= re->prh; + ntree->stats_draw = render_composit_stats; + ntree->test_break = re->test_break; + ntree->progress = re->progress; + ntree->sdh = re->sdh; + ntree->tbh = re->tbh; + ntree->prh = re->prh; /* in case it was never initialized */ - R.sdh= re->sdh; - R.stats_draw= re->stats_draw; + R.sdh = re->sdh; + R.stats_draw = re->stats_draw; if (update_newframe) BKE_scene_update_for_newframe(re->main, re->scene, re->lay); @@ -1597,13 +1597,13 @@ static void do_render_composite_fields_blur_3d(Render *re) if (re->r.scemode & R_FULL_SAMPLE) do_merge_fullsample(re, ntree); else { - ntreeCompositExecTree(ntree, &re->r, 1, G.background==0); + ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0); } - ntree->stats_draw= NULL; - ntree->test_break= NULL; - ntree->progress= NULL; - ntree->tbh= ntree->sdh= ntree->prh= NULL; + ntree->stats_draw = NULL; + ntree->test_break = NULL; + ntree->progress = NULL; + ntree->tbh = ntree->sdh = ntree->prh = NULL; } } else if (re->r.scemode & R_FULL_SAMPLE) @@ -1611,7 +1611,7 @@ static void do_render_composite_fields_blur_3d(Render *re) } /* weak... the display callback wants an active renderlayer pointer... */ - re->result->renlay= render_get_active_layer(re, re->result); + re->result->renlay = render_get_active_layer(re, re->result); re->display_draw(re->ddh, re->result, NULL); } @@ -1635,7 +1635,7 @@ int RE_seq_render_active(Scene *scene, RenderData *rd) if (!(rd->scemode & R_DOSEQ) || !ed || !ed->seqbase.first) return 0; - for (seq= ed->seqbase.first; seq; seq= seq->next) { + for (seq = ed->seqbase.first; seq; seq = seq->next) { if (seq->type != SEQ_TYPE_SOUND_RAM) return 1; } @@ -1643,7 +1643,7 @@ int RE_seq_render_active(Scene *scene, RenderData *rd) return 0; } -static void do_render_seq(Render * re) +static void do_render_seq(Render *re) { static int recurs_depth = 0; struct ImBuf *ibuf; @@ -1651,26 +1651,26 @@ static void do_render_seq(Render * re) int cfra = re->r.cfra; SeqRenderData context; - re->i.cfra= cfra; + re->i.cfra = cfra; - if (recurs_depth==0) { + if (recurs_depth == 0) { /* otherwise sequencer animation isn't updated */ BKE_animsys_evaluate_all_animation(re->main, re->scene, (float)cfra); // XXX, was BKE_scene_frame_get(re->scene) } recurs_depth++; - if ((re->r.mode & R_BORDER) && (re->r.mode & R_CROP)==0) { + if ((re->r.mode & R_BORDER) && (re->r.mode & R_CROP) == 0) { /* if border rendering is used and cropping is disabled, final buffer should * be as large as the whole frame */ context = seq_new_render_data(re->main, re->scene, - re->winx, re->winy, - 100); + re->winx, re->winy, + 100); } else { context = seq_new_render_data(re->main, re->scene, - re->result->rectx, re->result->recty, - 100); + re->result->rectx, re->result->recty, + 100); } ibuf = give_ibuf_seq(context, cfra, 0); @@ -1686,7 +1686,7 @@ static void do_render_seq(Render * re) render_result_rect_from_ibuf(rr, &re->r, ibuf); if (recurs_depth == 0) { /* with nested scenes, only free on toplevel... */ - Editing * ed = re->scene->ed; + Editing *ed = re->scene->ed; if (ed) free_imbuf_seq(re->scene, &ed->seqbase, TRUE, TRUE); } @@ -1703,8 +1703,8 @@ static void do_render_seq(Render * re) re->r.scemode |= R_DOSEQ; /* set overall progress of sequence rendering */ - if (re->r.efra!=re->r.sfra) - re->progress(re->prh, (float)(cfra-re->r.sfra) / (re->r.efra-re->r.sfra)); + if (re->r.efra != re->r.sfra) + re->progress(re->prh, (float)(cfra - re->r.sfra) / (re->r.efra - re->r.sfra)); else re->progress(re->prh, 1.0f); } @@ -1716,7 +1716,7 @@ static void do_render_all_options(Render *re) { BKE_scene_camera_switch_update(re->scene); - re->i.starttime= PIL_check_seconds_timer(); + re->i.starttime = PIL_check_seconds_timer(); /* ensure no images are in memory from previous animated sequences */ BKE_image_all_free_anim_ibufs(re->r.cfra); @@ -1736,7 +1736,7 @@ static void do_render_all_options(Render *re) do_render_composite_fields_blur_3d(re); } - re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime; + re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime; re->stats_draw(re->sdh, &re->i); @@ -1749,16 +1749,16 @@ static void do_render_all_options(Render *re) static int check_valid_camera(Scene *scene, Object *camera_override) { - int check_comp= 1; + int check_comp = 1; if (camera_override == NULL && scene->camera == NULL) - scene->camera= BKE_scene_camera_find(scene); + scene->camera = BKE_scene_camera_find(scene); - if (scene->r.scemode&R_DOSEQ) { + if (scene->r.scemode & R_DOSEQ) { if (scene->ed) { - Sequence *seq= scene->ed->seqbase.first; + Sequence *seq = scene->ed->seqbase.first; - check_comp= 0; + check_comp = 0; while (seq) { if (seq->type == SEQ_TYPE_SCENE && seq->scene) { @@ -1766,7 +1766,7 @@ static int check_valid_camera(Scene *scene, Object *camera_override) if (!seq->scene->camera && !BKE_scene_camera_find(seq->scene)) { if (seq->scene == scene) { /* for current scene camera could be unneeded due to compisite nodes */ - check_comp= 1; + check_comp = 1; } else { /* for other scenes camera is necessary */ @@ -1776,18 +1776,18 @@ static int check_valid_camera(Scene *scene, Object *camera_override) } } - seq= seq->next; + seq = seq->next; } } } if (check_comp) { /* no sequencer or sequencer depends on compositor */ - if (scene->r.scemode&R_DOCOMP && scene->use_nodes) { - bNode *node= scene->nodetree->nodes.first; + if (scene->r.scemode & R_DOCOMP && scene->use_nodes) { + bNode *node = scene->nodetree->nodes.first; while (node) { if (node->type == CMP_NODE_R_LAYERS) { - Scene *sce= node->id ? (Scene*)node->id : scene; + Scene *sce = node->id ? (Scene *)node->id : scene; if (!sce->camera && !BKE_scene_camera_find(sce)) { /* all render layers nodes need camera */ @@ -1795,7 +1795,7 @@ static int check_valid_camera(Scene *scene, Object *camera_override) } } - node= node->next; + node = node->next; } } else { @@ -1841,12 +1841,12 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r } } - if (scene->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE)) { + if (scene->r.scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE)) { char str[FILE_MAX]; render_result_exr_file_path(scene, 0, str); - if (BLI_file_is_writable(str)==0) { + if (BLI_file_is_writable(str) == 0) { BKE_report(reports, RPT_ERROR, "Can not save render buffers, check the temp default path"); return 0; } @@ -1859,7 +1859,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r } else - scene->r.scemode &= ~R_FULL_SAMPLE; /* clear to be sure */ + scene->r.scemode &= ~R_FULL_SAMPLE; /* clear to be sure */ if (scene->r.scemode & R_DOCOMP) { if (scene->use_nodes) { @@ -1874,7 +1874,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r } if (scene->r.scemode & R_FULL_SAMPLE) { - if (composite_needs_render(scene, 0)==0) { + if (composite_needs_render(scene, 0) == 0) { BKE_report(reports, RPT_ERROR, "Full Sample AA not supported without 3d rendering"); return 0; } @@ -1882,7 +1882,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r } } - /* check valid camera, without camera render is OK (compo, seq) */ + /* check valid camera, without camera render is OK (compo, seq) */ if (!check_valid_camera(scene, camera_override)) { BKE_report(reports, RPT_ERROR, "No camera"); return 0; @@ -1901,15 +1901,15 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r /* layer flag tests */ if (scene->r.scemode & R_SINGLE_LAYER) { - srl= BLI_findlink(&scene->r.layers, scene->r.actlay); + srl = BLI_findlink(&scene->r.layers, scene->r.actlay); /* force layer to be enabled */ srl->layflag &= ~SCE_LAY_DISABLE; } - for (srl= scene->r.layers.first; srl; srl= srl->next) + for (srl = scene->r.layers.first; srl; srl = srl->next) if (!(srl->layflag & SCE_LAY_DISABLE)) break; - if (srl==NULL) { + if (srl == NULL) { BKE_report(reports, RPT_ERROR, "All RenderLayers are disabled"); return 0; } @@ -1919,17 +1919,17 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r static void validate_render_settings(Render *re) { - if (re->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE)) { + if (re->r.scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE)) { /* no osa + fullsample won't work... */ - if (re->r.osa==0) + if (re->r.osa == 0) re->r.scemode &= ~R_FULL_SAMPLE; } - else re->r.scemode &= ~R_FULL_SAMPLE; /* clear to be sure */ + else re->r.scemode &= ~R_FULL_SAMPLE; /* clear to be sure */ if (RE_engine_is_external(re)) { /* not supported yet */ - re->r.scemode &= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE); - re->r.mode &= ~(R_FIELDS|R_MBLUR); + re->r.scemode &= ~(R_EXR_TILE_FILE | R_FULL_SAMPLE); + re->r.mode &= ~(R_FIELDS | R_MBLUR); } } @@ -1960,16 +1960,16 @@ static int render_initialize_from_main(Render *re, Main *bmain, Scene *scene, Sc * r.border is the clipping rect */ /* calculate actual render result and display size */ - winx= (scene->r.size*scene->r.xsch)/100; - winy= (scene->r.size*scene->r.ysch)/100; + winx = (scene->r.size * scene->r.xsch) / 100; + winy = (scene->r.size * scene->r.ysch) / 100; /* we always render smaller part, inserting it in larger image is compositor bizz, it uses disprect for it */ if (scene->r.mode & R_BORDER) { - disprect.xmin = scene->r.border.xmin*winx; - disprect.xmax = scene->r.border.xmax*winx; + disprect.xmin = scene->r.border.xmin * winx; + disprect.xmax = scene->r.border.xmax * winx; - disprect.ymin = scene->r.border.ymin*winy; - disprect.ymax = scene->r.border.ymax*winy; + disprect.ymin = scene->r.border.ymin * winy; + disprect.ymax = scene->r.border.ymax * winy; } else { disprect.xmin = disprect.ymin = 0; @@ -1977,14 +1977,14 @@ static int render_initialize_from_main(Render *re, Main *bmain, Scene *scene, Sc disprect.ymax = winy; } - re->main= bmain; - re->scene= scene; - re->camera_override= camera_override; - re->lay= lay; + re->main = bmain; + re->scene = scene; + re->camera_override = camera_override; + re->lay = lay; /* not too nice, but it survives anim-border render */ if (anim) { - re->disprect= disprect; + re->disprect = disprect; return 1; } @@ -2024,16 +2024,16 @@ static int render_initialize_from_main(Render *re, Main *bmain, Scene *scene, Sc void RE_SetReports(Render *re, ReportList *reports) { - re->reports= reports; + re->reports = reports; } /* general Blender frame render call */ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *srl, Object *camera_override, unsigned int lay, int frame, const short write_still) { /* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */ - G.rendering= 1; + G.rendering = 1; - scene->r.cfra= frame; + scene->r.cfra = frame; if (render_initialize_from_main(re, bmain, scene, srl, camera_override, lay, 0, 0)) { MEM_reset_peak_memory(); @@ -2062,15 +2062,15 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr BLI_callback_exec(re->main, (ID *)scene, G.afbreek ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE); /* UGLY WARNING */ - G.rendering= 0; + G.rendering = 0; } static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const char *name_override) { char name[FILE_MAX]; RenderResult rres; - Object *camera= RE_GetCamera(re); - int ok= 1; + Object *camera = RE_GetCamera(re); + int ok = 1; RE_AcquireResultImage(re, &rres); @@ -2080,13 +2080,13 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie unsigned int *rect32 = (unsigned int *)rres.rect32; /* note; the way it gets 32 bits rects is weak... */ if (rres.rect32 == NULL) { - rect32 = MEM_mapallocN(sizeof(int)*rres.rectx*rres.recty, "temp 32 bits rect"); + rect32 = MEM_mapallocN(sizeof(int) * rres.rectx * rres.recty, "temp 32 bits rect"); RE_ResultGet32(re, rect32); do_free = TRUE; } - ok= mh->append_movie(&re->r, scene->r.sfra, scene->r.cfra, (int *)rect32, - rres.rectx, rres.recty, re->reports); + ok = mh->append_movie(&re->r, scene->r.sfra, scene->r.cfra, (int *)rect32, + rres.rectx, rres.recty, re->reports); if (do_free) { MEM_freeN(rect32); } @@ -2098,36 +2098,36 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie else BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, TRUE); - if (re->r.im_format.imtype==R_IMF_IMTYPE_MULTILAYER) { + if (re->r.im_format.imtype == R_IMF_IMTYPE_MULTILAYER) { if (re->result) { RE_WriteRenderResult(re->reports, re->result, name, scene->r.im_format.exr_codec); printf("Saved: %s", name); } } else { - ImBuf *ibuf= render_result_rect_to_ibuf(&rres, &scene->r); + ImBuf *ibuf = render_result_rect_to_ibuf(&rres, &scene->r); - ok= BKE_imbuf_write_stamp(scene, camera, ibuf, name, &scene->r.im_format); + ok = BKE_imbuf_write_stamp(scene, camera, ibuf, name, &scene->r.im_format); - if (ok==0) { + if (ok == 0) { printf("Render error: cannot save %s\n", name); } else printf("Saved: %s", name); /* optional preview images for exr */ - if (ok && scene->r.im_format.imtype==R_IMF_IMTYPE_OPENEXR && (scene->r.im_format.flag & R_IMF_FLAG_PREVIEW_JPG)) { - ImageFormatData imf= scene->r.im_format; - imf.imtype= R_IMF_IMTYPE_JPEG90; + if (ok && scene->r.im_format.imtype == R_IMF_IMTYPE_OPENEXR && (scene->r.im_format.flag & R_IMF_FLAG_PREVIEW_JPG)) { + ImageFormatData imf = scene->r.im_format; + imf.imtype = R_IMF_IMTYPE_JPEG90; if (BLI_testextensie(name, ".exr")) - name[strlen(name)-4]= 0; + name[strlen(name) - 4] = 0; BKE_add_image_extension(name, R_IMF_IMTYPE_JPEG90); - ibuf->planes= 24; + ibuf->planes = 24; BKE_imbuf_write_stamp(scene, camera, ibuf, name, &imf); printf("\nSaved: %s", name); } - /* imbuf knows which rects are not part of ibuf */ + /* imbuf knows which rects are not part of ibuf */ IMB_freeImBuf(ibuf); } } @@ -2148,9 +2148,9 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie /* saves images to disk */ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_override, unsigned int lay, int sfra, int efra, int tfra) { - bMovieHandle *mh= BKE_movie_handle_get(scene->r.im_format.imtype); - int cfrao= scene->r.cfra; - int nfra, totrendered= 0, totskipped= 0; + bMovieHandle *mh = BKE_movie_handle_get(scene->r.im_format.imtype); + int cfrao = scene->r.cfra; + int nfra, totrendered = 0, totskipped = 0; /* do not fully call for each frame, it initializes & pops output window */ if (!render_initialize_from_main(re, bmain, scene, NULL, camera_override, lay, 0, 1)) @@ -2158,13 +2158,13 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ /* is also set by caller renderwin.c */ - G.rendering= 1; + G.rendering = 1; re->flag |= R_ANIMATION; if (BKE_imtype_is_movie(scene->r.im_format.imtype)) if (!mh->start_movie(scene, &re->r, re->rectx, re->recty, re->reports)) - G.afbreek= 1; + G.afbreek = 1; if (mh->get_next_frame) { while (!(G.afbreek == 1)) { @@ -2179,7 +2179,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri if (re->test_break(re->tbh) == 0) { if (!do_write_image_or_movie(re, bmain, scene, mh, NULL)) - G.afbreek= 1; + G.afbreek = 1; } if (G.afbreek == 0) { @@ -2188,18 +2188,18 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri } else { if (re->test_break(re->tbh)) - G.afbreek= 1; + G.afbreek = 1; } } } else { - for (nfra= sfra, scene->r.cfra= sfra; scene->r.cfra<=efra; scene->r.cfra++) { + for (nfra = sfra, scene->r.cfra = sfra; scene->r.cfra <= efra; scene->r.cfra++) { char name[FILE_MAX]; /* only border now, todo: camera lens. (ton) */ render_initialize_from_main(re, bmain, scene, NULL, camera_override, lay, 1, 0); - if (nfra!=scene->r.cfra) { + if (nfra != scene->r.cfra) { /* * Skip this frame, but update for physics and particles system. * From convertblender.c: @@ -2208,15 +2208,15 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri unsigned int updatelay; if (re->lay & 0xFF000000) - updatelay= re->lay & 0xFF000000; + updatelay = re->lay & 0xFF000000; else - updatelay= re->lay; + updatelay = re->lay; BKE_scene_update_for_newframe(bmain, scene, updatelay); continue; } else - nfra+= tfra; + nfra += tfra; /* Touch/NoOverwrite options are only valid for image's */ if (BKE_imtype_is_movie(scene->r.im_format.imtype) == 0) { @@ -2234,7 +2234,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri } } - re->r.cfra= scene->r.cfra; /* weak.... */ + re->r.cfra = scene->r.cfra; /* weak.... */ /* run callbacs before rendering, before the scene is updated */ BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE); @@ -2246,12 +2246,12 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri if (re->test_break(re->tbh) == 0) { if (!G.afbreek) if (!do_write_image_or_movie(re, bmain, scene, mh, NULL)) - G.afbreek= 1; + G.afbreek = 1; } else - G.afbreek= 1; + G.afbreek = 1; - if (G.afbreek==1) { + if (G.afbreek == 1) { /* remove touched file */ if (BKE_imtype_is_movie(scene->r.im_format.imtype) == 0) { if (scene->r.mode & R_TOUCH && BLI_exists(name) && BLI_file_size(name) == 0) { @@ -2262,7 +2262,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri break; } - if (G.afbreek==0) { + if (G.afbreek == 0) { BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */ } } @@ -2275,14 +2275,14 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri if (totskipped && totrendered == 0) BKE_report(re->reports, RPT_INFO, "No frames rendered, skipped to not overwrite"); - scene->r.cfra= cfrao; + scene->r.cfra = cfrao; re->flag &= ~R_ANIMATION; BLI_callback_exec(re->main, (ID *)scene, G.afbreek ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE); /* UGLY WARNING */ - G.rendering= 0; + G.rendering = 0; } void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) @@ -2290,8 +2290,8 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) Object *camera; int winx, winy; - winx= (sce->r.size*sce->r.xsch)/100; - winy= (sce->r.size*sce->r.ysch)/100; + winx = (sce->r.size * sce->r.xsch) / 100; + winy = (sce->r.size * sce->r.ysch) / 100; RE_InitState(re, NULL, &sce->r, NULL, winx, winy, NULL); @@ -2315,16 +2315,16 @@ int RE_ReadRenderResult(Scene *scene, Scene *scenode) rcti disprect; /* calculate actual render result and display size */ - winx= (scene->r.size*scene->r.xsch)/100; - winy= (scene->r.size*scene->r.ysch)/100; + winx = (scene->r.size * scene->r.xsch) / 100; + winy = (scene->r.size * scene->r.ysch) / 100; /* only in movie case we render smaller part */ if (scene->r.mode & R_BORDER) { - disprect.xmin = scene->r.border.xmin*winx; - disprect.xmax = scene->r.border.xmax*winx; + disprect.xmin = scene->r.border.xmin * winx; + disprect.xmax = scene->r.border.xmax * winx; - disprect.ymin = scene->r.border.ymin*winy; - disprect.ymax = scene->r.border.ymax*winy; + disprect.ymin = scene->r.border.ymin * winy; + disprect.ymax = scene->r.border.ymax * winy; } else { disprect.xmin = disprect.ymin = 0; @@ -2333,17 +2333,17 @@ int RE_ReadRenderResult(Scene *scene, Scene *scenode) } if (scenode) - scene= scenode; + scene = scenode; /* get render: it can be called from UI with draw callbacks */ - re= RE_GetRender(scene->id.name); - if (re==NULL) - re= RE_NewRender(scene->id.name); + re = RE_GetRender(scene->id.name); + if (re == NULL) + re = RE_NewRender(scene->id.name); RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect); - re->scene= scene; + re->scene = scene; BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - success= render_result_exr_file_read(re, 0); + success = render_result_exr_file_read(re, 0); BLI_rw_mutex_unlock(&re->resultmutex); return success; @@ -2351,11 +2351,11 @@ int RE_ReadRenderResult(Scene *scene, Scene *scenode) void RE_set_max_threads(int threads) { - if (threads==0) { + if (threads == 0) { RenderGlobal.threads = BLI_system_thread_count(); } - else if (threads>=1 && threads<=BLENDER_MAX_THREADS) { - RenderGlobal.threads= threads; + else if (threads >= 1 && threads <= BLENDER_MAX_THREADS) { + RenderGlobal.threads = threads; } else { printf("Error, threads has to be in range 0-%d\n", BLENDER_MAX_THREADS); @@ -2365,9 +2365,9 @@ void RE_set_max_threads(int threads) void RE_init_threadcount(Render *re) { if (RenderGlobal.threads >= 1) { /* only set as an arg in background mode */ - re->r.threads= MIN2(RenderGlobal.threads, BLENDER_MAX_THREADS); + re->r.threads = MIN2(RenderGlobal.threads, BLENDER_MAX_THREADS); } - else if ((re->r.mode & R_FIXED_THREADS)==0 || RenderGlobal.threads == 0) { /* Automatic threads */ + else if ((re->r.mode & R_FIXED_THREADS) == 0 || RenderGlobal.threads == 0) { /* Automatic threads */ re->r.threads = BLI_system_thread_count(); } } @@ -2380,23 +2380,23 @@ void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char if (ibuf && (ibuf->rect || ibuf->rect_float)) { if (ibuf->x == layer->rectx && ibuf->y == layer->recty) { - if (ibuf->rect_float==NULL) + if (ibuf->rect_float == NULL) IMB_float_from_rect(ibuf); - memcpy(layer->rectf, ibuf->rect_float, sizeof(float)*4*layer->rectx*layer->recty); + memcpy(layer->rectf, ibuf->rect_float, sizeof(float) * 4 * layer->rectx * layer->recty); } else { if ((ibuf->x - x >= layer->rectx) && (ibuf->y - y >= layer->recty)) { ImBuf *ibuf_clip; - if (ibuf->rect_float==NULL) + if (ibuf->rect_float == NULL) IMB_float_from_rect(ibuf); ibuf_clip = IMB_allocImBuf(layer->rectx, layer->recty, 32, IB_rectfloat); if (ibuf_clip) { IMB_rectcpy(ibuf_clip, ibuf, 0, 0, x, y, layer->rectx, layer->recty); - memcpy(layer->rectf, ibuf_clip->rect_float, sizeof(float)*4*layer->rectx*layer->recty); + memcpy(layer->rectf, ibuf_clip->rect_float, sizeof(float) * 4 * layer->rectx * layer->recty); IMB_freeImBuf(ibuf_clip); } else { @@ -2428,33 +2428,33 @@ const float default_envmap_layout[] = { 0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1 }; int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env, const char *relpath, const char imtype, float layout[12]) { ImageFormatData imf; - ImBuf *ibuf=NULL; + ImBuf *ibuf = NULL; int ok; int dx; - int maxX=0, maxY=0, i=0; + int maxX = 0, maxY = 0, i = 0; char filepath[FILE_MAX]; - if (env->cube[1]==NULL) { + if (env->cube[1] == NULL) { BKE_report(reports, RPT_ERROR, "There is no generated environment map available to save"); return 0; } - imf= scene->r.im_format; - imf.imtype= imtype; + imf = scene->r.im_format; + imf.imtype = imtype; - dx= env->cube[1]->x; + dx = env->cube[1]->x; if (env->type == ENV_CUBE) { - for (i=0; i < 12; i+=2) { + for (i = 0; i < 12; i += 2) { maxX = MAX2(maxX, layout[i] + 1); - maxY = MAX2(maxY, layout[i+1] + 1); + maxY = MAX2(maxY, layout[i + 1] + 1); } - ibuf = IMB_allocImBuf(maxX*dx, maxY*dx, 24, IB_rectfloat); + ibuf = IMB_allocImBuf(maxX * dx, maxY * dx, 24, IB_rectfloat); - for (i=0; i < 12; i+=2) - if (layout[i] > -1 && layout[i+1] > -1) - IMB_rectcpy(ibuf, env->cube[i/2], layout[i]*dx, layout[i+1]*dx, 0, 0, dx, dx); + for (i = 0; i < 12; i += 2) + if (layout[i] > -1 && layout[i + 1] > -1) + IMB_rectcpy(ibuf, env->cube[i / 2], layout[i] * dx, layout[i + 1] * dx, 0, 0, dx, dx); } else if (env->type == ENV_PLANE) { ibuf = IMB_allocImBuf(dx, dx, 24, IB_rectfloat); @@ -2472,7 +2472,7 @@ int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env, BLI_strncpy(filepath, relpath, sizeof(filepath)); BLI_path_abs(filepath, G.main->name); - ok= BKE_imbuf_write(ibuf, filepath, &imf); + ok = BKE_imbuf_write(ibuf, filepath, &imf); IMB_freeImBuf(ibuf); diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index a88057ef3d2..6f572b43a15 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -59,10 +59,10 @@ void render_result_free(RenderResult *res) { - if (res==NULL) return; + if (res == NULL) return; while (res->layers.first) { - RenderLayer *rl= res->layers.first; + RenderLayer *rl = res->layers.first; if (rl->rectf) MEM_freeN(rl->rectf); /* acolrect and scolrect are optionally allocated in shade_tile, only free here since it can be used for drawing */ @@ -70,7 +70,7 @@ void render_result_free(RenderResult *res) if (rl->scolrect) MEM_freeN(rl->scolrect); while (rl->passes.first) { - RenderPass *rpass= rl->passes.first; + RenderPass *rpass = rl->passes.first; if (rpass->rect) MEM_freeN(rpass->rect); BLI_remlink(&rl->passes, rpass); MEM_freeN(rpass); @@ -96,8 +96,8 @@ void render_result_free_list(ListBase *lb, RenderResult *rr) { RenderResult *rrnext; - for (; rr; rr= rrnext) { - rrnext= rr->next; + for (; rr; rr = rrnext) { + rrnext = rr->next; if (lb && lb->first) BLI_remlink(lb, rr); @@ -114,166 +114,166 @@ static const char *get_pass_name(int passtype, int channel) { if (passtype == SCE_PASS_COMBINED) { - if (channel==-1) return "Combined"; - if (channel==0) return "Combined.R"; - if (channel==1) return "Combined.G"; - if (channel==2) return "Combined.B"; + if (channel == -1) return "Combined"; + if (channel == 0) return "Combined.R"; + if (channel == 1) return "Combined.G"; + if (channel == 2) return "Combined.B"; return "Combined.A"; } if (passtype == SCE_PASS_Z) { - if (channel==-1) return "Depth"; + if (channel == -1) return "Depth"; return "Depth.Z"; } if (passtype == SCE_PASS_VECTOR) { - if (channel==-1) return "Vector"; - if (channel==0) return "Vector.X"; - if (channel==1) return "Vector.Y"; - if (channel==2) return "Vector.Z"; + if (channel == -1) return "Vector"; + if (channel == 0) return "Vector.X"; + if (channel == 1) return "Vector.Y"; + if (channel == 2) return "Vector.Z"; return "Vector.W"; } if (passtype == SCE_PASS_NORMAL) { - if (channel==-1) return "Normal"; - if (channel==0) return "Normal.X"; - if (channel==1) return "Normal.Y"; + if (channel == -1) return "Normal"; + if (channel == 0) return "Normal.X"; + if (channel == 1) return "Normal.Y"; return "Normal.Z"; } if (passtype == SCE_PASS_UV) { - if (channel==-1) return "UV"; - if (channel==0) return "UV.U"; - if (channel==1) return "UV.V"; + if (channel == -1) return "UV"; + if (channel == 0) return "UV.U"; + if (channel == 1) return "UV.V"; return "UV.A"; } if (passtype == SCE_PASS_RGBA) { - if (channel==-1) return "Color"; - if (channel==0) return "Color.R"; - if (channel==1) return "Color.G"; - if (channel==2) return "Color.B"; + if (channel == -1) return "Color"; + if (channel == 0) return "Color.R"; + if (channel == 1) return "Color.G"; + if (channel == 2) return "Color.B"; return "Color.A"; } if (passtype == SCE_PASS_EMIT) { - if (channel==-1) return "Emit"; - if (channel==0) return "Emit.R"; - if (channel==1) return "Emit.G"; + if (channel == -1) return "Emit"; + if (channel == 0) return "Emit.R"; + if (channel == 1) return "Emit.G"; return "Emit.B"; } if (passtype == SCE_PASS_DIFFUSE) { - if (channel==-1) return "Diffuse"; - if (channel==0) return "Diffuse.R"; - if (channel==1) return "Diffuse.G"; + if (channel == -1) return "Diffuse"; + if (channel == 0) return "Diffuse.R"; + if (channel == 1) return "Diffuse.G"; return "Diffuse.B"; } if (passtype == SCE_PASS_SPEC) { - if (channel==-1) return "Spec"; - if (channel==0) return "Spec.R"; - if (channel==1) return "Spec.G"; + if (channel == -1) return "Spec"; + if (channel == 0) return "Spec.R"; + if (channel == 1) return "Spec.G"; return "Spec.B"; } if (passtype == SCE_PASS_SHADOW) { - if (channel==-1) return "Shadow"; - if (channel==0) return "Shadow.R"; - if (channel==1) return "Shadow.G"; + if (channel == -1) return "Shadow"; + if (channel == 0) return "Shadow.R"; + if (channel == 1) return "Shadow.G"; return "Shadow.B"; } if (passtype == SCE_PASS_AO) { - if (channel==-1) return "AO"; - if (channel==0) return "AO.R"; - if (channel==1) return "AO.G"; + if (channel == -1) return "AO"; + if (channel == 0) return "AO.R"; + if (channel == 1) return "AO.G"; return "AO.B"; } if (passtype == SCE_PASS_ENVIRONMENT) { - if (channel==-1) return "Env"; - if (channel==0) return "Env.R"; - if (channel==1) return "Env.G"; + if (channel == -1) return "Env"; + if (channel == 0) return "Env.R"; + if (channel == 1) return "Env.G"; return "Env.B"; } if (passtype == SCE_PASS_INDIRECT) { - if (channel==-1) return "Indirect"; - if (channel==0) return "Indirect.R"; - if (channel==1) return "Indirect.G"; + if (channel == -1) return "Indirect"; + if (channel == 0) return "Indirect.R"; + if (channel == 1) return "Indirect.G"; return "Indirect.B"; } if (passtype == SCE_PASS_REFLECT) { - if (channel==-1) return "Reflect"; - if (channel==0) return "Reflect.R"; - if (channel==1) return "Reflect.G"; + if (channel == -1) return "Reflect"; + if (channel == 0) return "Reflect.R"; + if (channel == 1) return "Reflect.G"; return "Reflect.B"; } if (passtype == SCE_PASS_REFRACT) { - if (channel==-1) return "Refract"; - if (channel==0) return "Refract.R"; - if (channel==1) return "Refract.G"; + if (channel == -1) return "Refract"; + if (channel == 0) return "Refract.R"; + if (channel == 1) return "Refract.G"; return "Refract.B"; } if (passtype == SCE_PASS_INDEXOB) { - if (channel==-1) return "IndexOB"; + if (channel == -1) return "IndexOB"; return "IndexOB.X"; } if (passtype == SCE_PASS_INDEXMA) { - if (channel==-1) return "IndexMA"; + if (channel == -1) return "IndexMA"; return "IndexMA.X"; } if (passtype == SCE_PASS_MIST) { - if (channel==-1) return "Mist"; + if (channel == -1) return "Mist"; return "Mist.Z"; } if (passtype == SCE_PASS_RAYHITS) { - if (channel==-1) return "Rayhits"; - if (channel==0) return "Rayhits.R"; - if (channel==1) return "Rayhits.G"; + if (channel == -1) return "Rayhits"; + if (channel == 0) return "Rayhits.R"; + if (channel == 1) return "Rayhits.G"; return "Rayhits.B"; } if (passtype == SCE_PASS_DIFFUSE_DIRECT) { - if (channel==-1) return "DiffDir"; - if (channel==0) return "DiffDir.R"; - if (channel==1) return "DiffDir.G"; + if (channel == -1) return "DiffDir"; + if (channel == 0) return "DiffDir.R"; + if (channel == 1) return "DiffDir.G"; return "DiffDir.B"; } if (passtype == SCE_PASS_DIFFUSE_INDIRECT) { - if (channel==-1) return "DiffInd"; - if (channel==0) return "DiffInd.R"; - if (channel==1) return "DiffInd.G"; + if (channel == -1) return "DiffInd"; + if (channel == 0) return "DiffInd.R"; + if (channel == 1) return "DiffInd.G"; return "DiffInd.B"; } if (passtype == SCE_PASS_DIFFUSE_COLOR) { - if (channel==-1) return "DiffCol"; - if (channel==0) return "DiffCol.R"; - if (channel==1) return "DiffCol.G"; + if (channel == -1) return "DiffCol"; + if (channel == 0) return "DiffCol.R"; + if (channel == 1) return "DiffCol.G"; return "DiffCol.B"; } if (passtype == SCE_PASS_GLOSSY_DIRECT) { - if (channel==-1) return "GlossDir"; - if (channel==0) return "GlossDir.R"; - if (channel==1) return "GlossDir.G"; + if (channel == -1) return "GlossDir"; + if (channel == 0) return "GlossDir.R"; + if (channel == 1) return "GlossDir.G"; return "GlossDir.B"; } if (passtype == SCE_PASS_GLOSSY_INDIRECT) { - if (channel==-1) return "GlossInd"; - if (channel==0) return "GlossInd.R"; - if (channel==1) return "GlossInd.G"; + if (channel == -1) return "GlossInd"; + if (channel == 0) return "GlossInd.R"; + if (channel == 1) return "GlossInd.G"; return "GlossInd.B"; } if (passtype == SCE_PASS_GLOSSY_COLOR) { - if (channel==-1) return "GlossCol"; - if (channel==0) return "GlossCol.R"; - if (channel==1) return "GlossCol.G"; + if (channel == -1) return "GlossCol"; + if (channel == 0) return "GlossCol.R"; + if (channel == 1) return "GlossCol.G"; return "GlossCol.B"; } if (passtype == SCE_PASS_TRANSM_DIRECT) { - if (channel==-1) return "TransDir"; - if (channel==0) return "TransDir.R"; - if (channel==1) return "TransDir.G"; + if (channel == -1) return "TransDir"; + if (channel == 0) return "TransDir.R"; + if (channel == 1) return "TransDir.G"; return "TransDir.B"; } if (passtype == SCE_PASS_TRANSM_INDIRECT) { - if (channel==-1) return "TransInd"; - if (channel==0) return "TransInd.R"; - if (channel==1) return "TransInd.G"; + if (channel == -1) return "TransInd"; + if (channel == 0) return "TransInd.R"; + if (channel == 1) return "TransInd.G"; return "TransInd.B"; } if (passtype == SCE_PASS_TRANSM_COLOR) { - if (channel==-1) return "TransCol"; - if (channel==0) return "TransCol.R"; - if (channel==1) return "TransCol.G"; + if (channel == -1) return "TransCol"; + if (channel == 0) return "TransCol.R"; + if (channel == 1) return "TransCol.G"; return "TransCol.B"; } return "Unknown"; @@ -282,88 +282,88 @@ static const char *get_pass_name(int passtype, int channel) static int passtype_from_name(const char *str) { - if (strcmp(str, "Combined")==0) + if (strcmp(str, "Combined") == 0) return SCE_PASS_COMBINED; - if (strcmp(str, "Depth")==0) + if (strcmp(str, "Depth") == 0) return SCE_PASS_Z; - if (strcmp(str, "Vector")==0) + if (strcmp(str, "Vector") == 0) return SCE_PASS_VECTOR; - if (strcmp(str, "Normal")==0) + if (strcmp(str, "Normal") == 0) return SCE_PASS_NORMAL; - if (strcmp(str, "UV")==0) + if (strcmp(str, "UV") == 0) return SCE_PASS_UV; - if (strcmp(str, "Color")==0) + if (strcmp(str, "Color") == 0) return SCE_PASS_RGBA; - if (strcmp(str, "Emit")==0) + if (strcmp(str, "Emit") == 0) return SCE_PASS_EMIT; - if (strcmp(str, "Diffuse")==0) + if (strcmp(str, "Diffuse") == 0) return SCE_PASS_DIFFUSE; - if (strcmp(str, "Spec")==0) + if (strcmp(str, "Spec") == 0) return SCE_PASS_SPEC; - if (strcmp(str, "Shadow")==0) + if (strcmp(str, "Shadow") == 0) return SCE_PASS_SHADOW; - if (strcmp(str, "AO")==0) + if (strcmp(str, "AO") == 0) return SCE_PASS_AO; - if (strcmp(str, "Env")==0) + if (strcmp(str, "Env") == 0) return SCE_PASS_ENVIRONMENT; - if (strcmp(str, "Indirect")==0) + if (strcmp(str, "Indirect") == 0) return SCE_PASS_INDIRECT; - if (strcmp(str, "Reflect")==0) + if (strcmp(str, "Reflect") == 0) return SCE_PASS_REFLECT; - if (strcmp(str, "Refract")==0) + if (strcmp(str, "Refract") == 0) return SCE_PASS_REFRACT; - if (strcmp(str, "IndexOB")==0) + if (strcmp(str, "IndexOB") == 0) return SCE_PASS_INDEXOB; - if (strcmp(str, "IndexMA")==0) + if (strcmp(str, "IndexMA") == 0) return SCE_PASS_INDEXMA; - if (strcmp(str, "Mist")==0) + if (strcmp(str, "Mist") == 0) return SCE_PASS_MIST; - if (strcmp(str, "RayHits")==0) + if (strcmp(str, "RayHits") == 0) return SCE_PASS_RAYHITS; - if (strcmp(str, "DiffDir")==0) + if (strcmp(str, "DiffDir") == 0) return SCE_PASS_DIFFUSE_DIRECT; - if (strcmp(str, "DiffInd")==0) + if (strcmp(str, "DiffInd") == 0) return SCE_PASS_DIFFUSE_INDIRECT; - if (strcmp(str, "DiffCol")==0) + if (strcmp(str, "DiffCol") == 0) return SCE_PASS_DIFFUSE_COLOR; - if (strcmp(str, "GlossDir")==0) + if (strcmp(str, "GlossDir") == 0) return SCE_PASS_GLOSSY_DIRECT; - if (strcmp(str, "GlossInd")==0) + if (strcmp(str, "GlossInd") == 0) return SCE_PASS_GLOSSY_INDIRECT; - if (strcmp(str, "GlossCol")==0) + if (strcmp(str, "GlossCol") == 0) return SCE_PASS_GLOSSY_COLOR; - if (strcmp(str, "TransDir")==0) + if (strcmp(str, "TransDir") == 0) return SCE_PASS_TRANSM_DIRECT; - if (strcmp(str, "TransInd")==0) + if (strcmp(str, "TransInd") == 0) return SCE_PASS_TRANSM_INDIRECT; - if (strcmp(str, "TransCol")==0) + if (strcmp(str, "TransCol") == 0) return SCE_PASS_TRANSM_COLOR; return 0; @@ -373,38 +373,38 @@ static int passtype_from_name(const char *str) static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype) { - const char *typestr= get_pass_name(passtype, 0); - RenderPass *rpass= MEM_callocN(sizeof(RenderPass), typestr); - int rectsize= rr->rectx*rr->recty*channels; + const char *typestr = get_pass_name(passtype, 0); + RenderPass *rpass = MEM_callocN(sizeof(RenderPass), typestr); + int rectsize = rr->rectx * rr->recty * channels; BLI_addtail(&rl->passes, rpass); - rpass->passtype= passtype; - rpass->channels= channels; - rpass->rectx= rl->rectx; - rpass->recty= rl->recty; + rpass->passtype = passtype; + rpass->channels = channels; + rpass->rectx = rl->rectx; + rpass->recty = rl->recty; BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name)); if (rr->exrhandle) { int a; - for (a=0; aexrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL); } else { float *rect; int x; - rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr); + rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, typestr); - if (passtype==SCE_PASS_VECTOR) { + if (passtype == SCE_PASS_VECTOR) { /* initialize to max speed */ - rect= rpass->rect; - for (x= rectsize-1; x>=0; x--) - rect[x]= PASS_VECTOR_MAX; + rect = rpass->rect; + for (x = rectsize - 1; x >= 0; x--) + rect[x] = PASS_VECTOR_MAX; } - else if (passtype==SCE_PASS_Z) { - rect= rpass->rect; - for (x= rectsize-1; x>=0; x--) - rect[x]= 10e10; + else if (passtype == SCE_PASS_Z) { + rect = rpass->rect; + for (x = rectsize - 1; x >= 0; x--) + rect[x] = 10e10; } } } @@ -420,18 +420,18 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf SceneRenderLayer *srl; int rectx, recty, nr; - rectx= partrct->xmax - partrct->xmin; - recty= partrct->ymax - partrct->ymin; + rectx = partrct->xmax - partrct->xmin; + recty = partrct->ymax - partrct->ymin; - if (rectx<=0 || recty<=0) + if (rectx <= 0 || recty <= 0) return NULL; - rr= MEM_callocN(sizeof(RenderResult), "new render result"); - rr->rectx= rectx; - rr->recty= recty; - rr->renrect.xmin = 0; rr->renrect.xmax = rectx-2*crop; + rr = MEM_callocN(sizeof(RenderResult), "new render result"); + rr->rectx = rectx; + rr->recty = recty; + rr->renrect.xmin = 0; rr->renrect.xmax = rectx - 2 * crop; /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */ - rr->crop= crop; + rr->crop = crop; /* tilerect is relative coordinates within render disprect. do not subtract crop yet */ rr->tilerect.xmin = partrct->xmin - re->disprect.xmin; @@ -440,31 +440,31 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf rr->tilerect.ymax = partrct->ymax - re->disprect.ymax; if (savebuffers) { - rr->exrhandle= IMB_exr_get_handle(); + rr->exrhandle = IMB_exr_get_handle(); } /* check renderdata for amount of layers */ - for (nr=0, srl= re->r.layers.first; srl; srl= srl->next, nr++) { + for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) { - if ((re->r.scemode & R_SINGLE_LAYER) && nr!=re->r.actlay) + if ((re->r.scemode & R_SINGLE_LAYER) && nr != re->r.actlay) continue; if (srl->layflag & SCE_LAY_DISABLE) continue; - rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); + rl = MEM_callocN(sizeof(RenderLayer), "new render layer"); BLI_addtail(&rr->layers, rl); BLI_strncpy(rl->name, srl->name, sizeof(rl->name)); - rl->lay= srl->lay; - rl->lay_zmask= srl->lay_zmask; - rl->lay_exclude= srl->lay_exclude; - rl->layflag= srl->layflag; - rl->passflag= srl->passflag; // for debugging: srl->passflag|SCE_PASS_RAYHITS; - rl->pass_xor= srl->pass_xor; - rl->light_override= srl->light_override; - rl->mat_override= srl->mat_override; - rl->rectx= rectx; - rl->recty= recty; + rl->lay = srl->lay; + rl->lay_zmask = srl->lay_zmask; + rl->lay_exclude = srl->lay_exclude; + rl->layflag = srl->layflag; + rl->passflag = srl->passflag; // for debugging: srl->passflag|SCE_PASS_RAYHITS; + rl->pass_xor = srl->pass_xor; + rl->light_override = srl->light_override; + rl->mat_override = srl->mat_override; + rl->rectx = rectx; + rl->recty = recty; if (rr->exrhandle) { IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL); @@ -473,7 +473,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL); } else - rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba"); + rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba"); if (srl->passflag & SCE_PASS_Z) render_layer_add_pass(rr, rl, 1, SCE_PASS_Z); @@ -532,12 +532,12 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf } /* sss, previewrender and envmap don't do layers, so we make a default one */ - if (rr->layers.first==NULL) { - rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); + if (rr->layers.first == NULL) { + rl = MEM_callocN(sizeof(RenderLayer), "new render layer"); BLI_addtail(&rr->layers, rl); - rl->rectx= rectx; - rl->recty= recty; + rl->rectx = rectx; + rl->recty = recty; /* duplicate code... */ if (rr->exrhandle) { @@ -547,19 +547,19 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL); } else - rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba"); + rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba"); /* note, this has to be in sync with scene.c */ - rl->lay= (1<<20) -1; - rl->layflag= 0x7FFF; /* solid ztra halo strand */ - rl->passflag= SCE_PASS_COMBINED; + rl->lay = (1 << 20) - 1; + rl->layflag = 0x7FFF; /* solid ztra halo strand */ + rl->passflag = SCE_PASS_COMBINED; - re->r.actlay= 0; + re->r.actlay = 0; } /* border render; calculate offset for use in compositor. compo is centralized coords */ - rr->xof= re->disprect.xmin + (re->disprect.xmax - re->disprect.xmin)/2 - re->winx/2; - rr->yof= re->disprect.ymin + (re->disprect.ymax - re->disprect.ymin)/2 - re->winy/2; + rr->xof = re->disprect.xmin + (re->disprect.xmax - re->disprect.xmin) / 2 - re->winx / 2; + rr->yof = re->disprect.ymin + (re->disprect.ymax - re->disprect.ymin) / 2 - re->winy / 2; return rr; } @@ -569,13 +569,13 @@ RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *part { int a; - if (re->osa==0) + if (re->osa == 0) return render_result_new(re, partrct, crop, savebuffers); - for (a=0; aosa; a++) { - RenderResult *rr= render_result_new(re, partrct, crop, savebuffers); + for (a = 0; a < re->osa; a++) { + RenderResult *rr = render_result_new(re, partrct, crop, savebuffers); BLI_addtail(lb, rr); - rr->sample_nr= a; + rr->sample_nr = a; } return lb->first; @@ -584,10 +584,10 @@ RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *part /* callbacks for render_result_new_from_exr */ static void *ml_addlayer_cb(void *base, char *str) { - RenderResult *rr= base; + RenderResult *rr = base; RenderLayer *rl; - rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); + rl = MEM_callocN(sizeof(RenderLayer), "new render layer"); BLI_addtail(&rr->layers, rl); BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME); @@ -596,44 +596,44 @@ static void *ml_addlayer_cb(void *base, char *str) static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect, int totchan, char *chan_id) { - RenderLayer *rl= lay; - RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass"); + RenderLayer *rl = lay; + RenderPass *rpass = MEM_callocN(sizeof(RenderPass), "loaded pass"); int a; BLI_addtail(&rl->passes, rpass); - rpass->channels= totchan; + rpass->channels = totchan; - rpass->passtype= passtype_from_name(str); - if (rpass->passtype==0) printf("unknown pass %s\n", str); + rpass->passtype = passtype_from_name(str); + if (rpass->passtype == 0) printf("unknown pass %s\n", str); rl->passflag |= rpass->passtype; BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME); /* channel id chars */ - for (a=0; achan_id[a]= chan_id[a]; + for (a = 0; a < totchan; a++) + rpass->chan_id[a] = chan_id[a]; - rpass->rect= rect; + rpass->rect = rect; } /* from imbuf, if a handle was returned we convert this to render result */ RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty) { - RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result"); + RenderResult *rr = MEM_callocN(sizeof(RenderResult), "loaded render result"); RenderLayer *rl; RenderPass *rpass; - rr->rectx= rectx; - rr->recty= recty; + rr->rectx = rectx; + rr->recty = recty; IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb); - for (rl=rr->layers.first; rl; rl=rl->next) { - rl->rectx= rectx; - rl->recty= recty; + for (rl = rr->layers.first; rl; rl = rl->next) { + rl->rectx = rectx; + rl->recty = recty; - for (rpass=rl->passes.first; rpass; rpass=rpass->next) { - rpass->rectx= rectx; - rpass->recty= recty; + for (rpass = rl->passes.first; rpass; rpass = rpass->next) { + rpass->rectx = rectx; + rpass->recty = recty; } } @@ -646,31 +646,31 @@ static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, { int y, ofs, copylen, tilex, tiley; - copylen= tilex= rrpart->rectx; - tiley= rrpart->recty; + copylen = tilex = rrpart->rectx; + tiley = rrpart->recty; - if (rrpart->crop) { /* filters add pixel extra */ - tile+= pixsize*(rrpart->crop + rrpart->crop*tilex); + if (rrpart->crop) { /* filters add pixel extra */ + tile += pixsize * (rrpart->crop + rrpart->crop * tilex); - copylen= tilex - 2*rrpart->crop; - tiley -= 2*rrpart->crop; + copylen = tilex - 2 * rrpart->crop; + tiley -= 2 * rrpart->crop; - ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop); - target+= pixsize*ofs; + ofs = (rrpart->tilerect.ymin + rrpart->crop) * rr->rectx + (rrpart->tilerect.xmin + rrpart->crop); + target += pixsize * ofs; } else { - ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin); - target+= pixsize*ofs; + ofs = (rrpart->tilerect.ymin * rr->rectx + rrpart->tilerect.xmin); + target += pixsize * ofs; } - copylen *= sizeof(float)*pixsize; + copylen *= sizeof(float) * pixsize; tilex *= pixsize; - ofs= pixsize*rr->rectx; + ofs = pixsize * rr->rectx; - for (y=0; ylayers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) { + for (rl = rr->layers.first, rlp = rrpart->layers.first; rl && rlp; rl = rl->next, rlp = rlp->next) { /* combined */ if (rl->rectf && rlp->rectf) do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4); /* passes are allocated in sync */ - for (rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) { + for (rpass = rl->passes.first, rpassp = rlp->passes.first; rpass && rpassp; rpass = rpass->next, rpassp = rpassp->next) { do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels); } } @@ -702,10 +702,10 @@ static char *make_pass_name(RenderPass *rpass, int chan) int len; BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME); - len= strlen(name); - name[len]= '.'; - name[len+1]= rpass->chan_id[chan]; - name[len+2]= 0; + len = strlen(name); + name[len] = '.'; + name[len + 1] = rpass->chan_id[chan]; + name[len + 2] = 0; return name; } @@ -716,40 +716,40 @@ int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *file { RenderLayer *rl; RenderPass *rpass; - void *exrhandle= IMB_exr_get_handle(); + void *exrhandle = IMB_exr_get_handle(); int success; BLI_make_existing_file(filename); /* composite result */ if (rr->rectf) { - IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4*rr->rectx, rr->rectf); - IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4*rr->rectx, rr->rectf+1); - IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4*rr->rectx, rr->rectf+2); - IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4*rr->rectx, rr->rectf+3); + IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4 * rr->rectx, rr->rectf); + IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4 * rr->rectx, rr->rectf + 1); + IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4 * rr->rectx, rr->rectf + 2); + IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4 * rr->rectx, rr->rectf + 3); } /* add layers/passes and assign channels */ - for (rl= rr->layers.first; rl; rl= rl->next) { + for (rl = rr->layers.first; rl; rl = rl->next) { /* combined */ if (rl->rectf) { - int a, xstride= 4; - for (a=0; aname, get_pass_name(SCE_PASS_COMBINED, a), - xstride, xstride*rr->rectx, rl->rectf+a); + xstride, xstride * rr->rectx, rl->rectf + a); } /* passes are allocated in sync */ - for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - int a, xstride= rpass->channels; - for (a=0; apasses.first; rpass; rpass = rpass->next) { + int a, xstride = rpass->channels; + for (a = 0; a < xstride; a++) { if (rpass->passtype) IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), - xstride, xstride*rr->rectx, rpass->rect+a); + xstride, xstride * rr->rectx, rpass->rect + a); else IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a), - xstride, xstride*rr->rectx, rpass->rect+a); + xstride, xstride * rr->rectx, rpass->rect + a); } } } @@ -757,12 +757,12 @@ int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *file /* when the filename has no permissions, this can fail */ if (IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) { IMB_exr_write_channels(exrhandle); - success= TRUE; + success = TRUE; } else { /* TODO, get the error from openexr's exception */ BKE_report(reports, RPT_ERROR, "Error Writing Render Result, see console"); - success= FALSE; + success = FALSE; } IMB_exr_close(exrhandle); @@ -778,8 +778,8 @@ void render_result_single_layer_begin(Render *re) /* officially pushed result should be NULL... error can happen with do_seq */ RE_FreeRenderResult(re->pushedresult); - re->pushedresult= re->result; - re->result= NULL; + re->pushedresult = re->result; + re->result = NULL; } /* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */ @@ -790,7 +790,7 @@ void render_result_single_layer_end(Render *re) RenderLayer *rl; int nr; - if (re->result==NULL) { + if (re->result == NULL) { printf("pop render result error; no current result!\n"); return; } @@ -798,19 +798,19 @@ void render_result_single_layer_end(Render *re) if (!re->pushedresult) return; - if (re->pushedresult->rectx==re->result->rectx && re->pushedresult->recty==re->result->recty) { + if (re->pushedresult->rectx == re->result->rectx && re->pushedresult->recty == re->result->recty) { /* find which layer in re->pushedresult should be replaced */ - rl= re->result->layers.first; + rl = re->result->layers.first; /* render result should be empty after this */ BLI_remlink(&re->result->layers, rl); /* reconstruct render result layers */ - for (nr=0, srl= re->scene->r.layers.first; srl; srl= srl->next, nr++) { - if (nr==re->r.actlay) + for (nr = 0, srl = re->scene->r.layers.first; srl; srl = srl->next, nr++) { + if (nr == re->r.actlay) BLI_addtail(&re->result->layers, rl); else { - rlpush= RE_GetRenderLayer(re->pushedresult, srl->name); + rlpush = RE_GetRenderLayer(re->pushedresult, srl->name); if (rlpush) { BLI_remlink(&re->pushedresult->layers, rlpush); BLI_addtail(&re->result->layers, rlpush); @@ -820,7 +820,7 @@ void render_result_single_layer_end(Render *re) } RE_FreeRenderResult(re->pushedresult); - re->pushedresult= NULL; + re->pushedresult = NULL; } /************************* EXR Tile File Rendering ***************************/ @@ -833,35 +833,35 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart) BLI_lock_thread(LOCK_IMAGE); - for (rlp= rrpart->layers.first; rlp; rlp= rlp->next) { + for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) { - if (rrpart->crop) { /* filters add pixel extra */ - offs= (rrpart->crop + rrpart->crop*rrpart->rectx); + if (rrpart->crop) { /* filters add pixel extra */ + offs = (rrpart->crop + rrpart->crop * rrpart->rectx); } else { - offs= 0; + offs = 0; } /* combined */ if (rlp->rectf) { - int a, xstride= 4; - for (a=0; aexrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a), - xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs); + xstride, xstride * rrpart->rectx, rlp->rectf + a + xstride * offs); } /* passes are allocated in sync */ - for (rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) { - int a, xstride= rpassp->channels; - for (a=0; apasses.first; rpassp; rpassp = rpassp->next) { + int a, xstride = rpassp->channels; + for (a = 0; a < xstride; a++) IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a), - xstride, xstride*rrpart->rectx, rpassp->rect+a + xstride*offs); + xstride, xstride * rrpart->rectx, rpassp->rect + a + xstride * offs); } } - party= rrpart->tilerect.ymin + rrpart->crop; - partx= rrpart->tilerect.xmin + rrpart->crop; + party = rrpart->tilerect.ymin + rrpart->crop; + partx = rrpart->tilerect.xmin + rrpart->crop; IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0); BLI_unlock_thread(LOCK_IMAGE); @@ -872,13 +872,13 @@ static void save_empty_result_tiles(Render *re) RenderPart *pa; RenderResult *rr; - for (rr= re->result; rr; rr= rr->next) { + for (rr = re->result; rr; rr = rr->next) { IMB_exrtile_clear_channels(rr->exrhandle); - for (pa= re->parts.first; pa; pa= pa->next) { - if (pa->ready==0) { - int party= pa->disprect.ymin - re->disprect.ymin + pa->crop; - int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop; + for (pa = re->parts.first; pa; pa = pa->next) { + if (pa->ready == 0) { + int party = pa->disprect.ymin - re->disprect.ymin + pa->crop; + int partx = pa->disprect.xmin - re->disprect.xmin + pa->crop; IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0); } } @@ -891,7 +891,7 @@ void render_result_exr_file_begin(Render *re) RenderResult *rr; char str[FILE_MAX]; - for (rr= re->result; rr; rr= rr->next) { + for (rr = re->result; rr; rr = rr->next) { render_result_exr_file_path(re->scene, rr->sample_nr, str); printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str); @@ -906,13 +906,13 @@ void render_result_exr_file_end(Render *re) save_empty_result_tiles(re); - for (rr= re->result; rr; rr= rr->next) { + for (rr = re->result; rr; rr = rr->next) { IMB_exr_close(rr->exrhandle); - rr->exrhandle= NULL; + rr->exrhandle = NULL; } render_result_free_list(&re->fullresult, re->result); - re->result= NULL; + re->result = NULL; render_result_exr_file_read(re, 0); } @@ -920,22 +920,22 @@ void render_result_exr_file_end(Render *re) /* save part into exr file */ void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart) { - for (; rr && rrpart; rr= rr->next, rrpart= rrpart->next) + for (; rr && rrpart; rr = rr->next, rrpart = rrpart->next) save_render_result_tile(rr, rrpart); } /* path to temporary exr file */ void render_result_exr_file_path(Scene *scene, int sample, char *filepath) { - char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE]; + char di[FILE_MAX], name[FILE_MAXFILE + MAX_ID_NAME + 100], fi[FILE_MAXFILE]; BLI_strncpy(di, G.main->name, FILE_MAX); BLI_splitdirstring(di, fi); - if (sample==0) - BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name+2); + if (sample == 0) + BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name + 2); else - BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene->id.name+2, sample); + BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene->id.name + 2, sample); BLI_make_file_string("/", filepath, BLI_temporary_dir(), name); } @@ -947,17 +947,17 @@ int render_result_exr_file_read(Render *re, int sample) int success; RE_FreeRenderResult(re->result); - re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); + re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM); render_result_exr_file_path(re->scene, sample, str); printf("read exr tmp file: %s\n", str); if (render_result_exr_file_read_path(re->result, str)) { - success= TRUE; + success = TRUE; } else { printf("cannot read: %s\n", str); - success= FALSE; + success = FALSE; } @@ -969,16 +969,16 @@ int render_result_exr_file_read_path(RenderResult *rr, const char *filepath) { RenderLayer *rl; RenderPass *rpass; - void *exrhandle= IMB_exr_get_handle(); + void *exrhandle = IMB_exr_get_handle(); int rectx, recty; - if (IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty)==0) { + if (IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty) == 0) { printf("failed being read %s\n", filepath); IMB_exr_close(exrhandle); return 0; } - if (rr == NULL || rectx!=rr->rectx || recty!=rr->recty) { + if (rr == NULL || rectx != rr->rectx || recty != rr->recty) { if (rr) printf("error in reading render result: dimensions don't match\n"); else @@ -987,21 +987,21 @@ int render_result_exr_file_read_path(RenderResult *rr, const char *filepath) return 0; } - for (rl= rr->layers.first; rl; rl= rl->next) { + for (rl = rr->layers.first; rl; rl = rl->next) { /* combined */ if (rl->rectf) { - int a, xstride= 4; - for (a=0; aname, get_pass_name(SCE_PASS_COMBINED, a), - xstride, xstride*rectx, rl->rectf+a); + xstride, xstride * rectx, rl->rectf + a); } /* passes are allocated in sync */ - for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - int a, xstride= rpass->channels; - for (a=0; apasses.first; rpass; rpass = rpass->next) { + int a, xstride = rpass->channels; + for (a = 0; a < xstride; a++) IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), - xstride, xstride*rectx, rpass->rect+a); + xstride, xstride * rectx, rpass->rect + a); BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name)); } @@ -1017,23 +1017,23 @@ int render_result_exr_file_read_path(RenderResult *rr, const char *filepath) ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd) { - int flags = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE)? IB_cm_predivide: 0; - ImBuf *ibuf= IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, flags); + int flags = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) ? IB_cm_predivide : 0; + ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, flags); /* if not exists, BKE_imbuf_write makes one */ - ibuf->rect= (unsigned int *)rr->rect32; - ibuf->rect_float= rr->rectf; - ibuf->zbuf_float= rr->rectz; + ibuf->rect = (unsigned int *)rr->rect32; + ibuf->rect_float = rr->rectf; + ibuf->zbuf_float = rr->rectz; /* float factor for random dither, imbuf takes care of it */ - ibuf->dither= rd->dither_intensity; + ibuf->dither = rd->dither_intensity; /* prepare to gamma correct to sRGB color space */ if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) { /* sequence editor can generate 8bpc render buffers */ if (ibuf->rect) { ibuf->profile = IB_PROFILE_SRGB; - if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12|R_IMF_CHAN_DEPTH_16|R_IMF_CHAN_DEPTH_24|R_IMF_CHAN_DEPTH_32)) + if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_24 | R_IMF_CHAN_DEPTH_32)) IMB_float_from_rect(ibuf); } else { @@ -1044,10 +1044,10 @@ ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd) /* color -> greyscale */ /* editing directly would alter the render view */ if (rd->im_format.planes == R_IMF_PLANES_BW) { - ImBuf *ibuf_bw= IMB_dupImBuf(ibuf); + ImBuf *ibuf_bw = IMB_dupImBuf(ibuf); IMB_color_to_bw(ibuf_bw); IMB_freeImBuf(ibuf); - ibuf= ibuf_bw; + ibuf = ibuf_bw; } return ibuf; @@ -1058,34 +1058,34 @@ void render_result_rect_from_ibuf(RenderResult *rr, RenderData *rd, ImBuf *ibuf) if (ibuf->rect_float) { /* color management: when off ensure rectf is non-lin, since thats what the internal * render engine delivers */ - int profile_to= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; - int profile_from= (ibuf->profile == IB_PROFILE_LINEAR_RGB)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; - int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); + int profile_to = (rd->color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB; + int profile_from = (ibuf->profile == IB_PROFILE_LINEAR_RGB) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB; + int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); if (!rr->rectf) - rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf"); + rr->rectf = MEM_mallocN(4 * sizeof(float) * rr->rectx * rr->recty, "render_seq rectf"); IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float, - 4, profile_to, profile_from, predivide, - rr->rectx, rr->recty, rr->rectx, rr->rectx); + 4, profile_to, profile_from, predivide, + rr->rectx, rr->recty, rr->rectx, rr->rectx); /* TSK! Since sequence render doesn't free the *rr render result, the old rect32 * can hang around when sequence render has rendered a 32 bits one before */ if (rr->rect32) { MEM_freeN(rr->rect32); - rr->rect32= NULL; + rr->rect32 = NULL; } } else if (ibuf->rect) { if (!rr->rect32) - rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); + rr->rect32 = MEM_mallocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect"); - memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty); + memcpy(rr->rect32, ibuf->rect, 4 * rr->rectx * rr->recty); /* Same things as above, old rectf can hang around from previous render. */ if (rr->rectf) { MEM_freeN(rr->rectf); - rr->rectf= NULL; + rr->rectf = NULL; } } } @@ -1093,29 +1093,29 @@ void render_result_rect_from_ibuf(RenderResult *rr, RenderData *rd, ImBuf *ibuf) void render_result_rect_fill_zero(RenderResult *rr) { if (rr->rectf) - memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty); + memset(rr->rectf, 0, 4 * sizeof(float) * rr->rectx * rr->recty); else if (rr->rect32) - memset(rr->rect32, 0, 4*rr->rectx*rr->recty); + memset(rr->rect32, 0, 4 * rr->rectx * rr->recty); else - rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); + rr->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect"); } void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty) { if (rr->rect32) { - memcpy(rect, rr->rect32, sizeof(int)*rr->rectx*rr->recty); + memcpy(rect, rr->rect32, sizeof(int) * rr->rectx * rr->recty); } else if (rr->rectf) { - int profile_from= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; - int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); - int dither= 0; + int profile_from = (rd->color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB; + int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); + int dither = 0; - IMB_buffer_byte_from_float((unsigned char*)rect, rr->rectf, - 4, dither, IB_PROFILE_SRGB, profile_from, predivide, - rr->rectx, rr->recty, rr->rectx, rr->rectx); + IMB_buffer_byte_from_float((unsigned char *)rect, rr->rectf, + 4, dither, IB_PROFILE_SRGB, profile_from, predivide, + rr->rectx, rr->recty, rr->rectx, rr->rectx); } else /* else fill with black */ - memset(rect, 0, sizeof(int)*rectx*recty); + memset(rect, 0, sizeof(int) * rectx * recty); } From 9e6869ea8a58f536aabe196cfb07f1586325fee4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 17:27:49 +0000 Subject: [PATCH 281/360] style cleanup --- .../imbuf/intern/openexr/openexr_api.cpp | 695 +++++++++--------- 1 file changed, 348 insertions(+), 347 deletions(-) diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index baea18d4898..c3c7b7fa34c 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -4,7 +4,7 @@ * 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. + * 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 @@ -64,7 +64,7 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void) #include -#if defined (_WIN32) && !defined(FREE_WINDOWS) +#if defined(_WIN32) && !defined(FREE_WINDOWS) #include #include #include @@ -95,19 +95,21 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void) using namespace Imf; using namespace Imath; -class Mem_IStream: public Imf::IStream +class Mem_IStream : public Imf::IStream { public: - - Mem_IStream (unsigned char *exrbuf, size_t exrsize): - IStream("dummy"), _exrpos (0), _exrsize(exrsize) { _exrbuf = exrbuf; } - - virtual bool read (char c[], int n); - virtual Int64 tellg (); - virtual void seekg (Int64 pos); - virtual void clear (); + + Mem_IStream (unsigned char *exrbuf, size_t exrsize) : + IStream("dummy"), _exrpos(0), _exrsize(exrsize) { + _exrbuf = exrbuf; + } + + virtual bool read(char c[], int n); + virtual Int64 tellg(); + virtual void seekg(Int64 pos); + virtual void clear(); //virtual ~Mem_IStream() {}; // unused - + private: Int64 _exrpos; @@ -115,7 +117,7 @@ private: unsigned char *_exrbuf; }; -bool Mem_IStream::read (char c[], int n) +bool Mem_IStream::read(char c[], int n) { if (n + _exrpos <= _exrsize) { memcpy(c, (void *)(&_exrbuf[_exrpos]), n); @@ -126,22 +128,21 @@ bool Mem_IStream::read (char c[], int n) return false; } -Int64 Mem_IStream::tellg () +Int64 Mem_IStream::tellg() { return _exrpos; } -void Mem_IStream::seekg (Int64 pos) +void Mem_IStream::seekg(Int64 pos) { _exrpos = pos; } -void Mem_IStream::clear () -{ +void Mem_IStream::clear() +{ } -struct _RGBAZ -{ +struct _RGBAZ { half r; half g; half b; @@ -153,10 +154,10 @@ typedef struct _RGBAZ RGBAZ; extern "C" { - + int imb_is_a_openexr(unsigned char *mem) { - return Imf::isImfMagic ((const char *)mem); + return Imf::isImfMagic((const char *)mem); } static void openexr_header_compression(Header *header, int compression) @@ -179,15 +180,15 @@ static void openexr_header_compression(Header *header, int compression) break; default: header->compression() = ZIP_COMPRESSION; - break; + break; } } static void openexr_header_metadata(Header *header, struct ImBuf *ibuf) { - ImMetaData* info; + ImMetaData *info; - for (info= ibuf->metadata; info; info= info->next) + for (info = ibuf->metadata; info; info = info->next) header->insert(info->key, StringAttribute(info->value)); } @@ -197,51 +198,51 @@ static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags int width = ibuf->x; int height = ibuf->y; int write_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; // summarize - + try { - Header header (width, height); - + Header header(width, height); + openexr_header_compression(&header, ibuf->ftype & OPENEXR_COMPRESS); openexr_header_metadata(&header, ibuf); - - header.channels().insert ("R", Channel (HALF)); - header.channels().insert ("G", Channel (HALF)); - header.channels().insert ("B", Channel (HALF)); - if (ibuf->planes==32 && channels >= 4) - header.channels().insert ("A", Channel (HALF)); - if (write_zbuf) // z we do as float always - header.channels().insert ("Z", Channel (Imf::FLOAT)); - - FrameBuffer frameBuffer; - OutputFile *file = new OutputFile(name, header); - + + header.channels().insert("R", Channel(HALF)); + header.channels().insert("G", Channel(HALF)); + header.channels().insert("B", Channel(HALF)); + if (ibuf->planes == 32 && channels >= 4) + header.channels().insert("A", Channel(HALF)); + if (write_zbuf) // z we do as float always + header.channels().insert("Z", Channel(Imf::FLOAT)); + + FrameBuffer frameBuffer; + OutputFile *file = new OutputFile(name, header); + /* we store first everything in half array */ RGBAZ *pixels = new RGBAZ[height * width]; RGBAZ *to = pixels; - int xstride= sizeof (RGBAZ); - int ystride= xstride*width; + int xstride = sizeof (RGBAZ); + int ystride = xstride * width; /* indicate used buffers */ - frameBuffer.insert ("R", Slice (HALF, (char *) &pixels[0].r, xstride, ystride)); - frameBuffer.insert ("G", Slice (HALF, (char *) &pixels[0].g, xstride, ystride)); - frameBuffer.insert ("B", Slice (HALF, (char *) &pixels[0].b, xstride, ystride)); - if (ibuf->planes==32 && channels >= 4) - frameBuffer.insert ("A", Slice (HALF, (char *) &pixels[0].a, xstride, ystride)); + frameBuffer.insert("R", Slice(HALF, (char *) &pixels[0].r, xstride, ystride)); + frameBuffer.insert("G", Slice(HALF, (char *) &pixels[0].g, xstride, ystride)); + frameBuffer.insert("B", Slice(HALF, (char *) &pixels[0].b, xstride, ystride)); + if (ibuf->planes == 32 && channels >= 4) + frameBuffer.insert("A", Slice(HALF, (char *) &pixels[0].a, xstride, ystride)); if (write_zbuf) - frameBuffer.insert ("Z", Slice (Imf::FLOAT, (char *)(ibuf->zbuf_float + (height-1)*width), - sizeof(float), sizeof(float) * -width)); + frameBuffer.insert("Z", Slice(Imf::FLOAT, (char *)(ibuf->zbuf_float + (height - 1) * width), + sizeof(float), sizeof(float) * -width)); if (ibuf->rect_float) { float *from; - for (int i = ibuf->y-1; i >= 0; i--) { - from= ibuf->rect_float + channels*i*width; + for (int i = ibuf->y - 1; i >= 0; i--) { + from = ibuf->rect_float + channels * i * width; for (int j = ibuf->x; j > 0; j--) { to->r = from[0]; to->g = from[1]; to->b = from[2]; - to->a = (channels >= 4)? from[3]: 1.0f; + to->a = (channels >= 4) ? from[3] : 1.0f; to++; from += 4; } } @@ -250,48 +251,48 @@ static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags unsigned char *from; if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { - for (int i = ibuf->y-1; i >= 0; i--) { - from= (unsigned char *)ibuf->rect + channels*i*width; + for (int i = ibuf->y - 1; i >= 0; i--) { + from = (unsigned char *)ibuf->rect + channels * i * width; for (int j = ibuf->x; j > 0; j--) { - to->r = (float)(from[0])/255.0; - to->g = (float)(from[1])/255.0; - to->b = (float)(from[2])/255.0; - to->a = (float)(channels >= 4) ? from[3]/255.0 : 1.0f; + to->r = (float)(from[0]) / 255.0; + to->g = (float)(from[1]) / 255.0; + to->b = (float)(from[2]) / 255.0; + to->a = (float)(channels >= 4) ? from[3] / 255.0 : 1.0f; to++; from += 4; } } } else { - for (int i = ibuf->y-1; i >= 0; i--) { - from= (unsigned char *)ibuf->rect + channels*i*width; + for (int i = ibuf->y - 1; i >= 0; i--) { + from = (unsigned char *)ibuf->rect + channels * i * width; for (int j = ibuf->x; j > 0; j--) { to->r = srgb_to_linearrgb((float)from[0] / 255.0); to->g = srgb_to_linearrgb((float)from[1] / 255.0); to->b = srgb_to_linearrgb((float)from[2] / 255.0); - to->a = channels >= 4 ? (float)from[3]/255.0 : 1.0f; + to->a = channels >= 4 ? (float)from[3] / 255.0 : 1.0f; to++; from += 4; } } } } - + // printf("OpenEXR-save: Writing OpenEXR file of height %d.\n", height); - - file->setFrameBuffer (frameBuffer); - file->writePixels (height); + + file->setFrameBuffer(frameBuffer); + file->writePixels(height); delete file; - delete [] pixels; + delete[] pixels; } catch (const std::exception &exc) { printf("OpenEXR-save: ERROR: %s\n", exc.what()); if (ibuf) IMB_freeImBuf(ibuf); - + return (0); } - + return (1); } @@ -304,51 +305,51 @@ static int imb_save_openexr_float(struct ImBuf *ibuf, const char *name, int flag try { - Header header (width, height); - + Header header(width, height); + openexr_header_compression(&header, ibuf->ftype & OPENEXR_COMPRESS); openexr_header_metadata(&header, ibuf); - - header.channels().insert ("R", Channel (Imf::FLOAT)); - header.channels().insert ("G", Channel (Imf::FLOAT)); - header.channels().insert ("B", Channel (Imf::FLOAT)); - if (ibuf->planes==32 && channels >= 4) - header.channels().insert ("A", Channel (Imf::FLOAT)); + + header.channels().insert("R", Channel(Imf::FLOAT)); + header.channels().insert("G", Channel(Imf::FLOAT)); + header.channels().insert("B", Channel(Imf::FLOAT)); + if (ibuf->planes == 32 && channels >= 4) + header.channels().insert("A", Channel(Imf::FLOAT)); if (write_zbuf) - header.channels().insert ("Z", Channel (Imf::FLOAT)); - - FrameBuffer frameBuffer; - OutputFile *file = new OutputFile(name, header); + header.channels().insert("Z", Channel(Imf::FLOAT)); + + FrameBuffer frameBuffer; + OutputFile *file = new OutputFile(name, header); int xstride = sizeof(float) * channels; - int ystride = - xstride*width; + int ystride = -xstride * width; float *rect[4] = {NULL, NULL, NULL, NULL}; /* last scanline, stride negative */ - rect[0]= ibuf->rect_float + channels*(height-1)*width; - rect[1]= rect[0]+1; - rect[2]= rect[0]+2; - rect[3]= (channels >= 4)? rect[0]+3:rect[0]; /* red as alpha, is this needed since alpha isn't written? */ + rect[0] = ibuf->rect_float + channels * (height - 1) * width; + rect[1] = rect[0] + 1; + rect[2] = rect[0] + 2; + rect[3] = (channels >= 4) ? rect[0] + 3 : rect[0]; /* red as alpha, is this needed since alpha isn't written? */ - frameBuffer.insert ("R", Slice (Imf::FLOAT, (char *)rect[0], xstride, ystride)); - frameBuffer.insert ("G", Slice (Imf::FLOAT, (char *)rect[1], xstride, ystride)); - frameBuffer.insert ("B", Slice (Imf::FLOAT, (char *)rect[2], xstride, ystride)); - if (ibuf->planes==32 && channels >= 4) - frameBuffer.insert ("A", Slice (Imf::FLOAT, (char *)rect[3], xstride, ystride)); + frameBuffer.insert("R", Slice(Imf::FLOAT, (char *)rect[0], xstride, ystride)); + frameBuffer.insert("G", Slice(Imf::FLOAT, (char *)rect[1], xstride, ystride)); + frameBuffer.insert("B", Slice(Imf::FLOAT, (char *)rect[2], xstride, ystride)); + if (ibuf->planes == 32 && channels >= 4) + frameBuffer.insert("A", Slice(Imf::FLOAT, (char *)rect[3], xstride, ystride)); if (write_zbuf) - frameBuffer.insert ("Z", Slice (Imf::FLOAT, (char *) (ibuf->zbuf_float + (height-1)*width), - sizeof(float), sizeof(float) * -width)); - file->setFrameBuffer (frameBuffer); - file->writePixels (height); + frameBuffer.insert("Z", Slice(Imf::FLOAT, (char *) (ibuf->zbuf_float + (height - 1) * width), + sizeof(float), sizeof(float) * -width)); + file->setFrameBuffer(frameBuffer); + file->writePixels(height); delete file; } catch (const std::exception &exc) { printf("OpenEXR-save: ERROR: %s\n", exc.what()); if (ibuf) IMB_freeImBuf(ibuf); - + return (0); } - + return (1); // printf("OpenEXR-save: Done.\n"); } @@ -359,15 +360,15 @@ int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags) if (flags & IB_mem) { printf("OpenEXR-save: Create EXR in memory CURRENTLY NOT SUPPORTED !\n"); imb_addencodedbufferImBuf(ibuf); - ibuf->encodedsize = 0; + ibuf->encodedsize = 0; return(0); - } - - if (ibuf->ftype & OPENEXR_HALF) + } + + if (ibuf->ftype & OPENEXR_HALF) return imb_save_openexr_half(ibuf, name, flags); else { /* when no float rect, we save as half (16 bits is sufficient) */ - if (ibuf->rect_float==NULL) + if (ibuf->rect_float == NULL) return imb_save_openexr_half(ibuf, name, flags); else return imb_save_openexr_float(ibuf, name, flags); @@ -383,30 +384,30 @@ int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags) * - separated with a dot: the Layer name (like "Lamp1" or "Walls" or "Characters") */ -static ListBase exrhandles= {NULL, NULL}; +static ListBase exrhandles = {NULL, NULL}; typedef struct ExrHandle { struct ExrHandle *next, *prev; - + InputFile *ifile; TiledOutputFile *tofile; OutputFile *ofile; int tilex, tiley; int width, height; int mipmap; - - ListBase channels; /* flattened out, ExrChannel */ - ListBase layers; /* hierarchical, pointing in end to ExrChannel */ + + ListBase channels; /* flattened out, ExrChannel */ + ListBase layers; /* hierarchical, pointing in end to ExrChannel */ } ExrHandle; /* flattened out channel */ typedef struct ExrChannel { struct ExrChannel *next, *prev; - - char name[EXR_TOT_MAXNAME+1]; /* full name of layer+pass */ - int xstride, ystride; /* step to next pixel, to next scanline */ - float *rect; /* first pointer to write in */ - char chan_id; /* quick lookup of channel char */ + + char name[EXR_TOT_MAXNAME + 1]; /* full name of layer+pass */ + int xstride, ystride; /* step to next pixel, to next scanline */ + float *rect; /* first pointer to write in */ + char chan_id; /* quick lookup of channel char */ } ExrChannel; @@ -422,7 +423,7 @@ typedef struct ExrPass { typedef struct ExrLayer { struct ExrLayer *next, *prev; - char name[EXR_LAY_MAXNAME+1]; + char name[EXR_LAY_MAXNAME + 1]; ListBase passes; } ExrLayer; @@ -430,7 +431,7 @@ typedef struct ExrLayer { void *IMB_exr_get_handle(void) { - ExrHandle *data= (ExrHandle *)MEM_callocN(sizeof(ExrHandle), "exr handle"); + ExrHandle *data = (ExrHandle *)MEM_callocN(sizeof(ExrHandle), "exr handle"); BLI_addtail(&exrhandles, data); return data; } @@ -439,25 +440,26 @@ void *IMB_exr_get_handle(void) /* xstride, ystride and rect can be done in set_channel too, for tile writing */ void IMB_exr_add_channel(void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect) { - ExrHandle *data= (ExrHandle *)handle; + ExrHandle *data = (ExrHandle *)handle; ExrChannel *echan; - - echan= (ExrChannel *)MEM_callocN(sizeof(ExrChannel), "exr tile channel"); - + + echan = (ExrChannel *)MEM_callocN(sizeof(ExrChannel), "exr tile channel"); + if (layname) { - char lay[EXR_LAY_MAXNAME+1], pass[EXR_PASS_MAXNAME+1]; + char lay[EXR_LAY_MAXNAME + 1], pass[EXR_PASS_MAXNAME + 1]; BLI_strncpy(lay, layname, EXR_LAY_MAXNAME); BLI_strncpy(pass, passname, EXR_PASS_MAXNAME); - sprintf(echan->name, "%s.%s", lay, pass); + BLI_snprintf(echan->name, sizeof(echan->name), "%s.%s", lay, pass); } - else - BLI_strncpy(echan->name, passname, EXR_TOT_MAXNAME-1); - - echan->xstride= xstride; - echan->ystride= ystride; - echan->rect= rect; - + else { + BLI_strncpy(echan->name, passname, EXR_TOT_MAXNAME - 1); + } + + echan->xstride = xstride; + echan->ystride = ystride; + echan->rect = rect; + // printf("added channel %s\n", echan->name); BLI_addtail(&data->channels, echan); } @@ -465,21 +467,21 @@ void IMB_exr_add_channel(void *handle, const char *layname, const char *passname /* only used for writing temp. render results (not image files) */ int IMB_exr_begin_write(void *handle, const char *filename, int width, int height, int compress) { - ExrHandle *data= (ExrHandle *)handle; - Header header (width, height); + ExrHandle *data = (ExrHandle *)handle; + Header header(width, height); ExrChannel *echan; - - data->width= width; - data->height= height; - - for (echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) - header.channels().insert (echan->name, Channel (Imf::FLOAT)); - + + data->width = width; + data->height = height; + + for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) + header.channels().insert(echan->name, Channel(Imf::FLOAT)); + openexr_header_compression(&header, compress); // openexr_header_metadata(&header, ibuf); // no imbuf. cant write /* header.lineOrder() = DECREASING_Y; this crashes in windows for file read! */ - - header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.55.1 and newer")); + + header.insert("BlenderMultiChannel", StringAttribute("Blender V2.55.1 and newer")); /* avoid crash/abort when we don't have permission to write here */ try { @@ -495,45 +497,45 @@ int IMB_exr_begin_write(void *handle, const char *filename, int width, int heigh void IMB_exrtile_begin_write(void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley) { - ExrHandle *data= (ExrHandle *)handle; - Header header (width, height); + ExrHandle *data = (ExrHandle *)handle; + Header header(width, height); ExrChannel *echan; - - data->tilex= tilex; - data->tiley= tiley; - data->width= width; - data->height= height; - data->mipmap= mipmap; - - for (echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) - header.channels().insert (echan->name, Channel (Imf::FLOAT)); - - header.setTileDescription (TileDescription (tilex, tiley, (mipmap)? MIPMAP_LEVELS: ONE_LEVEL)); + + data->tilex = tilex; + data->tiley = tiley; + data->width = width; + data->height = height; + data->mipmap = mipmap; + + for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) + header.channels().insert(echan->name, Channel(Imf::FLOAT)); + + header.setTileDescription(TileDescription(tilex, tiley, (mipmap) ? MIPMAP_LEVELS : ONE_LEVEL)); header.lineOrder() = RANDOM_Y; header.compression() = RLE_COMPRESSION; - - header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43")); - + + header.insert("BlenderMultiChannel", StringAttribute("Blender V2.43")); + data->tofile = new TiledOutputFile(filename, header); } /* read from file */ int IMB_exr_begin_read(void *handle, const char *filename, int *width, int *height) { - ExrHandle *data= (ExrHandle *)handle; - - if (BLI_exists(filename) && BLI_file_size(filename)>32) { /* 32 is arbitrary, but zero length files crashes exr */ + ExrHandle *data = (ExrHandle *)handle; + + if (BLI_exists(filename) && BLI_file_size(filename) > 32) { /* 32 is arbitrary, but zero length files crashes exr */ data->ifile = new InputFile(filename); if (data->ifile) { Box2i dw = data->ifile->header().dataWindow(); - data->width= *width = dw.max.x - dw.min.x + 1; - data->height= *height = dw.max.y - dw.min.y + 1; - + data->width = *width = dw.max.x - dw.min.x + 1; + data->height = *height = dw.max.y - dw.min.y + 1; + const ChannelList &channels = data->ifile->header().channels(); - + for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) IMB_exr_add_channel(data, NULL, i.name(), 0, 0, NULL); - + return 1; } } @@ -543,26 +545,26 @@ int IMB_exr_begin_read(void *handle, const char *filename, int *width, int *heig /* still clumsy name handling, layers/channels can be ordered as list in list later */ void IMB_exr_set_channel(void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect) { - ExrHandle *data= (ExrHandle *)handle; + ExrHandle *data = (ExrHandle *)handle; ExrChannel *echan; char name[EXR_TOT_MAXNAME + 1]; - + if (layname) { - char lay[EXR_LAY_MAXNAME+1], pass[EXR_PASS_MAXNAME+1]; + char lay[EXR_LAY_MAXNAME + 1], pass[EXR_PASS_MAXNAME + 1]; BLI_strncpy(lay, layname, EXR_LAY_MAXNAME); BLI_strncpy(pass, passname, EXR_PASS_MAXNAME); - - sprintf(name, "%s.%s", lay, pass); + + BLI_snprintf(name, sizeof(name), "%s.%s", lay, pass); } else - BLI_strncpy(name, passname, EXR_TOT_MAXNAME-1); + BLI_strncpy(name, passname, EXR_TOT_MAXNAME - 1); - echan= (ExrChannel *)BLI_findstring(&data->channels, name, offsetof(ExrChannel, name)); + echan = (ExrChannel *)BLI_findstring(&data->channels, name, offsetof(ExrChannel, name)); if (echan) { - echan->xstride= xstride; - echan->ystride= ystride; - echan->rect= rect; + echan->xstride = xstride; + echan->ystride = ystride; + echan->rect = rect; } else printf("IMB_exrtile_set_channel error %s\n", name); @@ -570,28 +572,28 @@ void IMB_exr_set_channel(void *handle, const char *layname, const char *passname void IMB_exrtile_clear_channels(void *handle) { - ExrHandle *data= (ExrHandle *)handle; + ExrHandle *data = (ExrHandle *)handle; BLI_freelistN(&data->channels); } void IMB_exrtile_write_channels(void *handle, int partx, int party, int level) { - ExrHandle *data= (ExrHandle *)handle; + ExrHandle *data = (ExrHandle *)handle; FrameBuffer frameBuffer; ExrChannel *echan; - - for (echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) { - float *rect= echan->rect - echan->xstride*partx - echan->ystride*party; - frameBuffer.insert (echan->name, Slice (Imf::FLOAT, (char *)rect, - echan->xstride*sizeof(float), echan->ystride*sizeof(float))); + for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) { + float *rect = echan->rect - echan->xstride * partx - echan->ystride * party; + + frameBuffer.insert(echan->name, Slice(Imf::FLOAT, (char *)rect, + echan->xstride * sizeof(float), echan->ystride * sizeof(float))); } - - data->tofile->setFrameBuffer (frameBuffer); + + data->tofile->setFrameBuffer(frameBuffer); try { // printf("write tile %d %d\n", partx/data->tilex, party/data->tiley); - data->tofile->writeTile (partx/data->tilex, party/data->tiley, level); + data->tofile->writeTile(partx / data->tilex, party / data->tiley, level); } catch (const std::exception &exc) { std::cerr << "OpenEXR-writeTile: ERROR: " << exc.what() << std::endl; @@ -600,22 +602,22 @@ void IMB_exrtile_write_channels(void *handle, int partx, int party, int level) void IMB_exr_write_channels(void *handle) { - ExrHandle *data= (ExrHandle *)handle; + ExrHandle *data = (ExrHandle *)handle; FrameBuffer frameBuffer; ExrChannel *echan; - + if (data->channels.first) { - for (echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) { + for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) { /* last scanline, stride negative */ - float *rect = echan->rect + echan->xstride*(data->height-1)*data->width; - - frameBuffer.insert (echan->name, Slice (Imf::FLOAT, (char *)rect, - echan->xstride*sizeof(float), -echan->ystride*sizeof(float))); + float *rect = echan->rect + echan->xstride * (data->height - 1) * data->width; + + frameBuffer.insert(echan->name, Slice(Imf::FLOAT, (char *)rect, + echan->xstride * sizeof(float), -echan->ystride * sizeof(float))); } - - data->ofile->setFrameBuffer (frameBuffer); + + data->ofile->setFrameBuffer(frameBuffer); try { - data->ofile->writePixels (data->height); + data->ofile->writePixels(data->height); } catch (const std::exception &exc) { std::cerr << "OpenEXR-writePixels: ERROR: " << exc.what() << std::endl; @@ -628,58 +630,58 @@ void IMB_exr_write_channels(void *handle) void IMB_exr_read_channels(void *handle) { - ExrHandle *data= (ExrHandle *)handle; + ExrHandle *data = (ExrHandle *)handle; FrameBuffer frameBuffer; ExrChannel *echan; - + /* check if exr was saved with previous versions of blender which flipped images */ const StringAttribute *ta = data->ifile->header().findTypedAttribute ("BlenderMultiChannel"); - short flip = (ta && strncmp(ta->value().c_str(), "Blender V2.43", 13)==0); /* 'previous multilayer attribute, flipped */ - - for (echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) { - + short flip = (ta && strncmp(ta->value().c_str(), "Blender V2.43", 13) == 0); /* 'previous multilayer attribute, flipped */ + + for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) { + if (echan->rect) { if (flip) - frameBuffer.insert (echan->name, Slice (Imf::FLOAT, (char *)echan->rect, - echan->xstride*sizeof(float), echan->ystride*sizeof(float))); + frameBuffer.insert(echan->name, Slice(Imf::FLOAT, (char *)echan->rect, + echan->xstride * sizeof(float), echan->ystride * sizeof(float))); else - frameBuffer.insert (echan->name, Slice (Imf::FLOAT, (char *)(echan->rect + echan->xstride*(data->height-1)*data->width), - echan->xstride*sizeof(float), -echan->ystride*sizeof(float))); + frameBuffer.insert(echan->name, Slice(Imf::FLOAT, (char *)(echan->rect + echan->xstride * (data->height - 1) * data->width), + echan->xstride * sizeof(float), -echan->ystride * sizeof(float))); } - else + else printf("warning, channel with no rect set %s\n", echan->name); } - - data->ifile->setFrameBuffer (frameBuffer); + + data->ifile->setFrameBuffer(frameBuffer); try { - data->ifile->readPixels (0, data->height-1); + data->ifile->readPixels(0, data->height - 1); } catch (const std::exception &exc) { std::cerr << "OpenEXR-readPixels: ERROR: " << exc.what() << std::endl; } } -void IMB_exr_multilayer_convert(void *handle, void *base, - void * (*addlayer)(void *base, char *str), - void (*addpass)(void *base, void *lay, char *str, - float *rect, int totchan, char *chan_id)) +void IMB_exr_multilayer_convert(void *handle, void *base, + void * (*addlayer)(void *base, char *str), + void (*addpass)(void *base, void *lay, char *str, + float *rect, int totchan, char *chan_id)) { - ExrHandle *data= (ExrHandle *)handle; + ExrHandle *data = (ExrHandle *)handle; ExrLayer *lay; ExrPass *pass; - if (data->layers.first==NULL) { + if (data->layers.first == NULL) { printf("cannot convert multilayer, no layers in handle\n"); return; } - for (lay= (ExrLayer *)data->layers.first; lay; lay= lay->next) { - void *laybase= addlayer(base, lay->name); + for (lay = (ExrLayer *)data->layers.first; lay; lay = lay->next) { + void *laybase = addlayer(base, lay->name); if (laybase) { - for (pass= (ExrPass *)lay->passes.first; pass; pass= pass->next) { + for (pass = (ExrPass *)lay->passes.first; pass; pass = pass->next) { addpass(base, laybase, pass->name, pass->rect, pass->totchan, pass->chan_id); - pass->rect= NULL; + pass->rect = NULL; } } } @@ -688,31 +690,31 @@ void IMB_exr_multilayer_convert(void *handle, void *base, void IMB_exr_close(void *handle) { - ExrHandle *data= (ExrHandle *)handle; + ExrHandle *data = (ExrHandle *)handle; ExrLayer *lay; ExrPass *pass; - + if (data->ifile) delete data->ifile; else if (data->ofile) delete data->ofile; else if (data->tofile) delete data->tofile; - - data->ifile= NULL; - data->ofile= NULL; - data->tofile= NULL; - + + data->ifile = NULL; + data->ofile = NULL; + data->tofile = NULL; + BLI_freelistN(&data->channels); - - for (lay= (ExrLayer *)data->layers.first; lay; lay= lay->next) { - for (pass= (ExrPass *)lay->passes.first; pass; pass= pass->next) + + for (lay = (ExrLayer *)data->layers.first; lay; lay = lay->next) { + for (pass = (ExrPass *)lay->passes.first; pass; pass = pass->next) if (pass->rect) MEM_freeN(pass->rect); BLI_freelistN(&lay->passes); } BLI_freelistN(&data->layers); - + BLI_remlink(&exrhandles, data); MEM_freeN(data); } @@ -722,12 +724,12 @@ void IMB_exr_close(void *handle) /* get a substring from the end of the name, separated by '.' */ static int imb_exr_split_token(const char *str, const char *end, const char **token) { - int maxlen = end-str; + int maxlen = end - str; int len = 0; - while (len < maxlen && *(end-len-1) != '.') + while (len < maxlen && *(end - len - 1) != '.') ++len; - - *token = end-len; + + *token = end - len; return len; } @@ -738,7 +740,7 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa const char *token; char tokenbuf[EXR_TOT_MAXNAME]; int len; - + /* last token is single character channel identifier */ len = imb_exr_split_token(name, end, &token); if (len == 0) { @@ -751,32 +753,32 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa return 0; } echan->chan_id = token[0]; - end -= len + 1; /* +1 to skip '.' separator */ - + end -= len + 1; /* +1 to skip '.' separator */ + /* second token is pass name */ len = imb_exr_split_token(name, end, &token); if (len == 0) { printf("multilayer read: bad channel name: %s\n", name); return 0; } - BLI_strncpy(passname, token, len+1); - end -= len + 1; /* +1 to skip '.' separator */ - + BLI_strncpy(passname, token, len + 1); + end -= len + 1; /* +1 to skip '.' separator */ + /* all preceding tokens combined as layer name */ if (end > name) - BLI_strncpy(layname, name, (int)(end-name)+1); + BLI_strncpy(layname, name, (int)(end - name) + 1); else layname[0] = '\0'; - + return 1; } static ExrLayer *imb_exr_get_layer(ListBase *lb, char *layname) { - ExrLayer *lay= (ExrLayer *)BLI_findstring(lb, layname, offsetof(ExrLayer, name)); + ExrLayer *lay = (ExrLayer *)BLI_findstring(lb, layname, offsetof(ExrLayer, name)); - if (lay==NULL) { - lay= (ExrLayer *)MEM_callocN(sizeof(ExrLayer), "exr layer"); + if (lay == NULL) { + lay = (ExrLayer *)MEM_callocN(sizeof(ExrLayer), "exr layer"); BLI_addtail(lb, lay); BLI_strncpy(lay->name, layname, EXR_LAY_MAXNAME); } @@ -786,19 +788,19 @@ static ExrLayer *imb_exr_get_layer(ListBase *lb, char *layname) static ExrPass *imb_exr_get_pass(ListBase *lb, char *passname) { - ExrPass *pass= (ExrPass *)BLI_findstring(lb, passname, offsetof(ExrPass, name)); - - if (pass==NULL) { - pass= (ExrPass *)MEM_callocN(sizeof(ExrPass), "exr pass"); + ExrPass *pass = (ExrPass *)BLI_findstring(lb, passname, offsetof(ExrPass, name)); - if (strcmp(passname, "Combined")==0) + if (pass == NULL) { + pass = (ExrPass *)MEM_callocN(sizeof(ExrPass), "exr pass"); + + if (strcmp(passname, "Combined") == 0) BLI_addhead(lb, pass); else BLI_addtail(lb, pass); } BLI_strncpy(pass->name, passname, EXR_LAY_MAXNAME); - + return pass; } @@ -808,29 +810,29 @@ static ExrHandle *imb_exr_begin_read_mem(InputFile *file, int width, int height) ExrLayer *lay; ExrPass *pass; ExrChannel *echan; - ExrHandle *data= (ExrHandle *)IMB_exr_get_handle(); + ExrHandle *data = (ExrHandle *)IMB_exr_get_handle(); int a; char layname[EXR_TOT_MAXNAME], passname[EXR_TOT_MAXNAME]; - - data->ifile= file; - data->width= width; - data->height= height; - + + data->ifile = file; + data->width = width; + data->height = height; + const ChannelList &channels = data->ifile->header().channels(); for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) IMB_exr_add_channel(data, NULL, i.name(), 0, 0, NULL); - + /* now try to sort out how to assign memory to the channels */ /* first build hierarchical layer list */ - for (echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) { - if ( imb_exr_split_channel_name(echan, layname, passname) ) { - ExrLayer *lay= imb_exr_get_layer(&data->layers, layname); - ExrPass *pass= imb_exr_get_pass(&lay->passes, passname); - - pass->chan[pass->totchan]= echan; + for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) { + if (imb_exr_split_channel_name(echan, layname, passname) ) { + ExrLayer *lay = imb_exr_get_layer(&data->layers, layname); + ExrPass *pass = imb_exr_get_pass(&lay->passes, passname); + + pass->chan[pass->totchan] = echan; pass->totchan++; - if (pass->totchan>=EXR_PASS_MAXCHAN) + if (pass->totchan >= EXR_PASS_MAXCHAN) break; } } @@ -839,65 +841,65 @@ static ExrHandle *imb_exr_begin_read_mem(InputFile *file, int width, int height) IMB_exr_close(data); return NULL; } - + /* with some heuristics, try to merge the channels in buffers */ - for (lay= (ExrLayer *)data->layers.first; lay; lay= lay->next) { - for (pass= (ExrPass *)lay->passes.first; pass; pass= pass->next) { + for (lay = (ExrLayer *)data->layers.first; lay; lay = lay->next) { + for (pass = (ExrPass *)lay->passes.first; pass; pass = pass->next) { if (pass->totchan) { - pass->rect= (float *)MEM_mapallocN(width*height*pass->totchan*sizeof(float), "pass rect"); - if (pass->totchan==1) { - echan= pass->chan[0]; - echan->rect= pass->rect; - echan->xstride= 1; - echan->ystride= width; - pass->chan_id[0]= echan->chan_id; + pass->rect = (float *)MEM_mapallocN(width * height * pass->totchan * sizeof(float), "pass rect"); + if (pass->totchan == 1) { + echan = pass->chan[0]; + echan->rect = pass->rect; + echan->xstride = 1; + echan->ystride = width; + pass->chan_id[0] = echan->chan_id; } else { char lookup[256]; - + memset(lookup, 0, sizeof(lookup)); - + /* we can have RGB(A), XYZ(W), UVA */ - if (pass->totchan==3 || pass->totchan==4) { - if (pass->chan[0]->chan_id=='B' || pass->chan[1]->chan_id=='B' || pass->chan[2]->chan_id=='B') { - lookup[(unsigned int)'R']= 0; - lookup[(unsigned int)'G']= 1; - lookup[(unsigned int)'B']= 2; - lookup[(unsigned int)'A']= 3; + if (pass->totchan == 3 || pass->totchan == 4) { + if (pass->chan[0]->chan_id == 'B' || pass->chan[1]->chan_id == 'B' || pass->chan[2]->chan_id == 'B') { + lookup[(unsigned int)'R'] = 0; + lookup[(unsigned int)'G'] = 1; + lookup[(unsigned int)'B'] = 2; + lookup[(unsigned int)'A'] = 3; } - else if (pass->chan[0]->chan_id=='Y' || pass->chan[1]->chan_id=='Y' || pass->chan[2]->chan_id=='Y') { - lookup[(unsigned int)'X']= 0; - lookup[(unsigned int)'Y']= 1; - lookup[(unsigned int)'Z']= 2; - lookup[(unsigned int)'W']= 3; + else if (pass->chan[0]->chan_id == 'Y' || pass->chan[1]->chan_id == 'Y' || pass->chan[2]->chan_id == 'Y') { + lookup[(unsigned int)'X'] = 0; + lookup[(unsigned int)'Y'] = 1; + lookup[(unsigned int)'Z'] = 2; + lookup[(unsigned int)'W'] = 3; } else { - lookup[(unsigned int)'U']= 0; - lookup[(unsigned int)'V']= 1; - lookup[(unsigned int)'A']= 2; + lookup[(unsigned int)'U'] = 0; + lookup[(unsigned int)'V'] = 1; + lookup[(unsigned int)'A'] = 2; } - for (a=0; atotchan; a++) { - echan= pass->chan[a]; - echan->rect= pass->rect + lookup[(unsigned int)echan->chan_id]; - echan->xstride= pass->totchan; - echan->ystride= width*pass->totchan; - pass->chan_id[ (unsigned int)lookup[(unsigned int)echan->chan_id] ]= echan->chan_id; + for (a = 0; a < pass->totchan; a++) { + echan = pass->chan[a]; + echan->rect = pass->rect + lookup[(unsigned int)echan->chan_id]; + echan->xstride = pass->totchan; + echan->ystride = width * pass->totchan; + pass->chan_id[(unsigned int)lookup[(unsigned int)echan->chan_id]] = echan->chan_id; } } else { /* unknown */ - for (a=0; atotchan; a++) { - echan= pass->chan[a]; - echan->rect= pass->rect + a; - echan->xstride= pass->totchan; - echan->ystride= width*pass->totchan; - pass->chan_id[a]= echan->chan_id; + for (a = 0; a < pass->totchan; a++) { + echan = pass->chan[a]; + echan->rect = pass->rect + a; + echan->xstride = pass->totchan; + echan->ystride = width * pass->totchan; + pass->chan_id[a] = echan->chan_id; } } } } } } - + return data; } @@ -916,7 +918,7 @@ typedef struct RGBA { static void exr_print_filecontents(InputFile *file) { const ChannelList &channels = file->header().channels(); - + for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { const Channel &channel = i.channel(); printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type); @@ -927,13 +929,13 @@ static void exr_print_filecontents(InputFile *file) static const char *exr_rgba_channelname(InputFile *file, const char *chan) { const ChannelList &channels = file->header().channels(); - + for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { /* const Channel &channel = i.channel(); */ /* Not used yet */ - const char *str= i.name(); - int len= strlen(str); + const char *str = i.name(); + int len = strlen(str); if (len) { - if (BLI_strcasecmp(chan, str+len-1)==0) { + if (BLI_strcasecmp(chan, str + len - 1) == 0) { return str; } } @@ -950,98 +952,97 @@ static int exr_has_zbuffer(InputFile *file) static int exr_is_multilayer(InputFile *file) { - const StringAttribute *comments= file->header().findTypedAttribute("BlenderMultiChannel"); + const StringAttribute *comments = file->header().findTypedAttribute("BlenderMultiChannel"); const ChannelList &channels = file->header().channels(); std::set layerNames; channels.layers(layerNames); - if (comments || layerNames.size()>1) - return 1; + if (comments || layerNames.size() > 1) + return 1; return 0; } -struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags) -{ +struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags){ struct ImBuf *ibuf = NULL; InputFile *file = NULL; - + if (imb_is_a_openexr(mem) == 0) return(NULL); - + try { - Mem_IStream *membuf = new Mem_IStream(mem, size); + Mem_IStream *membuf = new Mem_IStream(mem, size); int is_multi; file = new InputFile(*membuf); - + Box2i dw = file->header().dataWindow(); int width = dw.max.x - dw.min.x + 1; int height = dw.max.y - dw.min.y + 1; - - //printf("OpenEXR-load: image data window %d %d %d %d\n", + + //printf("OpenEXR-load: image data window %d %d %d %d\n", // dw.min.x, dw.min.y, dw.max.x, dw.max.y); if (0) // debug exr_print_filecontents(file); - - is_multi= exr_is_multilayer(file); - + + is_multi = exr_is_multilayer(file); + /* do not make an ibuf when */ if (is_multi && !(flags & IB_test) && !(flags & IB_multilayer)) { printf("Error: can't process EXR multilayer file\n"); } else { - + ibuf = IMB_allocImBuf(width, height, 32, 0); ibuf->ftype = OPENEXR; /* openEXR is linear as per EXR spec */ ibuf->profile = IB_PROFILE_LINEAR_RGB; - + if (!(flags & IB_test)) { if (is_multi) { /* only enters with IB_multilayer flag set */ /* constructs channels for reading, allocates memory in channels */ - ExrHandle *handle= imb_exr_begin_read_mem(file, width, height); + ExrHandle *handle = imb_exr_begin_read_mem(file, width, height); if (handle) { IMB_exr_read_channels(handle); - ibuf->userdata= handle; /* potential danger, the caller has to check for this! */ + ibuf->userdata = handle; /* potential danger, the caller has to check for this! */ } } else { FrameBuffer frameBuffer; float *first; int xstride = sizeof(float) * 4; - int ystride = - xstride*width; - + int ystride = -xstride * width; + imb_addrectfloatImBuf(ibuf); - + /* inverse correct first pixel for datawindow coordinates (- dw.min.y because of y flip) */ - first= ibuf->rect_float - 4*(dw.min.x - dw.min.y*width); + first = ibuf->rect_float - 4 * (dw.min.x - dw.min.y * width); /* but, since we read y-flipped (negative y stride) we move to last scanline */ - first+= 4*(height-1)*width; - - frameBuffer.insert ( exr_rgba_channelname(file, "R"), - Slice (Imf::FLOAT, (char *) first, xstride, ystride)); - frameBuffer.insert ( exr_rgba_channelname(file, "G"), - Slice (Imf::FLOAT, (char *) (first+1), xstride, ystride)); - frameBuffer.insert ( exr_rgba_channelname(file, "B"), - Slice (Imf::FLOAT, (char *) (first+2), xstride, ystride)); - - frameBuffer.insert ( exr_rgba_channelname(file, "A"), - Slice (Imf::FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f)); /* 1.0 is fill value */ + first += 4 * (height - 1) * width; + + frameBuffer.insert(exr_rgba_channelname(file, "R"), + Slice(Imf::FLOAT, (char *) first, xstride, ystride)); + frameBuffer.insert(exr_rgba_channelname(file, "G"), + Slice(Imf::FLOAT, (char *) (first + 1), xstride, ystride)); + frameBuffer.insert(exr_rgba_channelname(file, "B"), + Slice(Imf::FLOAT, (char *) (first + 2), xstride, ystride)); + + frameBuffer.insert(exr_rgba_channelname(file, "A"), + Slice(Imf::FLOAT, (char *) (first + 3), xstride, ystride, 1, 1, 1.0f)); /* 1.0 is fill value */ if (exr_has_zbuffer(file)) { float *firstz; - + addzbuffloatImBuf(ibuf); - firstz= ibuf->zbuf_float - (dw.min.x - dw.min.y*width); - firstz+= (height-1)*width; - frameBuffer.insert("Z", Slice (Imf::FLOAT, (char *)firstz, sizeof(float), -width * sizeof(float))); + firstz = ibuf->zbuf_float - (dw.min.x - dw.min.y * width); + firstz += (height - 1) * width; + frameBuffer.insert("Z", Slice(Imf::FLOAT, (char *)firstz, sizeof(float), -width * sizeof(float))); } - - file->setFrameBuffer (frameBuffer); - file->readPixels (dw.min.y, dw.max.y); + + file->setFrameBuffer(frameBuffer); + file->readPixels(dw.min.y, dw.max.y); // XXX, ImBuf has no nice way to deal with this. // ideally IM_rect would be used when the caller wants a rect BUT @@ -1052,7 +1053,7 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags) // // if (flag & IM_rect) // IMB_rect_from_float(ibuf); - + /* file is no longer needed */ delete file; } @@ -1065,10 +1066,10 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags) std::cerr << exc.what() << std::endl; if (ibuf) IMB_freeImBuf(ibuf); delete file; - + return (0); } - + } void imb_initopenexr(void) From 4940482e5940a6f06e8473f1b647390608e952fc Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 13 Jun 2012 17:34:47 +0000 Subject: [PATCH 282/360] Fix issue with missing emission in non-progressive integrator. --- intern/cycles/kernel/kernel_path.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 80d66532506..2da6a7e4d8f 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -850,7 +850,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam #endif kernel_path_indirect(kg, rng, sample*num_samples, ray, buffer, - tp*num_samples_inv, min_ray_pdf, ray_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L); + tp*num_samples_inv, min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L); } } From 6dcacd62a52c813a7869ffa7b7e0ddd2ef5237ed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 19:07:09 +0000 Subject: [PATCH 283/360] style cleanup --- .../operations/COM_CompositorOperation.cpp | 41 +++++++++---------- .../operations/COM_CompositorOperation.h | 36 ++++++++-------- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index 4ce7ffac9ef..11cb4f7fc74 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ @@ -53,14 +53,14 @@ void CompositorOperation::initExecution() this->imageInput = getInputSocketReader(0); this->alphaInput = getInputSocketReader(1); if (this->getWidth() * this->getHeight() != 0) { - this->outputBuffer=(float*) MEM_callocN(this->getWidth()*this->getHeight()*4*sizeof(float), "CompositorOperation"); + this->outputBuffer = (float *) MEM_callocN(this->getWidth() * this->getHeight() * 4 * sizeof(float), "CompositorOperation"); } } void CompositorOperation::deinitExecution() { if (isBreaked()) { - const Scene * scene = this->scene; + const Scene *scene = this->scene; Render *re = RE_GetRender(scene->id.name); RenderResult *rr = RE_AcquireResultWrite(re); if (rr) { @@ -85,14 +85,14 @@ void CompositorOperation::deinitExecution() MEM_freeN(this->outputBuffer); } } - + this->outputBuffer = NULL; this->imageInput = NULL; this->alphaInput = NULL; } -void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) +void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers) { float color[8]; // 7 is enough float *buffer = this->outputBuffer; @@ -102,50 +102,47 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber, Mem int y1 = rect->ymin; int x2 = rect->xmax; int y2 = rect->ymax; - int offset = (y1*this->getWidth() + x1 ) * COM_NUMBER_OF_CHANNELS; + int offset = (y1 * this->getWidth() + x1) * COM_NUMBER_OF_CHANNELS; int x; int y; bool breaked = false; - for (y = y1 ; y < y2 && (!breaked); y++) { - for (x = x1 ; x < x2 && (!breaked) ; x++) { + for (y = y1; y < y2 && (!breaked); y++) { + for (x = x1; x < x2 && (!breaked); x++) { imageInput->read(color, x, y, COM_PS_NEAREST, memoryBuffers); if (alphaInput != NULL) { alphaInput->read(&(color[3]), x, y, COM_PS_NEAREST, memoryBuffers); } - buffer[offset] = color[0]; - buffer[offset+1] = color[1]; - buffer[offset+2] = color[2]; - buffer[offset+3] = color[3]; - offset +=COM_NUMBER_OF_CHANNELS; + copy_v4_v4(buffer + offset, color); + offset += COM_NUMBER_OF_CHANNELS; if (isBreaked()) { breaked = true; } } - offset += (this->getWidth()-(x2-x1))*COM_NUMBER_OF_CHANNELS; + offset += (this->getWidth() - (x2 - x1)) * COM_NUMBER_OF_CHANNELS; } } void CompositorOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { - int width = this->scene->r.xsch*this->scene->r.size/100; - int height = this->scene->r.ysch*this->scene->r.size/100; - + int width = this->scene->r.xsch * this->scene->r.size / 100; + int height = this->scene->r.ysch * this->scene->r.size / 100; + // check actual render resolution with cropping it may differ with cropped border.rendering // FIX for: [31777] Border Crop gives black (easy) - Render *re= RE_GetRender(this->scene->id.name); + Render *re = RE_GetRender(this->scene->id.name); if (re) { - RenderResult *rr= RE_AcquireResultRead(re); + RenderResult *rr = RE_AcquireResultRead(re); if (rr) { width = rr->rectx; height = rr->recty; } RE_ReleaseResult(re); } - + preferredResolution[0] = width; preferredResolution[1] = height; - + NodeOperation::determineResolution(resolution, preferredResolution); resolution[0] = width; diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h index 36099b3eb91..0129c953946 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.h +++ b/source/blender/compositor/operations/COM_CompositorOperation.h @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ @@ -27,37 +27,37 @@ #include "BLI_rect.h" /** - * @brief Compositor output operation - */ + * @brief Compositor output operation + */ class CompositorOperation : public NodeOperation { private: /** - * @brief local reference to the scene - */ + * @brief local reference to the scene + */ const Scene *scene; - + /** - * @brief reference to the output float buffer - */ + * @brief reference to the output float buffer + */ float *outputBuffer; - + /** - * @brief local reference to the input image operation - */ + * @brief local reference to the input image operation + */ SocketReader *imageInput; /** - * @brief local reference to the input alpha operation - */ + * @brief local reference to the input alpha operation + */ SocketReader *alphaInput; public: CompositorOperation(); - void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); - void setScene(const Scene *scene) {this->scene = scene;} - bool isOutputOperation(bool rendering) const {return true;} + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers); + void setScene(const Scene *scene) { this->scene = scene; } + bool isOutputOperation(bool rendering) const { return true; } void initExecution(); void deinitExecution(); - const CompositorPriority getRenderPriority() const {return COM_PRIORITY_MEDIUM;} + const CompositorPriority getRenderPriority() const { return COM_PRIORITY_MEDIUM; } void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); }; #endif From b006ed7d6586a4a53199b72463b1080903501e71 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Wed, 13 Jun 2012 19:10:52 +0000 Subject: [PATCH 284/360] fix: [#31684] Collada, add file extension automatically does not work --- source/blender/windowmanager/intern/wm_operators.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index cd6ef646e6b..e16a7befdd5 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2161,7 +2161,7 @@ static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED /* function used for WM_OT_save_mainfile too */ static int wm_collada_export_exec(bContext *C, wmOperator *op) { - char filename[FILE_MAX]; + char filepath[FILE_MAX]; int selected, second_life; int include_armatures; int apply_modifiers; @@ -2173,7 +2173,8 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - RNA_string_get(op->ptr, "filepath", filename); + RNA_string_get(op->ptr, "filepath", filepath); + BLI_ensure_extension(filepath, sizeof(filepath), ".dae"); /* Options panel */ selected = RNA_boolean_get(op->ptr, "selected"); @@ -2188,7 +2189,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) if (collada_export( CTX_data_scene(C), - filename, + filepath, selected, apply_modifiers, include_armatures, From 96099688c667dd601d6dc7c795dd508f5d28646c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 19:43:09 +0000 Subject: [PATCH 285/360] fix [#31819] New Compositor Ommits 'Composite' layer the bug was introduced by accident in r47826, finishing a render node acted as if escape was pressed. also changed order of signaling and releasing the buffer to match the old compositor. --- .../compositor/operations/COM_CompositorOperation.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index 11cb4f7fc74..2b1a804b432 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -59,7 +59,7 @@ void CompositorOperation::initExecution() void CompositorOperation::deinitExecution() { - if (isBreaked()) { + if (!isBreaked()) { const Scene *scene = this->scene; Render *re = RE_GetRender(scene->id.name); RenderResult *rr = RE_AcquireResultWrite(re); @@ -74,11 +74,13 @@ void CompositorOperation::deinitExecution() MEM_freeN(this->outputBuffer); } } + + BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE); + if (re) { RE_ReleaseResult(re); re = NULL; } - BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE); } else { if (this->outputBuffer) { From ceffc2cd50ea1e35757c8834b83b1d55f93d88c6 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Wed, 13 Jun 2012 19:57:23 +0000 Subject: [PATCH 286/360] add Anti-Aliasing (very rough draft algorithm, NOT FINAL version) to raskter lib. Code is still quite messy but will be replaced when final algo comes in anyway. --- intern/raskter/raskter.c | 643 +++++++++++++++++- intern/raskter/raskter.h | 4 +- source/blender/blenkernel/BKE_mask.h | 2 +- source/blender/blenkernel/intern/mask.c | 4 +- source/blender/blenkernel/intern/sequencer.c | 6 +- source/blender/blenkernel/intern/tracking.c | 2 +- .../blender/compositor/nodes/COM_MaskNode.cpp | 1 + .../operations/COM_MaskOperation.cpp | 6 +- .../compositor/operations/COM_MaskOperation.h | 2 + source/blender/editors/space_node/drawnode.c | 2 + source/blender/makesrna/intern/rna_nodetree.c | 5 + .../composite/nodes/node_composite_mask.c | 7 +- 12 files changed, 638 insertions(+), 46 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index 081a7c6bdbd..8bdd4dccbc0 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -34,7 +34,7 @@ /* from BLI_utildefines.h */ #define MIN2(x, y) ( (x) < (y) ? (x) : (y) ) #define MAX2(x, y) ( (x) > (y) ? (x) : (y) ) - +#define ABS(a) ( (a) < 0 ? (-(a)) : (a) ) struct e_status { int x; @@ -67,8 +67,7 @@ struct r_fill_context { * just the poly. Since the DEM code could end up being coupled with this, we'll keep it separate * for now. */ -static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, struct e_status *open_edge) -{ +static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, struct e_status *open_edge) { int i; int xbeg; int ybeg; @@ -94,8 +93,7 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v /* we're not at the last vert, so end of the edge is the previous vertex */ xend = v[i - 1].x; yend = v[i - 1].y; - } - else { + } else { /* we're at the first vertex, so the "end" of this edge is the last vertex */ xend = v[num_verts - 1].x; yend = v[num_verts - 1].y; @@ -124,8 +122,7 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v if (dx > 0) { e_new->xdir = 1; xdist = dx; - } - else { + } else { e_new->xdir = -1; xdist = -dx; } @@ -138,15 +135,13 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v /* calculate deltas for incremental drawing */ if (dx >= 0) { e_new->drift = 0; - } - else { + } else { e_new->drift = -dy + 1; } if (dy >= xdist) { e_new->drift_inc = xdist; e_new->xshift = 0; - } - else { + } else { e_new->drift_inc = xdist % dy; e_new->xshift = (xdist / dy) * e_new->xdir; } @@ -170,8 +165,7 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need * if it ends up being coupled with this function. */ -static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts) -{ +static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, float intensity) { int x_curr; /* current pixel position in X */ int y_curr; /* current scan line being drawn */ int yp; /* y-pixel's position in frame buffer */ @@ -260,8 +254,7 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i edgec = &ctx->all_edges->e_next; /* Set our list to the next edge's location in memory. */ ctx->all_edges = e_temp; /* Skip the NULL or bad X edge, set pointer to next edge. */ break; /* Stop looping edges (since we ran out or hit empty X span. */ - } - else { + } else { edgec = &e_curr->e_next; /* Set the pointer to the edge list the "next" edge. */ } } @@ -307,7 +300,7 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) { /* draw the pixels. */ - for (; cpxl <= mpxl; *cpxl++ = 1.0f); + for(; cpxl <= mpxl; *cpxl++ += intensity); } } @@ -323,8 +316,7 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) { if (!(--(e_curr->num))) { *edgec = e_curr->e_next; - } - else { + } else { e_curr->x += e_curr->xshift; if ((e_curr->drift += e_curr->drift_inc) > 0) { e_curr->x += e_curr->xdir; @@ -383,12 +375,17 @@ static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, i } int PLX_raskterize(float (*base_verts)[2], int num_base_verts, - float *buf, int buf_x, int buf_y) -{ + float *buf, int buf_x, int buf_y, int do_mask_AA) { + int subdiv_AA = (do_mask_AA != 0)? 8:0; int i; /* i: Loop counter. */ + int sAx; + int sAy; struct poly_vert *ply; /* ply: Pointer to a list of integer buffer-space vertex coordinates. */ struct r_fill_context ctx = {0}; - + const float buf_x_f = (float)(buf_x); + const float buf_y_f = (float)(buf_y); + float div_offset=(1.0f / (float)(subdiv_AA)); + float div_offset_static = 0.5f * (float)(subdiv_AA) * div_offset; /* * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert * data structure multiplied by the number of base_verts. @@ -400,6 +397,9 @@ int PLX_raskterize(float (*base_verts)[2], int num_base_verts, return(0); } + ctx.rb.buf = buf; /* Set the output buffer pointer. */ + ctx.rb.sizex = buf_x; /* Set the output buffer size in X. (width) */ + ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ /* * Loop over all verts passed in to be rasterized. Each vertex's X and Y coordinates are * then converted from normalized screen space (0.0 <= POS <= 1.0) to integer coordinates @@ -408,16 +408,25 @@ int PLX_raskterize(float (*base_verts)[2], int num_base_verts, * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel * drawn will be 1.0f in value, there is no anti-aliasing. */ + + if(!subdiv_AA) { for (i = 0; i < num_base_verts; i++) { /* Loop over all base_verts. */ - ply[i].x = (base_verts[i][0] * buf_x) + 0.5f; /* Range expand normalized X to integer buffer-space X. */ - ply[i].y = (base_verts[i][1] * buf_y) + 0.5f; /* Range expand normalized Y to integer buffer-space Y. */ + ply[i].x = (int)((base_verts[i][0] * buf_x_f) + 0.5f); /* Range expand normalized X to integer buffer-space X. */ + ply[i].y = (int)((base_verts[i][1] * buf_y_f) + 0.5f); /* Range expand normalized Y to integer buffer-space Y. */ } - ctx.rb.buf = buf; /* Set the output buffer pointer. */ - ctx.rb.sizex = buf_x; /* Set the output buffer size in X. (width) */ - ctx.rb.sizey = buf_y; /* Set the output buffer size in Y. (height) */ - - i = rast_scan_fill(&ctx, ply, num_base_verts); /* Call our rasterizer, passing in the integer coords for each vert. */ + i = rast_scan_fill(&ctx, ply, num_base_verts,1.0f); /* Call our rasterizer, passing in the integer coords for each vert. */ + } else { + for(sAx=0; sAx < subdiv_AA; sAx++) { + for(sAy=0; sAy < subdiv_AA; sAy++) { + for(i=0; i < num_base_verts; i++) { + ply[i].x = (int)((base_verts[i][0]*buf_x_f)+0.5f - div_offset_static + (div_offset*(float)(sAx))); + ply[i].y = (int)((base_verts[i][1]*buf_y_f)+0.5f - div_offset_static + (div_offset*(float)(sAy))); + } + i = rast_scan_fill(&ctx, ply, num_base_verts,(1.0f / (float)(subdiv_AA*subdiv_AA))); + } + } + } free(ply); /* Free the memory allocated for the integer coordinate table. */ return(i); /* Return the value returned by the rasterizer. */ } @@ -429,8 +438,7 @@ int PLX_raskterize(float (*base_verts)[2], int num_base_verts, */ static int rast_scan_feather(struct r_fill_context *ctx, float (*base_verts_f)[2], int num_base_verts, - struct poly_vert *feather_verts, float (*feather_verts_f)[2], int num_feather_verts) -{ + struct poly_vert *feather_verts, float(*feather_verts_f)[2], int num_feather_verts) { int x_curr; /* current pixel position in X */ int y_curr; /* current scan line being drawn */ int yp; /* y-pixel's position in frame buffer */ @@ -536,8 +544,7 @@ static int rast_scan_feather(struct r_fill_context *ctx, edgec = &ctx->all_edges->e_next; /* Set our list to the next edge's location in memory. */ ctx->all_edges = e_temp; /* Skip the NULL or bad X edge, set pointer to next edge. */ break; /* Stop looping edges (since we ran out or hit empty X span. */ - } - else { + } else { edgec = &e_curr->e_next; /* Set the pointer to the edge list the "next" edge. */ } } @@ -647,8 +654,7 @@ static int rast_scan_feather(struct r_fill_context *ctx, for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) { if (!(--(e_curr->num))) { *edgec = e_curr->e_next; - } - else { + } else { e_curr->x += e_curr->xshift; if ((e_curr->drift += e_curr->drift_inc) > 0) { e_curr->x += e_curr->xdir; @@ -708,8 +714,7 @@ static int rast_scan_feather(struct r_fill_context *ctx, } int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*feather_verts)[2], int num_feather_verts, - float *buf, int buf_x, int buf_y) -{ + float *buf, int buf_x, int buf_y) { int i; /* i: Loop counter. */ struct poly_vert *fe; /* fe: Pointer to a list of integer buffer-space feather vertex coords. */ struct r_fill_context ctx = {0}; @@ -751,3 +756,569 @@ int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*f free(fe); return i; /* Return the value returned by the rasterizer. */ } + +int get_range_expanded_pixel_coord(float normalized_value, int max_value) { + return (int)((normalized_value * (float)(max_value)) + 0.5f); +} + +float get_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y) { + if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) { + return 0.0f; + } + return buf[(pos_y * buf_y) + buf_x]; +} + +float get_pixel_intensity_bilinear(float *buf, int buf_x, int buf_y, float u, float v) { + int a; + int b; + int a_plus_1; + int b_plus_1; + float prop_u; + float prop_v; + float inv_prop_u; + float inv_prop_v; + if(u<0.0f || u>1.0f || v<0.0f || v>1.0f) { + return 0.0f; + } + u = u * (float)(buf_x) - 0.5f; + v = v * (float)(buf_y) - 0.5f; + a = (int)(u); + b = (int)(v); + prop_u = u - (float)(a); + prop_v = v - (float)(b); + inv_prop_u = 1.0f - prop_u; + inv_prop_v = 1.0f - prop_v; + a_plus_1 = MIN2((buf_x-1),a+1); + b_plus_1 = MIN2((buf_y-1),b+1); + return (buf[(b * buf_y) + a] * inv_prop_u + buf[(b*buf_y)+(a_plus_1)] * prop_u)*inv_prop_v+(buf[((b_plus_1) * buf_y)+a] * inv_prop_u + buf[((b_plus_1)*buf_y)+(a_plus_1)] * prop_u) * prop_v; + +} + +void set_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y, float intensity) { + if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) { + return; + } + buf[(pos_y * buf_y) + buf_x] = intensity; +} +#define __PLX__FAKE_AA__ +int PLX_antialias_buffer(float *buf, int buf_x, int buf_y) { +#ifdef __PLX__FAKE_AA__ +#ifdef __PLX_GREY_AA__ + int i=0; + int sz = buf_x * buf_y; + for(i=0; i= edgeVert ? 1:0; + subpixA = subpixNSWE * 2.0f + subpixNWSWNESE; + + if(!horzSpan) { + lumaN = lumaW; + lumaS = lumaE; + } else { + lengthSign = 1.0f / (float)(buf_y); + } + subpixB = (subpixA * (1.0f/12.0f)) - lumaM; + + gradientN = lumaN - lumaM; + gradientS = lumaS - lumaM; + lumaNN = lumaN + lumaM; + lumaSS = lumaS + lumaM; + pairN = (ABS(gradientN)) >= (ABS(gradientS)) ? 1:0; + gradient = MAX2(ABS(gradientN), ABS(gradientS)); + if(pairN) { + lengthSign = -lengthSign; + } + subpixC = MAX2(MIN2(ABS(subpixB) * subpixRcpRange,1.0f),0.0f); + + posB_x = posM_x; + posB_y = posM_y; + offNP_x = (!horzSpan) ? 0.0f:(1.0f / (float)(buf_x)); + offNP_y = (horzSpan) ? 0.0f:(1.0f / (float)(buf_y)); + if(!horzSpan) { + posB_x += lengthSign * 0.5f; + } else { + posB_y += lengthSign * 0.5f; + } + + posN_x = posB_x - offNP_x * p0; + posN_y = posB_y - offNP_y * p0; + posP_x = posB_x + offNP_x * p0; + posP_y = posB_y + offNP_y * p0; + subpixD = ((-2.0f)*subpixC) + 3.0f; + //may need bilinear filtered get_pixel_intensity() here...done + lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y); + subpixE = subpixC * subpixC; + //may need bilinear filtered get_pixel_intensity() here...done + lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y); + + if(!pairN) { + lumaNN = lumaSS; + } + gradientScaled = gradient * 1.0f/4.0f; + lumaMM =lumaM - lumaNN * 0.5f; + subpixF = subpixD * subpixE; + lumaMLTZero = lumaMM < 0.0f ? 1:0; + + lumaEndN -= lumaNN * 0.5f; + lumaEndP -= lumaNN * 0.5f; + doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0; + doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0; + if(!doneN) { + posN_x -= offNP_x * p1; + posN_y -= offNP_y * p1; + } + doneNP = (!doneN) || (!doneP) ? 1:0; + if(!doneP) { + posP_x += offNP_x * p1; + posP_y += offNP_y * p1; + } + + if(doneNP) { + if(!doneN) { + lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posN_x,posN_y); + } + if(!doneP) { + lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x, posP_y); + } + if(!doneN) { + lumaEndN = lumaEndN - lumaNN * 0.5; + } + if(!doneP) { + lumaEndP = lumaEndP - lumaNN * 0.5; + } + doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0; + doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0; + if(!doneN) { + posN_x -= offNP_x * p2; + posN_y -= offNP_y * p2; + } + doneNP = (!doneN) || (!doneP) ? 1:0; + if(!doneP) { + posP_x += offNP_x * p2; + posP_y += offNP_y * p2; + } + if(doneNP) { + if(!doneN) { + lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y); + } + if(!doneP) { + lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y); + } + if(!doneN) { + lumaEndN = lumaEndN - lumaNN * 0.5; + } + if(!doneP) { + lumaEndP = lumaEndP - lumaNN * 0.5; + } + doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0; + doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0; + if(!doneN) { + posN_x -= offNP_x * p3; + posN_y -= offNP_y * p3; + } + doneNP = (!doneN) || (!doneP) ? 1:0; + if(!doneP) { + posP_x += offNP_x * p3; + posP_y += offNP_y * p3; + } + if(doneNP) { + if(!doneN) { + lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y); + } + if(!doneP) { + lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y); + } + if(!doneN) { + lumaEndN = lumaEndN - lumaNN * 0.5; + } + if(!doneP) { + lumaEndP = lumaEndP - lumaNN * 0.5; + } + doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0; + doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0; + if(!doneN) { + posN_x -= offNP_x * p4; + posN_y -= offNP_y * p4; + } + doneNP = (!doneN) || (!doneP) ? 1:0; + if(!doneP) { + posP_x += offNP_x * p4; + posP_y += offNP_y * p4; + } + if(doneNP) { + if(!doneN) { + lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y); + } + if(!doneP) { + lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y); + } + if(!doneN) { + lumaEndN = lumaEndN - lumaNN * 0.5; + } + if(!doneP) { + lumaEndP = lumaEndP - lumaNN * 0.5; + } + doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0; + doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0; + if(!doneN) { + posN_x -= offNP_x * p5; + posN_y -= offNP_y * p5; + } + doneNP = (!doneN) || (!doneP) ? 1:0; + if(!doneP) { + posP_x += offNP_x * p5; + posP_y += offNP_y * p5; + } + if(doneNP) { + if(!doneN) { + lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y); + } + if(!doneP) { + lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y); + } + if(!doneN) { + lumaEndN = lumaEndN - lumaNN * 0.5; + } + if(!doneP) { + lumaEndP = lumaEndP - lumaNN * 0.5; + } + doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0; + doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0; + if(!doneN) { + posN_x -= offNP_x * p6; + posN_y -= offNP_y * p6; + } + doneNP = (!doneN) || (!doneP) ? 1:0; + if(!doneP) { + posP_x += offNP_x * p6; + posP_y += offNP_y * p6; + } + if(doneNP) { + if(!doneN) { + lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y); + } + if(!doneP) { + lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y); + } + if(!doneN) { + lumaEndN = lumaEndN - lumaNN * 0.5; + } + if(!doneP) { + lumaEndP = lumaEndP - lumaNN * 0.5; + } + doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0; + doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0; + if(!doneN) { + posN_x -= offNP_x * p7; + posN_y -= offNP_y * p7; + } + doneNP = (!doneN) || (!doneP) ? 1:0; + if(!doneP) { + posP_x += offNP_x * p7; + posP_y += offNP_y * p7; + } + if(doneNP) { + if(!doneN) { + lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y); + } + if(!doneP) { + lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y); + } + if(!doneN) { + lumaEndN = lumaEndN - lumaNN * 0.5; + } + if(!doneP) { + lumaEndP = lumaEndP - lumaNN * 0.5; + } + doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0; + doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0; + if(!doneN) { + posN_x -= offNP_x * p8; + posN_y -= offNP_y * p8; + } + doneNP = (!doneN) || (!doneP) ? 1:0; + if(!doneP) { + posP_x += offNP_x * p8; + posP_y += offNP_y * p8; + } + if(doneNP) { + if(!doneN) { + lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y); + } + if(!doneP) { + lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y); + } + if(!doneN) { + lumaEndN = lumaEndN - lumaNN * 0.5; + } + if(!doneP) { + lumaEndP = lumaEndP - lumaNN * 0.5; + } + doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0; + doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0; + if(!doneN) { + posN_x -= offNP_x * p9; + posN_y -= offNP_y * p9; + } + doneNP = (!doneN) || (!doneP) ? 1:0; + if(!doneP) { + posP_x += offNP_x * p9; + posP_y += offNP_y * p9; + } + if(doneNP) { + if(!doneN) { + lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y); + } + if(!doneP) { + lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y); + } + if(!doneN) { + lumaEndN = lumaEndN - lumaNN * 0.5; + } + if(!doneP) { + lumaEndP = lumaEndP - lumaNN * 0.5; + } + doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0; + doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0; + if(!doneN) { + posN_x -= offNP_x * p10; + posN_y -= offNP_y * p10; + } + doneNP = (!doneN) || (!doneP) ? 1:0; + if(!doneP) { + posP_x += offNP_x * p10; + posP_y += offNP_y * p10; + } + if(doneNP) { + if(!doneN) { + lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y); + } + if(!doneP) { + lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y); + } + if(!doneN) { + lumaEndN = lumaEndN - lumaNN * 0.5; + } + if(!doneP) { + lumaEndP = lumaEndP - lumaNN * 0.5; + } + doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0; + doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0; + if(!doneN) { + posN_x -= offNP_x * p11; + posN_y -= offNP_y * p11; + } + doneNP = (!doneN) || (!doneP) ? 1:0; + if(!doneP) { + posP_x += offNP_x * p11; + posP_y += offNP_y * p11; + } + } + } + } + } + } + } + } + } + } + } + dstN = posM_x - posN_x; + dstP = posP_x - posM_x; + if(!horzSpan) { + dstN = posM_y - posN_y; + dstP = posP_y - posM_y; + } + + goodSpanN = ((lumaEndN < 0.0f) ? 1:0) != lumaMLTZero ? 1:0; + spanLength = (dstP + dstN); + goodSpanP = ((lumaEndP < 0.0f) ? 1:0) != lumaMLTZero ? 1:0; + spanLengthRcp = 1.0f/spanLength; + + directionN = dstN < dstP ? 1:0; + dst = MIN2(dstN, dstP); + goodSpan = (directionN==1) ? goodSpanN:goodSpanP; + subpixG = subpixF * subpixF; + pixelOffset = (dst * (-spanLengthRcp)) + 0.5f; + subpixH = subpixG * quality_subpix; + + pixelOffsetGood = (goodSpan==1) ? pixelOffset : 0.0f; + pixelOffsetSubpix = MAX2(pixelOffsetGood, subpixH); + if(!horzSpan) { + posM_x += pixelOffsetSubpix * lengthSign; + } else { + posM_y += pixelOffsetSubpix * lengthSign; + } + //may need bilinear filtered get_pixel_intensity() here... + set_pixel_intensity(buf,buf_x,buf_y,curr_x,curr_y,get_pixel_intensity_bilinear(buf, buf_x, buf_y, posM_x,posM_y)* lumaM); + + } + } + return 1; + +#endif +} + diff --git a/intern/raskter/raskter.h b/intern/raskter/raskter.h index e80ca1d41c4..e078b0d26be 100644 --- a/intern/raskter/raskter.h +++ b/intern/raskter/raskter.h @@ -49,11 +49,11 @@ extern "C" { #endif int PLX_raskterize(float (*base_verts)[2], int num_base_verts, - float *buf, int buf_x, int buf_y); + float *buf, int buf_x, int buf_y, int do_mask_AA); int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*feather_verts)[2], int num_feather_verts, float *buf, int buf_x, int buf_y); - +int PLX_antialias_buffer(float *buf, int buf_x, int buf_y); #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index dd2c7cb3a18..0e93869a8b0 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -170,7 +170,7 @@ void BKE_mask_layer_shape_changed_remove(struct MaskLayer *masklay, int index, i /* rasterization */ int BKE_mask_get_duration(struct Mask *mask); void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer, - const short do_aspect_correct); + const short do_aspect_correct, int do_mask_aa); #define MASKPOINT_ISSEL_ANY(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT) #define MASKPOINT_ISSEL_KNOT(p) ( (p)->bezt.f2 & SELECT) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 012ce97b4d7..7e9f189ae01 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -2089,7 +2089,7 @@ int BKE_mask_get_duration(Mask *mask) /* rasterization */ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer, - const short do_aspect_correct) + const short do_aspect_correct, int do_mask_aa) { MaskLayer *masklay; @@ -2154,7 +2154,7 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer, if (tot_diff_point) { PLX_raskterize(diff_points, tot_diff_point, - buffer_tmp, width, height); + buffer_tmp, width, height, do_mask_aa); if (tot_diff_feather_points) { PLX_raskterize_feather(diff_points, tot_diff_point, diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 889eee25d6b..ddf30ecfa81 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2081,7 +2081,8 @@ static ImBuf *seq_render_mask_strip( BKE_mask_rasterize(seq->mask, context.rectx, context.recty, maskbuf, - TRUE); + TRUE, + FALSE /*XXX- TODO: make on/off for anti-aliasing*/); fp_src = maskbuf; fp_dst = ibuf->rect_float; @@ -2104,7 +2105,8 @@ static ImBuf *seq_render_mask_strip( BKE_mask_rasterize(seq->mask, context.rectx, context.recty, maskbuf, - TRUE); + TRUE, + FALSE /*XXX- TODO: mask on/off for anti-aliasing*/); fp_src = maskbuf; ub_dst = (unsigned char *)ibuf->rect; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index b61a39a2cd2..0aa0d36c537 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1428,7 +1428,7 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height fp[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height / mask_height; } - PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height); + PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height, FALSE /* XXX- TODO: make on/off for AA*/); MEM_freeN(mask_points); } diff --git a/source/blender/compositor/nodes/COM_MaskNode.cpp b/source/blender/compositor/nodes/COM_MaskNode.cpp index e26756cfc5b..4371a848a3d 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.cpp +++ b/source/blender/compositor/nodes/COM_MaskNode.cpp @@ -54,6 +54,7 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * c operation->setMask(mask); operation->setFramenumber(context->getFramenumber()); + operation->setSmooth((bool)editorNode->custom1); graph->addOperation(operation); } diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index bfbf2b42e82..8f7115659a1 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -32,6 +32,7 @@ extern "C" { #include "BKE_mask.h" + #include "../../../../intern/raskter/raskter.h" } MaskOperation::MaskOperation(): NodeOperation() @@ -74,7 +75,10 @@ void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers float *buffer; buffer = (float *)MEM_callocN(sizeof(float) * width * height, "rasterized mask"); - BKE_mask_rasterize(mask, width, height, buffer, TRUE); + BKE_mask_rasterize(mask, width, height, buffer, TRUE, this->smooth); + if(this->smooth) { + PLX_antialias_buffer(buffer, width, height); + } this->rasterizedMask = buffer; } diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h index 9f2c7f53f56..8534cb20416 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.h +++ b/source/blender/compositor/operations/COM_MaskOperation.h @@ -40,6 +40,7 @@ protected: int maskWidth; int maskHeight; int framenumber; + bool smooth; float *rasterizedMask; /** @@ -59,6 +60,7 @@ public: void setMaskWidth(int width) {this->maskWidth = width;} void setMaskHeight(int height) {this->maskHeight = height;} void setFramenumber(int framenumber) {this->framenumber = framenumber;} + void setSmooth(bool smooth) {this->smooth = smooth;} void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); }; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 12c369874fe..e6549034a85 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2421,6 +2421,8 @@ static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C), static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr) { uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL); + uiItemR(layout, ptr, "smooth_mask", 0, NULL, ICON_NONE); + } /* only once called */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 92de882d48b..73e2b5da4f0 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3089,6 +3089,11 @@ static void def_cmp_mask(StructRNA *srna) { PropertyRNA *prop; + prop = RNA_def_property(srna, "smooth_mask", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "custom1", 0); + RNA_def_property_ui_text(prop, "Anti-Alias", "Apply an anti-aliasing filter to the mask"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_struct_type(prop, "Mask"); diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c index dbe3c11ab55..d323839e690 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mask.c +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -38,6 +38,8 @@ #include "node_composite_util.h" +#include "../../../../intern/raskter/raskter.h" + /* **************** Translate ******************** */ static bNodeSocketTemplate cmp_node_mask_out[] = { @@ -68,8 +70,11 @@ static void exec(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack ** stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE); res = stackbuf->rect; - BKE_mask_rasterize(mask, sx, sy, res, TRUE); + BKE_mask_rasterize(mask, sx, sy, res, TRUE, node->custom1); + if(node->custom1){ + PLX_antialias_buffer(res,sx,sy); + } /* pass on output and free */ out[0]->data = stackbuf; } From 94a03557954ee2c8a4b5c45f8a4577640b099e73 Mon Sep 17 00:00:00 2001 From: Peter Larabell Date: Wed, 13 Jun 2012 21:37:39 +0000 Subject: [PATCH 287/360] simple assignments added to pre-processor temporary section of function to avoid unused argument compiler warnings. --- intern/raskter/raskter.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index 8bdd4dccbc0..0574d985d0c 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -810,6 +810,9 @@ int PLX_antialias_buffer(float *buf, int buf_x, int buf_y) { buf[i] *= 0.5f; } #endif + buf_x = buf_x; + buf_y = buf_y; + buf[0] = buf[0]; return 1; #else /*XXX - TODO: THIS IS NOT FINAL CODE - IT DOES NOT WORK - DO NOT ENABLE IT */ From fd212cd4bc1e82ad8b61f54ec75d09747f7a9536 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 22:38:31 +0000 Subject: [PATCH 288/360] image sample line now updates with the compositor changes (mango request) --- source/blender/blenkernel/BKE_colortools.h | 3 +- source/blender/blenkernel/intern/colortools.c | 56 +++++++++++++++++++ .../blender/editors/space_image/image_ops.c | 49 +--------------- .../blender/editors/space_image/space_image.c | 3 + 4 files changed, 62 insertions(+), 49 deletions(-) diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index d67e1a9118e..f58af8f39a0 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -35,6 +35,7 @@ struct CurveMapping; struct CurveMap; struct CurveMapPoint; struct Scopes; +struct Histogram; struct ImBuf; struct rctf; @@ -74,7 +75,7 @@ void curvemapping_premultiply(struct CurveMapping *cumap, int res int curvemapping_RGBA_does_something(struct CurveMapping *cumap); void curvemapping_initialize(struct CurveMapping *cumap); void curvemapping_table_RGBA(struct CurveMapping *cumap, float **array, int *size); - +void BKE_histogram_update_sample_line(struct Histogram *hist, struct ImBuf *ibuf, const short use_color_management); void scopes_update(struct Scopes *scopes, struct ImBuf *ibuf, int use_color_management); void scopes_free(struct Scopes *scopes); void scopes_new(struct Scopes *scopes); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 12dee600532..6879ec506f0 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -946,6 +946,62 @@ static void save_sample_line(Scopes *scopes, const int idx, const float fx, cons } } +void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short use_color_management) +{ + int i, x, y; + float *fp; + float rgb[3]; + unsigned char *cp; + + int x1 = 0.5f + hist->co[0][0] * ibuf->x; + int x2 = 0.5f + hist->co[1][0] * ibuf->x; + int y1 = 0.5f + hist->co[0][1] * ibuf->y; + int y2 = 0.5f + hist->co[1][1] * ibuf->y; + + hist->channels = 3; + hist->x_resolution = 256; + hist->xmax = 1.0f; + hist->ymax = 1.0f; + + if (ibuf->rect == NULL && ibuf->rect_float == NULL) return; + + /* persistent draw */ + hist->flag |= HISTO_FLAG_SAMPLELINE; /* keep drawing the flag after */ + + for (i = 0; i < 256; i++) { + x = (int)(0.5f + x1 + (float)i * (x2 - x1) / 255.0f); + y = (int)(0.5f + y1 + (float)i * (y2 - y1) / 255.0f); + + if (x < 0 || y < 0 || x >= ibuf->x || y >= ibuf->y) { + hist->data_luma[i] = hist->data_r[i] = hist->data_g[i] = hist->data_b[i] = hist->data_a[i] = 0.0f; + } + else { + if (ibuf->rect_float) { + fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); + + if (use_color_management) + linearrgb_to_srgb_v3_v3(rgb, fp); + else + copy_v3_v3(rgb, fp); + + hist->data_luma[i] = rgb_to_luma(rgb); + hist->data_r[i] = rgb[0]; + hist->data_g[i] = rgb[1]; + hist->data_b[i] = rgb[2]; + hist->data_a[i] = fp[3]; + } + else if (ibuf->rect) { + cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x); + hist->data_luma[i] = (float)rgb_to_luma_byte(cp) / 255.0f; + hist->data_r[i] = (float)cp[0] / 255.0f; + hist->data_g[i] = (float)cp[1] / 255.0f; + hist->data_b[i] = (float)cp[2] / 255.0f; + hist->data_a[i] = (float)cp[3] / 255.0f; + } + } + } +} + void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) { int x, y, c; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 97f3bd744dc..7e67e737cc2 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -2110,11 +2110,6 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) Histogram *hist = &sima->sample_line_hist; float x1f, y1f, x2f, y2f; - int x1, y1, x2, y2; - int i, x, y; - float *fp; - float rgb[3]; - unsigned char *cp; if (ibuf == NULL) { ED_space_image_release_buffer(sima, lock); @@ -2128,55 +2123,13 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) UI_view2d_region_to_view(&ar->v2d, x_start, y_start, &x1f, &y1f); UI_view2d_region_to_view(&ar->v2d, x_end, y_end, &x2f, &y2f); - x1 = 0.5f + x1f * ibuf->x; - x2 = 0.5f + x2f * ibuf->x; - y1 = 0.5f + y1f * ibuf->y; - y2 = 0.5f + y2f * ibuf->y; - - hist->channels = 3; - hist->x_resolution = 256; - hist->xmax = 1.0f; - hist->ymax = 1.0f; - /* persistent draw */ hist->co[0][0] = x1f; hist->co[0][1] = y1f; hist->co[1][0] = x2f; hist->co[1][1] = y2f; - hist->flag |= HISTO_FLAG_SAMPLELINE; /* keep drawing the flag after */ - for (i = 0; i < 256; i++) { - x = (int)(0.5f + x1 + (float)i * (x2 - x1) / 255.0f); - y = (int)(0.5f + y1 + (float)i * (y2 - y1) / 255.0f); - - if (x < 0 || y < 0 || x >= ibuf->x || y >= ibuf->y) { - hist->data_luma[i] = hist->data_r[i] = hist->data_g[i] = hist->data_b[i] = hist->data_a[i] = 0.0f; - } - else { - if (ibuf->rect_float) { - fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); - - if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) - linearrgb_to_srgb_v3_v3(rgb, fp); - else - copy_v3_v3(rgb, fp); - - hist->data_luma[i] = rgb_to_luma(rgb); - hist->data_r[i] = rgb[0]; - hist->data_g[i] = rgb[1]; - hist->data_b[i] = rgb[2]; - hist->data_a[i] = fp[3]; - } - else if (ibuf->rect) { - cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x); - hist->data_luma[i] = (float)rgb_to_luma_byte(cp) / 255.0f; - hist->data_r[i] = (float)cp[0] / 255.0f; - hist->data_g[i] = (float)cp[1] / 255.0f; - hist->data_b[i] = (float)cp[2] / 255.0f; - hist->data_a[i] = (float)cp[3] / 255.0f; - } - } - } + BKE_histogram_update_sample_line(hist, ibuf, (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) != 0); ED_space_image_release_buffer(sima, lock); diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 6652a7470c2..32e6f588e27 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -914,6 +914,9 @@ static void image_scope_area_draw(const bContext *C, ARegion *ar) void *lock; ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock); if (ibuf) { + if (!sima->scopes.ok) { + BKE_histogram_update_sample_line(&sima->sample_line_hist, ibuf, scene->r.color_mgt_flag & R_COLOR_MANAGEMENT); + } scopes_update(&sima->scopes, ibuf, scene->r.color_mgt_flag & R_COLOR_MANAGEMENT); } ED_space_image_release_buffer(sima, lock); From 906b9e0584b93094b1c45514fbf6fd8c62e6d015 Mon Sep 17 00:00:00 2001 From: Dan Eicher Date: Wed, 13 Jun 2012 23:04:32 +0000 Subject: [PATCH 289/360] [#26630] Several problems with API constraint_orientation Added a check to TRANSFORM_OT_create_orientation so it throws an exception instead of crashing blender (due to invalid view3d) Can still create an orientation from the console just can't set it to active with the 'use' parameter --- source/blender/editors/transform/transform_ops.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index f00e2418ad9..81a4c082dcc 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -40,6 +40,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_armature.h" +#include "BKE_report.h" #include "WM_api.h" #include "WM_types.h" @@ -282,6 +283,11 @@ static int create_orientation_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "name", name); + if (use && !CTX_wm_view3d(C)) { + BKE_report(op->reports, RPT_ERROR, "Create Orientation \"use\" parameter only valid in a 3dView context"); + return OPERATOR_CANCELLED; + } + BIF_createTransformOrientation(C, op->reports, name, use, overwrite); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); From bde7e6c96b9e180b293ee6e49ab813a30fac0635 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jun 2012 23:31:47 +0000 Subject: [PATCH 290/360] stule cleanup: node headers --- source/blender/compositor/COM_compositor.h | 486 +++++++++--------- source/blender/compositor/COM_defines.h | 42 +- .../blender/compositor/intern/COM_CPUDevice.h | 14 +- .../compositor/intern/COM_ChannelInfo.h | 72 +-- .../compositor/intern/COM_ChunkOrder.h | 10 +- .../compositor/intern/COM_CompositorContext.h | 112 ++-- .../blender/compositor/intern/COM_Converter.h | 54 +- source/blender/compositor/intern/COM_Device.h | 24 +- .../compositor/intern/COM_ExecutionGroup.h | 418 +++++++-------- .../compositor/intern/COM_ExecutionSystem.h | 260 +++++----- .../intern/COM_ExecutionSystemHelper.h | 144 +++--- .../compositor/intern/COM_InputSocket.h | 104 ++-- .../compositor/intern/COM_MemoryBuffer.h | 102 ++-- .../compositor/intern/COM_MemoryProxy.h | 88 ++-- source/blender/compositor/intern/COM_Node.h | 90 ++-- .../blender/compositor/intern/COM_NodeBase.h | 160 +++--- .../compositor/intern/COM_NodeOperation.h | 288 +++++------ .../compositor/intern/COM_OpenCLDevice.h | 54 +- .../compositor/intern/COM_OutputSocket.h | 56 +- .../intern/COM_SingleThreadedNodeOperation.h | 18 +- source/blender/compositor/intern/COM_Socket.h | 58 +-- .../compositor/intern/COM_SocketConnection.h | 102 ++-- .../compositor/intern/COM_SocketReader.h | 58 +-- .../compositor/intern/COM_WorkPackage.h | 34 +- .../compositor/intern/COM_WorkScheduler.h | 90 ++-- .../compositor/nodes/COM_AlphaOverNode.h | 12 +- .../compositor/nodes/COM_BilateralBlurNode.h | 10 +- .../blender/compositor/nodes/COM_BlurNode.h | 10 +- .../compositor/nodes/COM_BokehBlurNode.h | 10 +- .../compositor/nodes/COM_BokehImageNode.h | 10 +- .../compositor/nodes/COM_BoxMaskNode.h | 10 +- .../compositor/nodes/COM_BrightnessNode.h | 10 +- .../compositor/nodes/COM_ChannelMatteNode.h | 6 +- .../compositor/nodes/COM_ChromaMatteNode.h | 6 +- .../compositor/nodes/COM_ColorBalanceNode.h | 6 +- .../nodes/COM_ColorCorrectionNode.h | 10 +- .../compositor/nodes/COM_ColorCurveNode.h | 10 +- .../compositor/nodes/COM_ColorMatteNode.h | 6 +- .../blender/compositor/nodes/COM_ColorNode.h | 10 +- .../compositor/nodes/COM_ColorRampNode.h | 8 +- .../compositor/nodes/COM_ColorSpillNode.h | 6 +- .../compositor/nodes/COM_ColorToBWNode.h | 8 +- .../compositor/nodes/COM_CombineHSVANode.h | 8 +- .../compositor/nodes/COM_CombineRGBANode.h | 8 +- .../compositor/nodes/COM_CombineYCCANode.h | 6 +- .../compositor/nodes/COM_CombineYUVANode.h | 6 +- .../compositor/nodes/COM_CompositorNode.h | 8 +- .../compositor/nodes/COM_ConvertAlphaNode.h | 12 +- .../blender/compositor/nodes/COM_CropNode.h | 4 +- .../compositor/nodes/COM_DefocusNode.h | 10 +- .../nodes/COM_DifferenceMatteNode.h | 8 +- .../compositor/nodes/COM_DilateErodeNode.h | 10 +- .../nodes/COM_DirectionalBlurNode.h | 10 +- .../compositor/nodes/COM_DisplaceNode.h | 2 +- .../compositor/nodes/COM_DistanceMatteNode.h | 6 +- .../compositor/nodes/COM_DoubleEdgeMaskNode.h | 10 +- .../compositor/nodes/COM_EllipseMaskNode.h | 10 +- .../blender/compositor/nodes/COM_FilterNode.h | 8 +- .../blender/compositor/nodes/COM_FlipNode.h | 10 +- .../blender/compositor/nodes/COM_GammaNode.h | 10 +- .../blender/compositor/nodes/COM_GlareNode.h | 10 +- .../blender/compositor/nodes/COM_GroupNode.h | 34 +- .../nodes/COM_HueSaturationValueCorrectNode.h | 8 +- .../nodes/COM_HueSaturationValueNode.h | 8 +- .../blender/compositor/nodes/COM_IDMaskNode.h | 10 +- .../blender/compositor/nodes/COM_ImageNode.h | 8 +- .../blender/compositor/nodes/COM_InvertNode.h | 10 +- .../compositor/nodes/COM_LensDistortionNode.h | 10 +- .../compositor/nodes/COM_LuminanceMatteNode.h | 6 +- .../blender/compositor/nodes/COM_MapUVNode.h | 2 +- .../compositor/nodes/COM_MapValueNode.h | 8 +- .../blender/compositor/nodes/COM_MaskNode.h | 6 +- .../blender/compositor/nodes/COM_MathNode.h | 12 +- source/blender/compositor/nodes/COM_MixNode.h | 8 +- .../compositor/nodes/COM_MovieClipNode.h | 8 +- .../nodes/COM_MovieDistortionNode.h | 10 +- .../blender/compositor/nodes/COM_MuteNode.h | 12 +- .../blender/compositor/nodes/COM_NormalNode.h | 8 +- .../compositor/nodes/COM_NormalizeNode.h | 10 +- .../compositor/nodes/COM_OutputFileNode.h | 8 +- .../compositor/nodes/COM_RenderLayersNode.h | 10 +- .../blender/compositor/nodes/COM_RotateNode.h | 10 +- .../blender/compositor/nodes/COM_ScaleNode.h | 10 +- .../compositor/nodes/COM_SeparateHSVANode.h | 8 +- .../compositor/nodes/COM_SeparateRGBANode.h | 8 +- .../compositor/nodes/COM_SeparateYCCANode.h | 6 +- .../compositor/nodes/COM_SeparateYUVANode.h | 6 +- .../compositor/nodes/COM_SetAlphaNode.h | 12 +- .../compositor/nodes/COM_SocketProxyNode.h | 10 +- .../compositor/nodes/COM_SplitViewerNode.h | 8 +- .../compositor/nodes/COM_Stabilize2dNode.h | 8 +- .../blender/compositor/nodes/COM_SwitchNode.h | 8 +- .../compositor/nodes/COM_TextureNode.h | 8 +- .../blender/compositor/nodes/COM_TimeNode.h | 10 +- .../compositor/nodes/COM_TonemapNode.h | 10 +- .../compositor/nodes/COM_TransformNode.h | 8 +- .../compositor/nodes/COM_TranslateNode.h | 10 +- .../blender/compositor/nodes/COM_ValueNode.h | 10 +- .../compositor/nodes/COM_VectorBlurNode.h | 10 +- .../compositor/nodes/COM_VectorCurveNode.h | 10 +- .../compositor/nodes/COM_ViewLevelsNode.h | 10 +- .../blender/compositor/nodes/COM_ViewerNode.h | 8 +- .../compositor/nodes/COM_ZCombineNode.h | 12 +- .../operations/COM_AlphaOverKeyOperation.h | 16 +- .../operations/COM_AlphaOverMixedOperation.h | 18 +- .../COM_AlphaOverPremultiplyOperation.h | 16 +- .../operations/COM_AntiAliasOperation.h | 28 +- .../operations/COM_BilateralBlurOperation.h | 16 +- .../operations/COM_BlurBaseOperation.h | 22 +- .../operations/COM_BokehBlurOperation.h | 16 +- .../operations/COM_BokehImageOperation.h | 18 +- .../operations/COM_BoxMaskOperation.h | 28 +- .../operations/COM_BrightnessOperation.h | 18 +- .../operations/COM_CalculateMeanOperation.h | 28 +- .../COM_CalculateStandardDeviationOperation.h | 12 +- .../operations/COM_ChangeHSVOperation.h | 26 +- .../operations/COM_ChannelMatteOperation.h | 30 +- .../operations/COM_ChromaMatteOperation.h | 18 +- .../COM_ColorBalanceASCCDLOperation.h | 51 +- .../operations/COM_ColorBalanceLGGOperation.h | 32 +- .../operations/COM_ColorCorrectionOperation.h | 26 +- .../operations/COM_ColorCurveOperation.h | 52 +- .../operations/COM_ColorMatteOperation.h | 18 +- .../operations/COM_ColorRampOperation.h | 24 +- .../operations/COM_ColorSpillOperation.h | 22 +- .../operations/COM_CombineChannelsOperation.h | 4 +- .../COM_ConvertColorProfileOperation.h | 48 +- .../COM_ConvertColorToBWOperation.h | 30 +- .../COM_ConvertColorToVectorOperation.h | 30 +- .../operations/COM_ConvertColourToValueProg.h | 30 +- .../COM_ConvertDepthToRadiusOperation.h | 36 +- .../operations/COM_ConvertHSVToRGBOperation.h | 30 +- .../COM_ConvertKeyToPremulOperation.h | 16 +- .../COM_ConvertPremulToKeyOperation.h | 16 +- .../operations/COM_ConvertRGBToHSVOperation.h | 30 +- .../operations/COM_ConvertRGBToYCCOperation.h | 38 +- .../operations/COM_ConvertRGBToYUVOperation.h | 30 +- .../operations/COM_ConvertValueToColourProg.h | 18 +- .../COM_ConvertValueToVectorOperation.h | 30 +- .../COM_ConvertVectorToColorOperation.h | 30 +- .../COM_ConvertVectorToValueOperation.h | 30 +- .../operations/COM_ConvertYCCToRGBOperation.h | 38 +- .../operations/COM_ConvertYUVToRGBOperation.h | 30 +- .../COM_ConvolutionEdgeFilterOperation.h | 4 +- .../COM_ConvolutionFilterOperation.h | 4 +- .../compositor/operations/COM_CropOperation.h | 14 +- .../operations/COM_CurveBaseOperation.h | 6 +- .../operations/COM_DifferenceMatteOperation.h | 20 +- .../operations/COM_DilateErodeOperation.h | 86 ++-- .../operations/COM_DirectionalBlurOperation.h | 16 +- .../operations/COM_DisplaceOperation.h | 6 +- .../operations/COM_DisplaceSimpleOperation.h | 6 +- .../operations/COM_DistanceMatteOperation.h | 18 +- .../operations/COM_DotproductOperation.h | 4 +- .../operations/COM_DoubleEdgeMaskOperation.h | 26 +- .../operations/COM_EllipseMaskOperation.h | 28 +- .../COM_FastGaussianBlurOperation.h | 4 +- .../compositor/operations/COM_FlipOperation.h | 8 +- .../operations/COM_FogGlowImageOperation.h | 6 +- .../operations/COM_GammaCorrectOperation.h | 40 +- .../operations/COM_GammaOperation.h | 20 +- .../COM_GaussianBokehBlurOperation.h | 10 +- .../operations/COM_GaussianXBlurOperation.h | 14 +- .../operations/COM_GaussianYBlurOperation.h | 14 +- .../operations/COM_GlareBaseOperation.h | 28 +- .../COM_HueSaturationValueCorrectOperation.h | 20 +- .../operations/COM_IDMaskOperation.h | 20 +- .../operations/COM_ImageOperation.h | 40 +- .../operations/COM_InvertOperation.h | 26 +- .../operations/COM_LuminanceMatteOperation.h | 18 +- .../operations/COM_MapUVOperation.h | 6 +- .../operations/COM_MapValueOperation.h | 38 +- .../compositor/operations/COM_MaskOperation.h | 20 +- .../operations/COM_MathBaseOperation.h | 104 ++-- .../operations/COM_MixAddOperation.h | 16 +- .../operations/COM_MixBaseOperation.h | 32 +- .../operations/COM_MixBlendOperation.h | 16 +- .../operations/COM_MixBurnOperation.h | 16 +- .../operations/COM_MixColorOperation.h | 16 +- .../operations/COM_MixDarkenOperation.h | 16 +- .../operations/COM_MixDifferenceOperation.h | 16 +- .../operations/COM_MixDivideOperation.h | 16 +- .../operations/COM_MixDodgeOperation.h | 16 +- .../operations/COM_MixHueOperation.h | 16 +- .../operations/COM_MixLightenOperation.h | 16 +- .../operations/COM_MixLinearLightOperation.h | 16 +- .../operations/COM_MixMultiplyOperation.h | 16 +- .../operations/COM_MixOverlayOperation.h | 16 +- .../operations/COM_MixSaturationOperation.h | 16 +- .../operations/COM_MixScreenOperation.h | 16 +- .../operations/COM_MixSoftLightOperation.h | 16 +- .../operations/COM_MixSubtractOperation.h | 16 +- .../operations/COM_MixValueOperation.h | 16 +- .../COM_MovieClipAttributeOperation.h | 24 +- .../operations/COM_MovieClipOperation.h | 22 +- .../operations/COM_MovieDistortionOperation.h | 48 +- .../operations/COM_MultilayerImageOperation.h | 26 +- .../operations/COM_NormalizeOperation.h | 34 +- .../operations/COM_OutputFileOperation.h | 14 +- .../operations/COM_PreviewOperation.h | 10 +- .../COM_ProjectorLensDistortionOperation.h | 26 +- .../operations/COM_QualityStepHelper.h | 10 +- .../operations/COM_ReadBufferOperation.h | 22 +- .../operations/COM_RenderLayersAlphaProg.h | 2 +- .../operations/COM_RenderLayersBaseProg.h | 55 +- .../operations/COM_RotateOperation.h | 6 +- .../operations/COM_ScaleOperation.h | 4 +- .../COM_ScreenLensDistortionOperation.h | 26 +- .../operations/COM_SeparateChannelOperation.h | 6 +- .../operations/COM_SetAlphaOperation.h | 16 +- .../operations/COM_SetColorOperation.h | 18 +- .../operations/COM_SetSamplerOperation.h | 18 +- .../operations/COM_SetValueOperation.h | 22 +- .../operations/COM_SetVectorOperation.h | 34 +- .../operations/COM_SocketProxyOperation.h | 4 +- .../operations/COM_SplitViewerOperation.h | 6 +- .../operations/COM_TextureOperation.h | 28 +- .../operations/COM_TonemapOperation.h | 60 +-- .../operations/COM_TranslateOperation.h | 12 +- .../COM_VariableSizeBokehBlurOperation.h | 20 +- .../operations/COM_VectorBlurOperation.h | 32 +- .../operations/COM_VectorCurveOperation.h | 20 +- .../operations/COM_ViewerBaseOperation.h | 28 +- .../operations/COM_ViewerOperation.h | 2 +- .../operations/COM_WriteBufferOperation.h | 20 +- .../operations/COM_ZCombineOperation.h | 20 +- 226 files changed, 3184 insertions(+), 3192 deletions(-) diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h index b33a48464e1..4789fed2efd 100644 --- a/source/blender/compositor/COM_compositor.h +++ b/source/blender/compositor/COM_compositor.h @@ -21,256 +21,256 @@ */ #ifdef __cplusplus - extern "C" { +extern "C" { #endif #include "DNA_node_types.h" /** - * @defgroup Model The data model of the compositor - * @defgroup Memory The memory management stuff - * @defgroup Execution The execution logic - * @defgroup Conversion Conversion logic - * @defgroup Node All nodes of the compositor - * @defgroup Operation All operations of the compositor - * - * @mainpage Introduction of the Blender Compositor - * - * @section bcomp Blender compositor - * This project redesigns the interals of Blender's compositor. The project has been executed in 2011 by At Mind. - * At Mind is a technology company located in Amsterdam, The Netherlands. - * The project has been crowdfunded. This code has been released under GPL2 to be used in Blender. - * - * @section goals The goals of the project - * the new compositor has 2 goals. - * - Make a faster compositor (speed of calculation) - * - Make the compositor work faster for you (workflow) - * - * @section speed Faster compositor - * The speedup has been done by making better use of the hardware Blenders is working on. The previous compositor only - * used a single threaded model to calculate a node. The only exception to this is the Defocus node. - * Only when it is possible to calculate two full nodes in parallel a second thread was used. - * Current workstations have 8-16 threads available, and most of the time these are idle. - * - * In the new compositor we want to use as much of threads as possible. Even new OpenCL capable GPU-hardware can be - * used for calculation. - * - * @section workflow Work faster - * The previous compositor only showed the final image. The compositor could wait a long time before seeing the result - * of his work. The new compositor will work in a way that it will focus on getting information back to the user. - * It will prioritise its work to get earlier user feedback. - * - * @page memory Memory model - * The main issue is the type of memory model to use. Blender is used by consumers and professionals. - * Ranging from low-end machines to very high-end machines. - * The system should work on high-end machines and on low-end machines. - * - * - * @page executing Executing - * @section prepare Prepare execution - * - * during the preparation of the execution All ReadBufferOperation will receive an offset. - * This offset is used during execution as an optimization trick - * Next all operations will be initialized for execution @see NodeOperation.initExecution - * Next all ExecutionGroup's will be initialized for execution @see ExecutionGroup.initExecution - * this all is controlled from @see ExecutionSystem.execute - * - * @section priority Render priority - * Render priority is an priority of an output node. A user has a different need of Render priorities of output nodes - * than during editing. - * for example. the Active ViewerNode has top priority during editing, but during rendering a CompositeNode has. - * All NodeOperation has a setting for their renderpriority, but only for output NodeOperation these have effect. - * In ExecutionSystem.execute all priorities are checked. For every priority the ExecutionGroup's are check if the - * priority do match. - * When match the ExecutionGroup will be executed (this happens in serial) - * - * @see ExecutionSystem.execute control of the Render priority - * @see NodeOperation.getRenderPriority receive the render priority - * @see ExecutionGroup.execute the main loop to execute a whole ExecutionGroup - * - * @section order Chunk order - * - * When a ExecutionGroup is executed, first the order of chunks are determined. - * The settings are stored in the ViewerNode inside the ExecutionGroup. ExecutionGroups that have no viewernode, - * will use a default one. - * There are several possible chunk orders - * - [@ref OrderOfChunks.COM_TO_CENTER_OUT]: Start calculating from a configurable point and order by nearest chunk - * - [@ref OrderOfChunks.COM_TO_RANDOM]: Randomize all chunks. - * - [@ref OrderOfChunks.COM_TO_TOP_DOWN]: Start calculation from the bottom to the top of the image - * - [@ref OrderOfChunks.COM_TO_RULE_OF_THIRDS]: Experimental order based on 9 hotspots in the image - * - * When the chunkorder is determined, the first few chunks will be checked if they can be scheduled. - * Chunks can have three states: - * - [@ref ChunkExecutionState.COM_ES_NOT_SCHEDULED]: Chunk is not yet scheduled, or dependacies are not met - * - [@ref ChunkExecutionState.COM_ES_SCHEDULED]: All dependacies are met, chunk is scheduled, but not finished - * - [@ref ChunkExecutionState.COM_ES_EXECUTED]: Chunk is finished - * - * @see ExecutionGroup.execute - * @see ViewerBaseOperation.getChunkOrder - * @see OrderOfChunks - * - * @section interest Area of interest - * An ExecutionGroup can have dependancies to other ExecutionGroup's. Data passing from one ExecutionGroup to another - * one are stored in 'chunks'. - * If not all input chunks are available the chunk execution will not be scheduled. - *
-  * +-------------------------------------+              +--------------------------------------+
-  * | ExecutionGroup A                    |              | ExecutionGroup B                     |
-  * | +----------------+  +-------------+ |              | +------------+   +-----------------+ |
-  * | | NodeOperation a|  | WriteBuffer | |              | | ReadBuffer |   | ViewerOperation | |
-  * | |                *==* Operation   | |              | | Operation  *===*                 | |
-  * | |                |  |             | |              | |            |   |                 | |
-  * | +----------------+  +-------------+ |              | +------------+   +-----------------+ |
-  * |                                |    |              |   |                                  |
-  * +--------------------------------|----+              +---|----------------------------------+
-  *                                  |                       |
-  *                                  |                       |
-  *                                +---------------------------+
-  *                                | MemoryProxy               |
-  *                                | +----------+  +---------+ |
-  *                                | | Chunk a  |  | Chunk b | |
-  *                                | |          |  |         | |
-  *                                | +----------+  +---------+ |
-  *                                |                           |
-  *                                +---------------------------+
-  * 
- * - * In the above example ExecutionGroup B has an outputoperation (ViewerOperation) and is being executed. - * The first chunk is evaluated [@ref ExecutionGroup.scheduleChunkWhenPossible], - * but not all input chunks are available. The relevant ExecutionGroup (that can calculate the missing chunks; - * ExecutionGroup A) is asked to calculate the area ExecutionGroup B is missing. - * [@ref ExecutionGroup.scheduleAreaWhenPossible] - * ExecutionGroup B checks what chunks the area spans, and tries to schedule these chunks. - * If all input data is available these chunks are scheduled [@ref ExecutionGroup.scheduleChunk] - * - *
-  *
-  * +-------------------------+        +----------------+                           +----------------+
-  * | ExecutionSystem.execute |        | ExecutionGroup |                           | ExecutionGroup |
-  * +-------------------------+        | (B)            |                           | (A)            |
-  *            O                       +----------------+                           +----------------+
-  *            O                                |                                            |
-  *            O       ExecutionGroup.execute   |                                            |
-  *            O------------------------------->O                                            |
-  *            .                                O                                            |
-  *            .                                O-------\                                    |
-  *            .                                .       | ExecutionGroup.scheduleChunkWhenPossible
-  *            .                                .  O----/ (*)                                |
-  *            .                                .  O                                         |
-  *            .                                .  O                                         |
-  *            .                                .  O  ExecutionGroup.scheduleAreaWhenPossible|
-  *            .                                .  O---------------------------------------->O
-  *            .                                .  .                                         O----------\ ExecutionGroup.scheduleChunkWhenPossible
-  *            .                                .  .                                         .          | (*)
-  *            .                                .  .                                         .  O-------/
-  *            .                                .  .                                         .  O
-  *            .                                .  .                                         .  O
-  *            .                                .  .                                         .  O-------\ ExecutionGroup.scheduleChunk
-  *            .                                .  .                                         .  .       |
-  *            .                                .  .                                         .  .  O----/
-  *            .                                .  .                                         .  O<=O
-  *            .                                .  .                                         O<=O
-  *            .                                .  .                                         O
-  *            .                                .  O<========================================O
-  *            .                                .  O                                         |
-  *            .                                O<=O                                         |
-  *            .                                O                                            |
-  *            .                                O                                            |
-  * 
- * - * This happens until all chunks of (ExecutionGroup B) are finished executing or the user break's the process. - * - * NodeOperation like the ScaleOperation can influence the area of interest by reimplementing the - * [@ref NodeOperation.determineAreaOfInterest] method - * - *
-  *
-  * +--------------------------+                             +---------------------------------+
-  * | ExecutionGroup A         |                             | ExecutionGroup B                |
-  * |                          |                             |                                 |
-  * +--------------------------+                             +---------------------------------+
-  *           Needed chunks from ExecutionGroup A               |   Chunk of ExecutionGroup B (to be evaluated)
-  *            +-------+ +-------+                              |                  +--------+
-  *            |Chunk 1| |Chunk 2|               +----------------+                |Chunk 1 |
-  *            |       | |       |               | ScaleOperation |                |        |
-  *            +-------+ +-------+               +----------------+                +--------+
-  *
-  *            +-------+ +-------+
-  *            |Chunk 3| |Chunk 4|
-  *            |       | |       |
-  *            +-------+ +-------+
-  *
-  * 
- * - * @see ExecutionGroup.execute Execute a complete ExecutionGroup. Halts until finished or breaked by user - * @see ExecutionGroup.scheduleChunkWhenPossible Tries to schedule a single chunk, - * checks if all input data is available. Can trigger dependant chunks to be calculated - * @see ExecutionGroup.scheduleAreaWhenPossible Tries to schedule an area. This can be multiple chunks - * (is called from [@ref ExecutionGroup.scheduleChunkWhenPossible]) - * @see ExecutionGroup.scheduleChunk Schedule a chunk on the WorkScheduler - * @see NodeOperation.determineDependingAreaOfInterest Influence the area of interest of a chunk. - * @see WriteBufferOperation NodeOperation to write to a MemoryProxy/MemoryBuffer - * @see ReadBufferOperation NodeOperation to read from a MemoryProxy/MemoryBuffer - * @see MemoryProxy proxy for information about memory image (a image consist out of multiple chunks) - * @see MemoryBuffer Allocated memory for a single chunk - * - * @section workscheduler WorkScheduler - * the WorkScheduler is implemented as a static class. the responsibility of the WorkScheduler is to balance - * WorkPackages to the available and free devices. - * the workscheduler can work in 2 states. For witching these between the state you need to recompile blender - * - * @subsection multithread Multi threaded - * Default the workscheduler will place all work as WorkPackage in a queue. - * For every CPUcore a working thread is created. These working threads will ask the WorkScheduler if there is work - * for a specific Device. - * the workscheduler will find work for the device and the device will be asked to execute the WorkPackage + * @defgroup Model The data model of the compositor + * @defgroup Memory The memory management stuff + * @defgroup Execution The execution logic + * @defgroup Conversion Conversion logic + * @defgroup Node All nodes of the compositor + * @defgroup Operation All operations of the compositor + * + * @mainpage Introduction of the Blender Compositor + * + * @section bcomp Blender compositor + * This project redesigns the interals of Blender's compositor. The project has been executed in 2011 by At Mind. + * At Mind is a technology company located in Amsterdam, The Netherlands. + * The project has been crowdfunded. This code has been released under GPL2 to be used in Blender. + * + * @section goals The goals of the project + * the new compositor has 2 goals. + * - Make a faster compositor (speed of calculation) + * - Make the compositor work faster for you (workflow) + * + * @section speed Faster compositor + * The speedup has been done by making better use of the hardware Blenders is working on. The previous compositor only + * used a single threaded model to calculate a node. The only exception to this is the Defocus node. + * Only when it is possible to calculate two full nodes in parallel a second thread was used. + * Current workstations have 8-16 threads available, and most of the time these are idle. + * + * In the new compositor we want to use as much of threads as possible. Even new OpenCL capable GPU-hardware can be + * used for calculation. + * + * @section workflow Work faster + * The previous compositor only showed the final image. The compositor could wait a long time before seeing the result + * of his work. The new compositor will work in a way that it will focus on getting information back to the user. + * It will prioritise its work to get earlier user feedback. + * + * @page memory Memory model + * The main issue is the type of memory model to use. Blender is used by consumers and professionals. + * Ranging from low-end machines to very high-end machines. + * The system should work on high-end machines and on low-end machines. + * + * + * @page executing Executing + * @section prepare Prepare execution + * + * during the preparation of the execution All ReadBufferOperation will receive an offset. + * This offset is used during execution as an optimization trick + * Next all operations will be initialized for execution @see NodeOperation.initExecution + * Next all ExecutionGroup's will be initialized for execution @see ExecutionGroup.initExecution + * this all is controlled from @see ExecutionSystem.execute + * + * @section priority Render priority + * Render priority is an priority of an output node. A user has a different need of Render priorities of output nodes + * than during editing. + * for example. the Active ViewerNode has top priority during editing, but during rendering a CompositeNode has. + * All NodeOperation has a setting for their renderpriority, but only for output NodeOperation these have effect. + * In ExecutionSystem.execute all priorities are checked. For every priority the ExecutionGroup's are check if the + * priority do match. + * When match the ExecutionGroup will be executed (this happens in serial) + * + * @see ExecutionSystem.execute control of the Render priority + * @see NodeOperation.getRenderPriority receive the render priority + * @see ExecutionGroup.execute the main loop to execute a whole ExecutionGroup + * + * @section order Chunk order + * + * When a ExecutionGroup is executed, first the order of chunks are determined. + * The settings are stored in the ViewerNode inside the ExecutionGroup. ExecutionGroups that have no viewernode, + * will use a default one. + * There are several possible chunk orders + * - [@ref OrderOfChunks.COM_TO_CENTER_OUT]: Start calculating from a configurable point and order by nearest chunk + * - [@ref OrderOfChunks.COM_TO_RANDOM]: Randomize all chunks. + * - [@ref OrderOfChunks.COM_TO_TOP_DOWN]: Start calculation from the bottom to the top of the image + * - [@ref OrderOfChunks.COM_TO_RULE_OF_THIRDS]: Experimental order based on 9 hotspots in the image + * + * When the chunkorder is determined, the first few chunks will be checked if they can be scheduled. + * Chunks can have three states: + * - [@ref ChunkExecutionState.COM_ES_NOT_SCHEDULED]: Chunk is not yet scheduled, or dependacies are not met + * - [@ref ChunkExecutionState.COM_ES_SCHEDULED]: All dependacies are met, chunk is scheduled, but not finished + * - [@ref ChunkExecutionState.COM_ES_EXECUTED]: Chunk is finished + * + * @see ExecutionGroup.execute + * @see ViewerBaseOperation.getChunkOrder + * @see OrderOfChunks + * + * @section interest Area of interest + * An ExecutionGroup can have dependancies to other ExecutionGroup's. Data passing from one ExecutionGroup to another + * one are stored in 'chunks'. + * If not all input chunks are available the chunk execution will not be scheduled. + *
+ * +-------------------------------------+              +--------------------------------------+
+ * | ExecutionGroup A                    |              | ExecutionGroup B                     |
+ * | +----------------+  +-------------+ |              | +------------+   +-----------------+ |
+ * | | NodeOperation a|  | WriteBuffer | |              | | ReadBuffer |   | ViewerOperation | |
+ * | |                *==* Operation   | |              | | Operation  *===*                 | |
+ * | |                |  |             | |              | |            |   |                 | |
+ * | +----------------+  +-------------+ |              | +------------+   +-----------------+ |
+ * |                                |    |              |   |                                  |
+ * +--------------------------------|----+              +---|----------------------------------+
+ *                                  |                       |
+ *                                  |                       |
+ *                                +---------------------------+
+ *                                | MemoryProxy               |
+ *                                | +----------+  +---------+ |
+ *                                | | Chunk a  |  | Chunk b | |
+ *                                | |          |  |         | |
+ *                                | +----------+  +---------+ |
+ *                                |                           |
+ *                                +---------------------------+
+ * 
+ * + * In the above example ExecutionGroup B has an outputoperation (ViewerOperation) and is being executed. + * The first chunk is evaluated [@ref ExecutionGroup.scheduleChunkWhenPossible], + * but not all input chunks are available. The relevant ExecutionGroup (that can calculate the missing chunks; + * ExecutionGroup A) is asked to calculate the area ExecutionGroup B is missing. + * [@ref ExecutionGroup.scheduleAreaWhenPossible] + * ExecutionGroup B checks what chunks the area spans, and tries to schedule these chunks. + * If all input data is available these chunks are scheduled [@ref ExecutionGroup.scheduleChunk] + * + *
+ *
+ * +-------------------------+        +----------------+                           +----------------+
+ * | ExecutionSystem.execute |        | ExecutionGroup |                           | ExecutionGroup |
+ * +-------------------------+        | (B)            |                           | (A)            |
+ *            O                       +----------------+                           +----------------+
+ *            O                                |                                            |
+ *            O       ExecutionGroup.execute   |                                            |
+ *            O------------------------------->O                                            |
+ *            .                                O                                            |
+ *            .                                O-------\                                    |
+ *            .                                .       | ExecutionGroup.scheduleChunkWhenPossible
+ *            .                                .  O----/ (*)                                |
+ *            .                                .  O                                         |
+ *            .                                .  O                                         |
+ *            .                                .  O  ExecutionGroup.scheduleAreaWhenPossible|
+ *            .                                .  O---------------------------------------->O
+ *            .                                .  .                                         O----------\ ExecutionGroup.scheduleChunkWhenPossible
+ *            .                                .  .                                         .          | (*)
+ *            .                                .  .                                         .  O-------/
+ *            .                                .  .                                         .  O
+ *            .                                .  .                                         .  O
+ *            .                                .  .                                         .  O-------\ ExecutionGroup.scheduleChunk
+ *            .                                .  .                                         .  .       |
+ *            .                                .  .                                         .  .  O----/
+ *            .                                .  .                                         .  O<=O
+ *            .                                .  .                                         O<=O
+ *            .                                .  .                                         O
+ *            .                                .  O<========================================O
+ *            .                                .  O                                         |
+ *            .                                O<=O                                         |
+ *            .                                O                                            |
+ *            .                                O                                            |
+ * 
+ * + * This happens until all chunks of (ExecutionGroup B) are finished executing or the user break's the process. + * + * NodeOperation like the ScaleOperation can influence the area of interest by reimplementing the + * [@ref NodeOperation.determineAreaOfInterest] method + * + *
+ *
+ * +--------------------------+                             +---------------------------------+
+ * | ExecutionGroup A         |                             | ExecutionGroup B                |
+ * |                          |                             |                                 |
+ * +--------------------------+                             +---------------------------------+
+ *           Needed chunks from ExecutionGroup A               |   Chunk of ExecutionGroup B (to be evaluated)
+ *            +-------+ +-------+                              |                  +--------+
+ *            |Chunk 1| |Chunk 2|               +----------------+                |Chunk 1 |
+ *            |       | |       |               | ScaleOperation |                |        |
+ *            +-------+ +-------+               +----------------+                +--------+
+ *
+ *            +-------+ +-------+
+ *            |Chunk 3| |Chunk 4|
+ *            |       | |       |
+ *            +-------+ +-------+
+ *
+ * 
+ * + * @see ExecutionGroup.execute Execute a complete ExecutionGroup. Halts until finished or breaked by user + * @see ExecutionGroup.scheduleChunkWhenPossible Tries to schedule a single chunk, + * checks if all input data is available. Can trigger dependant chunks to be calculated + * @see ExecutionGroup.scheduleAreaWhenPossible Tries to schedule an area. This can be multiple chunks + * (is called from [@ref ExecutionGroup.scheduleChunkWhenPossible]) + * @see ExecutionGroup.scheduleChunk Schedule a chunk on the WorkScheduler + * @see NodeOperation.determineDependingAreaOfInterest Influence the area of interest of a chunk. + * @see WriteBufferOperation NodeOperation to write to a MemoryProxy/MemoryBuffer + * @see ReadBufferOperation NodeOperation to read from a MemoryProxy/MemoryBuffer + * @see MemoryProxy proxy for information about memory image (a image consist out of multiple chunks) + * @see MemoryBuffer Allocated memory for a single chunk + * + * @section workscheduler WorkScheduler + * the WorkScheduler is implemented as a static class. the responsibility of the WorkScheduler is to balance + * WorkPackages to the available and free devices. + * the workscheduler can work in 2 states. For witching these between the state you need to recompile blender + * + * @subsection multithread Multi threaded + * Default the workscheduler will place all work as WorkPackage in a queue. + * For every CPUcore a working thread is created. These working threads will ask the WorkScheduler if there is work + * for a specific Device. + * the workscheduler will find work for the device and the device will be asked to execute the WorkPackage - * @subsection singlethread Single threaded - * For debugging reasons the multi-threading can be disabled. This is done by changing the COM_CURRENT_THREADING_MODEL - * to COM_TM_NOTHREAD. When compiling the workscheduler - * will be changes to support no threading and run everything on the CPU. - * - * @section devices Devices - * A Device within the compositor context is a Hardware component that can used to calculate chunks. - * This chunk is encapseled in a WorkPackage. - * the WorkScheduler controls the devices and selects the device where a WorkPackage will be calculated. - * - * @subsection WS_Devices Workscheduler - * The WorkScheduler controls all Devices. When initializing the compositor the WorkScheduler selects - * all devices that will be used during compositor. - * There are two types of Devices, CPUDevice and OpenCLDevice. - * When an ExecutionGroup schedules a Chunk the schedule method of the WorkScheduler - * The Workscheduler determines if the chunk can be run on an OpenCLDevice - * (and that there are available OpenCLDevice). If this is the case the chunk will be added to the worklist for - * OpenCLDevice's - * otherwise the chunk will be added to the worklist of CPUDevices. - * - * A thread will read the work-list and sends a workpackage to its device. - * - * @see WorkScheduler.schedule method that is called to schedule a chunk - * @see Device.execute method called to execute a chunk - * - * @subsection CPUDevice CPUDevice - * When a CPUDevice gets a WorkPackage the Device will get the inputbuffer that is needed to calculate the chunk. - * Allocation is already done by the ExecutionGroup. - * The outputbuffer of the chunk is being created. - * The OutputOperation of the ExecutionGroup is called to execute the area of the outputbuffer. - * - * @see ExecutionGroup - * @see NodeOperation.executeRegion executes a single chunk of a NodeOperation - * @see CPUDevice.execute - * - * @subsection GPUDevice OpenCLDevice - * - * To be completed! - * @see NodeOperation.executeOpenCLRegion - * @see OpenCLDevice.execute - * - * @section executePixel executing a pixel - * Finally the last step, the node functionality :) + * @subsection singlethread Single threaded + * For debugging reasons the multi-threading can be disabled. This is done by changing the COM_CURRENT_THREADING_MODEL + * to COM_TM_NOTHREAD. When compiling the workscheduler + * will be changes to support no threading and run everything on the CPU. + * + * @section devices Devices + * A Device within the compositor context is a Hardware component that can used to calculate chunks. + * This chunk is encapseled in a WorkPackage. + * the WorkScheduler controls the devices and selects the device where a WorkPackage will be calculated. + * + * @subsection WS_Devices Workscheduler + * The WorkScheduler controls all Devices. When initializing the compositor the WorkScheduler selects + * all devices that will be used during compositor. + * There are two types of Devices, CPUDevice and OpenCLDevice. + * When an ExecutionGroup schedules a Chunk the schedule method of the WorkScheduler + * The Workscheduler determines if the chunk can be run on an OpenCLDevice + * (and that there are available OpenCLDevice). If this is the case the chunk will be added to the worklist for + * OpenCLDevice's + * otherwise the chunk will be added to the worklist of CPUDevices. + * + * A thread will read the work-list and sends a workpackage to its device. + * + * @see WorkScheduler.schedule method that is called to schedule a chunk + * @see Device.execute method called to execute a chunk + * + * @subsection CPUDevice CPUDevice + * When a CPUDevice gets a WorkPackage the Device will get the inputbuffer that is needed to calculate the chunk. + * Allocation is already done by the ExecutionGroup. + * The outputbuffer of the chunk is being created. + * The OutputOperation of the ExecutionGroup is called to execute the area of the outputbuffer. + * + * @see ExecutionGroup + * @see NodeOperation.executeRegion executes a single chunk of a NodeOperation + * @see CPUDevice.execute + * + * @subsection GPUDevice OpenCLDevice + * + * To be completed! + * @see NodeOperation.executeOpenCLRegion + * @see OpenCLDevice.execute + * + * @section executePixel executing a pixel + * Finally the last step, the node functionality :) - * @page newnode Creating new nodes - */ + * @page newnode Creating new nodes + */ /** * @brief The main method that is used to execute the compositor tree. diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h index 1aa023bea3a..d072b4ca727 100644 --- a/source/blender/compositor/COM_defines.h +++ b/source/blender/compositor/COM_defines.h @@ -24,9 +24,9 @@ #define _COM_defines_h_ /** - * @brief possible data types for SocketConnection - * @ingroup Model - */ + * @brief possible data types for SocketConnection + * @ingroup Model + */ typedef enum DataType { /** @brief Unknown data type (or not yet known) */ COM_DT_UNKNOWN = 0, @@ -39,13 +39,13 @@ typedef enum DataType { } DataType; /** - * @brief Possible quality settings - * @see CompositorContext.quality - * @ingroup Execution - */ + * @brief Possible quality settings + * @see CompositorContext.quality + * @ingroup Execution + */ typedef enum CompositorQuality { /** @brief High quality setting */ - COM_QUALITY_HIGH = 0 , + COM_QUALITY_HIGH = 0, /** @brief Medium quality setting */ COM_QUALITY_MEDIUM = 1, /** @brief Low quality setting */ @@ -53,12 +53,12 @@ typedef enum CompositorQuality { } CompositorQuality; /** - * @brief Possible priority settings - * @ingroup Execution - */ + * @brief Possible priority settings + * @ingroup Execution + */ typedef enum CompositorPriority { /** @brief High quality setting */ - COM_PRIORITY_HIGH = 2 , + COM_PRIORITY_HIGH = 2, /** @brief Medium quality setting */ COM_PRIORITY_MEDIUM = 1, /** @brief Low quality setting */ @@ -74,24 +74,24 @@ typedef enum CompositorPriority { // workscheduler threading models /** - * COM_TM_QUEUE is a multithreaded model, which uses the BLI_thread_queue pattern. This is the default option. - */ + * COM_TM_QUEUE is a multithreaded model, which uses the BLI_thread_queue pattern. This is the default option. + */ #define COM_TM_QUEUE 1 /** - * COM_TM_NOTHREAD is a single threading model, everything is executed in the caller thread. easy for debugging - */ + * COM_TM_NOTHREAD is a single threading model, everything is executed in the caller thread. easy for debugging + */ #define COM_TM_NOTHREAD 0 /** - * COM_CURRENT_THREADING_MODEL can be one of the above, COM_TM_QUEUE is currently default. - */ + * COM_CURRENT_THREADING_MODEL can be one of the above, COM_TM_QUEUE is currently default. + */ #define COM_CURRENT_THREADING_MODEL COM_TM_QUEUE // chunk order /** - * @brief The order of chunks to be scheduled - * @ingroup Execution - */ + * @brief The order of chunks to be scheduled + * @ingroup Execution + */ typedef enum OrderOfChunks { /** @brief order from a distance to centerX/centerY */ COM_TO_CENTER_OUT = 0, diff --git a/source/blender/compositor/intern/COM_CPUDevice.h b/source/blender/compositor/intern/COM_CPUDevice.h index f577e2b8926..3dc8fff66a3 100644 --- a/source/blender/compositor/intern/COM_CPUDevice.h +++ b/source/blender/compositor/intern/COM_CPUDevice.h @@ -26,15 +26,15 @@ #include "COM_Device.h" /** - * @brief class representing a CPU device. - * @note for every hardware thread in the system a CPUDevice instance will exist in the workscheduler - */ -class CPUDevice: public Device { + * @brief class representing a CPU device. + * @note for every hardware thread in the system a CPUDevice instance will exist in the workscheduler + */ +class CPUDevice : public Device { public: /** - * @brief execute a WorkPackage - * @param work the WorkPackage to execute - */ + * @brief execute a WorkPackage + * @param work the WorkPackage to execute + */ void execute(WorkPackage *work); }; diff --git a/source/blender/compositor/intern/COM_ChannelInfo.h b/source/blender/compositor/intern/COM_ChannelInfo.h index 40933bce6f5..399fdc62fa2 100644 --- a/source/blender/compositor/intern/COM_ChannelInfo.h +++ b/source/blender/compositor/intern/COM_ChannelInfo.h @@ -32,9 +32,9 @@ using namespace std; /** - * @brief List of possible channel types - * @ingroup Model - */ + * @brief List of possible channel types + * @ingroup Model + */ typedef enum ChannelType { COM_CT_ColorComponent /** @brief this channel is contains color information. Specific used is determined by channelnumber, and in the future color space */, COM_CT_Alpha /** @brief this channel is contains transparency value */, @@ -47,31 +47,31 @@ typedef enum ChannelType { } ChannelType; /** - * @brief ChannelInfo holds information about a channel. - * - * Channels are transported from node to node via a SocketConnection. - * ChannelInfo holds specific setting of these channels in order that the to-node of the connection - * Can handle specific logic per channel setting. - * - * @note currently this is not used, but a future place to implement color spacing and other things. - * @ingroup Model - */ + * @brief ChannelInfo holds information about a channel. + * + * Channels are transported from node to node via a SocketConnection. + * ChannelInfo holds specific setting of these channels in order that the to-node of the connection + * Can handle specific logic per channel setting. + * + * @note currently this is not used, but a future place to implement color spacing and other things. + * @ingroup Model + */ class ChannelInfo { private: /** - * @brief the channel number, in the connection. [0-3] - */ + * @brief the channel number, in the connection. [0-3] + */ int number; /** - * @brief type of channel - */ + * @brief type of channel + */ ChannelType type; /** - * @brieg Is this value in this channel premultiplied with its alpha - * @note only valid if type = ColorComponent; - */ + * @brieg Is this value in this channel premultiplied with its alpha + * @note only valid if type = ColorComponent; + */ bool premultiplied; // /** @@ -82,39 +82,39 @@ private: public: /** - * @brief creates a new ChannelInfo and set default values - */ + * @brief creates a new ChannelInfo and set default values + */ ChannelInfo(); /** - * @brief set the index of this channel in the SocketConnection - */ + * @brief set the index of this channel in the SocketConnection + */ void setNumber(const int number) { this->number = number; } /** - * @brief get the index of this channel in the SocketConnection - */ - const int getNumber() const {return this->number; } + * @brief get the index of this channel in the SocketConnection + */ + const int getNumber() const { return this->number; } /** - * @brief set the type of channel - */ + * @brief set the type of channel + */ void setType(const ChannelType type) { this->type = type; } /** - * @brief get the type of channel - */ - const ChannelType getType() const {return this->type; } + * @brief get the type of channel + */ + const ChannelType getType() const { return this->type; } /** - * @brief set the premultiplicatioin of this channel - */ + * @brief set the premultiplicatioin of this channel + */ void setPremultiplied(const bool premultiplied) { this->premultiplied = premultiplied; } /** - * @brief is this channel premultiplied - */ - const bool isPremultiplied() const {return this->premultiplied;} + * @brief is this channel premultiplied + */ + const bool isPremultiplied() const { return this->premultiplied; } }; diff --git a/source/blender/compositor/intern/COM_ChunkOrder.h b/source/blender/compositor/intern/COM_ChunkOrder.h index 3dbb4ae8080..f096ebeebfe 100644 --- a/source/blender/compositor/intern/COM_ChunkOrder.h +++ b/source/blender/compositor/intern/COM_ChunkOrder.h @@ -35,11 +35,11 @@ public: void determineDistance(ChunkOrderHotspot **hotspots, unsigned int numberOfHotspots); friend bool operator<(const ChunkOrder& a, const ChunkOrder& b); - void setChunkNumber(unsigned int chunknumber) {this->number = chunknumber;} - void setX(int x) {this->x = x;} - void setY(int y) {this->y = y;} - unsigned int getChunkNumber() {return this->number;} - double getDistance() {return this->distance;} + void setChunkNumber(unsigned int chunknumber) { this->number = chunknumber; } + void setX(int x) { this->x = x; } + void setY(int y) { this->y = y; } + unsigned int getChunkNumber() { return this->number; } + double getDistance() { return this->distance; } }; #endif diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h index 8425030aec2..93872f4839f 100644 --- a/source/blender/compositor/intern/COM_CompositorContext.h +++ b/source/blender/compositor/intern/COM_CompositorContext.h @@ -32,36 +32,36 @@ #include "COM_defines.h" /** - * @brief Overall context of the compositor - */ + * @brief Overall context of the compositor + */ class CompositorContext { private: /** - * @brief The rendering field describes if we are rendering (F12) or if we are editing (Node editor) - * This field is initialized in ExecutionSystem and must only be read from that point on. - * @see ExecutionSystem - */ + * @brief The rendering field describes if we are rendering (F12) or if we are editing (Node editor) + * This field is initialized in ExecutionSystem and must only be read from that point on. + * @see ExecutionSystem + */ bool rendering; /** - * @brief The quality of the composite. - * This field is initialized in ExecutionSystem and must only be read from that point on. - * @see ExecutionSystem - */ + * @brief The quality of the composite. + * This field is initialized in ExecutionSystem and must only be read from that point on. + * @see ExecutionSystem + */ CompositorQuality quality; /** - * @brief Reference to the scene that is being composited. - * This field is initialized in ExecutionSystem and must only be read from that point on. - * @see ExecutionSystem - */ + * @brief Reference to the scene that is being composited. + * This field is initialized in ExecutionSystem and must only be read from that point on. + * @see ExecutionSystem + */ Scene *scene; /** - * @brief reference to the bNodeTree - * This field is initialized in ExecutionSystem and must only be read from that point on. - * @see ExecutionSystem - */ + * @brief reference to the bNodeTree + * This field is initialized in ExecutionSystem and must only be read from that point on. + * @see ExecutionSystem + */ bNodeTree *bnodetree; /** @@ -70,90 +70,90 @@ private: bNode *activegNode; /** - * @brief does this system have active opencl devices? - */ + * @brief does this system have active opencl devices? + */ bool hasActiveOpenCLDevices; public: /** - * @brief constructor initializes the context with default values. - */ + * @brief constructor initializes the context with default values. + */ CompositorContext(); /** - * @brief set the rendering field of the context - */ + * @brief set the rendering field of the context + */ void setRendering(bool rendering) { this->rendering = rendering; } /** - * @brief get the rendering field of the context - */ - bool isRendering() const {return this->rendering;} + * @brief get the rendering field of the context + */ + bool isRendering() const { return this->rendering; } /** - * @brief set the scene of the context - */ - void setScene(Scene *scene) {this->scene = scene;} + * @brief set the scene of the context + */ + void setScene(Scene *scene) { this->scene = scene; } /** - * @brief set the bnodetree of the context - */ - void setbNodeTree(bNodeTree *bnodetree) {this->bnodetree = bnodetree;} + * @brief set the bnodetree of the context + */ + void setbNodeTree(bNodeTree *bnodetree) { this->bnodetree = bnodetree; } /** - * @brief get the bnodetree of the context - */ - const bNodeTree * getbNodeTree() const {return this->bnodetree;} + * @brief get the bnodetree of the context + */ + const bNodeTree *getbNodeTree() const { return this->bnodetree; } /** - * @brief set the active groupnode of the context - */ - void setActivegNode(bNode *gnode) {this->activegNode = gnode;} + * @brief set the active groupnode of the context + */ + void setActivegNode(bNode *gnode) { this->activegNode = gnode; } /** - * @brief get the active groupnode of the context - */ - const bNode * getActivegNode() const {return this->activegNode;} + * @brief get the active groupnode of the context + */ + const bNode *getActivegNode() const { return this->activegNode; } /** - * @brief get the scene of the context - */ - const Scene *getScene() const {return this->scene;} + * @brief get the scene of the context + */ + const Scene *getScene() const { return this->scene; } /** - * @brief set the quality - */ + * @brief set the quality + */ void setQuality(CompositorQuality quality) { this->quality = quality; } /** - * @brief get the quality - */ + * @brief get the quality + */ const CompositorQuality getQuality() const { return quality; } /** - * @brief get the current framenumber of the scene in this context - */ + * @brief get the current framenumber of the scene in this context + */ const int getFramenumber() const; /** - * @brief has this system active openclDevices? - */ + * @brief has this system active openclDevices? + */ const bool getHasActiveOpenCLDevices() const { return this->hasActiveOpenCLDevices; } /** - * @brief set has this system active openclDevices? - */ + * @brief set has this system active openclDevices? + */ void setHasActiveOpenCLDevices(bool hasAvtiveOpenCLDevices) { this->hasActiveOpenCLDevices = hasAvtiveOpenCLDevices; } - int getChunksize() {return this->getbNodeTree()->chunksize;} + int getChunksize() { return this->getbNodeTree()->chunksize; } const int isColorManaged() const; }; diff --git a/source/blender/compositor/intern/COM_Converter.h b/source/blender/compositor/intern/COM_Converter.h index fa12be4e79a..d01556cc79c 100644 --- a/source/blender/compositor/intern/COM_Converter.h +++ b/source/blender/compositor/intern/COM_Converter.h @@ -32,39 +32,39 @@ class Converter { public: /** - * @brief Convert/wraps a bNode in its Node instance. - * - * For all nodetypes a wrapper class is created. - * Muted nodes are wrapped with MuteNode. - * - * @note When adding a new node to blender, this method needs to be changed to return the correct Node instance. - * - * @see Node - * @see MuteNode - */ + * @brief Convert/wraps a bNode in its Node instance. + * + * For all nodetypes a wrapper class is created. + * Muted nodes are wrapped with MuteNode. + * + * @note When adding a new node to blender, this method needs to be changed to return the correct Node instance. + * + * @see Node + * @see MuteNode + */ static Node *convert(bNode *bNode); /** - * @brief This method will add a datetype conversion rule when the to-socket does not support the from-socket actual data type. - * - * @note this method is called when conversion is needed. - * - * @param connection the SocketConnection what needs conversion - * @param system the ExecutionSystem to add the conversion to. - * @see SocketConnection - a link between two sockets - */ + * @brief This method will add a datetype conversion rule when the to-socket does not support the from-socket actual data type. + * + * @note this method is called when conversion is needed. + * + * @param connection the SocketConnection what needs conversion + * @param system the ExecutionSystem to add the conversion to. + * @see SocketConnection - a link between two sockets + */ static void convertDataType(SocketConnection *connection, ExecutionSystem *system); /** - * @brief This method will add a resolution rule based on the settings of the InputSocket. - * - * @note Conversion logic is implemented in this method - * @see InputSocketResizeMode for the possible conversions. - - * @param connection the SocketConnection what needs conversion - * @param system the ExecutionSystem to add the conversion to. - * @see SocketConnection - a link between two sockets - */ + * @brief This method will add a resolution rule based on the settings of the InputSocket. + * + * @note Conversion logic is implemented in this method + * @see InputSocketResizeMode for the possible conversions. + + * @param connection the SocketConnection what needs conversion + * @param system the ExecutionSystem to add the conversion to. + * @see SocketConnection - a link between two sockets + */ static void convertResolution(SocketConnection *connection, ExecutionSystem *system); }; #endif diff --git a/source/blender/compositor/intern/COM_Device.h b/source/blender/compositor/intern/COM_Device.h index 74a9400f8f3..08fdb5bb578 100644 --- a/source/blender/compositor/intern/COM_Device.h +++ b/source/blender/compositor/intern/COM_Device.h @@ -30,26 +30,26 @@ #include "COM_MemoryBuffer.h" /** - * @brief Abstract class for device implementations to be used by the Compositor. - * devices are queried, initialized and used by the WorkScheduler. - * work are packaged as a WorkPackage instance. - */ + * @brief Abstract class for device implementations to be used by the Compositor. + * devices are queried, initialized and used by the WorkScheduler. + * work are packaged as a WorkPackage instance. + */ class Device { public: /** - * @brief initialize the device - */ - virtual bool initialize() {return true;} + * @brief initialize the device + */ + virtual bool initialize() { return true; } /** - * @brief deinitialize the device - */ + * @brief deinitialize the device + */ virtual void deinitialize() {} /** - * @brief execute a WorkPackage - * @param work the WorkPackage to execute - */ + * @brief execute a WorkPackage + * @param work the WorkPackage to execute + */ virtual void execute(WorkPackage *work) = 0; }; diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index 1698890cc34..541b3e4866d 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -33,21 +33,21 @@ /** - * @brief the execution state of a chunk in an ExecutionGroup - * @ingroup Execution - */ + * @brief the execution state of a chunk in an ExecutionGroup + * @ingroup Execution + */ typedef enum ChunkExecutionState { /** - * @brief chunk is not yet scheduled - */ + * @brief chunk is not yet scheduled + */ COM_ES_NOT_SCHEDULED = 0, /** - * @brief chunk is scheduled, but not yet executed - */ + * @brief chunk is scheduled, but not yet executed + */ COM_ES_SCHEDULED = 1, /** - * @brief chunk is executed. - */ + * @brief chunk is executed. + */ COM_ES_EXECUTED = 2 } ChunkExecutionState; @@ -56,64 +56,64 @@ class ReadBufferOperation; class Device; /** - * @brief Class ExecutionGroup is a group of NodeOperations that are executed as one. - * This grouping is used to combine Operations that can be executed as one whole when multi-processing. - * @ingroup Execution - */ + * @brief Class ExecutionGroup is a group of NodeOperations that are executed as one. + * This grouping is used to combine Operations that can be executed as one whole when multi-processing. + * @ingroup Execution + */ class ExecutionGroup { private: // fields /** - * @brief list of operations in this ExecutionGroup - */ - vector operations; + * @brief list of operations in this ExecutionGroup + */ + vector operations; /** - * @brief is this ExecutionGroup an input ExecutionGroup - * an input execution group is a group that is at the end of the calculation (the output is important for the user) - */ + * @brief is this ExecutionGroup an input ExecutionGroup + * an input execution group is a group that is at the end of the calculation (the output is important for the user) + */ int isOutput; /** - * @brief Width of the output - */ + * @brief Width of the output + */ unsigned int width; /** - * @brief Height of the output - */ + * @brief Height of the output + */ unsigned int height; /** - * @brief size of a single chunk, being Width or of height - * a chunk is always a square, except at the edges of the MemoryBuffer - */ + * @brief size of a single chunk, being Width or of height + * a chunk is always a square, except at the edges of the MemoryBuffer + */ unsigned int chunkSize; /** - * @brief number of chunks in the x-axis - */ + * @brief number of chunks in the x-axis + */ unsigned int numberOfXChunks; /** - * @brief number of chunks in the y-axis - */ + * @brief number of chunks in the y-axis + */ unsigned int numberOfYChunks; /** - * @brief total number of chunks - */ + * @brief total number of chunks + */ unsigned int numberOfChunks; /** - * @brief contains this ExecutionGroup a complex NodeOperation. - */ + * @brief contains this ExecutionGroup a complex NodeOperation. + */ bool complex; /** - * @brief can this ExecutionGroup be scheduled on an OpenCLDevice - */ + * @brief can this ExecutionGroup be scheduled on an OpenCLDevice + */ bool openCL; /** @@ -122,113 +122,113 @@ private: bool singleThreaded; /** - * @brief what is the maximum number field of all ReadBufferOperation in this ExecutionGroup. - * @note this is used to construct the MemoryBuffers that will be passed during execution. - */ + * @brief what is the maximum number field of all ReadBufferOperation in this ExecutionGroup. + * @note this is used to construct the MemoryBuffers that will be passed during execution. + */ unsigned int cachedMaxReadBufferOffset; /** - * @brief a cached vector of all read operations in the execution group. - */ - vector cachedReadOperations; + * @brief a cached vector of all read operations in the execution group. + */ + vector cachedReadOperations; /** - * @brief reference to the original bNodeTree, this field is only set for the 'top' execution group. - * @note can only be used to call the callbacks for progress, status and break - */ - const bNodeTree * bTree; + * @brief reference to the original bNodeTree, this field is only set for the 'top' execution group. + * @note can only be used to call the callbacks for progress, status and break + */ + const bNodeTree *bTree; /** - * @brief total number of chunks that have been calculated for this ExecutionGroup - */ + * @brief total number of chunks that have been calculated for this ExecutionGroup + */ unsigned int chunksFinished; /** - * @brief the chunkExecutionStates holds per chunk the execution state. this state can be - * - COM_ES_NOT_SCHEDULED: not scheduled - * - COM_ES_SCHEDULED: scheduled - * - COM_ES_EXECUTED: executed - */ + * @brief the chunkExecutionStates holds per chunk the execution state. this state can be + * - COM_ES_NOT_SCHEDULED: not scheduled + * - COM_ES_SCHEDULED: scheduled + * - COM_ES_EXECUTED: executed + */ ChunkExecutionState *chunkExecutionStates; /** - * @brief indicator when this ExecutionGroup has valid NodeOperations in its vector for Execution - * @note When building the ExecutionGroup NodeOperations are added via recursion. First a WriteBufferOperations is added, then the - * @note Operation containing the settings that is important for the ExecutiongGroup is added, - * @note When this occurs, these settings are copied over from the node to the ExecutionGroup - * @note and the Initialized flag is set to true. + * @brief indicator when this ExecutionGroup has valid NodeOperations in its vector for Execution + * @note When building the ExecutionGroup NodeOperations are added via recursion. First a WriteBufferOperations is added, then the + * @note Operation containing the settings that is important for the ExecutiongGroup is added, + * @note When this occurs, these settings are copied over from the node to the ExecutionGroup + * @note and the Initialized flag is set to true. * @see complex - * @see openCL - */ + * @see openCL + */ bool initialized; // methods /** - * @brief check whether parameter operation can be added to the execution group - * @param operation the operation to be added - */ + * @brief check whether parameter operation can be added to the execution group + * @param operation the operation to be added + */ bool canContainOperation(NodeOperation *operation); /** - * @brief calculate the actual chunk size of this execution group. - * @note A chunk size is an unsigned int that is both the height and width of a chunk. - * @note The chunk size will not be stored in the chunkSize field. This needs to be done - * @note by the calling method. - */ + * @brief calculate the actual chunk size of this execution group. + * @note A chunk size is an unsigned int that is both the height and width of a chunk. + * @note The chunk size will not be stored in the chunkSize field. This needs to be done + * @note by the calling method. + */ unsigned int determineChunkSize(); /** - * @brief Determine the rect (minx, maxx, miny, maxy) of a chunk at a position. - * @note Only gives usefull results ater the determination of the chunksize - * @see determineChunkSize() - */ + * @brief Determine the rect (minx, maxx, miny, maxy) of a chunk at a position. + * @note Only gives usefull results ater the determination of the chunksize + * @see determineChunkSize() + */ void determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk) const; /** - * @brief determine the number of chunks, based on the chunkSize, width and height. - * @note The result are stored in the fields numberOfChunks, numberOfXChunks, numberOfYChunks - */ + * @brief determine the number of chunks, based on the chunkSize, width and height. + * @note The result are stored in the fields numberOfChunks, numberOfXChunks, numberOfYChunks + */ void determineNumberOfChunks(); /** - * @brief try to schedule a specific chunk. - * @note scheduling succeeds when all input requirements are met and the chunks hasen't been scheduled yet. - * @param graph - * @param xChunk - * @param yChunk - * @return [true:false] - * true: package(s) are scheduled - * false: scheduling is deferred (depending workpackages are scheduled) - */ - bool scheduleChunkWhenPossible(ExecutionSystem * graph, int xChunk, int yChunk); - + * @brief try to schedule a specific chunk. + * @note scheduling succeeds when all input requirements are met and the chunks hasen't been scheduled yet. + * @param graph + * @param xChunk + * @param yChunk + * @return [true:false] + * true: package(s) are scheduled + * false: scheduling is deferred (depending workpackages are scheduled) + */ + bool scheduleChunkWhenPossible(ExecutionSystem *graph, int xChunk, int yChunk); + /** - * @brief try to schedule a specific area. - * @note Check if a certain area is available, when not available this are will be checked. - * @note This method is called from other ExecutionGroup's. - * @param graph - * @param rect - * @return [true:false] - * true: package(s) are scheduled - * false: scheduling is deferred (depending workpackages are scheduled) - */ - bool scheduleAreaWhenPossible(ExecutionSystem * graph, rcti * rect); - + * @brief try to schedule a specific area. + * @note Check if a certain area is available, when not available this are will be checked. + * @note This method is called from other ExecutionGroup's. + * @param graph + * @param rect + * @return [true:false] + * true: package(s) are scheduled + * false: scheduling is deferred (depending workpackages are scheduled) + */ + bool scheduleAreaWhenPossible(ExecutionSystem *graph, rcti *rect); + /** - * @brief add a chunk to the WorkScheduler. - * @param chunknumber - */ + * @brief add a chunk to the WorkScheduler. + * @param chunknumber + */ bool scheduleChunk(unsigned int chunkNumber); /** - * @brief determine the area of interest of a certain input area - * @note This method only evaluates a single ReadBufferOperation - * @param input the input area - * @param readOperation The ReadBufferOperation where the area needs to be evaluated - * @param output the area needed of the ReadBufferOperation. Result - */ - void determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti *output); + * @brief determine the area of interest of a certain input area + * @note This method only evaluates a single ReadBufferOperation + * @param input the input area + * @param readOperation The ReadBufferOperation where the area needs to be evaluated + * @param output the area needed of the ReadBufferOperation. Result + */ + void determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); public: @@ -237,162 +237,162 @@ public: // methods /** - * @brief check to see if a NodeOperation is already inside this execution group - * @param operation the NodeOperation to check - * @return [true,false] - */ + * @brief check to see if a NodeOperation is already inside this execution group + * @param operation the NodeOperation to check + * @return [true,false] + */ bool containsOperation(NodeOperation *operation); /** - * @brief add an operation to this ExecutionGroup - * @note this method will add input of the operations recursivly - * @note this method can create multiple ExecutionGroup's - * @param system - * @param operation - */ + * @brief add an operation to this ExecutionGroup + * @note this method will add input of the operations recursivly + * @note this method can create multiple ExecutionGroup's + * @param system + * @param operation + */ void addOperation(ExecutionSystem *system, NodeOperation *operation); /** - * @brief is this ExecutionGroup an output ExecutionGroup - * @note An OutputExecution group are groups containing a - * @note ViewerOperation, CompositeOperation, PreviewOperation. - * @see NodeOperation.isOutputOperation - */ - const int isOutputExecutionGroup() const {return this->isOutput;} - + * @brief is this ExecutionGroup an output ExecutionGroup + * @note An OutputExecution group are groups containing a + * @note ViewerOperation, CompositeOperation, PreviewOperation. + * @see NodeOperation.isOutputOperation + */ + const int isOutputExecutionGroup() const { return this->isOutput; } + /** - * @brief set whether this ExecutionGroup is an output - * @param isOutput - */ - void setOutputExecutionGroup(int isOutput) {this->isOutput = isOutput;} - + * @brief set whether this ExecutionGroup is an output + * @param isOutput + */ + void setOutputExecutionGroup(int isOutput) { this->isOutput = isOutput; } + /** - * @brief determine the resolution of this ExecutionGroup - * @param resolution - */ + * @brief determine the resolution of this ExecutionGroup + * @param resolution + */ void determineResolution(unsigned int resolution[]); /** - * @brief set the resolution of this executiongroup - * @param resolution - */ - void setResolution(unsigned int resolution[]) {this->width = resolution[0];this->height = resolution[1];} + * @brief set the resolution of this executiongroup + * @param resolution + */ + void setResolution(unsigned int resolution[]) { this->width = resolution[0]; this->height = resolution[1]; } /** - * @brief get the width of this execution group - */ - const unsigned int getWidth() {return this->width;} + * @brief get the width of this execution group + */ + const unsigned int getWidth() { return this->width; } /** - * @brief get the height of this execution group - */ - const unsigned int getHeight() {return this->height;} + * @brief get the height of this execution group + */ + const unsigned int getHeight() { return this->height; } /** - * @brief does this ExecutionGroup contains a complex NodeOperation - */ + * @brief does this ExecutionGroup contains a complex NodeOperation + */ const bool isComplex() const; /** - * @brief get the output operation of this ExecutionGroup - * @return NodeOperation *output operation - */ - NodeOperation *getOutputNodeOperation() const; + * @brief get the output operation of this ExecutionGroup + * @return NodeOperation *output operation + */ + NodeOperation *getOutputNodeOperation() const; /** - * @brief compose multiple chunks into a single chunk - * @return Memorybuffer *consolidated chunk - */ + * @brief compose multiple chunks into a single chunk + * @return Memorybuffer *consolidated chunk + */ MemoryBuffer *constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *output); /** - * @brief initExecution is called just before the execution of the whole graph will be done. - * @note The implementation will calculate the chunkSize of this execution group. - */ + * @brief initExecution is called just before the execution of the whole graph will be done. + * @note The implementation will calculate the chunkSize of this execution group. + */ void initExecution(); /** - * @brief get all inputbuffers needed to calculate an chunk - * @note all inputbuffers must be executed - * @param chunkNumber the chunk to be calculated - * @return MemoryBuffer** the inputbuffers - */ - MemoryBuffer** getInputBuffersCPU(); + * @brief get all inputbuffers needed to calculate an chunk + * @note all inputbuffers must be executed + * @param chunkNumber the chunk to be calculated + * @return MemoryBuffer** the inputbuffers + */ + MemoryBuffer **getInputBuffersCPU(); /** - * @brief get all inputbuffers needed to calculate an chunk - * @note all inputbuffers must be executed - * @param chunkNumber the chunk to be calculated - * @return MemoryBuffer** the inputbuffers - */ - MemoryBuffer** getInputBuffersOpenCL(int chunkNumber); + * @brief get all inputbuffers needed to calculate an chunk + * @note all inputbuffers must be executed + * @param chunkNumber the chunk to be calculated + * @return MemoryBuffer** the inputbuffers + */ + MemoryBuffer **getInputBuffersOpenCL(int chunkNumber); /** - * @brief allocate the outputbuffer of a chunk - * @param chunkNumber the number of the chunk in the ExecutionGroup - * @param rect the rect of that chunk - * @see determineChunkRect - */ + * @brief allocate the outputbuffer of a chunk + * @param chunkNumber the number of the chunk in the ExecutionGroup + * @param rect the rect of that chunk + * @see determineChunkRect + */ MemoryBuffer *allocateOutputBuffer(int chunkNumber, rcti *rect); /** - * @brief after a chunk is executed the needed resources can be freed or unlocked. - * @param chunknumber - * @param memorybuffers - */ - void finalizeChunkExecution(int chunkNumber, MemoryBuffer** memoryBuffers); + * @brief after a chunk is executed the needed resources can be freed or unlocked. + * @param chunknumber + * @param memorybuffers + */ + void finalizeChunkExecution(int chunkNumber, MemoryBuffer **memoryBuffers); /** - * @brief deinitExecution is called just after execution the whole graph. - * @note It will release all needed resources - */ + * @brief deinitExecution is called just after execution the whole graph. + * @note It will release all needed resources + */ void deinitExecution(); /** - * @brief schedule an ExecutionGroup - * @note this method will return when all chunks have been calculated, or the execution has breaked (by user) - * - * first the order of the chunks will be determined. This is determined by finding the ViewerOperation and get the relevant information from it. - * - ChunkOrdering - * - CenterX - * - CenterY - * - * After determining the order of the chunks the chunks will be scheduled - * - * @see ViewerOperation - * @param system - */ + * @brief schedule an ExecutionGroup + * @note this method will return when all chunks have been calculated, or the execution has breaked (by user) + * + * first the order of the chunks will be determined. This is determined by finding the ViewerOperation and get the relevant information from it. + * - ChunkOrdering + * - CenterX + * - CenterY + * + * After determining the order of the chunks the chunks will be scheduled + * + * @see ViewerOperation + * @param system + */ void execute(ExecutionSystem *system); /** - * @brief this method determines the MemoryProxy's where this execution group depends on. - * @note After this method determineDependingAreaOfInterest can be called to determine - * @note the area of the MemoryProxy.creator thas has to be executed. - * @param memoryProxies result - */ - void determineDependingMemoryProxies(vector *memoryProxies); + * @brief this method determines the MemoryProxy's where this execution group depends on. + * @note After this method determineDependingAreaOfInterest can be called to determine + * @note the area of the MemoryProxy.creator thas has to be executed. + * @param memoryProxies result + */ + void determineDependingMemoryProxies(vector *memoryProxies); /** - * @brief Determine the rect (minx, maxx, miny, maxy) of a chunk. - * @note Only gives usefull results ater the determination of the chunksize - * @see determineChunkSize() - */ + * @brief Determine the rect (minx, maxx, miny, maxy) of a chunk. + * @note Only gives usefull results ater the determination of the chunksize + * @see determineChunkSize() + */ void determineChunkRect(rcti *rect, const unsigned int chunkNumber) const; /** - * @brief can this ExecutionGroup be scheduled on an OpenCLDevice - * @see WorkScheduler.schedule - */ + * @brief can this ExecutionGroup be scheduled on an OpenCLDevice + * @see WorkScheduler.schedule + */ bool isOpenCL(); - void setChunksize(int chunksize) {this->chunkSize = chunksize;} + void setChunksize(int chunksize) { this->chunkSize = chunksize; } /** - * @brief get the Render priority of this ExecutionGroup - * @see ExecutionSystem.execute - */ + * @brief get the Render priority of this ExecutionGroup + * @see ExecutionSystem.execute + */ CompositorPriority getRenderPriotrity(); }; diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h index 510e58ba1bb..70fd94ca57f 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.h +++ b/source/blender/compositor/intern/COM_ExecutionSystem.h @@ -36,69 +36,69 @@ class ExecutionGroup; using namespace std; /** - * @page execution Execution model - * In order to get to an efficient model for execution, serveral steps are being done. these steps are explained below. - * - * @section EM_Step1 Step 1: translating blender node system to the new compsitor system - * Blenders node structure is based on C structs (DNA). These structs are not efficient in the new architecture. We want to use classes in order to simplify the system. - * during this step the blender node_tree is evaluated and converted to a CPP node system. - * - * @see ExecutionSystem - * @see Converter.convert - * @see Node - * - * @section EM_Step2 Step2: translating nodes to operations - * Ungrouping the GroupNodes. Group nodes are node_tree's in node_tree's. The new system only supports a single level of node_tree. We will 'flatten' the system in a single level. - * @see GroupNode - * @see ExecutionSystemHelper.ungroup - * - * Every node has the ability to convert itself to operations. The node itself is responsible to create a correct NodeOperation setup based on its internal settings. - * Most Node only need to convert it to its NodeOperation. Like a ColorToBWNode doesn't check anything, but replaces itself with a ConvertColorToBWOperation. - * More complex nodes can use different NodeOperation based on settings; like MixNode. based on the selected Mixtype a different operation will be used. - * for more information see the page about creating new Nodes. [@subpage newnode] - * - * @see ExecutionSystem.convertToOperations - * @see Node.convertToOperations - * @see NodeOperation base class for all operations in the system - * - * @section EM_Step3 Step3: add additional conversions to the operation system - * - Data type conversions: the system has 3 data types COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR. The user can connect a Value socket to a color socket. As values are ordered differently than colors a conversion happens. - * - * - Image size conversions: the system can automatically convert when resolutions do not match. An InputSocket has a resize mode. This can be any of the folowing settings. - * - [@ref InputSocketResizeMode.COM_SC_CENTER]: The center of both images are aligned - * - [@ref InputSocketResizeMode.COM_SC_FIT_WIDTH]: The width of both images are aligned - * - [@ref InputSocketResizeMode.COM_SC_FIT_HEIGHT]: the height of both images are aligned - * - [@ref InputSocketResizeMode.COM_SC_FIT]: The width, or the height of both images are aligned to make sure that it fits. - * - [@ref InputSocketResizeMode.COM_SC_STRETCH]: The width and the height of both images are aligned - * - [@ref InputSocketResizeMode.COM_SC_NO_RESIZE]: bottom left of the images are aligned. - * - * @see Converter.convertDataType Datatype conversions - * @see Converter.convertResolution Image size conversions - * - * @section EM_Step4 Step4: group operations in executions groups - * ExecutionGroup are groups of operations that are calculated as being one bigger operation. All operations will be part of an ExecutionGroup. - * Complex nodes will be added to separate groups. Between ExecutionGroup's the data will be stored in MemoryBuffers. ReadBufferOperations and WriteBufferOperations are added where needed. - * - *
-  *
-  *        +------------------------------+      +----------------+
-  *        | ExecutionGroup A             |      |ExecutionGroup B|   ExecutionGroup
-  *        | +----------+     +----------+|      |+----------+    |
-  *   /----->| Operation|---->| Operation|-\ /--->| Operation|-\  |   NodeOperation
-  *   |    | | A        |     | B        ||| |   || C        | |  |
-  *   |    | | cFFA     |  /->| cFFA     ||| |   || cFFA     | |  |
-  *   |    | +----------+  |  +----------+|| |   |+----------+ |  |
-  *   |    +---------------|--------------+v |   +-------------v--+
-  * +-*----+           +---*--+         +--*-*--+           +--*----+
-  * |inputA|           |inputB|         |outputA|           |outputB| MemoryBuffer
-  * |cFAA  |           |cFAA  |         |cFAA   |           |cFAA   |
-  * +------+           +------+         +-------+           +-------+
-  * 
- * @see ExecutionSystem.groupOperations method doing this step - * @see ExecutionSystem.addReadWriteBufferOperations - * @see NodeOperation.isComplex - * @see ExecutionGroup class representing the ExecutionGroup - */ + * @page execution Execution model + * In order to get to an efficient model for execution, serveral steps are being done. these steps are explained below. + * + * @section EM_Step1 Step 1: translating blender node system to the new compsitor system + * Blenders node structure is based on C structs (DNA). These structs are not efficient in the new architecture. We want to use classes in order to simplify the system. + * during this step the blender node_tree is evaluated and converted to a CPP node system. + * + * @see ExecutionSystem + * @see Converter.convert + * @see Node + * + * @section EM_Step2 Step2: translating nodes to operations + * Ungrouping the GroupNodes. Group nodes are node_tree's in node_tree's. The new system only supports a single level of node_tree. We will 'flatten' the system in a single level. + * @see GroupNode + * @see ExecutionSystemHelper.ungroup + * + * Every node has the ability to convert itself to operations. The node itself is responsible to create a correct NodeOperation setup based on its internal settings. + * Most Node only need to convert it to its NodeOperation. Like a ColorToBWNode doesn't check anything, but replaces itself with a ConvertColorToBWOperation. + * More complex nodes can use different NodeOperation based on settings; like MixNode. based on the selected Mixtype a different operation will be used. + * for more information see the page about creating new Nodes. [@subpage newnode] + * + * @see ExecutionSystem.convertToOperations + * @see Node.convertToOperations + * @see NodeOperation base class for all operations in the system + * + * @section EM_Step3 Step3: add additional conversions to the operation system + * - Data type conversions: the system has 3 data types COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR. The user can connect a Value socket to a color socket. As values are ordered differently than colors a conversion happens. + * + * - Image size conversions: the system can automatically convert when resolutions do not match. An InputSocket has a resize mode. This can be any of the folowing settings. + * - [@ref InputSocketResizeMode.COM_SC_CENTER]: The center of both images are aligned + * - [@ref InputSocketResizeMode.COM_SC_FIT_WIDTH]: The width of both images are aligned + * - [@ref InputSocketResizeMode.COM_SC_FIT_HEIGHT]: the height of both images are aligned + * - [@ref InputSocketResizeMode.COM_SC_FIT]: The width, or the height of both images are aligned to make sure that it fits. + * - [@ref InputSocketResizeMode.COM_SC_STRETCH]: The width and the height of both images are aligned + * - [@ref InputSocketResizeMode.COM_SC_NO_RESIZE]: bottom left of the images are aligned. + * + * @see Converter.convertDataType Datatype conversions + * @see Converter.convertResolution Image size conversions + * + * @section EM_Step4 Step4: group operations in executions groups + * ExecutionGroup are groups of operations that are calculated as being one bigger operation. All operations will be part of an ExecutionGroup. + * Complex nodes will be added to separate groups. Between ExecutionGroup's the data will be stored in MemoryBuffers. ReadBufferOperations and WriteBufferOperations are added where needed. + * + *
+ *
+ *        +------------------------------+      +----------------+
+ *        | ExecutionGroup A             |      |ExecutionGroup B|   ExecutionGroup
+ *        | +----------+     +----------+|      |+----------+    |
+ *   /----->| Operation|---->| Operation|-\ /--->| Operation|-\  |   NodeOperation
+ *   |    | | A        |     | B        ||| |   || C        | |  |
+ *   |    | | cFFA     |  /->| cFFA     ||| |   || cFFA     | |  |
+ *   |    | +----------+  |  +----------+|| |   |+----------+ |  |
+ *   |    +---------------|--------------+v |   +-------------v--+
+ * +-*----+           +---*--+         +--*-*--+           +--*----+
+ * |inputA|           |inputB|         |outputA|           |outputB| MemoryBuffer
+ * |cFAA  |           |cFAA  |         |cFAA   |           |cFAA   |
+ * +------+           +------+         +-------+           +-------+
+ * 
+ * @see ExecutionSystem.groupOperations method doing this step + * @see ExecutionSystem.addReadWriteBufferOperations + * @see NodeOperation.isComplex + * @see ExecutionGroup class representing the ExecutionGroup + */ /** * @brief the ExecutionSystem contains the whole compositor tree. @@ -106,129 +106,129 @@ using namespace std; class ExecutionSystem { private: /** - * @brief the context used during execution - */ + * @brief the context used during execution + */ CompositorContext context; /** - * @brief vector of nodes - */ - vector nodes; + * @brief vector of nodes + */ + vector nodes; /** - * @brief vector of operations - */ - vector operations; + * @brief vector of operations + */ + vector operations; /** - * @brief vector of groups - */ - vector groups + * @brief vector of groups + */ + vector groups /** - * @brief vector of connections - */; - vector connections; + * @brief vector of connections + */; + vector connections; private: //methods /** - * @brief add ReadBufferOperation and WriteBufferOperation around an operation - * @param operation the operation to add the bufferoperations around. - */ + * @brief add ReadBufferOperation and WriteBufferOperation around an operation + * @param operation the operation to add the bufferoperations around. + */ void addReadWriteBufferOperations(NodeOperation *operation); /** - * find all execution group with output nodes - */ - void findOutputExecutionGroup(vector *result, CompositorPriority priority) const; + * find all execution group with output nodes + */ + void findOutputExecutionGroup(vector *result, CompositorPriority priority) const; /** - * find all execution group with output nodes - */ - void findOutputExecutionGroup(vector *result) const; + * find all execution group with output nodes + */ + void findOutputExecutionGroup(vector *result) const; public: /** - * @brief Create a new ExecutionSystem and initialize it with the - * editingtree. - * - * @param editingtree [bNodeTree*] - * @param rendering [true false] - */ + * @brief Create a new ExecutionSystem and initialize it with the + * editingtree. + * + * @param editingtree [bNodeTree*] + * @param rendering [true false] + */ ExecutionSystem(bNodeTree *editingtree, bool rendering); /** - * Destructor - */ + * Destructor + */ ~ExecutionSystem(); /** - * @brief execute this system - * - initialize the NodeOperation's and ExecutionGroup's - * - schedule the output ExecutionGroup's based on their priority - * - deinitialize the ExecutionGroup's and NodeOperation's - */ + * @brief execute this system + * - initialize the NodeOperation's and ExecutionGroup's + * - schedule the output ExecutionGroup's based on their priority + * - deinitialize the ExecutionGroup's and NodeOperation's + */ void execute(); /** - * @brief Add an operation to the operation list - * - * @param operation the operation to add - */ + * @brief Add an operation to the operation list + * + * @param operation the operation to add + */ void addOperation(NodeOperation *operation); /** - * Add an editor link to the system. convert it to an socketconnection (CPP-representative) - * this converted socket is returned. - */ + * Add an editor link to the system. convert it to an socketconnection (CPP-representative) + * this converted socket is returned. + */ SocketConnection *addNodeLink(bNodeLink *bNodeLink); void addSocketConnection(SocketConnection *connection); /** - * @brief Convert all nodes to operations - */ + * @brief Convert all nodes to operations + */ void convertToOperations(); /** - * @brief group operations in ExecutionGroup's - * @see ExecutionGroup - */ + * @brief group operations in ExecutionGroup's + * @see ExecutionGroup + */ void groupOperations(); /** - * @brief get the reference to the compositor context - */ - CompositorContext& getContext() {return this->context;} + * @brief get the reference to the compositor context + */ + CompositorContext& getContext() { return this->context; } /** - * @brief get the reference to the compositor nodes - */ - vector& getNodes() {return this->nodes;} + * @brief get the reference to the compositor nodes + */ + vector& getNodes() { return this->nodes; } /** - * @brief get the reference to the compositor connections - */ - vector& getConnections() {return this->connections;} + * @brief get the reference to the compositor connections + */ + vector& getConnections() { return this->connections; } /** - * @brief get the reference to the list of execution groups - */ - vector& getExecutionGroups() {return this->groups;} + * @brief get the reference to the list of execution groups + */ + vector& getExecutionGroups() { return this->groups; } /** - * @brief get the reference to the list of operations - */ - vector& getOperations() {return this->operations;} + * @brief get the reference to the list of operations + */ + vector& getOperations() { return this->operations; } private: /** - * @brief determine the actual data types of all sockets - * @param nodes list of nodes or operations to do the data type determination - */ - void determineActualSocketDataTypes(vector &nodes); + * @brief determine the actual data types of all sockets + * @param nodes list of nodes or operations to do the data type determination + */ + void determineActualSocketDataTypes(vector &nodes); void executeGroups(CompositorPriority priority); diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.h b/source/blender/compositor/intern/COM_ExecutionSystemHelper.h index 9321cb571e8..99a05472075 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.h +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.h @@ -42,86 +42,86 @@ class ExecutionSystemHelper { public: /** - * @brief add an bNodeTree to the nodes list and connections - * @param system Execution system - * @param nodes_start Starting index in the system's nodes list for nodes in this tree. - * @param tree bNodeTree to add - * @return Node representing the "Compositor node" of the maintree. or NULL when a subtree is added - */ - static Node *addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree* tree, bNode *groupnode); - + * @brief add an bNodeTree to the nodes list and connections + * @param system Execution system + * @param nodes_start Starting index in the system's nodes list for nodes in this tree. + * @param tree bNodeTree to add + * @return Node representing the "Compositor node" of the maintree. or NULL when a subtree is added + */ + static Node *addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree, bNode *groupnode); + /** - * @brief add an editor node to the system. - * this node is converted to a Node instance. - * and the converted node is returned - * - * @param bNode node to add - * @return Node that represents the bNode or null when not able to convert. - */ - static Node *addNode(vector& nodes, bNode *bNode, bool isInActiveGroup); - + * @brief add an editor node to the system. + * this node is converted to a Node instance. + * and the converted node is returned + * + * @param bNode node to add + * @return Node that represents the bNode or null when not able to convert. + */ + static Node *addNode(vector& nodes, bNode *bNode, bool isInActiveGroup); + /** - * @brief Add a Node to a list - * - * @param nodes the list where the node needs to be added to - * @param node the node to be added - */ - static void addNode(vector& nodes, Node *node); - + * @brief Add a Node to a list + * + * @param nodes the list where the node needs to be added to + * @param node the node to be added + */ + static void addNode(vector& nodes, Node *node); + /** - * @brief Add an operation to the operation list - * - * The id of the operation is updated. - * - * @param operations the list where the operation need to be added to - * @param operation the operation to add - */ - static void addOperation(vector &operations, NodeOperation *operation); - + * @brief Add an operation to the operation list + * + * The id of the operation is updated. + * + * @param operations the list where the operation need to be added to + * @param operation the operation to add + */ + static void addOperation(vector &operations, NodeOperation *operation); + /** - * @brief Add an ExecutionGroup to a list - * - * The id of the ExecutionGroup is updated. - * - * @param executionGroups the list where the executionGroup need to be added to - * @param executionGroup the ExecutionGroup to add - */ - static void addExecutionGroup(vector& executionGroups, ExecutionGroup *executionGroup); - + * @brief Add an ExecutionGroup to a list + * + * The id of the ExecutionGroup is updated. + * + * @param executionGroups the list where the executionGroup need to be added to + * @param executionGroup the ExecutionGroup to add + */ + static void addExecutionGroup(vector& executionGroups, ExecutionGroup *executionGroup); + /** - * Find all Node Operations that needs to be executed. - * @param rendering - * the rendering parameter will tell what type of execution we are doing - * FALSE is editing, TRUE is rendering - */ - static void findOutputNodeOperations(vector* result, vector& operations , bool rendering); - + * Find all Node Operations that needs to be executed. + * @param rendering + * the rendering parameter will tell what type of execution we are doing + * FALSE is editing, TRUE is rendering + */ + static void findOutputNodeOperations(vector *result, vector& operations, bool rendering); + /** - * @brief add a bNodeLink to the list of links - * the bNodeLink will be wrapped in a SocketConnection - * - * @note Cyclic links will be ignored - * - * @param node_range list of possible nodes for lookup. - * @param links list of links to add the bNodeLink to - * @param bNodeLink the link to be added - * @return the created SocketConnection or NULL - */ - static SocketConnection *addNodeLink(NodeRange &node_range, vector& links, bNodeLink *bNodeLink); - + * @brief add a bNodeLink to the list of links + * the bNodeLink will be wrapped in a SocketConnection + * + * @note Cyclic links will be ignored + * + * @param node_range list of possible nodes for lookup. + * @param links list of links to add the bNodeLink to + * @param bNodeLink the link to be added + * @return the created SocketConnection or NULL + */ + static SocketConnection *addNodeLink(NodeRange &node_range, vector& links, bNodeLink *bNodeLink); + /** - * @brief create a new SocketConnection and add to a vector of links - * @param links the vector of links - * @param fromSocket the startpoint of the connection - * @param toSocket the endpoint of the connection - * @return the new created SocketConnection - */ - static SocketConnection *addLink(vector& links, OutputSocket *fromSocket, InputSocket *toSocket); - + * @brief create a new SocketConnection and add to a vector of links + * @param links the vector of links + * @param fromSocket the startpoint of the connection + * @param toSocket the endpoint of the connection + * @return the new created SocketConnection + */ + static SocketConnection *addLink(vector& links, OutputSocket *fromSocket, InputSocket *toSocket); + /** - * @brief dumps the content of the execution system to standard out - * @param system the execution system to dump - */ + * @brief dumps the content of the execution system to standard out + * @param system the execution system to dump + */ static void debugDump(ExecutionSystem *system); }; #endif diff --git a/source/blender/compositor/intern/COM_InputSocket.h b/source/blender/compositor/intern/COM_InputSocket.h index b1c75e34844..6ac6ad09126 100644 --- a/source/blender/compositor/intern/COM_InputSocket.h +++ b/source/blender/compositor/intern/COM_InputSocket.h @@ -36,10 +36,10 @@ class ChannelInfo; class NodeOperation; /** - * @brief Resize modes of inputsockets - * How are the input and working resolutions matched - * @ingroup Model - */ + * @brief Resize modes of inputsockets + * How are the input and working resolutions matched + * @ingroup Model + */ typedef enum InputSocketResizeMode { /** @brief Center the input image to the center of the working area of the node, no resizing occurs */ COM_SC_CENTER = NS_CR_CENTER, @@ -56,34 +56,34 @@ typedef enum InputSocketResizeMode { } InputSocketResizeMode; /** - * @brief InputSocket are sockets that can receive data/input - * @ingroup Model - */ + * @brief InputSocket are sockets that can receive data/input + * @ingroup Model + */ class InputSocket : public Socket { private: /** - * @brief connection connected to this InputSocket. - * An input socket can only have a single connection - */ + * @brief connection connected to this InputSocket. + * An input socket can only have a single connection + */ SocketConnection *connection; /** - * @brief resize mode of this socket - */ + * @brief resize mode of this socket + */ InputSocketResizeMode resizeMode; /** - * @brief convert a data type to a by the socket supported data type. - * - * @param datatype the datatype that needs to be checked - * @section data-conversion - */ + * @brief convert a data type to a by the socket supported data type. + * + * @param datatype the datatype that needs to be checked + * @section data-conversion + */ DataType convertToSupportedDataType(DataType datatype); /** - * @brief called when the ActualDataType is set. notifies other parties - */ + * @brief called when the ActualDataType is set. notifies other parties + */ void fireActualDataTypeSet(); public: @@ -98,55 +98,59 @@ public: int isInputSocket() const; /** - * @brief determine the resolution of this data going through this socket - * @param resolution the result of this operation - * @param preferredResolution the preferrable resolution as no resolution could be determined - */ - void determineResolution(unsigned int resolution[],unsigned int preferredResolution[]); + * @brief determine the resolution of this data going through this socket + * @param resolution the result of this operation + * @param preferredResolution the preferrable resolution as no resolution could be determined + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); void determineActualDataType(); /** - * @brief Notifies the Input of the data type (via a SocketConnection) - * @param datatype the datatype to evaluate - */ + * @brief Notifies the Input of the data type (via a SocketConnection) + * @param datatype the datatype to evaluate + */ void notifyActualInputType(DataType datatype); /** - * @brief move all connections of this input socket to another socket - * only use this method when already checked the availability of a SocketConnection - * @param relinkToSocket the socket to move to connections to - */ + * @brief move all connections of this input socket to another socket + * only use this method when already checked the availability of a SocketConnection + * @param relinkToSocket the socket to move to connections to + */ void relinkConnections(InputSocket *relinkToSocket); /** - * @brief move all connections of this input socket to another socket - * @param relinkToSocket the socket to move to connections to - * @param autoconnect will a set operation be added when no connections exist - * @param editorNodeInputSocketIndex index of the socket number of the bNode (used to retrieve the value for autoconnection) - * @param system ExecutionSystem to update to - */ + * @brief move all connections of this input socket to another socket + * @param relinkToSocket the socket to move to connections to + * @param autoconnect will a set operation be added when no connections exist + * @param editorNodeInputSocketIndex index of the socket number of the bNode (used to retrieve the value for autoconnection) + * @param system ExecutionSystem to update to + */ void relinkConnections(InputSocket *relinkToSocket, int editorNodeInputSocketIndex, ExecutionSystem *system); /** - * @brief move all connections of this input socket to another socket - * @param relinkToSocket the socket to move to connections to - * @param editorNodeInputSocketIndex index of the socket number of the bNode (used to retrieve the value for autoconnection) - * @param system ExecutionSystem to update to - */ + * @brief move all connections of this input socket to another socket + * @param relinkToSocket the socket to move to connections to + * @param editorNodeInputSocketIndex index of the socket number of the bNode (used to retrieve the value for autoconnection) + * @param system ExecutionSystem to update to + */ void relinkConnectionsDuplicate(InputSocket *relinkToSocket, int editorNodeInputSocketIndex, ExecutionSystem *system); /** - * @brief set the resize mode - * @param resizeMode the new resize mode. - */ - void setResizeMode(InputSocketResizeMode resizeMode) {this->resizeMode = resizeMode;} + * @brief set the resize mode + * @param resizeMode the new resize mode. + */ + void setResizeMode(InputSocketResizeMode resizeMode) { + this->resizeMode = resizeMode; + } /** - * @brief get the resize mode of this socket - * @return InputSocketResizeMode - */ - InputSocketResizeMode getResizeMode() const {return this->resizeMode;} + * @brief get the resize mode of this socket + * @return InputSocketResizeMode + */ + InputSocketResizeMode getResizeMode() const { + return this->resizeMode; + } const ChannelInfo *getChannelInfo(const int channelnumber); diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h index fd90e5fcb5a..dee2c9b771f 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.h +++ b/source/blender/compositor/intern/COM_MemoryBuffer.h @@ -34,9 +34,9 @@ extern "C" { #include /** - * @brief state of a memory buffer - * @ingroup Memory - */ + * @brief state of a memory buffer + * @ingroup Memory + */ typedef enum MemoryBufferState { /** @brief memory has been allocated on creator device and CPU machine, but kernel has not been executed */ COM_MB_ALLOCATED = 1, @@ -49,77 +49,77 @@ typedef enum MemoryBufferState { class MemoryProxy; /** - * @brief a MemoryBuffer contains access to the data of a chunk - */ + * @brief a MemoryBuffer contains access to the data of a chunk + */ class MemoryBuffer { private: /** - * @brief proxy of the memory (same for all chunks in the same buffer) - */ - MemoryProxy * memoryProxy; + * @brief proxy of the memory (same for all chunks in the same buffer) + */ + MemoryProxy *memoryProxy; /** - * @brief the type of buffer COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR - */ + * @brief the type of buffer COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR + */ DataType datatype; /** - * @brief region of this buffer inside reative to the MemoryProxy - */ + * @brief region of this buffer inside reative to the MemoryProxy + */ rcti rect; /** - * brief refers to the chunknumber within the executiongroup where related to the MemoryProxy - * @see memoryProxy - */ + * brief refers to the chunknumber within the executiongroup where related to the MemoryProxy + * @see memoryProxy + */ unsigned int chunkNumber; /** - * @brief width of the chunk - */ + * @brief width of the chunk + */ unsigned int chunkWidth; /** - * @brief state of the buffer - */ + * @brief state of the buffer + */ MemoryBufferState state; /** - * @brief the actual float buffer/data - */ + * @brief the actual float buffer/data + */ float *buffer; public: /** - * @brief construct new MemoryBuffer for a chunk - */ + * @brief construct new MemoryBuffer for a chunk + */ MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect); /** - * @brief construct new temporarily MemoryBuffer for an area - */ + * @brief construct new temporarily MemoryBuffer for an area + */ MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect); /** - * @brief destructor - */ + * @brief destructor + */ ~MemoryBuffer(); /** - * @brief read the ChunkNumber of this MemoryBuffer - */ - unsigned int getChunkNumber() {return this->chunkNumber;} + * @brief read the ChunkNumber of this MemoryBuffer + */ + unsigned int getChunkNumber() { return this->chunkNumber; } /** - * @brief get the data of this MemoryBuffer - * @note buffer should already be available in memory - */ - float *getBuffer() {return this->buffer;} + * @brief get the data of this MemoryBuffer + * @note buffer should already be available in memory + */ + float *getBuffer() { return this->buffer; } /** - * @brief after execution the state will be set to available by calling this method - */ + * @brief after execution the state will be set to available by calling this method + */ void setCreatedState() { this->state = COM_MB_AVAILABLE; } @@ -130,34 +130,34 @@ public: void readEWA(float result[4], float fx, float fy, float dx, float dy); /** - * @brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk) - */ - inline const bool isTemporarily() const {return this->state == COM_MB_TEMPORARILY;} + * @brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk) + */ + inline const bool isTemporarily() const { return this->state == COM_MB_TEMPORARILY; } /** - * @brief add the content from otherBuffer to this MemoryBuffer - * @param otherBuffer source buffer - */ + * @brief add the content from otherBuffer to this MemoryBuffer + * @param otherBuffer source buffer + */ void copyContentFrom(MemoryBuffer *otherBuffer); /** - * @brief get the rect of this MemoryBuffer - */ - rcti *getRect() {return &this->rect;} + * @brief get the rect of this MemoryBuffer + */ + rcti *getRect() { return &this->rect; } /** - * @brief get the width of this MemoryBuffer - */ + * @brief get the width of this MemoryBuffer + */ int getWidth() const; /** - * @brief get the height of this MemoryBuffer - */ + * @brief get the height of this MemoryBuffer + */ int getHeight() const; /** - * @brief clear the buffer. Make all pixels black transparant. - */ + * @brief clear the buffer. Make all pixels black transparant. + */ void clear(); MemoryBuffer *duplicate(); diff --git a/source/blender/compositor/intern/COM_MemoryProxy.h b/source/blender/compositor/intern/COM_MemoryProxy.h index e0ac72de0d3..e7e7f1cf3a0 100644 --- a/source/blender/compositor/intern/COM_MemoryProxy.h +++ b/source/blender/compositor/intern/COM_MemoryProxy.h @@ -30,78 +30,78 @@ class MemoryProxy; class ExecutionGroup; /** - * @brief A MemoryProxy is a unique identifier for a memory buffer. - * A single MemoryProxy is used among all chunks of the same buffer, - * the MemoryBuffer only stores the data of a single chunk. - * @ingroup Memory - */ + * @brief A MemoryProxy is a unique identifier for a memory buffer. + * A single MemoryProxy is used among all chunks of the same buffer, + * the MemoryBuffer only stores the data of a single chunk. + * @ingroup Memory + */ class MemoryProxy { private: /** - * @brief reference to the ouput operation of the executiongroup - */ + * @brief reference to the ouput operation of the executiongroup + */ WriteBufferOperation *writeBufferOperation; /** - * @brief reference to the executor. the Execution group that can fill a chunk - */ + * @brief reference to the executor. the Execution group that can fill a chunk + */ ExecutionGroup *executor; /** - * @brief datatype of this MemoryProxy - */ + * @brief datatype of this MemoryProxy + */ DataType datatype; /** - * @brief channel information of this buffer - */ + * @brief channel information of this buffer + */ ChannelInfo channelInfo[COM_NUMBER_OF_CHANNELS]; /** - * @brief the allocated memory - */ - MemoryBuffer* buffer; + * @brief the allocated memory + */ + MemoryBuffer *buffer; public: MemoryProxy(); /** - * @brief set the ExecutionGroup that can be scheduled to calculate a certain chunk. - * @param group the ExecutionGroup to set - */ - void setExecutor(ExecutionGroup *executor) {this->executor = executor;} - - /** - * @brief get the ExecutionGroup that can be scheduled to calculate a certain chunk. - */ - ExecutionGroup *getExecutor() {return this->executor;} - - /** - * @brief set the WriteBufferOperation that is responsible for writing to this MemoryProxy - * @param operation - */ - void setWriteBufferOperation(WriteBufferOperation *operation) {this->writeBufferOperation = operation;} - - /** - * @brief get the WriteBufferOperation that is responsible for writing to this MemoryProxy - * @return WriteBufferOperation - */ - WriteBufferOperation *getWriteBufferOperation() {return this->writeBufferOperation;} + * @brief set the ExecutionGroup that can be scheduled to calculate a certain chunk. + * @param group the ExecutionGroup to set + */ + void setExecutor(ExecutionGroup *executor) { this->executor = executor; } /** - * @brief allocate memory of size widht x height - */ + * @brief get the ExecutionGroup that can be scheduled to calculate a certain chunk. + */ + ExecutionGroup *getExecutor() { return this->executor; } + + /** + * @brief set the WriteBufferOperation that is responsible for writing to this MemoryProxy + * @param operation + */ + void setWriteBufferOperation(WriteBufferOperation *operation) { this->writeBufferOperation = operation; } + + /** + * @brief get the WriteBufferOperation that is responsible for writing to this MemoryProxy + * @return WriteBufferOperation + */ + WriteBufferOperation *getWriteBufferOperation() { return this->writeBufferOperation; } + + /** + * @brief allocate memory of size widht x height + */ void allocate(unsigned int width, unsigned int height); /** - * @brief free the allocated memory - */ + * @brief free the allocated memory + */ void free(); /** - * @brief get the allocated memory - */ - inline MemoryBuffer* getBuffer() {return this->buffer;} + * @brief get the allocated memory + */ + inline MemoryBuffer *getBuffer() { return this->buffer; } }; #endif diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h index 0546062f790..12baa26cd6e 100644 --- a/source/blender/compositor/intern/COM_Node.h +++ b/source/blender/compositor/intern/COM_Node.h @@ -38,18 +38,18 @@ class Node; class NodeOperation; class ExecutionSystem; -typedef vector NodeList; +typedef vector NodeList; typedef NodeList::iterator NodeIterator; typedef pair NodeRange; /** - * My node documentation. - */ -class Node:public NodeBase { + * My node documentation. + */ +class Node : public NodeBase { private: /** - * @brief stores the reference to the SDNA bNode struct - */ + * @brief stores the reference to the SDNA bNode struct + */ bNode *editorNode; /** @@ -58,18 +58,18 @@ private: bool inActiveGroup; public: - Node(bNode *editorNode, bool create_sockets=true); + Node(bNode *editorNode, bool create_sockets = true); /** - * @brief get the reference to the SDNA bNode struct - */ + * @brief get the reference to the SDNA bNode struct + */ bNode *getbNode(); /** * @brief Is this node in the active group (the group that is being edited) * @param isInActiveGroup */ - void setIsInActiveGroup(bool isInActiveGroup) {this->inActiveGroup = isInActiveGroup; } + void setIsInActiveGroup(bool isInActiveGroup) { this->inActiveGroup = isInActiveGroup; } /** * @brief Is this node part of the active group @@ -77,63 +77,63 @@ public: * the active group will be the main tree (all nodes that are not part of a group will be active) * @return bool [false:true] */ - inline bool isInActiveGroup() {return this->inActiveGroup;} + inline bool isInActiveGroup() { return this->inActiveGroup; } + + /** + * @brief convert node to operation + * + * @todo this must be described furter + * + * @param system the ExecutionSystem where the operations need to be added + * @param context reference to the CompositorContext + */ + virtual void convertToOperations(ExecutionSystem *system, CompositorContext *context) = 0; /** - * @brief convert node to operation - * - * @todo this must be described furter - * - * @param system the ExecutionSystem where the operations need to be added - * @param context reference to the CompositorContext - */ - virtual void convertToOperations(ExecutionSystem *system, CompositorContext * context) =0; - - /** - * this method adds a SetValueOperation as input of the input socket. - * This can only be used from the convertToOperation method. all other usages are not allowed - */ + * this method adds a SetValueOperation as input of the input socket. + * This can only be used from the convertToOperation method. all other usages are not allowed + */ void addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex); /** - * this method adds a SetColorOperation as input of the input socket. - * This can only be used from the convertToOperation method. all other usages are not allowed - */ + * this method adds a SetColorOperation as input of the input socket. + * This can only be used from the convertToOperation method. all other usages are not allowed + */ void addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex); /** - * this method adds a SetVectorOperation as input of the input socket. - * This can only be used from the convertToOperation method. all other usages are not allowed - */ + * this method adds a SetVectorOperation as input of the input socket. + * This can only be used from the convertToOperation method. all other usages are not allowed + */ void addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex); /** - * Creates a new link between an outputSocket and inputSocket and registrates the link to the graph - * @return the new created link - */ + * Creates a new link between an outputSocket and inputSocket and registrates the link to the graph + * @return the new created link + */ SocketConnection *addLink(ExecutionSystem *graph, OutputSocket *outputSocket, InputSocket *inputsocket); /** - * is this node a group node. - */ + * is this node a group node. + */ virtual bool isGroupNode() const { return false; } /** - * is this node a proxy node. - */ + * is this node a proxy node. + */ virtual bool isProxyNode() const { return false; } /** - * @brief find the InputSocket by bNodeSocket - * - * @param socket - */ + * @brief find the InputSocket by bNodeSocket + * + * @param socket + */ InputSocket *findInputSocketBybNodeSocket(bNodeSocket *socket); /** - * @brief find the OutputSocket by bNodeSocket - * - * @param socket - */ + * @brief find the OutputSocket by bNodeSocket + * + * @param socket + */ OutputSocket *findOutputSocketBybNodeSocket(bNodeSocket *socket); protected: diff --git a/source/blender/compositor/intern/COM_NodeBase.h b/source/blender/compositor/intern/COM_NodeBase.h index 123797c780a..3917904afe3 100644 --- a/source/blender/compositor/intern/COM_NodeBase.h +++ b/source/blender/compositor/intern/COM_NodeBase.h @@ -37,136 +37,136 @@ class NodeOperation; class ExecutionSystem; /** - * @brief The NodeBase class is the super-class of all node related objects like @see Node @see NodeOperation - * the reason for the existence of this class is to support graph-nodes when using ExecutionSystem - * the NodeBase also contains the reference to InputSocket and OutputSocket. - * @ingroup Model - */ + * @brief The NodeBase class is the super-class of all node related objects like @see Node @see NodeOperation + * the reason for the existence of this class is to support graph-nodes when using ExecutionSystem + * the NodeBase also contains the reference to InputSocket and OutputSocket. + * @ingroup Model + */ class NodeBase { private: /** - * @brief the list of actual inputsockets @see InputSocket - */ - vector inputsockets; + * @brief the list of actual inputsockets @see InputSocket + */ + vector inputsockets; /** - * @brief the list of actual outputsockets @see OutputSocket - */ - vector outputsockets; + * @brief the list of actual outputsockets @see OutputSocket + */ + vector outputsockets; protected: /** - * @brief get access to the vector of input sockets - */ - inline vector& getInputSockets() {return this->inputsockets;} + * @brief get access to the vector of input sockets + */ + inline vector& getInputSockets() { return this->inputsockets; } /** - * @brief get access to the vector of input sockets - */ - inline vector& getOutputSockets() {return this->outputsockets;} + * @brief get access to the vector of input sockets + */ + inline vector& getOutputSockets() { return this->outputsockets; } public: /** - * @brief destructor - * clean up memory related to this NodeBase. - */ + * @brief destructor + * clean up memory related to this NodeBase. + */ virtual ~NodeBase(); /** - * @brief determine the actual socket data types that will go through the system - */ + * @brief determine the actual socket data types that will go through the system + */ virtual void determineActualSocketDataTypes(); /** - * @brief determine the actual socket data types of a specific outputsocket - * - * @param outputsocket - * a reference to the actual outputsocket where the datatype must be determined from - * - * @return - * COM_DT_VALUE if it is a value (1 float buffer) - * COM_DT_COLOR if it is a value (4 float buffer) - * COM_DT_VECTOR if it is a value (3 float buffer) - */ + * @brief determine the actual socket data types of a specific outputsocket + * + * @param outputsocket + * a reference to the actual outputsocket where the datatype must be determined from + * + * @return + * COM_DT_VALUE if it is a value (1 float buffer) + * COM_DT_COLOR if it is a value (4 float buffer) + * COM_DT_VECTOR if it is a value (3 float buffer) + */ virtual DataType determineActualDataType(OutputSocket *outputsocket); /** - * @brief is this node an operation? - * This is true when the instance is of the subclass NodeOperation. - * @return [true:false] - * @see NodeOperation - */ - virtual const int isOperation() const {return false;} + * @brief is this node an operation? + * This is true when the instance is of the subclass NodeOperation. + * @return [true:false] + * @see NodeOperation + */ + virtual const int isOperation() const { return false; } /** - * @brief check if this is an input node - * An input node is a node that only has output sockets and no input sockets - * @return [false..true] - */ + * @brief check if this is an input node + * An input node is a node that only has output sockets and no input sockets + * @return [false..true] + */ const bool isInputNode() const; /** - * @brief Return the number of input sockets of this node. - */ - const unsigned int getNumberOfInputSockets() const {return this->inputsockets.size();} - + * @brief Return the number of input sockets of this node. + */ + const unsigned int getNumberOfInputSockets() const { return this->inputsockets.size(); } + /** - * @brief Return the number of output sockets of this node. - */ - const unsigned int getNumberOfOutputSockets() const {return this->outputsockets.size();} - + * @brief Return the number of output sockets of this node. + */ + const unsigned int getNumberOfOutputSockets() const { return this->outputsockets.size(); } + /** - * after the data has been determined of an outputsocket that has a connection with an inputsocket this method is called on the - * node that contains the inputsocket. - * @param socket - * the reference of the inputsocket where connected data type is found - * @param actualType [COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR] - * the actual data type that is coming from the connected output socket - */ + * after the data has been determined of an outputsocket that has a connection with an inputsocket this method is called on the + * node that contains the inputsocket. + * @param socket + * the reference of the inputsocket where connected data type is found + * @param actualType [COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR] + * the actual data type that is coming from the connected output socket + */ virtual void notifyActualDataTypeSet(InputSocket *socket, const DataType actualType); /** - * get the reference to a certain outputsocket - * @param index - * the index of the needed outputsocket - */ + * get the reference to a certain outputsocket + * @param index + * the index of the needed outputsocket + */ OutputSocket *getOutputSocket(const int index); /** - * get the reference to the first outputsocket - * @param index - * the index of the needed outputsocket - */ - inline OutputSocket *getOutputSocket() {return getOutputSocket(0);} + * get the reference to the first outputsocket + * @param index + * the index of the needed outputsocket + */ + inline OutputSocket *getOutputSocket() { return getOutputSocket(0); } /** - * get the reference to a certain inputsocket - * @param index - * the index of the needed inputsocket - */ + * get the reference to a certain inputsocket + * @param index + * the index of the needed inputsocket + */ InputSocket *getInputSocket(const int index); - virtual bool isStatic() const {return false;} - void getStaticValues(float *result) const {} + virtual bool isStatic() const { return false; } + void getStaticValues(float *result) const { } protected: NodeBase(); /** - * @brief add an InputSocket to the collection of inputsockets - * @note may only be called in an constructor - * @param socket the InputSocket to add - */ + * @brief add an InputSocket to the collection of inputsockets + * @note may only be called in an constructor + * @param socket the InputSocket to add + */ void addInputSocket(DataType datatype); void addInputSocket(DataType datatype, InputSocketResizeMode resizeMode); void addInputSocket(DataType datatype, InputSocketResizeMode resizeMode, bNodeSocket *socket); /** - * @brief add an OutputSocket to the collection of outputsockets - * @note may only be called in an constructor - * @param socket the OutputSocket to add - */ + * @brief add an OutputSocket to the collection of outputsockets + * @note may only be called in an constructor + * @param socket the OutputSocket to add + */ void addOutputSocket(DataType datatype); void addOutputSocket(DataType datatype, bNodeSocket *socket); }; diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index e56ac7bd51f..30731572712 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -41,41 +41,41 @@ class NodeOperation; class ReadBufferOperation; /** - * @brief NodeOperation are contains calculation logic - * - * Subclasses needs to implement the execution method (defined in SocketReader) to implement logic. - * @ingroup Model - */ + * @brief NodeOperation are contains calculation logic + * + * Subclasses needs to implement the execution method (defined in SocketReader) to implement logic. + * @ingroup Model + */ class NodeOperation : public NodeBase, public SocketReader { private: /** - * @brief the index of the input socket that will be used to determine the resolution - */ + * @brief the index of the input socket that will be used to determine the resolution + */ unsigned int resolutionInputSocketIndex; /** - * @brief is this operation a complex one. - * - * Complex operations are typically doing many reads to calculate the output of a single pixel. - * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true. - */ + * @brief is this operation a complex one. + * + * Complex operations are typically doing many reads to calculate the output of a single pixel. + * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true. + */ bool complex; /** - * @brief can this operation be scheduled on an OpenCL device. - * @note Only applicable if complex is True - */ + * @brief can this operation be scheduled on an OpenCL device. + * @note Only applicable if complex is True + */ bool openCL; /** - * @brief mutex reference for very special node initializations - * @note only use when you really know what you are doing. - * this mutex is used to share data among chunks in the same operation - * @see TonemapOperation for an example of usage - * @see NodeOperation.initMutex initializes this mutex - * @see NodeOperation.deinitMutex deinitializes this mutex - * @see NodeOperation.getMutex retrieve a pointer to this mutex. - */ + * @brief mutex reference for very special node initializations + * @note only use when you really know what you are doing. + * this mutex is used to share data among chunks in the same operation + * @see TonemapOperation for an example of usage + * @see NodeOperation.initMutex initializes this mutex + * @see NodeOperation.deinitMutex deinitializes this mutex + * @see NodeOperation.getMutex retrieve a pointer to this mutex. + */ ThreadMutex mutex; /** @@ -85,87 +85,87 @@ private: public: /** - * @brief is this node an operation? - * This is true when the instance is of the subclass NodeOperation. - * @return [true:false] - * @see NodeBase - */ - const int isOperation() const {return true;} + * @brief is this node an operation? + * This is true when the instance is of the subclass NodeOperation. + * @return [true:false] + * @see NodeBase + */ + const int isOperation() const { return true; } /** - * @brief determine the resolution of this node - * @note this method will not set the resolution, this is the responsibility of the caller - * @param resolution the result of this operation - * @param preferredResolution the preferrable resolution as no resolution could be determined - */ + * @brief determine the resolution of this node + * @note this method will not set the resolution, this is the responsibility of the caller + * @param resolution the result of this operation + * @param preferredResolution the preferrable resolution as no resolution could be determined + */ virtual void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); /** - * @brief isOutputOperation determines whether this operation is an output of the ExecutionSystem during rendering or editing. - * - * Default behaviour if not overriden, this operation will not be evaluated as being an output of the ExecutionSystem. - * - * @see ExecutionSystem - * @group check - * @param rendering [true false] - * true: rendering - * false: editing - * - * @return bool the result of this method - */ - virtual bool isOutputOperation(bool rendering) const {return false;} + * @brief isOutputOperation determines whether this operation is an output of the ExecutionSystem during rendering or editing. + * + * Default behaviour if not overriden, this operation will not be evaluated as being an output of the ExecutionSystem. + * + * @see ExecutionSystem + * @group check + * @param rendering [true false] + * true: rendering + * false: editing + * + * @return bool the result of this method + */ + virtual bool isOutputOperation(bool rendering) const { return false; } /** - * isBufferOperation returns if this is an operation that work directly on buffers. - * - * there are only 2 implementation where this is true: - * @see ReadBufferOperation - * @see WriteBufferOperation - * for all other operations this will result in false. - */ - virtual int isBufferOperation() {return false;} - virtual int isSingleThreaded() {return false;} + * isBufferOperation returns if this is an operation that work directly on buffers. + * + * there are only 2 implementation where this is true: + * @see ReadBufferOperation + * @see WriteBufferOperation + * for all other operations this will result in false. + */ + virtual int isBufferOperation() { return false; } + virtual int isSingleThreaded() { return false; } - void setbNodeTree(const bNodeTree * tree) {this->btree = tree;} + void setbNodeTree(const bNodeTree *tree) { this->btree = tree; } virtual void initExecution(); /** - * @brief when a chunk is executed by a CPUDevice, this method is called - * @ingroup execution - * @param rect the rectangle of the chunk (location and size) - * @param chunkNumber the chunkNumber to be calculated - * @param memoryBuffers all input MemoryBuffer's needed - */ - virtual void executeRegion(rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers) {} + * @brief when a chunk is executed by a CPUDevice, this method is called + * @ingroup execution + * @param rect the rectangle of the chunk (location and size) + * @param chunkNumber the chunkNumber to be calculated + * @param memoryBuffers all input MemoryBuffer's needed + */ + virtual void executeRegion(rcti *rect, unsigned int chunkNumber, MemoryBuffer **memoryBuffers) {} /** - * @brief when a chunk is executed by an OpenCLDevice, this method is called - * @ingroup execution - * @note this method is only implemented in WriteBufferOperation - * @param context the OpenCL context - * @param program the OpenCL program containing all compositor kernels - * @param queue the OpenCL command queue of the device the chunk is executed on - * @param rect the rectangle of the chunk (location and size) - * @param chunkNumber the chunkNumber to be calculated - * @param memoryBuffers all input MemoryBuffer's needed - * @param outputBuffer the outputbuffer to write to - */ + * @brief when a chunk is executed by an OpenCLDevice, this method is called + * @ingroup execution + * @note this method is only implemented in WriteBufferOperation + * @param context the OpenCL context + * @param program the OpenCL program containing all compositor kernels + * @param queue the OpenCL command queue of the device the chunk is executed on + * @param rect the rectangle of the chunk (location and size) + * @param chunkNumber the chunkNumber to be calculated + * @param memoryBuffers all input MemoryBuffer's needed + * @param outputBuffer the outputbuffer to write to + */ virtual void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, - unsigned int chunkNumber, MemoryBuffer** memoryBuffers, MemoryBuffer* outputBuffer) {} + unsigned int chunkNumber, MemoryBuffer **memoryBuffers, MemoryBuffer *outputBuffer) {} /** - * @brief custom handle to add new tasks to the OpenCL command queue in order to execute a chunk on an GPUDevice - * @ingroup execution - * @param context the OpenCL context - * @param program the OpenCL program containing all compositor kernels - * @param queue the OpenCL command queue of the device the chunk is executed on - * @param outputMemoryBuffer the allocated memory buffer in main CPU memory - * @param clOutputBuffer the allocated memory buffer in OpenCLDevice memory - * @param inputMemoryBuffers all input MemoryBuffer's needed - * @param clMemToCleanUp all created cl_mem references must be added to this list. Framework will clean this after execution - * @param clKernelsToCleanUp all created cl_kernel references must be added to this list. Framework will clean this after execution - */ - virtual void executeOpenCL(cl_context context,cl_program program, cl_command_queue queue, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer** inputMemoryBuffers, list *clMemToCleanUp, list *clKernelsToCleanUp) {} + * @brief custom handle to add new tasks to the OpenCL command queue in order to execute a chunk on an GPUDevice + * @ingroup execution + * @param context the OpenCL context + * @param program the OpenCL program containing all compositor kernels + * @param queue the OpenCL command queue of the device the chunk is executed on + * @param outputMemoryBuffer the allocated memory buffer in main CPU memory + * @param clOutputBuffer the allocated memory buffer in OpenCLDevice memory + * @param inputMemoryBuffers all input MemoryBuffer's needed + * @param clMemToCleanUp all created cl_mem references must be added to this list. Framework will clean this after execution + * @param clKernelsToCleanUp all created cl_kernel references must be added to this list. Framework will clean this after execution + */ + virtual void executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, list *clKernelsToCleanUp) {} virtual void deinitExecution(); bool isResolutionSet() { @@ -173,9 +173,9 @@ public: } /** - * @brief set the resolution - * @param resolution the resolution to set - */ + * @brief set the resolution + * @param resolution the resolution to set + */ void setResolution(unsigned int resolution[]) { if (!isResolutionSet()) { this->width = resolution[0]; @@ -184,63 +184,63 @@ public: } - void getConnectedInputSockets(vector *sockets); + void getConnectedInputSockets(vector *sockets); /** - * @brief is this operation complex - * - * Complex operations are typically doing many reads to calculate the output of a single pixel. - * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true. - */ - const bool isComplex() const {return this->complex;} - virtual const bool isSetOperation() const {return false;} + * @brief is this operation complex + * + * Complex operations are typically doing many reads to calculate the output of a single pixel. + * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true. + */ + const bool isComplex() const { return this->complex; } + virtual const bool isSetOperation() const { return false; } /** - * @brief is this operation of type ReadBufferOperation - * @return [true:false] - * @see ReadBufferOperation - */ - virtual const bool isReadBufferOperation() const {return false;} + * @brief is this operation of type ReadBufferOperation + * @return [true:false] + * @see ReadBufferOperation + */ + virtual const bool isReadBufferOperation() const { return false; } /** - * @brief is this operation of type WriteBufferOperation - * @return [true:false] - * @see WriteBufferOperation - */ - virtual const bool isWriteBufferOperation() const {return false;} + * @brief is this operation of type WriteBufferOperation + * @return [true:false] + * @see WriteBufferOperation + */ + virtual const bool isWriteBufferOperation() const { return false; } /** - * @brief is this operation the active viewer output - * user can select an ViewerNode to be active (the result of this node will be drawn on the backdrop) - * @return [true:false] - * @see BaseViewerOperation - */ - virtual const bool isActiveViewerOutput() const {return false;} + * @brief is this operation the active viewer output + * user can select an ViewerNode to be active (the result of this node will be drawn on the backdrop) + * @return [true:false] + * @see BaseViewerOperation + */ + virtual const bool isActiveViewerOutput() const { return false; } - virtual bool determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti *output); + virtual bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); /** - * @brief set the index of the input socket that will determine the resolution of this operation - * @param index the index to set - */ + * @brief set the index of the input socket that will determine the resolution of this operation + * @param index the index to set + */ void setResolutionInputSocketIndex(unsigned int index); /** - * @brief get the render priority of this node. - * @note only applicable for output operations like ViewerOperation - * @return CompositorPriority - */ - virtual const CompositorPriority getRenderPriority() const {return COM_PRIORITY_LOW;} + * @brief get the render priority of this node. + * @note only applicable for output operations like ViewerOperation + * @return CompositorPriority + */ + virtual const CompositorPriority getRenderPriority() const { return COM_PRIORITY_LOW; } /** - * @brief can this NodeOperation be scheduled on an OpenCLDevice - * @see WorkScheduler.schedule - * @see ExecutionGroup.addOperation - */ + * @brief can this NodeOperation be scheduled on an OpenCLDevice + * @see WorkScheduler.schedule + * @see ExecutionGroup.addOperation + */ bool isOpenCL() { return this->openCL; } - virtual bool isViewerOperation() {return false;} - virtual bool isPreviewOperation() {return false;} + virtual bool isViewerOperation() { return false; } + virtual bool isPreviewOperation() { return false; } inline bool isBreaked() { return btree->test_break(btree->tbh); @@ -249,8 +249,8 @@ public: protected: NodeOperation(); - void setWidth(unsigned int width) {this->width = width;} - void setHeight(unsigned int height) {this->height = height;} + void setWidth(unsigned int width) { this->width = width; } + void setHeight(unsigned int height) { this->height = height; } SocketReader *getInputSocketReader(unsigned int inputSocketindex); NodeOperation *getInputOperation(unsigned int inputSocketindex); @@ -261,25 +261,25 @@ protected: /** - * @brief set whether this operation is complex - * - * Complex operations are typically doing many reads to calculate the output of a single pixel. - * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true. - */ - void setComplex(bool complex) {this->complex = complex;} + * @brief set whether this operation is complex + * + * Complex operations are typically doing many reads to calculate the output of a single pixel. + * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true. + */ + void setComplex(bool complex) { this->complex = complex; } /** - * @brief set if this NodeOperation can be scheduled on a OpenCLDevice - */ - void setOpenCL(bool openCL) {this->openCL = openCL;} + * @brief set if this NodeOperation can be scheduled on a OpenCLDevice + */ + void setOpenCL(bool openCL) { this->openCL = openCL; } - static cl_mem COM_clAttachMemoryBufferToKernelParameter(cl_context context, cl_kernel kernel, int parameterIndex, int offsetIndex, list *cleanup, MemoryBuffer **inputMemoryBuffers, SocketReader* reader); + static cl_mem COM_clAttachMemoryBufferToKernelParameter(cl_context context, cl_kernel kernel, int parameterIndex, int offsetIndex, list *cleanup, MemoryBuffer **inputMemoryBuffers, SocketReader *reader); static void COM_clAttachMemoryBufferOffsetToKernelParameter(cl_kernel kernel, int offsetIndex, MemoryBuffer *memoryBuffers); static void COM_clAttachOutputMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, cl_mem clOutputMemoryBuffer); void COM_clAttachSizeToKernelParameter(cl_kernel kernel, int offsetIndex); - static void COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer* outputMemoryBuffer); + static void COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer *outputMemoryBuffer); void COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer *outputMemoryBuffer, int offsetIndex); - cl_kernel COM_clCreateKernel(cl_program program, const char* kernelname, list *clKernelsToCleanUp); + cl_kernel COM_clCreateKernel(cl_program program, const char *kernelname, list *clKernelsToCleanUp); }; diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.h b/source/blender/compositor/intern/COM_OpenCLDevice.h index f61c555558d..75c326eda23 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.h +++ b/source/blender/compositor/intern/COM_OpenCLDevice.h @@ -31,57 +31,57 @@ class OpenCLDevice; /** - * @brief device representing an GPU OpenCL device. - * an instance of this class represents a single cl_device - */ -class OpenCLDevice: public Device { + * @brief device representing an GPU OpenCL device. + * an instance of this class represents a single cl_device + */ +class OpenCLDevice : public Device { private: /** - *@brief opencl context - */ + *@brief opencl context + */ cl_context context; /** - *@brief opencl device - */ + *@brief opencl device + */ cl_device_id device; /** - *@brief opencl program - */ + *@brief opencl program + */ cl_program program; /** - *@brief opencl command queue - */ + *@brief opencl command queue + */ cl_command_queue queue; public: /** - *@brief constructor with opencl device - *@param context - *@param device - */ + *@brief constructor with opencl device + *@param context + *@param device + */ OpenCLDevice(cl_context context, cl_device_id device, cl_program program); /** - * @brief initialize the device - * During initialization the OpenCL cl_command_queue is created - * the command queue is stored in the field queue. - * @see queue - */ + * @brief initialize the device + * During initialization the OpenCL cl_command_queue is created + * the command queue is stored in the field queue. + * @see queue + */ bool initialize(); /** - * @brief deinitialize the device - * During deintiialization the command queue is cleared - */ + * @brief deinitialize the device + * During deintiialization the command queue is cleared + */ void deinitialize(); /** - * @brief execute a WorkPackage - * @param work the WorkPackage to execute - */ + * @brief execute a WorkPackage + * @param work the WorkPackage to execute + */ void execute(WorkPackage *work); }; diff --git a/source/blender/compositor/intern/COM_OutputSocket.h b/source/blender/compositor/intern/COM_OutputSocket.h index 640588417b4..e008d651046 100644 --- a/source/blender/compositor/intern/COM_OutputSocket.h +++ b/source/blender/compositor/intern/COM_OutputSocket.h @@ -37,18 +37,18 @@ class WriteBufferOperation; //#define COM_ST_OUTPUT 1 /** - * @brief OutputSocket are sockets that can send data/input - * @ingroup Model - */ + * @brief OutputSocket are sockets that can send data/input + * @ingroup Model + */ class OutputSocket : public Socket { private: - vector connections; + vector connections; /** - * @brief index of the inputsocket that determines the datatype of this outputsocket - * -1 will not use any inputsocket to determine the datatype, but use the outputsocket - * default datatype. - */ + * @brief index of the inputsocket that determines the datatype of this outputsocket + * -1 will not use any inputsocket to determine the datatype, but use the outputsocket + * default datatype. + */ int inputSocketDataTypeDeterminatorIndex; ChannelInfo channelinfo[4]; @@ -56,47 +56,47 @@ private: public: OutputSocket(DataType datatype); OutputSocket(DataType datatype, int inputSocketDataTypeDeterminatorIndex); - OutputSocket(OutputSocket * from); + OutputSocket(OutputSocket *from); void addConnection(SocketConnection *connection); - SocketConnection *getConnection(unsigned int index) {return this->connections[index];} + SocketConnection *getConnection(unsigned int index) { return this->connections[index]; } const int isConnected() const; int isOutputSocket() const; /** - * @brief determine the resolution of this socket - * @param resolution the result of this operation - * @param preferredResolution the preferrable resolution as no resolution could be determined - */ + * @brief determine the resolution of this socket + * @param resolution the result of this operation + * @param preferredResolution the preferrable resolution as no resolution could be determined + */ void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); /** - * @brief determine the actual data type and channel info. - */ + * @brief determine the actual data type and channel info. + */ void determineActualDataType(); - void relinkConnections(OutputSocket *relinkToSocket) {this->relinkConnections(relinkToSocket, false);}; + void relinkConnections(OutputSocket *relinkToSocket) { this->relinkConnections(relinkToSocket, false); }; void relinkConnections(OutputSocket *relinkToSocket, bool single); bool isActualDataTypeDeterminedByInputSocket() { - return this->inputSocketDataTypeDeterminatorIndex>-1; + return this->inputSocketDataTypeDeterminatorIndex > -1; } - const int getNumberOfConnections() {return connections.size();} + const int getNumberOfConnections() { return connections.size(); } /** - * @brief get the index of the inputsocket that determines the datatype of this outputsocket - */ - int getInputSocketDataTypeDeterminatorIndex() {return this->inputSocketDataTypeDeterminatorIndex;} + * @brief get the index of the inputsocket that determines the datatype of this outputsocket + */ + int getInputSocketDataTypeDeterminatorIndex() { return this->inputSocketDataTypeDeterminatorIndex; } void clearConnections(); /** - * @brief find a connected write buffer operation to this OutputSocket - * @return WriteBufferOperation or NULL - */ + * @brief find a connected write buffer operation to this OutputSocket + * @return WriteBufferOperation or NULL + */ WriteBufferOperation *findAttachedWriteBufferOperation() const; ChannelInfo *getChannelInfo(const int channelnumber); /** - * @brief trigger determine actual data type to all connected sockets - * @note will only be triggered just after the actual data type is set. - */ + * @brief trigger determine actual data type to all connected sockets + * @note will only be triggered just after the actual data type is set. + */ void fireActualDataType(); private: diff --git a/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h b/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h index ace48365752..b1bf28c9c07 100644 --- a/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h +++ b/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h @@ -37,24 +37,24 @@ public: SingleThreadedNodeOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); - virtual MemoryBuffer* createMemoryBuffer(rcti *rect, MemoryBuffer **memoryBuffers) = 0; + virtual MemoryBuffer *createMemoryBuffer(rcti *rect, MemoryBuffer **memoryBuffers) = 0; - int isSingleThreaded() {return true;} + int isSingleThreaded() { return true; } }; #endif diff --git a/source/blender/compositor/intern/COM_Socket.h b/source/blender/compositor/intern/COM_Socket.h index 8ad7a5c7fde..0be21a6b1b8 100644 --- a/source/blender/compositor/intern/COM_Socket.h +++ b/source/blender/compositor/intern/COM_Socket.h @@ -34,33 +34,33 @@ class SocketConnection; class NodeBase; /** - * @brief Base class for InputSocket and OutputSocket. - * - * A socket are the points on an node where the user can make a connection between. - * Sockets are always part of a node or an operation. - * - * @see InputSocket - * @see OutputSocket - * @see SocketConnection - a connection between an InputSocket and an OutputSocket - * @ingroup Model - */ + * @brief Base class for InputSocket and OutputSocket. + * + * A socket are the points on an node where the user can make a connection between. + * Sockets are always part of a node or an operation. + * + * @see InputSocket + * @see OutputSocket + * @see SocketConnection - a connection between an InputSocket and an OutputSocket + * @ingroup Model + */ class Socket { private: /** - * Reference to the node where this Socket belongs to - */ + * Reference to the node where this Socket belongs to + */ NodeBase *node; /** - * the datatype of this socket. Is used for automatically data transformation. - * @section data-conversion - */ + * the datatype of this socket. Is used for automatically data transformation. + * @section data-conversion + */ DataType datatype; /** - * the actual data type during execution. This can be different than the field datatype, based on the conversion rules of the node - * @section data-conversion - */ + * the actual data type during execution. This can be different than the field datatype, based on the conversion rules of the node + * @section data-conversion + */ DataType actualType; bNodeSocket *editorSocket; @@ -72,17 +72,17 @@ public: NodeBase *getNode() const; /** - * @brief get the actual data type - * - * @note The actual data type can differ from the data type this socket expects. - * @return actual DataType - */ + * @brief get the actual data type + * + * @note The actual data type can differ from the data type this socket expects. + * @return actual DataType + */ DataType getActualDataType() const; /** - * @brief set the actual data type - * @param actualType the new actual type - */ + * @brief set the actual data type + * @param actualType the new actual type + */ void setActualDataType(DataType actualType); const virtual int isConnected() const; @@ -90,9 +90,9 @@ public: int isOutputSocket() const; virtual void determineResolution(int resolution[], unsigned int preferredResolution[]) {} virtual void determineActualDataType() {} - - void setEditorSocket(bNodeSocket *editorSocket) {this->editorSocket = editorSocket;} - bNodeSocket *getbNodeSocket() const {return this->editorSocket;} + + void setEditorSocket(bNodeSocket *editorSocket) { this->editorSocket = editorSocket; } + bNodeSocket *getbNodeSocket() const { return this->editorSocket; } }; diff --git a/source/blender/compositor/intern/COM_SocketConnection.h b/source/blender/compositor/intern/COM_SocketConnection.h index 1c4dcebfe07..5385c5be49b 100644 --- a/source/blender/compositor/intern/COM_SocketConnection.h +++ b/source/blender/compositor/intern/COM_SocketConnection.h @@ -29,94 +29,94 @@ #include "COM_ChannelInfo.h" /** - * @brief An SocketConnection is an connection between an InputSocket and an OutputSocket. - * - *
-  * +----------+     To InputSocket +----------+
-  * | From     |  SocketConnection \| To Node  |
-  * | Node     *====================*          |
-  * |          |\                   |          |
-  * |          | From OutputSocket  +----------+
-  * +----------+
-  * 
- * @ingroup Model - * @see InputSocket - * @see OutputSocket - */ + * @brief An SocketConnection is an connection between an InputSocket and an OutputSocket. + * + *
+ * +----------+     To InputSocket +----------+
+ * | From     |  SocketConnection \| To Node  |
+ * | Node     *====================*          |
+ * |          |\                   |          |
+ * |          | From OutputSocket  +----------+
+ * +----------+
+ * 
+ * @ingroup Model + * @see InputSocket + * @see OutputSocket + */ class SocketConnection { private: /** - * @brief Startpoint of the connection - */ + * @brief Startpoint of the connection + */ OutputSocket *fromSocket; /** - * @brief Endpoint of the connection - */ + * @brief Endpoint of the connection + */ InputSocket *toSocket; /** - * @brief has the resize already been done for this connection - */ + * @brief has the resize already been done for this connection + */ bool ignoreResizeCheck; public: SocketConnection(); /** - * @brief set the startpoint of the connection - * @param fromsocket - */ + * @brief set the startpoint of the connection + * @param fromsocket + */ void setFromSocket(OutputSocket *fromsocket); /** - * @brief get the startpoint of the connection - * @return from OutputSocket - */ + * @brief get the startpoint of the connection + * @return from OutputSocket + */ OutputSocket *getFromSocket() const; /** - * @brief set the endpoint of the connection - * @param tosocket - */ + * @brief set the endpoint of the connection + * @param tosocket + */ void setToSocket(InputSocket *tosocket); /** - * @brief get the endpoint of the connection - * @return to InputSocket - */ + * @brief get the endpoint of the connection + * @return to InputSocket + */ InputSocket *getToSocket() const; /** - * @brief check if this connection is valid - */ + * @brief check if this connection is valid + */ bool isValid() const; /** - * @brief return the Node where this connection is connected from - */ - NodeBase * getFromNode() const; + * @brief return the Node where this connection is connected from + */ + NodeBase *getFromNode() const; /** - * @brief return the Node where this connection is connected to - */ - NodeBase * getToNode() const; + * @brief return the Node where this connection is connected to + */ + NodeBase *getToNode() const; /** - * @brief set, whether the resize has already been done for this SocketConnection - */ - void setIgnoreResizeCheck(bool check) {this->ignoreResizeCheck = check;} + * @brief set, whether the resize has already been done for this SocketConnection + */ + void setIgnoreResizeCheck(bool check) { this->ignoreResizeCheck = check; } /** - * @brief has the resize already been done for this SocketConnection - */ - bool isIgnoreResizeCheck() const { return this->ignoreResizeCheck;} + * @brief has the resize already been done for this SocketConnection + */ + bool isIgnoreResizeCheck() const { return this->ignoreResizeCheck; } /** - * @brief does this SocketConnection need resolution conversion - * @note PreviewOperation's will be ignored - * @note Already converted SocketConnection's will be ignored - * @return needs conversion [true:false] - */ + * @brief does this SocketConnection need resolution conversion + * @note PreviewOperation's will be ignored + * @note Already converted SocketConnection's will be ignored + * @return needs conversion [true:false] + */ bool needsResolutionConversion() const; }; diff --git a/source/blender/compositor/intern/COM_SocketReader.h b/source/blender/compositor/intern/COM_SocketReader.h index 24322847517..3eb39e4bf02 100644 --- a/source/blender/compositor/intern/COM_SocketReader.h +++ b/source/blender/compositor/intern/COM_SocketReader.h @@ -33,43 +33,43 @@ typedef enum PixelSampler { class MemoryBuffer; /** - * @brief Helper class for reading socket data. - * Only use this class for dispatching (un-ary and n-ary) executions. - * @ingroup Execution - */ + * @brief Helper class for reading socket data. + * Only use this class for dispatching (un-ary and n-ary) executions. + * @ingroup Execution + */ class SocketReader { private: protected: /** - * @brief Holds the width of the output of this operation. - */ + * @brief Holds the width of the output of this operation. + */ unsigned int width; /** - * @brief Holds the height of the output of this operation. - */ + * @brief Holds the height of the output of this operation. + */ unsigned int height; /** - * @brief calculate a single pixel - * @note this method is called for non-complex - * @param result is a float[4] array to store the result - * @param x the x-coordinate of the pixel to calculate in image space - * @param y the y-coordinate of the pixel to calculate in image space - * @param inputBuffers chunks that can be read by their ReadBufferOperation. - */ + * @brief calculate a single pixel + * @note this method is called for non-complex + * @param result is a float[4] array to store the result + * @param x the x-coordinate of the pixel to calculate in image space + * @param y the y-coordinate of the pixel to calculate in image space + * @param inputBuffers chunks that can be read by their ReadBufferOperation. + */ virtual void executePixel(float *result, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) {} /** - * @brief calculate a single pixel - * @note this method is called for complex - * @param result is a float[4] array to store the result - * @param x the x-coordinate of the pixel to calculate in image space - * @param y the y-coordinate of the pixel to calculate in image space - * @param inputBuffers chunks that can be read by their ReadBufferOperation. - * @param chunkData chunk specific data a during execution time. - */ + * @brief calculate a single pixel + * @note this method is called for complex + * @param result is a float[4] array to store the result + * @param x the x-coordinate of the pixel to calculate in image space + * @param y the y-coordinate of the pixel to calculate in image space + * @param inputBuffers chunks that can be read by their ReadBufferOperation. + * @param chunkData chunk specific data a during execution time. + */ virtual void executePixel(float *result, int x, int y, MemoryBuffer *inputBuffers[], void *chunkData) { executePixel(result, x, y, COM_PS_NEAREST, inputBuffers); } @@ -97,17 +97,15 @@ public: executePixel(result, x, y, dx, dy, inputBuffers); } - virtual void *initializeTileData(rcti *rect, MemoryBuffer** memoryBuffers) { - return 0; - } - virtual void deinitializeTileData(rcti *rect, MemoryBuffer** memoryBuffers, void *data) { + virtual void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { return 0; } + virtual void deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data) { } - virtual MemoryBuffer *getInputMemoryBuffer(MemoryBuffer** memoryBuffers) {return 0;} + virtual MemoryBuffer *getInputMemoryBuffer(MemoryBuffer **memoryBuffers) { return 0; } - inline const unsigned int getWidth() const {return this->width;} - inline const unsigned int getHeight() const {return this->height;} + inline const unsigned int getWidth() const { return this->width; } + inline const unsigned int getHeight() const { return this->height; } }; #endif diff --git a/source/blender/compositor/intern/COM_WorkPackage.h b/source/blender/compositor/intern/COM_WorkPackage.h index 8bdf21499cf..18d83cc151c 100644 --- a/source/blender/compositor/intern/COM_WorkPackage.h +++ b/source/blender/compositor/intern/COM_WorkPackage.h @@ -28,37 +28,37 @@ class WorkPackage; #include "COM_ExecutionGroup.h" /** - * @brief contains data about work that can be scheduled - * @see WorkScheduler - */ + * @brief contains data about work that can be scheduled + * @see WorkScheduler + */ class WorkPackage { private: /** - * @brief executionGroup with the operations-setup to be evaluated - */ + * @brief executionGroup with the operations-setup to be evaluated + */ ExecutionGroup *executionGroup; /** - * @brief number of the chunk to be executed - */ + * @brief number of the chunk to be executed + */ unsigned int chunkNumber; public: /** - * @constructor - * @param group the ExecutionGroup - * @param chunkNumber the number of the chunk - */ + * @constructor + * @param group the ExecutionGroup + * @param chunkNumber the number of the chunk + */ WorkPackage(ExecutionGroup *group, unsigned int chunkNumber); /** - * @brief get the ExecutionGroup - */ - ExecutionGroup *getExecutionGroup() const {return this->executionGroup;} + * @brief get the ExecutionGroup + */ + ExecutionGroup *getExecutionGroup() const { return this->executionGroup; } /** - * @brief get the number of the chunk - */ - unsigned int getChunkNumber() const {return this->chunkNumber;} + * @brief get the number of the chunk + */ + unsigned int getChunkNumber() const { return this->chunkNumber; } }; #endif diff --git a/source/blender/compositor/intern/COM_WorkScheduler.h b/source/blender/compositor/intern/COM_WorkScheduler.h index b03b514d139..e52e0295607 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.h +++ b/source/blender/compositor/intern/COM_WorkScheduler.h @@ -32,83 +32,83 @@ extern "C" { #include "COM_Device.h" /** @brief the workscheduler - * @ingroup execution - */ + * @ingroup execution + */ class WorkScheduler { #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE /** - * @brief are we being stopped. - */ + * @brief are we being stopped. + */ static bool isStopping(); /** - * @brief main thread loop for cpudevices - * inside this loop new work is queried and being executed - */ + * @brief main thread loop for cpudevices + * inside this loop new work is queried and being executed + */ static void *thread_execute_cpu(void *data); /** - * @brief main thread loop for gpudevices - * inside this loop new work is queried and being executed - */ + * @brief main thread loop for gpudevices + * inside this loop new work is queried and being executed + */ static void *thread_execute_gpu(void *data); #endif public: /** - * @brief schedule a chunk of a group to be calculated. - * An execution group schedules a chunk in the WorkScheduler - * when ExecutionGroup.isOpenCL is set the work will be handled by a OpenCLDevice - * otherwide the work is scheduled for an CPUDevice - * @see ExecutionGroup.execute - * @param group the execution group - * @param chunkNumber the number of the chunk in the group to be executed - */ + * @brief schedule a chunk of a group to be calculated. + * An execution group schedules a chunk in the WorkScheduler + * when ExecutionGroup.isOpenCL is set the work will be handled by a OpenCLDevice + * otherwide the work is scheduled for an CPUDevice + * @see ExecutionGroup.execute + * @param group the execution group + * @param chunkNumber the number of the chunk in the group to be executed + */ static void schedule(ExecutionGroup *group, int chunkNumber); /** - * @brief initialize the WorkScheduler - * - * during initialization the mutexes are initialized. - * there are two mutexes (for every device type one) - * After mutex initialization the system is queried in order to count the number of CPUDevices and GPUDevices to be created. - * For every hardware thread a CPUDevice and for every OpenCL GPU device a OpenCLDevice is created. - * these devices are stored in a separate list (cpudevices & gpudevices) - */ + * @brief initialize the WorkScheduler + * + * during initialization the mutexes are initialized. + * there are two mutexes (for every device type one) + * After mutex initialization the system is queried in order to count the number of CPUDevices and GPUDevices to be created. + * For every hardware thread a CPUDevice and for every OpenCL GPU device a OpenCLDevice is created. + * these devices are stored in a separate list (cpudevices & gpudevices) + */ static void initialize(); /** - * @brief deinitialize the WorkScheduler - * free all allocated resources - */ + * @brief deinitialize the WorkScheduler + * free all allocated resources + */ static void deinitialize(); /** - * @brief Start the execution - * this methods will start the WorkScheduler. Inside this method all threads are initialized. - * for every device a thread is created. - * @see initialize Initialization and query of the number of devices - */ + * @brief Start the execution + * this methods will start the WorkScheduler. Inside this method all threads are initialized. + * for every device a thread is created. + * @see initialize Initialization and query of the number of devices + */ static void start(CompositorContext &context); /** - * @brief stop the execution - * All created thread by the start method are destroyed. - * @see start - */ + * @brief stop the execution + * All created thread by the start method are destroyed. + * @see start + */ static void stop(); /** - * @brief wait for all work to be completed. - */ + * @brief wait for all work to be completed. + */ static void finish(); /** - * @brief Are there OpenCL capable GPU devices initialized? - * the result of this method is stored in the CompositorContext - * A node can generate a different operation tree when OpenCLDevices exists. - * @see CompositorContext.getHasActiveOpenCLDevices - */ + * @brief Are there OpenCL capable GPU devices initialized? + * the result of this method is stored in the CompositorContext + * A node can generate a different operation tree when OpenCLDevices exists. + * @see CompositorContext.getHasActiveOpenCLDevices + */ static bool hasGPUDevices(); }; #endif diff --git a/source/blender/compositor/nodes/COM_AlphaOverNode.h b/source/blender/compositor/nodes/COM_AlphaOverNode.h index 64f78e76837..f7375d9a7c5 100644 --- a/source/blender/compositor/nodes/COM_AlphaOverNode.h +++ b/source/blender/compositor/nodes/COM_AlphaOverNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief AlphaOverNode - * @ingroup Node - */ -class AlphaOverNode: public Node { + * @brief AlphaOverNode + * @ingroup Node + */ +class AlphaOverNode : public Node { public: - AlphaOverNode(bNode *editorNode) :Node(editorNode) {} - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + AlphaOverNode(bNode *editorNode) : Node(editorNode) {} + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_BilateralBlurNode.h b/source/blender/compositor/nodes/COM_BilateralBlurNode.h index a92de0eaa62..e6f9242fa32 100644 --- a/source/blender/compositor/nodes/COM_BilateralBlurNode.h +++ b/source/blender/compositor/nodes/COM_BilateralBlurNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief BilateralBlurNode - * @ingroup Node - */ -class BilateralBlurNode: public Node { + * @brief BilateralBlurNode + * @ingroup Node + */ +class BilateralBlurNode : public Node { public: BilateralBlurNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_BlurNode.h b/source/blender/compositor/nodes/COM_BlurNode.h index 04a680c32cf..e7daff1c414 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.h +++ b/source/blender/compositor/nodes/COM_BlurNode.h @@ -26,14 +26,14 @@ #include "COM_Node.h" /** - * @brief BlurNode - * @ingroup Node - */ + * @brief BlurNode + * @ingroup Node + */ -class BlurNode: public Node { +class BlurNode : public Node { public: BlurNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.h b/source/blender/compositor/nodes/COM_BokehBlurNode.h index eb9fada5112..5ce75a7d42b 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.h +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.h @@ -26,14 +26,14 @@ #include "COM_Node.h" /** - * @brief BokehBlurNode - * @ingroup Node - */ + * @brief BokehBlurNode + * @ingroup Node + */ -class BokehBlurNode: public Node { +class BokehBlurNode : public Node { public: BokehBlurNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.h b/source/blender/compositor/nodes/COM_BokehImageNode.h index d4fabf0e516..a4bfe2bedc0 100644 --- a/source/blender/compositor/nodes/COM_BokehImageNode.h +++ b/source/blender/compositor/nodes/COM_BokehImageNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief BokehImageNode - * @ingroup Node - */ -class BokehImageNode: public Node { + * @brief BokehImageNode + * @ingroup Node + */ +class BokehImageNode : public Node { public: BokehImageNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_BoxMaskNode.h b/source/blender/compositor/nodes/COM_BoxMaskNode.h index c71c6a18388..9ebe2cc755a 100644 --- a/source/blender/compositor/nodes/COM_BoxMaskNode.h +++ b/source/blender/compositor/nodes/COM_BoxMaskNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief BoxMaskNode - * @ingroup Node - */ -class BoxMaskNode: public Node { + * @brief BoxMaskNode + * @ingroup Node + */ +class BoxMaskNode : public Node { public: BoxMaskNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.h b/source/blender/compositor/nodes/COM_BrightnessNode.h index 4c3b6421322..a10372049f0 100644 --- a/source/blender/compositor/nodes/COM_BrightnessNode.h +++ b/source/blender/compositor/nodes/COM_BrightnessNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief BrightnessNode - * @ingroup Node - */ -class BrightnessNode: public Node { + * @brief BrightnessNode + * @ingroup Node + */ +class BrightnessNode : public Node { public: BrightnessNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.h b/source/blender/compositor/nodes/COM_ChannelMatteNode.h index cb67ac604b2..45d03e18a6a 100644 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.h @@ -25,9 +25,9 @@ #include "COM_Node.h" /** - * @brief ChannelMatteNode - * @ingroup Node - */ + * @brief ChannelMatteNode + * @ingroup Node + */ class ChannelMatteNode : public Node { public: diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.h b/source/blender/compositor/nodes/COM_ChromaMatteNode.h index 6008137b4a7..ed8250b0329 100644 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.h @@ -25,9 +25,9 @@ #include "COM_Node.h" /** - * @brief ChromaMatteNode - * @ingroup Node - */ + * @brief ChromaMatteNode + * @ingroup Node + */ class ChromaMatteNode : public Node { public: diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.h b/source/blender/compositor/nodes/COM_ColorBalanceNode.h index 61a09d28c01..c2bdc306e20 100644 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.h +++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.h @@ -26,9 +26,9 @@ #include "COM_Node.h" /** - * @brief ColorBalanceNode - * @ingroup Node - */ + * @brief ColorBalanceNode + * @ingroup Node + */ class ColorBalanceNode : public Node { public: diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h b/source/blender/compositor/nodes/COM_ColorCorrectionNode.h index 46b7fe5e0bc..f1b0f69bec5 100644 --- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h +++ b/source/blender/compositor/nodes/COM_ColorCorrectionNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief ColorCorrectionNode - * @ingroup Node - */ -class ColorCorrectionNode: public Node { + * @brief ColorCorrectionNode + * @ingroup Node + */ +class ColorCorrectionNode : public Node { public: ColorCorrectionNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.h b/source/blender/compositor/nodes/COM_ColorCurveNode.h index 264e2691566..ecfae1f86f8 100644 --- a/source/blender/compositor/nodes/COM_ColorCurveNode.h +++ b/source/blender/compositor/nodes/COM_ColorCurveNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief ColorCurveNode - * @ingroup Node - */ -class ColorCurveNode: public Node { + * @brief ColorCurveNode + * @ingroup Node + */ +class ColorCurveNode : public Node { public: ColorCurveNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.h b/source/blender/compositor/nodes/COM_ColorMatteNode.h index af64616d054..375c914a122 100644 --- a/source/blender/compositor/nodes/COM_ColorMatteNode.h +++ b/source/blender/compositor/nodes/COM_ColorMatteNode.h @@ -25,9 +25,9 @@ #include "COM_Node.h" /** - * @brief ColorMatteNode - * @ingroup Node - */ + * @brief ColorMatteNode + * @ingroup Node + */ class ColorMatteNode : public Node { public: diff --git a/source/blender/compositor/nodes/COM_ColorNode.h b/source/blender/compositor/nodes/COM_ColorNode.h index 937979dd961..3e3df63e90a 100644 --- a/source/blender/compositor/nodes/COM_ColorNode.h +++ b/source/blender/compositor/nodes/COM_ColorNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief ColorNode - * @ingroup Node - */ -class ColorNode: public Node { + * @brief ColorNode + * @ingroup Node + */ +class ColorNode : public Node { public: ColorNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.h b/source/blender/compositor/nodes/COM_ColorRampNode.h index 53fff2b0d98..4d706e126e1 100644 --- a/source/blender/compositor/nodes/COM_ColorRampNode.h +++ b/source/blender/compositor/nodes/COM_ColorRampNode.h @@ -26,14 +26,14 @@ #include "COM_Node.h" /** - * @brief ColorRampNode - * @ingroup Node - */ + * @brief ColorRampNode + * @ingroup Node + */ class ColorRampNode : public Node { public: ColorRampNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif // COM_ColorRampNODE_H diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.h b/source/blender/compositor/nodes/COM_ColorSpillNode.h index ed0e33b0742..d8ce6878fa0 100644 --- a/source/blender/compositor/nodes/COM_ColorSpillNode.h +++ b/source/blender/compositor/nodes/COM_ColorSpillNode.h @@ -26,9 +26,9 @@ #include "COM_Node.h" /** - * @brief ColorSpillNode - * @ingroup Node - */ + * @brief ColorSpillNode + * @ingroup Node + */ class ColorSpillNode : public Node { public: diff --git a/source/blender/compositor/nodes/COM_ColorToBWNode.h b/source/blender/compositor/nodes/COM_ColorToBWNode.h index e2badd1b104..34a157c73d8 100644 --- a/source/blender/compositor/nodes/COM_ColorToBWNode.h +++ b/source/blender/compositor/nodes/COM_ColorToBWNode.h @@ -26,12 +26,12 @@ #include "COM_Node.h" #include "DNA_node_types.h" /** - * @brief ColourToBWNode - * @ingroup Node - */ + * @brief ColourToBWNode + * @ingroup Node + */ class ColourToBWNode : public Node { public: ColourToBWNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_CombineHSVANode.h b/source/blender/compositor/nodes/COM_CombineHSVANode.h index fabd6f91f7e..d8aba71d456 100644 --- a/source/blender/compositor/nodes/COM_CombineHSVANode.h +++ b/source/blender/compositor/nodes/COM_CombineHSVANode.h @@ -27,12 +27,12 @@ #include "DNA_node_types.h" #include "COM_CombineRGBANode.h" /** - * @brief CombineHSVANode - * @ingroup Node - */ + * @brief CombineHSVANode + * @ingroup Node + */ class CombineHSVANode : public CombineRGBANode { public: CombineHSVANode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_CombineRGBANode.h b/source/blender/compositor/nodes/COM_CombineRGBANode.h index 182bfece6d3..1f25d8deed9 100644 --- a/source/blender/compositor/nodes/COM_CombineRGBANode.h +++ b/source/blender/compositor/nodes/COM_CombineRGBANode.h @@ -26,12 +26,12 @@ #include "COM_Node.h" #include "DNA_node_types.h" /** - * @brief CombineRGBANode - * @ingroup Node - */ + * @brief CombineRGBANode + * @ingroup Node + */ class CombineRGBANode : public Node { public: CombineRGBANode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_CombineYCCANode.h b/source/blender/compositor/nodes/COM_CombineYCCANode.h index 86e2d50e950..3b143aabc7f 100644 --- a/source/blender/compositor/nodes/COM_CombineYCCANode.h +++ b/source/blender/compositor/nodes/COM_CombineYCCANode.h @@ -26,9 +26,9 @@ #include "DNA_node_types.h" #include "COM_CombineRGBANode.h" /** - * @brief CombineYCCANode - * @ingroup Node - */ + * @brief CombineYCCANode + * @ingroup Node + */ class CombineYCCANode : public CombineRGBANode { public: CombineYCCANode(bNode *editorNode); diff --git a/source/blender/compositor/nodes/COM_CombineYUVANode.h b/source/blender/compositor/nodes/COM_CombineYUVANode.h index 7d2f9cddf7e..1eae44c83a5 100644 --- a/source/blender/compositor/nodes/COM_CombineYUVANode.h +++ b/source/blender/compositor/nodes/COM_CombineYUVANode.h @@ -26,9 +26,9 @@ #include "DNA_node_types.h" #include "COM_CombineRGBANode.h" /** - * @brief CombineYUVANode - * @ingroup Node - */ + * @brief CombineYUVANode + * @ingroup Node + */ class CombineYUVANode : public CombineRGBANode { public: CombineYUVANode(bNode *editorNode); diff --git a/source/blender/compositor/nodes/COM_CompositorNode.h b/source/blender/compositor/nodes/COM_CompositorNode.h index e77d1d2f225..585dae7761e 100644 --- a/source/blender/compositor/nodes/COM_CompositorNode.h +++ b/source/blender/compositor/nodes/COM_CompositorNode.h @@ -26,12 +26,12 @@ #include "COM_Node.h" #include "DNA_node_types.h" /** - * @brief CompositorNode - * @ingroup Node - */ + * @brief CompositorNode + * @ingroup Node + */ class CompositorNode : public Node { public: CompositorNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h b/source/blender/compositor/nodes/COM_ConvertAlphaNode.h index 2e3fe743f4e..d9077c23a02 100644 --- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h +++ b/source/blender/compositor/nodes/COM_ConvertAlphaNode.h @@ -25,13 +25,13 @@ #include "COM_Node.h" /** - * @brief ConvertAlphaNode - * @ingroup Node - */ -class ConvertAlphaNode: public Node { + * @brief ConvertAlphaNode + * @ingroup Node + */ +class ConvertAlphaNode : public Node { public: - ConvertAlphaNode(bNode *editorNode) :Node(editorNode) {} - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + ConvertAlphaNode(bNode *editorNode) : Node(editorNode) {} + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_CropNode.h b/source/blender/compositor/nodes/COM_CropNode.h index 0bdfffc8fec..44fdeecc180 100644 --- a/source/blender/compositor/nodes/COM_CropNode.h +++ b/source/blender/compositor/nodes/COM_CropNode.h @@ -25,10 +25,10 @@ #include "COM_Node.h" -class CropNode: public Node { +class CropNode : public Node { public: CropNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_DefocusNode.h b/source/blender/compositor/nodes/COM_DefocusNode.h index d52ee3da77b..a3cffbd98c4 100644 --- a/source/blender/compositor/nodes/COM_DefocusNode.h +++ b/source/blender/compositor/nodes/COM_DefocusNode.h @@ -26,14 +26,14 @@ #include "COM_Node.h" /** - * @brief DefocusNode - * @ingroup Node - */ + * @brief DefocusNode + * @ingroup Node + */ -class DefocusNode: public Node { +class DefocusNode : public Node { public: DefocusNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h index 3b270ebc3b7..faaf235bf34 100644 --- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h @@ -26,14 +26,14 @@ #include "COM_Node.h" /** - * @brief DifferenceMatteNode - * @ingroup Node - */ + * @brief DifferenceMatteNode + * @ingroup Node + */ class DifferenceMatteNode : public Node { public: DifferenceMatteNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif // COM_DifferenceMatteNODE_H diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.h b/source/blender/compositor/nodes/COM_DilateErodeNode.h index 496bd0203dd..fa4e368e00d 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.h +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief DilateErodeNode - * @ingroup Node - */ -class DilateErodeNode: public Node { + * @brief DilateErodeNode + * @ingroup Node + */ +class DilateErodeNode : public Node { public: DilateErodeNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h b/source/blender/compositor/nodes/COM_DirectionalBlurNode.h index 1cf36fdeae7..d387ecf81dc 100644 --- a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h +++ b/source/blender/compositor/nodes/COM_DirectionalBlurNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief DirectionalBlurNode - * @ingroup Node - */ -class DirectionalBlurNode: public Node { + * @brief DirectionalBlurNode + * @ingroup Node + */ +class DirectionalBlurNode : public Node { public: DirectionalBlurNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_DisplaceNode.h b/source/blender/compositor/nodes/COM_DisplaceNode.h index 3451f05dd1f..ecbe07b06b9 100644 --- a/source/blender/compositor/nodes/COM_DisplaceNode.h +++ b/source/blender/compositor/nodes/COM_DisplaceNode.h @@ -31,6 +31,6 @@ class DisplaceNode : public Node { public: DisplaceNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.h b/source/blender/compositor/nodes/COM_DistanceMatteNode.h index 740eb767a71..42582ef10a0 100644 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.h @@ -25,9 +25,9 @@ #include "COM_Node.h" /** - * @brief DistanceMatteNode - * @ingroup Node - */ + * @brief DistanceMatteNode + * @ingroup Node + */ class DistanceMatteNode : public Node { public: diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h index 2c52e988946..ebcddc06b05 100644 --- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h +++ b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief DoubleEdgeMaskNode - * @ingroup Node - */ -class DoubleEdgeMaskNode: public Node { + * @brief DoubleEdgeMaskNode + * @ingroup Node + */ +class DoubleEdgeMaskNode : public Node { public: DoubleEdgeMaskNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_EllipseMaskNode.h b/source/blender/compositor/nodes/COM_EllipseMaskNode.h index be6956e30b5..3e534451b13 100644 --- a/source/blender/compositor/nodes/COM_EllipseMaskNode.h +++ b/source/blender/compositor/nodes/COM_EllipseMaskNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief EllipseMaskNode - * @ingroup Node - */ -class EllipseMaskNode: public Node { + * @brief EllipseMaskNode + * @ingroup Node + */ +class EllipseMaskNode : public Node { public: EllipseMaskNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_FilterNode.h b/source/blender/compositor/nodes/COM_FilterNode.h index 080682dcefe..17f590b9cfc 100644 --- a/source/blender/compositor/nodes/COM_FilterNode.h +++ b/source/blender/compositor/nodes/COM_FilterNode.h @@ -26,14 +26,14 @@ #include "COM_Node.h" /** - * @brief FilterNode - * @ingroup Node - */ + * @brief FilterNode + * @ingroup Node + */ class FilterNode : public Node { public: FilterNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif // COM_FILTERNODE_H diff --git a/source/blender/compositor/nodes/COM_FlipNode.h b/source/blender/compositor/nodes/COM_FlipNode.h index 53bcc504f80..1e372a80b57 100644 --- a/source/blender/compositor/nodes/COM_FlipNode.h +++ b/source/blender/compositor/nodes/COM_FlipNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief FlipNode - * @ingroup Node - */ -class FlipNode: public Node { + * @brief FlipNode + * @ingroup Node + */ +class FlipNode : public Node { public: FlipNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_GammaNode.h b/source/blender/compositor/nodes/COM_GammaNode.h index 121d99cbd57..d4e1f0abd5a 100644 --- a/source/blender/compositor/nodes/COM_GammaNode.h +++ b/source/blender/compositor/nodes/COM_GammaNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief GammaNode - * @ingroup Node - */ -class GammaNode: public Node { + * @brief GammaNode + * @ingroup Node + */ +class GammaNode : public Node { public: GammaNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_GlareNode.h b/source/blender/compositor/nodes/COM_GlareNode.h index 97a75445db7..beb01db733a 100644 --- a/source/blender/compositor/nodes/COM_GlareNode.h +++ b/source/blender/compositor/nodes/COM_GlareNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief GlareNode - * @ingroup Node - */ -class GlareNode: public Node { + * @brief GlareNode + * @ingroup Node + */ +class GlareNode : public Node { public: GlareNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_GroupNode.h b/source/blender/compositor/nodes/COM_GroupNode.h index e35c9cbce33..ba270eaf16c 100644 --- a/source/blender/compositor/nodes/COM_GroupNode.h +++ b/source/blender/compositor/nodes/COM_GroupNode.h @@ -27,30 +27,30 @@ #include "COM_ExecutionSystem.h" /** - * @brief Represents a group node - * @ingroup Node - */ -class GroupNode: public Node { + * @brief Represents a group node + * @ingroup Node + */ +class GroupNode : public Node { public: GroupNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); /** - * @brief check if this node a group node. - * @returns true - */ + * @brief check if this node a group node. + * @returns true + */ bool isGroupNode() const { return true; } /** - * @brief ungroup this group node. - * during ungroup the subtree (internal nodes and links) of the group node - * are added to the ExecutionSystem. - * - * Between the main tree and the subtree proxy nodes will be added - * to translate between InputSocket and OutputSocket - * - * @param system the ExecutionSystem where to add the subtree - */ + * @brief ungroup this group node. + * during ungroup the subtree (internal nodes and links) of the group node + * are added to the ExecutionSystem. + * + * Between the main tree and the subtree proxy nodes will be added + * to translate between InputSocket and OutputSocket + * + * @param system the ExecutionSystem where to add the subtree + */ void ungroup(ExecutionSystem &system); }; diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h index d69990f712c..ed5f2b51ce3 100644 --- a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h +++ b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h @@ -26,12 +26,12 @@ #include "COM_Node.h" /** - * @brief HueSaturationValueCorrectNode - * @ingroup Node - */ + * @brief HueSaturationValueCorrectNode + * @ingroup Node + */ class HueSaturationValueCorrectNode : public Node { public: HueSaturationValueCorrectNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueNode.h index 4fa1a4f547c..92c18019196 100644 --- a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h +++ b/source/blender/compositor/nodes/COM_HueSaturationValueNode.h @@ -26,12 +26,12 @@ #include "COM_Node.h" /** - * @brief HueSaturationValueNode - * @ingroup Node - */ + * @brief HueSaturationValueNode + * @ingroup Node + */ class HueSaturationValueNode : public Node { public: HueSaturationValueNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.h b/source/blender/compositor/nodes/COM_IDMaskNode.h index 2ccbbc08f9a..9fd52be2120 100644 --- a/source/blender/compositor/nodes/COM_IDMaskNode.h +++ b/source/blender/compositor/nodes/COM_IDMaskNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief IDMaskNode - * @ingroup Node - */ -class IDMaskNode: public Node { + * @brief IDMaskNode + * @ingroup Node + */ +class IDMaskNode : public Node { public: IDMaskNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_ImageNode.h b/source/blender/compositor/nodes/COM_ImageNode.h index 70c3ab7f4b0..384dd6c09ff 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.h +++ b/source/blender/compositor/nodes/COM_ImageNode.h @@ -30,15 +30,15 @@ extern "C" { } /** - * @brief ImageNode - * @ingroup Node - */ + * @brief ImageNode + * @ingroup Node + */ class ImageNode : public Node { private: NodeOperation *doMultilayerCheck(ExecutionSystem *system, RenderLayer *rl, Image *image, ImageUser *user, int framenumber, int outputsocketIndex, int pass, DataType datatype); public: ImageNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; diff --git a/source/blender/compositor/nodes/COM_InvertNode.h b/source/blender/compositor/nodes/COM_InvertNode.h index 570e86445e6..d061f1c12bd 100644 --- a/source/blender/compositor/nodes/COM_InvertNode.h +++ b/source/blender/compositor/nodes/COM_InvertNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief InvertNode - * @ingroup Node - */ -class InvertNode: public Node { + * @brief InvertNode + * @ingroup Node + */ +class InvertNode : public Node { public: InvertNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.h b/source/blender/compositor/nodes/COM_LensDistortionNode.h index 64de740fde8..52529823441 100644 --- a/source/blender/compositor/nodes/COM_LensDistortionNode.h +++ b/source/blender/compositor/nodes/COM_LensDistortionNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief LensDistortionNode - * @ingroup Node - */ -class LensDistortionNode: public Node { + * @brief LensDistortionNode + * @ingroup Node + */ +class LensDistortionNode : public Node { public: LensDistortionNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h index e2dd8b47833..c699a0d1168 100644 --- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h +++ b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h @@ -25,9 +25,9 @@ #include "COM_Node.h" /** - * @brief LuminanceMatteNode - * @ingroup Node - */ + * @brief LuminanceMatteNode + * @ingroup Node + */ class LuminanceMatteNode : public Node { public: diff --git a/source/blender/compositor/nodes/COM_MapUVNode.h b/source/blender/compositor/nodes/COM_MapUVNode.h index 3092e84990f..a1df790f192 100644 --- a/source/blender/compositor/nodes/COM_MapUVNode.h +++ b/source/blender/compositor/nodes/COM_MapUVNode.h @@ -31,6 +31,6 @@ class MapUVNode : public Node { public: MapUVNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_MapValueNode.h b/source/blender/compositor/nodes/COM_MapValueNode.h index 47a6ea6adce..c7a842dff95 100644 --- a/source/blender/compositor/nodes/COM_MapValueNode.h +++ b/source/blender/compositor/nodes/COM_MapValueNode.h @@ -26,12 +26,12 @@ #include "COM_Node.h" #include "DNA_node_types.h" /** - * @brief MapValueNode - * @ingroup Node - */ + * @brief MapValueNode + * @ingroup Node + */ class MapValueNode : public Node { public: MapValueNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_MaskNode.h b/source/blender/compositor/nodes/COM_MaskNode.h index 9d2ea1889d9..8a9bc50eac7 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.h +++ b/source/blender/compositor/nodes/COM_MaskNode.h @@ -25,9 +25,9 @@ #include "DNA_node_types.h" /** - * @brief MaskNode - * @ingroup Node - */ + * @brief MaskNode + * @ingroup Node + */ class MaskNode : public Node { diff --git a/source/blender/compositor/nodes/COM_MathNode.h b/source/blender/compositor/nodes/COM_MathNode.h index 1e2cccda396..16d65843b0d 100644 --- a/source/blender/compositor/nodes/COM_MathNode.h +++ b/source/blender/compositor/nodes/COM_MathNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief MathNode - * @ingroup Node - */ -class MathNode: public Node { + * @brief MathNode + * @ingroup Node + */ +class MathNode : public Node { public: - MathNode(bNode *editorNode) :Node(editorNode) {} - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + MathNode(bNode *editorNode) : Node(editorNode) {} + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_MixNode.h b/source/blender/compositor/nodes/COM_MixNode.h index 4b57bdbc02a..99e8b4d48f0 100644 --- a/source/blender/compositor/nodes/COM_MixNode.h +++ b/source/blender/compositor/nodes/COM_MixNode.h @@ -26,12 +26,12 @@ #include "COM_Node.h" #include "DNA_node_types.h" /** - * @brief MixNode - * @ingroup Node - */ + * @brief MixNode + * @ingroup Node + */ class MixNode : public Node { public: MixNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.h b/source/blender/compositor/nodes/COM_MovieClipNode.h index 8ad2fa8cbb0..d70881a6725 100644 --- a/source/blender/compositor/nodes/COM_MovieClipNode.h +++ b/source/blender/compositor/nodes/COM_MovieClipNode.h @@ -24,14 +24,14 @@ #include "DNA_node_types.h" /** - * @brief MovieClipNode - * @ingroup Node - */ + * @brief MovieClipNode + * @ingroup Node + */ class MovieClipNode : public Node { public: MovieClipNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; diff --git a/source/blender/compositor/nodes/COM_MovieDistortionNode.h b/source/blender/compositor/nodes/COM_MovieDistortionNode.h index 5ee328c9df3..b97600bb64e 100644 --- a/source/blender/compositor/nodes/COM_MovieDistortionNode.h +++ b/source/blender/compositor/nodes/COM_MovieDistortionNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief MovieDistortionNode - * @ingroup Node - */ -class MovieDistortionNode: public Node { + * @brief MovieDistortionNode + * @ingroup Node + */ +class MovieDistortionNode : public Node { public: MovieDistortionNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_MuteNode.h b/source/blender/compositor/nodes/COM_MuteNode.h index 2dfc786ef2b..aab37e5f888 100644 --- a/source/blender/compositor/nodes/COM_MuteNode.h +++ b/source/blender/compositor/nodes/COM_MuteNode.h @@ -26,15 +26,15 @@ #include "COM_Node.h" /** - * @brief MuteNode - * @ingroup Node - */ -class MuteNode: public Node { + * @brief MuteNode + * @ingroup Node + */ +class MuteNode : public Node { public: MuteNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); private: - void reconnect(ExecutionSystem *graph, OutputSocket * output); + void reconnect(ExecutionSystem *graph, OutputSocket *output); }; #endif diff --git a/source/blender/compositor/nodes/COM_NormalNode.h b/source/blender/compositor/nodes/COM_NormalNode.h index 1e7c7c584c3..bf684298e65 100644 --- a/source/blender/compositor/nodes/COM_NormalNode.h +++ b/source/blender/compositor/nodes/COM_NormalNode.h @@ -26,14 +26,14 @@ #include "COM_Node.h" /** - * @brief NormalNode - * @ingroup Node - */ + * @brief NormalNode + * @ingroup Node + */ class NormalNode : public Node { public: NormalNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif // COM_NormalNODE_H diff --git a/source/blender/compositor/nodes/COM_NormalizeNode.h b/source/blender/compositor/nodes/COM_NormalizeNode.h index ce7a6e1f7ab..ea1497efdc6 100644 --- a/source/blender/compositor/nodes/COM_NormalizeNode.h +++ b/source/blender/compositor/nodes/COM_NormalizeNode.h @@ -25,13 +25,13 @@ #include "COM_Node.h" /** - * @brief NormalizeNode - * @ingroup Node - */ -class NormalizeNode: public Node { + * @brief NormalizeNode + * @ingroup Node + */ +class NormalizeNode : public Node { public: NormalizeNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.h b/source/blender/compositor/nodes/COM_OutputFileNode.h index 10cbba7d50f..79c9b577643 100644 --- a/source/blender/compositor/nodes/COM_OutputFileNode.h +++ b/source/blender/compositor/nodes/COM_OutputFileNode.h @@ -28,13 +28,13 @@ #include "DNA_node_types.h" /** - * @brief OutputFileNode - * @ingroup Node - */ + * @brief OutputFileNode + * @ingroup Node + */ class OutputFileNode : public Node { public: OutputFileNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.h b/source/blender/compositor/nodes/COM_RenderLayersNode.h index f796a7147d9..32672c8ba2d 100644 --- a/source/blender/compositor/nodes/COM_RenderLayersNode.h +++ b/source/blender/compositor/nodes/COM_RenderLayersNode.h @@ -25,13 +25,13 @@ #include "COM_RenderLayersBaseProg.h" /** - * @brief RenderLayersNode - * @ingroup Node - */ + * @brief RenderLayersNode + * @ingroup Node + */ class RenderLayersNode : public Node { public: RenderLayersNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); private: - void testSocketConnection(ExecutionSystem *graph, int outputSocketNumber, RenderLayersBaseProg * operation); + void testSocketConnection(ExecutionSystem *graph, int outputSocketNumber, RenderLayersBaseProg *operation); }; diff --git a/source/blender/compositor/nodes/COM_RotateNode.h b/source/blender/compositor/nodes/COM_RotateNode.h index 9b471742aab..6e3801e5353 100644 --- a/source/blender/compositor/nodes/COM_RotateNode.h +++ b/source/blender/compositor/nodes/COM_RotateNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief RotateNode - * @ingroup Node - */ -class RotateNode: public Node { + * @brief RotateNode + * @ingroup Node + */ +class RotateNode : public Node { public: RotateNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_ScaleNode.h b/source/blender/compositor/nodes/COM_ScaleNode.h index 310ae96a65e..17c7b672a59 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.h +++ b/source/blender/compositor/nodes/COM_ScaleNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief ScaleNode - * @ingroup Node - */ -class ScaleNode: public Node { + * @brief ScaleNode + * @ingroup Node + */ +class ScaleNode : public Node { public: ScaleNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_SeparateHSVANode.h b/source/blender/compositor/nodes/COM_SeparateHSVANode.h index 9fbd0212509..4a7e86849dc 100644 --- a/source/blender/compositor/nodes/COM_SeparateHSVANode.h +++ b/source/blender/compositor/nodes/COM_SeparateHSVANode.h @@ -28,12 +28,12 @@ #include "COM_SeparateRGBANode.h" /** - * @brief SeparateHSVANode - * @ingroup Node - */ + * @brief SeparateHSVANode + * @ingroup Node + */ class SeparateHSVANode : public SeparateRGBANode { public: SeparateHSVANode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_SeparateRGBANode.h b/source/blender/compositor/nodes/COM_SeparateRGBANode.h index 5fb00600790..c1be02753da 100644 --- a/source/blender/compositor/nodes/COM_SeparateRGBANode.h +++ b/source/blender/compositor/nodes/COM_SeparateRGBANode.h @@ -26,12 +26,12 @@ #include "COM_Node.h" #include "DNA_node_types.h" /** - * @brief SeparateRGBANode - * @ingroup Node - */ + * @brief SeparateRGBANode + * @ingroup Node + */ class SeparateRGBANode : public Node { public: SeparateRGBANode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_SeparateYCCANode.h b/source/blender/compositor/nodes/COM_SeparateYCCANode.h index 441eba9bc93..4b216841e2a 100644 --- a/source/blender/compositor/nodes/COM_SeparateYCCANode.h +++ b/source/blender/compositor/nodes/COM_SeparateYCCANode.h @@ -27,9 +27,9 @@ #include "COM_SeparateRGBANode.h" /** - * @brief SeparateYCCANode - * @ingroup Node - */ + * @brief SeparateYCCANode + * @ingroup Node + */ class SeparateYCCANode : public SeparateRGBANode { public: SeparateYCCANode(bNode *editorNode); diff --git a/source/blender/compositor/nodes/COM_SeparateYUVANode.h b/source/blender/compositor/nodes/COM_SeparateYUVANode.h index 136ce1b4f20..e1763e37dff 100644 --- a/source/blender/compositor/nodes/COM_SeparateYUVANode.h +++ b/source/blender/compositor/nodes/COM_SeparateYUVANode.h @@ -27,9 +27,9 @@ #include "COM_SeparateRGBANode.h" /** - * @brief SeparateYUVANode - * @ingroup Node - */ + * @brief SeparateYUVANode + * @ingroup Node + */ class SeparateYUVANode : public SeparateRGBANode { public: SeparateYUVANode(bNode *editorNode); diff --git a/source/blender/compositor/nodes/COM_SetAlphaNode.h b/source/blender/compositor/nodes/COM_SetAlphaNode.h index c6b603049c5..0707cf5dac1 100644 --- a/source/blender/compositor/nodes/COM_SetAlphaNode.h +++ b/source/blender/compositor/nodes/COM_SetAlphaNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief SetAlphaNode - * @ingroup Node - */ -class SetAlphaNode: public Node { + * @brief SetAlphaNode + * @ingroup Node + */ +class SetAlphaNode : public Node { public: - SetAlphaNode(bNode *editorNode) :Node(editorNode) {} - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + SetAlphaNode(bNode *editorNode) : Node(editorNode) {} + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.h b/source/blender/compositor/nodes/COM_SocketProxyNode.h index b73ca24a45e..ea50be418e2 100644 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.h +++ b/source/blender/compositor/nodes/COM_SocketProxyNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief SocketProxyNode - * @ingroup Node - */ -class SocketProxyNode: public Node { + * @brief SocketProxyNode + * @ingroup Node + */ +class SocketProxyNode : public Node { public: SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); virtual bool isProxyNode() const { return true; } }; diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.h b/source/blender/compositor/nodes/COM_SplitViewerNode.h index e2d7a8c0dc9..6c532d4e813 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.h +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.h @@ -26,12 +26,12 @@ #include "COM_Node.h" #include "DNA_node_types.h" /** - * @brief SplitViewerNode - * @ingroup Node - */ + * @brief SplitViewerNode + * @ingroup Node + */ class SplitViewerNode : public Node { public: SplitViewerNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_Stabilize2dNode.h b/source/blender/compositor/nodes/COM_Stabilize2dNode.h index 63bf50b4d69..589e090b48c 100644 --- a/source/blender/compositor/nodes/COM_Stabilize2dNode.h +++ b/source/blender/compositor/nodes/COM_Stabilize2dNode.h @@ -24,11 +24,11 @@ #include "DNA_node_types.h" /** - * @brief Stabilize2dNode - * @ingroup Node - */ + * @brief Stabilize2dNode + * @ingroup Node + */ class Stabilize2dNode : public Node { public: Stabilize2dNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; diff --git a/source/blender/compositor/nodes/COM_SwitchNode.h b/source/blender/compositor/nodes/COM_SwitchNode.h index da93af42489..be3d54c3000 100644 --- a/source/blender/compositor/nodes/COM_SwitchNode.h +++ b/source/blender/compositor/nodes/COM_SwitchNode.h @@ -27,12 +27,12 @@ #include "COM_NodeOperation.h" #include "DNA_node_types.h" /** - * @brief SwitchNode - * @ingroup Node - */ + * @brief SwitchNode + * @ingroup Node + */ class SwitchNode : public Node { public: SwitchNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_TextureNode.h b/source/blender/compositor/nodes/COM_TextureNode.h index 15c39db9077..e0d931c65da 100644 --- a/source/blender/compositor/nodes/COM_TextureNode.h +++ b/source/blender/compositor/nodes/COM_TextureNode.h @@ -24,11 +24,11 @@ #include "DNA_node_types.h" /** - * @brief TextureNode - * @ingroup Node - */ + * @brief TextureNode + * @ingroup Node + */ class TextureNode : public Node { public: TextureNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; diff --git a/source/blender/compositor/nodes/COM_TimeNode.h b/source/blender/compositor/nodes/COM_TimeNode.h index 26751f6f104..df3cf024714 100644 --- a/source/blender/compositor/nodes/COM_TimeNode.h +++ b/source/blender/compositor/nodes/COM_TimeNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief TimeNode - * @ingroup Node - */ -class TimeNode: public Node { + * @brief TimeNode + * @ingroup Node + */ +class TimeNode : public Node { public: TimeNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_TonemapNode.h b/source/blender/compositor/nodes/COM_TonemapNode.h index d6dd8474afa..ad0d218826a 100644 --- a/source/blender/compositor/nodes/COM_TonemapNode.h +++ b/source/blender/compositor/nodes/COM_TonemapNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief TonemapNode - * @ingroup Node - */ -class TonemapNode: public Node { + * @brief TonemapNode + * @ingroup Node + */ +class TonemapNode : public Node { public: TonemapNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_TransformNode.h b/source/blender/compositor/nodes/COM_TransformNode.h index 237da44afd9..da40b655f29 100644 --- a/source/blender/compositor/nodes/COM_TransformNode.h +++ b/source/blender/compositor/nodes/COM_TransformNode.h @@ -24,11 +24,11 @@ #include "DNA_node_types.h" /** - * @brief TransformNode - * @ingroup Node - */ + * @brief TransformNode + * @ingroup Node + */ class TransformNode : public Node { public: TransformNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; diff --git a/source/blender/compositor/nodes/COM_TranslateNode.h b/source/blender/compositor/nodes/COM_TranslateNode.h index 295024d6beb..8c350e9cfb3 100644 --- a/source/blender/compositor/nodes/COM_TranslateNode.h +++ b/source/blender/compositor/nodes/COM_TranslateNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief TranslateNode - * @ingroup Node - */ -class TranslateNode: public Node { + * @brief TranslateNode + * @ingroup Node + */ +class TranslateNode : public Node { public: TranslateNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_ValueNode.h b/source/blender/compositor/nodes/COM_ValueNode.h index 4faf193fc8e..4f478ae93af 100644 --- a/source/blender/compositor/nodes/COM_ValueNode.h +++ b/source/blender/compositor/nodes/COM_ValueNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief ValueNode - * @ingroup Node - */ -class ValueNode: public Node { + * @brief ValueNode + * @ingroup Node + */ +class ValueNode : public Node { public: ValueNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.h b/source/blender/compositor/nodes/COM_VectorBlurNode.h index 1df945731ce..6b5d277a54b 100644 --- a/source/blender/compositor/nodes/COM_VectorBlurNode.h +++ b/source/blender/compositor/nodes/COM_VectorBlurNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief VectorBlurNode - * @ingroup Node - */ -class VectorBlurNode: public Node { + * @brief VectorBlurNode + * @ingroup Node + */ +class VectorBlurNode : public Node { public: VectorBlurNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_VectorCurveNode.h b/source/blender/compositor/nodes/COM_VectorCurveNode.h index 9fbcfd50156..3201090df14 100644 --- a/source/blender/compositor/nodes/COM_VectorCurveNode.h +++ b/source/blender/compositor/nodes/COM_VectorCurveNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief VectorCurveNode - * @ingroup Node - */ -class VectorCurveNode: public Node { + * @brief VectorCurveNode + * @ingroup Node + */ +class VectorCurveNode : public Node { public: VectorCurveNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.h b/source/blender/compositor/nodes/COM_ViewLevelsNode.h index 11be6216cba..2ac84fad22f 100644 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.h +++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief ViewLevelsNode - * @ingroup Node - */ -class ViewLevelsNode: public Node { + * @brief ViewLevelsNode + * @ingroup Node + */ +class ViewLevelsNode : public Node { public: ViewLevelsNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_ViewerNode.h b/source/blender/compositor/nodes/COM_ViewerNode.h index 59371f04e87..e1f1226f1f1 100644 --- a/source/blender/compositor/nodes/COM_ViewerNode.h +++ b/source/blender/compositor/nodes/COM_ViewerNode.h @@ -26,12 +26,12 @@ #include "COM_Node.h" #include "DNA_node_types.h" /** - * @brief ViewerNode - * @ingroup Node - */ + * @brief ViewerNode + * @ingroup Node + */ class ViewerNode : public Node { public: ViewerNode(bNode *editorNode); - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.h b/source/blender/compositor/nodes/COM_ZCombineNode.h index e9ce2f27469..a2ceedfc2cd 100644 --- a/source/blender/compositor/nodes/COM_ZCombineNode.h +++ b/source/blender/compositor/nodes/COM_ZCombineNode.h @@ -26,13 +26,13 @@ #include "COM_Node.h" /** - * @brief ZCombineNode - * @ingroup Node - */ -class ZCombineNode: public Node { + * @brief ZCombineNode + * @ingroup Node + */ +class ZCombineNode : public Node { public: - ZCombineNode(bNode *editorNode) :Node(editorNode) {} - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); + ZCombineNode(bNode *editorNode) : Node(editorNode) {} + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; #endif diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h index d3077a05706..e5b1f56f06c 100644 --- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h @@ -26,19 +26,19 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class AlphaOverKeyOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ AlphaOverKeyOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h index 92936a20b79..2807b3b489a 100644 --- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h @@ -26,23 +26,23 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class AlphaOverMixedOperation : public MixBaseOperation { private: float x; public: /** - * Default constructor - */ + * Default constructor + */ AlphaOverMixedOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); - void setX(float x) {this->x = x;} + void setX(float x) { this->x = x; } }; #endif diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h index 2fe4422d03e..bba3b714f6b 100644 --- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class AlphaOverPremultiplyOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ AlphaOverPremultiplyOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.h b/source/blender/compositor/operations/COM_AntiAliasOperation.h index fe160763828..906da598da1 100644 --- a/source/blender/compositor/operations/COM_AntiAliasOperation.h +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.h @@ -26,35 +26,35 @@ #include "DNA_node_types.h" /** - * @brief AntiAlias operations - * it only supports anti aliasing on BW buffers. - * @ingroup operation - */ + * @brief AntiAlias operations + * it only supports anti aliasing on BW buffers. + * @ingroup operation + */ class AntiAliasOperation : public NodeOperation { protected: /** - * @brief Cached reference to the reader - */ - SocketReader * valueReader; + * @brief Cached reference to the reader + */ + SocketReader *valueReader; char *buffer; public: AntiAliasOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); }; diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.h b/source/blender/compositor/operations/COM_BilateralBlurOperation.h index 8ec1ba8df99..08b379dc4ea 100644 --- a/source/blender/compositor/operations/COM_BilateralBlurOperation.h +++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.h @@ -36,22 +36,22 @@ public: BilateralBlurOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void setData(NodeBilateralBlurData *data) {this->data = data;} + void setData(NodeBilateralBlurData *data) { this->data = data; } }; #endif diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h index 24002588413..84fc243a5af 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.h +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.h @@ -30,11 +30,11 @@ private: protected: /** - * Cached reference to the inputProgram - */ + * Cached reference to the inputProgram + */ SocketReader *inputProgram; SocketReader *inputSize; - NodeBlurData * data; + NodeBlurData *data; BlurBaseOperation(); float *make_gausstab(int rad); float size; @@ -43,19 +43,19 @@ protected: void updateSize(MemoryBuffer **memoryBuffers); public: /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setData(NodeBlurData *data) {this->data = data;} - - void deleteDataWhenFinished() {this->deleteData = true;} + void setData(NodeBlurData *data) { this->data = data; } - void setSize(float size) {this->size = size; sizeavailable = true;} + void deleteDataWhenFinished() { this->deleteData = true; } + + void setSize(float size) { this->size = size; sizeavailable = true; } }; #endif diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.h b/source/blender/compositor/operations/COM_BokehBlurOperation.h index 3cdd995b1df..3ec61c5ce01 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.h @@ -39,23 +39,23 @@ public: void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void setSize(float size) {this->size = size;} + void setSize(float size) { this->size = size; } void executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, list *clKernelsToCleanUp); }; diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.h b/source/blender/compositor/operations/COM_BokehImageOperation.h index 516cc1da4f0..8edd32a4f77 100644 --- a/source/blender/compositor/operations/COM_BokehImageOperation.h +++ b/source/blender/compositor/operations/COM_BokehImageOperation.h @@ -45,23 +45,23 @@ public: BokehImageOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); - void setData(NodeBokehImage *data) {this->data = data;} - void deleteDataOnFinish() {this->deleteData = true;} + void setData(NodeBokehImage *data) { this->data = data; } + void deleteDataOnFinish() { this->deleteData = true; } }; #endif diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.h b/source/blender/compositor/operations/COM_BoxMaskOperation.h index c3af95578d4..65327abc9a6 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.h +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.h @@ -28,10 +28,10 @@ class BoxMaskOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputMask; - SocketReader * inputValue; + * Cached reference to the inputProgram + */ + SocketReader *inputMask; + SocketReader *inputValue; float sine; float cosine; @@ -43,23 +43,23 @@ public: BoxMaskOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setData(NodeBoxMask *data) {this->data = data;} - - void setMaskType(int maskType) {this->maskType = maskType;} + void setData(NodeBoxMask *data) { this->data = data; } + + void setMaskType(int maskType) { this->maskType = maskType; } }; #endif diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.h b/source/blender/compositor/operations/COM_BrightnessOperation.h index 0c718a8b131..74c648fd8fb 100644 --- a/source/blender/compositor/operations/COM_BrightnessOperation.h +++ b/source/blender/compositor/operations/COM_BrightnessOperation.h @@ -28,8 +28,8 @@ class BrightnessOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ + * Cached reference to the inputProgram + */ SocketReader *inputProgram; SocketReader *inputBrightnessProgram; SocketReader *inputContrastProgram; @@ -38,18 +38,18 @@ public: BrightnessOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.h b/source/blender/compositor/operations/COM_CalculateMeanOperation.h index b21743aa8bc..7a28eb3774a 100644 --- a/source/blender/compositor/operations/COM_CalculateMeanOperation.h +++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.h @@ -26,15 +26,15 @@ #include "DNA_node_types.h" /** - * @brief base class of CalculateMean, implementing the simple CalculateMean - * @ingroup operation - */ + * @brief base class of CalculateMean, implementing the simple CalculateMean + * @ingroup operation + */ class CalculateMeanOperation : public NodeOperation { protected: /** - * @brief Cached reference to the reader - */ - SocketReader * imageReader; + * @brief Cached reference to the reader + */ + SocketReader *imageReader; bool iscalculated; float result; @@ -44,24 +44,24 @@ public: CalculateMeanOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void setSetting(int setting) {this->setting = setting;} + void setSetting(int setting) { this->setting = setting; } protected: void calculateMean(MemoryBuffer *tile); diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h index 05c94401c86..d3163d4cc32 100644 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h @@ -26,9 +26,9 @@ #include "DNA_node_types.h" #include "COM_CalculateMeanOperation.h" /** - * @brief base class of CalculateStandardDeviation, implementing the simple CalculateStandardDeviation - * @ingroup operation - */ + * @brief base class of CalculateStandardDeviation, implementing the simple CalculateStandardDeviation + * @ingroup operation + */ class CalculateStandardDeviationOperation : public CalculateMeanOperation { protected: float standardDeviation; @@ -37,9 +37,9 @@ public: CalculateStandardDeviationOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.h b/source/blender/compositor/operations/COM_ChangeHSVOperation.h index a89487f9d7b..a2a6c034a82 100644 --- a/source/blender/compositor/operations/COM_ChangeHSVOperation.h +++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.h @@ -26,12 +26,12 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ChangeHSVOperation : public NodeOperation { private: - SocketReader * inputOperation; + SocketReader *inputOperation; float hue; float saturation; @@ -39,21 +39,21 @@ private: public: /** - * Default constructor - */ + * Default constructor + */ ChangeHSVOperation(); void initExecution(); void deinitExecution(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); - - void setHue(float hue) {this->hue = hue;} - void setSaturation(float saturation) {this->saturation = saturation;} - void setValue(float value) {this->value = value;} + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); + + void setHue(float hue) { this->hue = hue; } + void setSaturation(float saturation) { this->saturation = saturation; } + void setValue(float value) { this->value = value; } }; #endif diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.h b/source/blender/compositor/operations/COM_ChannelMatteOperation.h index a4b5f454f92..17db0f9ffe2 100644 --- a/source/blender/compositor/operations/COM_ChannelMatteOperation.h +++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.h @@ -25,9 +25,9 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ChannelMatteOperation : public NodeOperation { private: SocketReader *inputImageProgram; @@ -42,24 +42,24 @@ private: float limit_range; /** ids to use for the operations (max and simple) - * alpha = in[ids[0]] - max(in[ids[1]], in[ids[2]]) - * the simple operation is using: - * alpha = in[ids[0]] - in[ids[1]] - * but to use the same formula and operation for both we do: - * ids[2] = ids[1] - * alpha = in[ids[0]] - max(in[ids[1]], in[ids[2]]) - */ + * alpha = in[ids[0]] - max(in[ids[1]], in[ids[2]]) + * the simple operation is using: + * alpha = in[ids[0]] - in[ids[1]] + * but to use the same formula and operation for both we do: + * ids[2] = ids[1] + * alpha = in[ids[0]] - max(in[ids[1]], in[ids[2]]) + */ int ids[3]; public: /** - * Default constructor - */ + * Default constructor + */ ChannelMatteOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.h b/source/blender/compositor/operations/COM_ChromaMatteOperation.h index 9c5a5ff997b..a09203f29b3 100644 --- a/source/blender/compositor/operations/COM_ChromaMatteOperation.h +++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.h @@ -25,9 +25,9 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ChromaMatteOperation : public NodeOperation { private: NodeChroma *settings; @@ -35,18 +35,18 @@ private: SocketReader *inputKeyProgram; public: /** - * Default constructor - */ + * Default constructor + */ ChromaMatteOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); - void setSettings(NodeChroma *nodeChroma) {this->settings = nodeChroma;} + void setSettings(NodeChroma *nodeChroma) { this->settings = nodeChroma; } }; #endif diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h index fb973e75c15..9e7db59d99d 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h +++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h @@ -24,18 +24,17 @@ #define _COM_ColorBalanceASCCDLOperation_h #include "COM_NodeOperation.h" - /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ColorBalanceASCCDLOperation : public NodeOperation { protected: /** - * Prefetched reference to the inputProgram - */ - SocketReader * inputValueOperation; - SocketReader * inputColorOperation; + * Prefetched reference to the inputProgram + */ + SocketReader *inputValueOperation; + SocketReader *inputColorOperation; float gain[3]; float lift[3]; @@ -43,39 +42,27 @@ protected: public: /** - * Default constructor - */ + * Default constructor + */ ColorBalanceASCCDLOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setGain(float gain[3]) { - this->gain[0] = gain[0]; - this->gain[1] = gain[1]; - this->gain[2] = gain[2]; - } - void setLift(float lift[3]) { - this->lift[0] = lift[0]; - this->lift[1] = lift[1]; - this->lift[2] = lift[2]; - } - void setGamma(float gamma[3]) { - this->gamma[0] = gamma[0]; - this->gamma[1] = gamma[1]; - this->gamma[2] = gamma[2]; - } + void setGain(float gain[3]) { copy_v3_v3(this->gain, gain); } + void setLift(float lift[3]) { copy_v3_v3(this->lift, lift); } + void setGamma(float gamma[3]) { copy_v3_v3(this->gamma, gamma); } }; #endif diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h index e0df76cf2c5..54cfb49327f 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h @@ -26,16 +26,16 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ColorBalanceLGGOperation : public NodeOperation { protected: /** - * Prefetched reference to the inputProgram - */ - SocketReader * inputValueOperation; - SocketReader * inputColorOperation; + * Prefetched reference to the inputProgram + */ + SocketReader *inputValueOperation; + SocketReader *inputColorOperation; float gain[3]; float lift[3]; @@ -43,23 +43,23 @@ protected: public: /** - * Default constructor - */ + * Default constructor + */ ColorBalanceLGGOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); void setGain(float gain[3]) { diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h index 89107150ebd..c0c33f7f2fa 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h @@ -28,8 +28,8 @@ class ColorCorrectionOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ + * Cached reference to the inputProgram + */ SocketReader *inputImage; SocketReader *inputMask; NodeColorCorrection *data; @@ -42,23 +42,23 @@ public: ColorCorrectionOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setData(NodeColorCorrection * data) {this->data = data;} - void setRedChannelEnabled(bool enabled) {this->redChannelEnabled = enabled;} - void setGreenChannelEnabled(bool enabled) {this->greenChannelEnabled = enabled;} - void setBlueChannelEnabled(bool enabled) {this->blueChannelEnabled = enabled;} + void setData(NodeColorCorrection *data) { this->data = data; } + void setRedChannelEnabled(bool enabled) { this->redChannelEnabled = enabled; } + void setGreenChannelEnabled(bool enabled) { this->greenChannelEnabled = enabled; } + void setBlueChannelEnabled(bool enabled) { this->blueChannelEnabled = enabled; } }; #endif diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.h b/source/blender/compositor/operations/COM_ColorCurveOperation.h index 6ce5befb14a..fcd78be8372 100644 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.h +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.h @@ -29,38 +29,38 @@ class ColorCurveOperation : public CurveBaseOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputFacProgram; - SocketReader * inputImageProgram; - SocketReader * inputBlackProgram; - SocketReader * inputWhiteProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputFacProgram; + SocketReader *inputImageProgram; + SocketReader *inputBlackProgram; + SocketReader *inputWhiteProgram; public: ColorCurveOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; class ConstantLevelColorCurveOperation : public CurveBaseOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputFacProgram; - SocketReader * inputImageProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputFacProgram; + SocketReader *inputImageProgram; float black[3]; float white[3]; @@ -68,22 +68,22 @@ public: ConstantLevelColorCurveOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setBlackLevel(float black[3]) {this->black[0] =black[0];this->black[1] =black[1];this->black[2] =black[2]; } - void setWhiteLevel(float white[3]) {this->white[0] =white[0];this->white[1] =white[1];this->white[2] =white[2]; } + void setBlackLevel(float black[3]) { this->black[0] = black[0]; this->black[1] = black[1]; this->black[2] = black[2]; } + void setWhiteLevel(float white[3]) { this->white[0] = white[0]; this->white[1] = white[1]; this->white[2] = white[2]; } }; #endif diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.h b/source/blender/compositor/operations/COM_ColorMatteOperation.h index 904a51128c8..e5dd9efd820 100644 --- a/source/blender/compositor/operations/COM_ColorMatteOperation.h +++ b/source/blender/compositor/operations/COM_ColorMatteOperation.h @@ -25,9 +25,9 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ColorMatteOperation : public NodeOperation { private: NodeChroma *settings; @@ -35,18 +35,18 @@ private: SocketReader *inputKeyProgram; public: /** - * Default constructor - */ + * Default constructor + */ ColorMatteOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); - void setSettings(NodeChroma *nodeChroma) {this->settings = nodeChroma;} + void setSettings(NodeChroma *nodeChroma) { this->settings = nodeChroma; } }; #endif diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.h b/source/blender/compositor/operations/COM_ColorRampOperation.h index 8b8635cc5cd..eef5321eb19 100644 --- a/source/blender/compositor/operations/COM_ColorRampOperation.h +++ b/source/blender/compositor/operations/COM_ColorRampOperation.h @@ -28,29 +28,31 @@ class ColorRampOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputProgram; ColorBand *colorBand; public: ColorRampOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setColorBand(ColorBand *colorBand) {this->colorBand = colorBand;} + void setColorBand(ColorBand *colorBand) { + this->colorBand = colorBand; + } }; diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.h b/source/blender/compositor/operations/COM_ColorSpillOperation.h index 69f51882496..e890a1e1564 100644 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.h +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.h @@ -25,9 +25,9 @@ #include "COM_NodeOperation.h" /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ColorSpillOperation : public NodeOperation { protected: NodeColorspill *settings; @@ -39,25 +39,25 @@ protected: float rmut, gmut, bmut; public: /** - * Default constructor - */ + * Default constructor + */ ColorSpillOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); - void setSettings(NodeColorspill *nodeColorSpill) {this->settings = nodeColorSpill;} - void setSpillChannel(int channel) {this->spillChannel = channel;} + void setSettings(NodeColorspill *nodeColorSpill) { this->settings = nodeColorSpill; } + void setSpillChannel(int channel) { this->spillChannel = channel; } float calculateMapValue(float fac, float *input); }; -class ColorSpillAverageOperation: public ColorSpillOperation { +class ColorSpillAverageOperation : public ColorSpillOperation { public: float calculateMapValue(float fac, float *input); }; diff --git a/source/blender/compositor/operations/COM_CombineChannelsOperation.h b/source/blender/compositor/operations/COM_CombineChannelsOperation.h index 18dd1fd2ec9..d2977155e14 100644 --- a/source/blender/compositor/operations/COM_CombineChannelsOperation.h +++ b/source/blender/compositor/operations/COM_CombineChannelsOperation.h @@ -25,7 +25,7 @@ #include "COM_NodeOperation.h" -class CombineChannelsOperation: public NodeOperation { +class CombineChannelsOperation : public NodeOperation { private: SocketReader *inputChannel1Operation; SocketReader *inputChannel2Operation; @@ -33,7 +33,7 @@ private: SocketReader *inputChannel4Operation; public: CombineChannelsOperation(); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h index 1868de6d815..b11a06f7749 100644 --- a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h +++ b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h @@ -26,53 +26,53 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertColorProfileOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; /** - * @brief color profile where to convert from - */ + * @brief color profile where to convert from + */ int fromProfile; /** - * @brief color profile where to convert to - */ + * @brief color profile where to convert to + */ int toProfile; /** - * @brief is color predivided - */ + * @brief is color predivided + */ bool predivided; public: /** - * Default constructor - */ + * Default constructor + */ ConvertColorProfileOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setFromColorProfile(int colorProfile) {this->fromProfile = colorProfile;} - void setToColorProfile(int colorProfile) {this->toProfile = colorProfile;} - void setPredivided(bool predivided) {this->predivided = predivided;} + void setFromColorProfile(int colorProfile) { this->fromProfile = colorProfile; } + void setToColorProfile(int colorProfile) { this->toProfile = colorProfile; } + void setPredivided(bool predivided) { this->predivided = predivided; } }; #endif diff --git a/source/blender/compositor/operations/COM_ConvertColorToBWOperation.h b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.h index 616cf0f2d01..814c0c2e808 100644 --- a/source/blender/compositor/operations/COM_ConvertColorToBWOperation.h +++ b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.h @@ -26,34 +26,34 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertColorToBWOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; public: /** - * Default constructor - */ + * Default constructor + */ ConvertColorToBWOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; diff --git a/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.h b/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.h index 11a1bf30a07..1167b565a8e 100644 --- a/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.h +++ b/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.h @@ -26,34 +26,34 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertColorToVectorOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; public: /** - * Default constructor - */ + * Default constructor + */ ConvertColorToVectorOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; #endif diff --git a/source/blender/compositor/operations/COM_ConvertColourToValueProg.h b/source/blender/compositor/operations/COM_ConvertColourToValueProg.h index 7aa07dd46f2..9c43ec47604 100644 --- a/source/blender/compositor/operations/COM_ConvertColourToValueProg.h +++ b/source/blender/compositor/operations/COM_ConvertColourToValueProg.h @@ -26,34 +26,34 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertColourToValueProg : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; public: /** - * Default constructor - */ + * Default constructor + */ ConvertColourToValueProg(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; #endif diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h index c199ea87fe3..c6da6bc94a9 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h @@ -26,15 +26,15 @@ #include "DNA_object_types.h" /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertDepthToRadiusOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; float fStop; float aspect; float maxRadius; @@ -45,28 +45,28 @@ private: Object *cameraObject; public: /** - * Default constructor - */ + * Default constructor + */ ConvertDepthToRadiusOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setfStop(float fStop) {this->fStop = fStop;} - void setMaxRadius(float maxRadius) {this->maxRadius = maxRadius;} - void setCameraObject(Object *camera) {this->cameraObject = camera;} + void setfStop(float fStop) { this->fStop = fStop; } + void setMaxRadius(float maxRadius) { this->maxRadius = maxRadius; } + void setCameraObject(Object *camera) { this->cameraObject = camera; } float determineFocalDistance(); }; #endif diff --git a/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.h b/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.h index 327b4089934..29c82361d12 100644 --- a/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.h +++ b/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.h @@ -26,34 +26,34 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertHSVToRGBOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; public: /** - * Default constructor - */ + * Default constructor + */ ConvertHSVToRGBOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; #endif diff --git a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h index 1d5a1c1c4a6..fe0586f7a88 100644 --- a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h +++ b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h @@ -25,22 +25,22 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertKeyToPremulOperation : public NodeOperation { private: SocketReader *inputColor; public: /** - * Default constructor - */ + * Default constructor + */ ConvertKeyToPremulOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h index 17597fa8f15..093f28df3e5 100644 --- a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h +++ b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h @@ -25,22 +25,22 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertPremulToKeyOperation : public NodeOperation { private: SocketReader *inputColor; public: /** - * Default constructor - */ + * Default constructor + */ ConvertPremulToKeyOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.h b/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.h index 5064bd06993..61270539e70 100644 --- a/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.h +++ b/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.h @@ -26,34 +26,34 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertRGBToHSVOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; public: /** - * Default constructor - */ + * Default constructor + */ ConvertRGBToHSVOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; diff --git a/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.h b/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.h index a952627893b..33075cda509 100644 --- a/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.h +++ b/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.h @@ -25,44 +25,44 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertRGBToYCCOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; /** - * YCbCr mode (Jpeg, ITU601, ITU709) - */ + * YCbCr mode (Jpeg, ITU601, ITU709) + */ int mode; public: /** - * Default constructor - */ + * Default constructor + */ ConvertRGBToYCCOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); /** - * Set the YCC mode - */ + * Set the YCC mode + */ void setMode(int mode); }; #endif diff --git a/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.h b/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.h index 5bc763dde00..4fc525456f8 100644 --- a/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.h +++ b/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.h @@ -25,34 +25,34 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertRGBToYUVOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; public: /** - * Default constructor - */ + * Default constructor + */ ConvertRGBToYUVOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; diff --git a/source/blender/compositor/operations/COM_ConvertValueToColourProg.h b/source/blender/compositor/operations/COM_ConvertValueToColourProg.h index 4956f7196f5..ff1d1aaeae7 100644 --- a/source/blender/compositor/operations/COM_ConvertValueToColourProg.h +++ b/source/blender/compositor/operations/COM_ConvertValueToColourProg.h @@ -28,25 +28,25 @@ class ConvertValueToColourProg : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ + * Cached reference to the inputProgram + */ SocketReader *inputProgram; public: ConvertValueToColourProg(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; diff --git a/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.h b/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.h index 1e6a7d4b3e7..fbb294d6a26 100644 --- a/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.h +++ b/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.h @@ -26,34 +26,34 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertValueToVectorOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; public: /** - * Default constructor - */ + * Default constructor + */ ConvertValueToVectorOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; #endif diff --git a/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.h b/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.h index 45ffd0675bd..c26adc5a6b1 100644 --- a/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.h +++ b/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.h @@ -26,34 +26,34 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertVectorToColorOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; public: /** - * Default constructor - */ + * Default constructor + */ ConvertVectorToColorOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; #endif diff --git a/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.h b/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.h index 59bae18ed26..dd29d1bb9a9 100644 --- a/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.h +++ b/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.h @@ -26,34 +26,34 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertVectorToValueOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; public: /** - * Default constructor - */ + * Default constructor + */ ConvertVectorToValueOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; #endif diff --git a/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.h b/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.h index a13c2826a79..d7ddd910ed7 100644 --- a/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.h +++ b/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.h @@ -25,44 +25,44 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertYCCToRGBOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; /** - * YCbCr mode (Jpeg, ITU601, ITU709) - */ + * YCbCr mode (Jpeg, ITU601, ITU709) + */ int mode; public: /** - * Default constructor - */ + * Default constructor + */ ConvertYCCToRGBOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); /** - * Set the YCC mode - */ + * Set the YCC mode + */ void setMode(int mode); }; #endif diff --git a/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.h b/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.h index 380510d0100..f77954606cf 100644 --- a/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.h +++ b/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.h @@ -25,34 +25,34 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ConvertYUVToRGBOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; public: /** - * Default constructor - */ + * Default constructor + */ ConvertYUVToRGBOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; #endif diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h index a0f9c1b3452..92e45c7104f 100644 --- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h +++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h @@ -25,10 +25,10 @@ #include "COM_ConvolutionFilterOperation.h" -class ConvolutionEdgeFilterOperation: public ConvolutionFilterOperation { +class ConvolutionEdgeFilterOperation : public ConvolutionFilterOperation { public: ConvolutionEdgeFilterOperation(); - void executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data); + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); }; #endif diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h index 3276038726b..f3347eb583a 100644 --- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h +++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h @@ -25,7 +25,7 @@ #include "COM_NodeOperation.h" -class ConvolutionFilterOperation: public NodeOperation { +class ConvolutionFilterOperation : public NodeOperation { private: int filterWidth; int filterHeight; @@ -39,7 +39,7 @@ public: ConvolutionFilterOperation(); void set3x3Filter(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data); + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_CropOperation.h b/source/blender/compositor/operations/COM_CropOperation.h index e8edabf08ed..48e5ab7f75b 100644 --- a/source/blender/compositor/operations/COM_CropOperation.h +++ b/source/blender/compositor/operations/COM_CropOperation.h @@ -25,7 +25,7 @@ #include "COM_NodeOperation.h" -class CropBaseOperation: public NodeOperation { +class CropBaseOperation : public NodeOperation { protected: SocketReader *inputOperation; NodeTwoXYs *settings; @@ -40,24 +40,24 @@ public: CropBaseOperation(); void initExecution(); void deinitExecution(); - void setCropSettings(NodeTwoXYs *settings) {this->settings = settings;} - void setRelative(bool rel) {this->relative = rel;} + void setCropSettings(NodeTwoXYs *settings) { this->settings = settings; } + void setRelative(bool rel) { this->relative = rel; } }; -class CropOperation: public CropBaseOperation { +class CropOperation : public CropBaseOperation { private: public: CropOperation(); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class CropImageOperation: public CropBaseOperation { +class CropImageOperation : public CropBaseOperation { private: public: CropImageOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); void determineResolution(unsigned int resolution[], unsigned int preferedResolution[]); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.h b/source/blender/compositor/operations/COM_CurveBaseOperation.h index 366af5b07cb..9cddb3be46b 100644 --- a/source/blender/compositor/operations/COM_CurveBaseOperation.h +++ b/source/blender/compositor/operations/COM_CurveBaseOperation.h @@ -28,8 +28,8 @@ class CurveBaseOperation : public NodeOperation { protected: /** - * Cached reference to the inputProgram - */ + * Cached reference to the inputProgram + */ CurveMapping *curveMapping; public: CurveBaseOperation(); @@ -39,6 +39,6 @@ public: */ void initExecution(); - void setCurveMapping(CurveMapping *mapping) {this->curveMapping = mapping;} + void setCurveMapping(CurveMapping *mapping) { this->curveMapping = mapping; } }; #endif diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h index 95ebed6f63d..3bdc3384556 100644 --- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h +++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h @@ -26,28 +26,28 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class DifferenceMatteOperation : public NodeOperation { private: NodeChroma *settings; - SocketReader * inputImage1Program; + SocketReader *inputImage1Program; SocketReader *inputImage2Program; public: /** - * Default constructor - */ + * Default constructor + */ DifferenceMatteOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); - void setSettings(NodeChroma *nodeChroma) {this->settings = nodeChroma;} + void setSettings(NodeChroma *nodeChroma) { this->settings = nodeChroma; } }; #endif diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h index 63cee4c333a..b11356129b4 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.h +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.h @@ -28,41 +28,41 @@ class DilateErodeThresholdOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputProgram; float distance; float _switch; float inset; /** - * determines the area of interest to track pixels - * keep this one as small as possible for speed gain. - */ + * determines the area of interest to track pixels + * keep this one as small as possible for speed gain. + */ int scope; public: DilateErodeThresholdOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setDistance(float distance) {this->distance = distance;} - void setSwitch(float sw) {this->_switch = sw;} - void setInset(float inset) {this->inset = inset;} + void setDistance(float distance) { this->distance = distance; } + void setSwitch(float sw) { this->_switch = sw; } + void setInset(float inset) { this->inset = inset; } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); @@ -72,46 +72,46 @@ class DilateDistanceOperation : public NodeOperation { private: protected: /** - * Cached reference to the inputProgram - */ - SocketReader * inputProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputProgram; float distance; int scope; public: DilateDistanceOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setDistance(float distance) {this->distance = distance;} + void setDistance(float distance) { this->distance = distance; } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); void executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, - MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, - list *clKernelsToCleanUp); + MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, + list *clKernelsToCleanUp); }; class ErodeDistanceOperation : public DilateDistanceOperation { public: ErodeDistanceOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); void executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, @@ -122,9 +122,9 @@ public: class DilateStepOperation : public NodeOperation { protected: /** - * Cached reference to the inputProgram - */ - SocketReader * inputProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputProgram; int iterations; @@ -133,22 +133,22 @@ public: DilateStepOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setIterations(int iterations) {this->iterations = iterations;} + void setIterations(int iterations) { this->iterations = iterations; } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); }; diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.h b/source/blender/compositor/operations/COM_DirectionalBlurOperation.h index 280e9247c1b..9cc0a4361f1 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.h +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.h @@ -38,22 +38,22 @@ public: DirectionalBlurOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void setData(NodeDBlurData *data) {this->data = data;} + void setData(NodeDBlurData *data) { this->data = data; } }; #endif diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.h b/source/blender/compositor/operations/COM_DisplaceOperation.h index 9c59c928854..82788e37e3a 100644 --- a/source/blender/compositor/operations/COM_DisplaceOperation.h +++ b/source/blender/compositor/operations/COM_DisplaceOperation.h @@ -41,14 +41,14 @@ public: DisplaceOperation(); /** - * we need a 2x2 differential filter for Vector Input and full buffer for the image - */ + * we need a 2x2 differential filter for Vector Input and full buffer for the image + */ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); /** * the inner loop of this program */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h index 0e3bcc1b1f0..1ebb238855b 100644 --- a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h +++ b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h @@ -41,14 +41,14 @@ public: DisplaceSimpleOperation(); /** - * we need a full buffer for the image - */ + * we need a full buffer for the image + */ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); /** * the inner loop of this program */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_DistanceMatteOperation.h b/source/blender/compositor/operations/COM_DistanceMatteOperation.h index 2a668f31f8f..cf1172a8c11 100644 --- a/source/blender/compositor/operations/COM_DistanceMatteOperation.h +++ b/source/blender/compositor/operations/COM_DistanceMatteOperation.h @@ -25,9 +25,9 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class DistanceMatteOperation : public NodeOperation { private: NodeChroma *settings; @@ -35,18 +35,18 @@ private: SocketReader *inputKeyProgram; public: /** - * Default constructor - */ + * Default constructor + */ DistanceMatteOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); - void setSettings(NodeChroma *nodeChroma) {this->settings = nodeChroma;} + void setSettings(NodeChroma *nodeChroma) { this->settings = nodeChroma; } }; #endif diff --git a/source/blender/compositor/operations/COM_DotproductOperation.h b/source/blender/compositor/operations/COM_DotproductOperation.h index 0244fffa110..849dc83a9cd 100644 --- a/source/blender/compositor/operations/COM_DotproductOperation.h +++ b/source/blender/compositor/operations/COM_DotproductOperation.h @@ -25,13 +25,13 @@ #include "COM_NodeOperation.h" -class DotproductOperation: public NodeOperation { +class DotproductOperation : public NodeOperation { private: SocketReader *input1Operation; SocketReader *input2Operation; public: DotproductOperation(); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h index 85c4fd9e5b7..a18d59ae5a2 100644 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h @@ -28,10 +28,10 @@ class DoubleEdgeMaskOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOuterMask; - SocketReader * inputInnerMask; + * Cached reference to the inputProgram + */ + SocketReader *inputOuterMask; + SocketReader *inputInnerMask; bool adjecentOnly; bool keepInside; float *cachedInstance; @@ -40,25 +40,25 @@ public: void doDoubleEdgeMask(float *inner, float *outer, float *res); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void setAdjecentOnly(bool adjecentOnly) {this->adjecentOnly = adjecentOnly;} - void setKeepInside(bool keepInside) {this->keepInside = keepInside;} + void setAdjecentOnly(bool adjecentOnly) { this->adjecentOnly = adjecentOnly; } + void setKeepInside(bool keepInside) { this->keepInside = keepInside; } }; #endif diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.h b/source/blender/compositor/operations/COM_EllipseMaskOperation.h index bff94941190..61d724c2f15 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.h +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.h @@ -28,10 +28,10 @@ class EllipseMaskOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputMask; - SocketReader * inputValue; + * Cached reference to the inputProgram + */ + SocketReader *inputMask; + SocketReader *inputValue; float sine; float cosine; @@ -43,23 +43,23 @@ public: EllipseMaskOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setData(NodeEllipseMask *data) {this->data = data;} - - void setMaskType(int maskType) {this->maskType = maskType;} + void setData(NodeEllipseMask *data) { this->data = data; } + + void setMaskType(int maskType) { this->maskType = maskType; } }; #endif diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h index 1f71fe7f9ed..9c8973f6a3a 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h @@ -26,11 +26,11 @@ #include "COM_BlurBaseOperation.h" #include "DNA_node_types.h" -class FastGaussianBlurOperation: public BlurBaseOperation { +class FastGaussianBlurOperation : public BlurBaseOperation { private: float sx; float sy; - MemoryBuffer* iirgaus; + MemoryBuffer *iirgaus; public: FastGaussianBlurOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); diff --git a/source/blender/compositor/operations/COM_FlipOperation.h b/source/blender/compositor/operations/COM_FlipOperation.h index 9774cfd7bcd..f83fa6ac3a8 100644 --- a/source/blender/compositor/operations/COM_FlipOperation.h +++ b/source/blender/compositor/operations/COM_FlipOperation.h @@ -25,7 +25,7 @@ #include "COM_NodeOperation.h" -class FlipOperation: public NodeOperation { +class FlipOperation : public NodeOperation { private: SocketReader *inputOperation; bool flipX; @@ -33,12 +33,12 @@ private: public: FlipOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); - void setFlipX(bool flipX) {this->flipX = flipX;} - void setFlipY(bool flipY) {this->flipY = flipY;} + void setFlipX(bool flipX) { this->flipX = flipX; } + void setFlipY(bool flipY) { this->flipY = flipY; } }; #endif diff --git a/source/blender/compositor/operations/COM_FogGlowImageOperation.h b/source/blender/compositor/operations/COM_FogGlowImageOperation.h index d0fc107638e..8330115718f 100644 --- a/source/blender/compositor/operations/COM_FogGlowImageOperation.h +++ b/source/blender/compositor/operations/COM_FogGlowImageOperation.h @@ -30,9 +30,9 @@ public: FogGlowImageOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); }; diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.h b/source/blender/compositor/operations/COM_GammaCorrectOperation.h index 6132f04edba..4bf03eac0a1 100644 --- a/source/blender/compositor/operations/COM_GammaCorrectOperation.h +++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.h @@ -28,52 +28,52 @@ class GammaCorrectOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputProgram; public: GammaCorrectOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; class GammaUncorrectOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputProgram; public: GammaUncorrectOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; diff --git a/source/blender/compositor/operations/COM_GammaOperation.h b/source/blender/compositor/operations/COM_GammaOperation.h index 2f3d8cdf9f7..8c007d27843 100644 --- a/source/blender/compositor/operations/COM_GammaOperation.h +++ b/source/blender/compositor/operations/COM_GammaOperation.h @@ -28,27 +28,27 @@ class GammaOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputProgram; SocketReader *inputGammaProgram; public: GammaOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; #endif diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h index 78c6437eac6..616a6539ad4 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h @@ -37,13 +37,13 @@ public: void initExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h index a957b8c12af..5dc896fafaa 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h @@ -34,18 +34,18 @@ public: GaussianXBlurOperation(); /** - *@brief the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + *@brief the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - *@brief initialize the execution - */ + *@brief initialize the execution + */ void initExecution(); /** - *@brief Deinitialize the execution - */ + *@brief Deinitialize the execution + */ void deinitExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h index f33d38de14e..e8d362e4c32 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h @@ -34,18 +34,18 @@ public: GaussianYBlurOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - *@brief initialize the execution - */ + * @brief initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h index 0d20dd363c7..2ef413a936b 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.h +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.h @@ -30,29 +30,31 @@ /* utility functions used by glare, tonemap and lens distortion */ /* soms macros for color handling */ typedef float fRGB[4]; + +/* TODO - replace with BLI_math_vector */ /* clear color */ -#define fRGB_clear(c) { c[0]=c[1]=c[2]=0.f; } (void)0 +#define fRGB_clear(c) { c[0] = c[1] = c[2] = 0.f; } (void)0 /* copy c2 to c1 */ -#define fRGB_copy(c1, c2) { c1[0]=c2[0]; c1[1]=c2[1]; c1[2]=c2[2]; c1[3]=c2[3]; } (void)0 +#define fRGB_copy(c1, c2) { c1[0] = c2[0]; c1[1] = c2[1]; c1[2] = c2[2]; c1[3] = c2[3]; } (void)0 /* add c2 to c1 */ -#define fRGB_add(c1, c2) { c1[0]+=c2[0]; c1[1]+=c2[1]; c1[2]+=c2[2]; } (void)0 +#define fRGB_add(c1, c2) { c1[0] += c2[0]; c1[1] += c2[1]; c1[2] += c2[2]; } (void)0 /* subtract c2 from c1 */ -#define fRGB_sub(c1, c2) { c1[0]-=c2[0]; c1[1]-=c2[1]; c1[2]-=c2[2]; } (void)0 +#define fRGB_sub(c1, c2) { c1[0] -= c2[0]; c1[1] -= c2[1]; c1[2] -= c2[2]; } (void)0 /* multiply c by float value s */ -#define fRGB_mult(c, s) { c[0]*=s; c[1]*=s; c[2]*=s; } (void)0 +#define fRGB_mult(c, s) { c[0] *= s; c[1] *= s; c[2] *= s; } (void)0 /* multiply c2 by s and add to c1 */ -#define fRGB_madd(c1, c2, s) { c1[0]+=c2[0]*s; c1[1]+=c2[1]*s; c1[2]+=c2[2]*s; } (void)0 +#define fRGB_madd(c1, c2, s) { c1[0] += c2[0] * s; c1[1] += c2[1] * s; c1[2] += c2[2] * s; } (void)0 /* multiply c2 by color c1 */ -#define fRGB_colormult(c, cs) { c[0]*=cs[0]; c[1]*=cs[1]; c[2]*=cs[2]; } (void)0 +#define fRGB_colormult(c, cs) { c[0] *= cs[0]; c[1] *= cs[1]; c[2] *= cs[2]; } (void)0 /* multiply c2 by color c3 and add to c1 */ -#define fRGB_colormadd(c1, c2, c3) { c1[0]+=c2[0]*c3[0]; c1[1]+=c2[1]*c3[1]; c1[2]+=c2[2]*c3[2]; } (void)0 +#define fRGB_colormadd(c1, c2, c3) { c1[0] += c2[0] * c3[0]; c1[1] += c2[1] * c3[1]; c1[2] += c2[2] * c3[2]; } (void)0 /* multiply c2 by color rgb, rgb as separate arguments */ -#define fRGB_rgbmult(c, r, g, b) { c[0]*=(r); c[1]*=(g); c[2]*=(b); } (void)0 +#define fRGB_rgbmult(c, r, g, b) { c[0] *= (r); c[1] *= (g); c[2] *= (b); } (void)0 /* swap colors c1 & c2 */ -#define fRGB_swap(c1, c2) { float _t=c1[0]; c1[0]=c2[0]; c2[0]=_t;\ - _t=c1[1]; c1[1]=c2[1]; c2[1]=_t;\ - _t=c1[2]; c1[2]=c2[2]; c2[2]=_t;\ - _t=c1[3]; c1[3]=c2[3]; c3[3]=_t;\ +#define fRGB_swap(c1, c2) { float _t = c1[0]; c1[0] = c2[0]; c2[0] = _t; \ + _t = c1[1]; c1[1] = c2[1]; c2[1] = _t; \ + _t = c1[2]; c1[2] = c2[2]; c2[2] = _t; \ + _t = c1[3]; c1[3] = c2[3]; c3[3] = _t; \ } (void)0 diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h index 860bb71a0f1..5ede0491773 100644 --- a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h +++ b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h @@ -28,25 +28,25 @@ class HueSaturationValueCorrectOperation : public CurveBaseOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputProgram; public: HueSaturationValueCorrectOperation(); /** - * the inner loop of this program - */ - void executePixel(float *Vector, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *Vector, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.h b/source/blender/compositor/operations/COM_IDMaskOperation.h index 9f897c53d18..229e1b2dd82 100644 --- a/source/blender/compositor/operations/COM_IDMaskOperation.h +++ b/source/blender/compositor/operations/COM_IDMaskOperation.h @@ -28,8 +28,8 @@ class IDMaskOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ + * Cached reference to the inputProgram + */ SocketReader *inputProgram; float objectIndex; @@ -37,21 +37,21 @@ public: IDMaskOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setObjectIndex(float objectIndex) {this->objectIndex = objectIndex;} + void setObjectIndex(float objectIndex) { this->objectIndex = objectIndex; } }; #endif diff --git a/source/blender/compositor/operations/COM_ImageOperation.h b/source/blender/compositor/operations/COM_ImageOperation.h index 0bd112304a8..a4645c9d504 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.h +++ b/source/blender/compositor/operations/COM_ImageOperation.h @@ -36,8 +36,8 @@ extern "C" { } /** - * @brief Base class for all image operations - */ + * @brief Base class for all image operations + */ class BaseImageOperation : public NodeOperation { protected: ImBuf *buffer; @@ -52,8 +52,8 @@ protected: BaseImageOperation(); /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ + * Determine the output resolution. The resolution is retrieved from the Renderer + */ void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); virtual ImBuf *getImBuf(); @@ -62,33 +62,33 @@ public: void initExecution(); void deinitExecution(); - void setImage(Image *image) {this->image = image;} - void setImageUser(ImageUser *imageuser) {this->imageUser = imageuser;} - - void setFramenumber(int framenumber) {this->framenumber = framenumber;} + void setImage(Image *image) { this->image = image; } + void setImageUser(ImageUser *imageuser) { this->imageUser = imageuser; } + + void setFramenumber(int framenumber) { this->framenumber = framenumber; } }; -class ImageOperation: public BaseImageOperation { +class ImageOperation : public BaseImageOperation { public: /** - * Constructor - */ + * Constructor + */ ImageOperation(); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class ImageAlphaOperation: public BaseImageOperation { +class ImageAlphaOperation : public BaseImageOperation { public: /** - * Constructor - */ + * Constructor + */ ImageAlphaOperation(); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class ImageDepthOperation: public BaseImageOperation { +class ImageDepthOperation : public BaseImageOperation { public: /** - * Constructor - */ + * Constructor + */ ImageDepthOperation(); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_InvertOperation.h b/source/blender/compositor/operations/COM_InvertOperation.h index 27a995238c7..48432aecdd0 100644 --- a/source/blender/compositor/operations/COM_InvertOperation.h +++ b/source/blender/compositor/operations/COM_InvertOperation.h @@ -28,10 +28,10 @@ class InvertOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputValueProgram; - SocketReader * inputColorProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputValueProgram; + SocketReader *inputColorProgram; bool alpha; bool color; @@ -40,21 +40,21 @@ public: InvertOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setColor(bool color) {this->color = color;} - void setAlpha(bool alpha) {this->alpha = alpha;} + void setColor(bool color) { this->color = color; } + void setAlpha(bool alpha) { this->alpha = alpha; } }; #endif diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h index 1c2cd2dca51..f44e32396a3 100644 --- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h +++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h @@ -25,27 +25,27 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class LuminanceMatteOperation : public NodeOperation { private: NodeChroma *settings; SocketReader *inputImageProgram; public: /** - * Default constructor - */ + * Default constructor + */ LuminanceMatteOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); - void setSettings(NodeChroma *nodeChroma) {this->settings = nodeChroma;} + void setSettings(NodeChroma *nodeChroma) { this->settings = nodeChroma; } }; #endif diff --git a/source/blender/compositor/operations/COM_MapUVOperation.h b/source/blender/compositor/operations/COM_MapUVOperation.h index 4d7bc814dc2..22e3531e838 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.h +++ b/source/blender/compositor/operations/COM_MapUVOperation.h @@ -38,14 +38,14 @@ public: MapUVOperation(); /** - * we need a 3x3 differential filter for UV Input and full buffer for the image - */ + * we need a 3x3 differential filter for UV Input and full buffer for the image + */ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); /** * the inner loop of this program */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_MapValueOperation.h b/source/blender/compositor/operations/COM_MapValueOperation.h index ac320256fe4..5fae74e0a6a 100644 --- a/source/blender/compositor/operations/COM_MapValueOperation.h +++ b/source/blender/compositor/operations/COM_MapValueOperation.h @@ -26,41 +26,41 @@ #include "DNA_texture_types.h" /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MapValueOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputOperation; - TexMapping * settings; + * Cached reference to the inputProgram + */ + SocketReader *inputOperation; + TexMapping *settings; public: /** - * Default constructor - */ + * Default constructor + */ MapValueOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); /** - * @brief set the TexMapping settings - */ - void setSettings(TexMapping *settings) {this->settings = settings;} + * @brief set the TexMapping settings + */ + void setSettings(TexMapping *settings) { this->settings = settings; } }; #endif diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h index 8534cb20416..8507cb994c0 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.h +++ b/source/blender/compositor/operations/COM_MaskOperation.h @@ -32,20 +32,20 @@ #include "IMB_imbuf_types.h" /** - * Class with implementation of mask rasterization - */ + * Class with implementation of mask rasterization + */ class MaskOperation : public NodeOperation { protected: Mask *mask; int maskWidth; int maskHeight; int framenumber; - bool smooth; + bool smooth; float *rasterizedMask; /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ + * Determine the output resolution. The resolution is retrieved from the Renderer + */ void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); public: @@ -56,11 +56,11 @@ public: void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); - void setMask(Mask *mask) {this->mask = mask;} - void setMaskWidth(int width) {this->maskWidth = width;} - void setMaskHeight(int height) {this->maskHeight = height;} - void setFramenumber(int framenumber) {this->framenumber = framenumber;} - void setSmooth(bool smooth) {this->smooth = smooth;} + void setMask(Mask *mask) { this->mask = mask; } + void setMaskWidth(int width) { this->maskWidth = width; } + void setMaskHeight(int height) { this->maskHeight = height; } + void setFramenumber(int framenumber) { this->framenumber = framenumber; } + void setSmooth(bool smooth) { this->smooth = smooth; } void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); }; diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h index 64e8c4af88f..12dc5fa36c7 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.h +++ b/source/blender/compositor/operations/COM_MathBaseOperation.h @@ -26,129 +26,129 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MathBaseOperation : public NodeOperation { protected: /** - * Prefetched reference to the inputProgram - */ - SocketReader * inputValue1Operation; - SocketReader * inputValue2Operation; + * Prefetched reference to the inputProgram + */ + SocketReader *inputValue1Operation; + SocketReader *inputValue2Operation; protected: /** - * Default constructor - */ + * Default constructor + */ MathBaseOperation(); public: /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) = 0; + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]) = 0; /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); /** - * Determine resolution - */ + * Determine resolution + */ void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); }; -class MathAddOperation: public MathBaseOperation { +class MathAddOperation : public MathBaseOperation { public: MathAddOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathSubtractOperation: public MathBaseOperation { +class MathSubtractOperation : public MathBaseOperation { public: MathSubtractOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathMultiplyOperation: public MathBaseOperation { +class MathMultiplyOperation : public MathBaseOperation { public: MathMultiplyOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathDivideOperation: public MathBaseOperation { +class MathDivideOperation : public MathBaseOperation { public: MathDivideOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathSineOperation: public MathBaseOperation { +class MathSineOperation : public MathBaseOperation { public: MathSineOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathCosineOperation: public MathBaseOperation { +class MathCosineOperation : public MathBaseOperation { public: MathCosineOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathTangentOperation: public MathBaseOperation { +class MathTangentOperation : public MathBaseOperation { public: MathTangentOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathArcSineOperation: public MathBaseOperation { +class MathArcSineOperation : public MathBaseOperation { public: MathArcSineOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathArcCosineOperation: public MathBaseOperation { +class MathArcCosineOperation : public MathBaseOperation { public: MathArcCosineOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathArcTangentOperation: public MathBaseOperation { +class MathArcTangentOperation : public MathBaseOperation { public: MathArcTangentOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathPowerOperation: public MathBaseOperation { +class MathPowerOperation : public MathBaseOperation { public: MathPowerOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathLogarithmOperation: public MathBaseOperation { +class MathLogarithmOperation : public MathBaseOperation { public: MathLogarithmOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathMinimumOperation: public MathBaseOperation { +class MathMinimumOperation : public MathBaseOperation { public: MathMinimumOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathMaximumOperation: public MathBaseOperation { +class MathMaximumOperation : public MathBaseOperation { public: MathMaximumOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathRoundOperation: public MathBaseOperation { +class MathRoundOperation : public MathBaseOperation { public: MathRoundOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathLessThanOperation: public MathBaseOperation { +class MathLessThanOperation : public MathBaseOperation { public: MathLessThanOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MathGreaterThanOperation: public MathBaseOperation { +class MathGreaterThanOperation : public MathBaseOperation { public: MathGreaterThanOperation() : MathBaseOperation() {} - void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixAddOperation.h b/source/blender/compositor/operations/COM_MixAddOperation.h index 99a6af67d7d..7b03802cf7e 100644 --- a/source/blender/compositor/operations/COM_MixAddOperation.h +++ b/source/blender/compositor/operations/COM_MixAddOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixAddOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixAddOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.h b/source/blender/compositor/operations/COM_MixBaseOperation.h index b9bb94d58d8..3637cc9eacf 100644 --- a/source/blender/compositor/operations/COM_MixBaseOperation.h +++ b/source/blender/compositor/operations/COM_MixBaseOperation.h @@ -26,42 +26,42 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixBaseOperation : public NodeOperation { protected: /** - * Prefetched reference to the inputProgram - */ + * Prefetched reference to the inputProgram + */ SocketReader *inputValueOperation; SocketReader *inputColor1Operation; SocketReader *inputColor2Operation; bool valueAlphaMultiply; public: /** - * Default constructor - */ + * Default constructor + */ MixBaseOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); - void setUseValueAlphaMultiply(const bool value) {this->valueAlphaMultiply = value;} - bool useValueAlphaMultiply() {return this->valueAlphaMultiply;} + void setUseValueAlphaMultiply(const bool value) { this->valueAlphaMultiply = value; } + bool useValueAlphaMultiply() { return this->valueAlphaMultiply; } }; #endif diff --git a/source/blender/compositor/operations/COM_MixBlendOperation.h b/source/blender/compositor/operations/COM_MixBlendOperation.h index da3342c0e4a..b906134f5cb 100644 --- a/source/blender/compositor/operations/COM_MixBlendOperation.h +++ b/source/blender/compositor/operations/COM_MixBlendOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixBlendOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixBlendOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixBurnOperation.h b/source/blender/compositor/operations/COM_MixBurnOperation.h index ff7de119605..af09772edde 100644 --- a/source/blender/compositor/operations/COM_MixBurnOperation.h +++ b/source/blender/compositor/operations/COM_MixBurnOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixBurnOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixBurnOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixColorOperation.h b/source/blender/compositor/operations/COM_MixColorOperation.h index 1a98e847ccd..9b0d93f934d 100644 --- a/source/blender/compositor/operations/COM_MixColorOperation.h +++ b/source/blender/compositor/operations/COM_MixColorOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixColorOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixColorOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixDarkenOperation.h b/source/blender/compositor/operations/COM_MixDarkenOperation.h index b1792d4930e..69fb4450458 100644 --- a/source/blender/compositor/operations/COM_MixDarkenOperation.h +++ b/source/blender/compositor/operations/COM_MixDarkenOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixDarkenOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixDarkenOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixDifferenceOperation.h b/source/blender/compositor/operations/COM_MixDifferenceOperation.h index 554d7b2f1fe..c71b22214cc 100644 --- a/source/blender/compositor/operations/COM_MixDifferenceOperation.h +++ b/source/blender/compositor/operations/COM_MixDifferenceOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixDifferenceOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixDifferenceOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixDivideOperation.h b/source/blender/compositor/operations/COM_MixDivideOperation.h index e9c4cf81cd3..375e7129e8b 100644 --- a/source/blender/compositor/operations/COM_MixDivideOperation.h +++ b/source/blender/compositor/operations/COM_MixDivideOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixDivideOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixDivideOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixDodgeOperation.h b/source/blender/compositor/operations/COM_MixDodgeOperation.h index 6baa73e8f6f..a4adf6fde47 100644 --- a/source/blender/compositor/operations/COM_MixDodgeOperation.h +++ b/source/blender/compositor/operations/COM_MixDodgeOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixDodgeOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixDodgeOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixHueOperation.h b/source/blender/compositor/operations/COM_MixHueOperation.h index d3d1717f448..56310e253c0 100644 --- a/source/blender/compositor/operations/COM_MixHueOperation.h +++ b/source/blender/compositor/operations/COM_MixHueOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixHueOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixHueOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixLightenOperation.h b/source/blender/compositor/operations/COM_MixLightenOperation.h index 73ac3e6e165..bb251a44653 100644 --- a/source/blender/compositor/operations/COM_MixLightenOperation.h +++ b/source/blender/compositor/operations/COM_MixLightenOperation.h @@ -26,19 +26,19 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixLightenOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixLightenOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixLinearLightOperation.h b/source/blender/compositor/operations/COM_MixLinearLightOperation.h index 7e26b25e5c0..39d5b6495d1 100644 --- a/source/blender/compositor/operations/COM_MixLinearLightOperation.h +++ b/source/blender/compositor/operations/COM_MixLinearLightOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixLinearLightOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixLinearLightOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixMultiplyOperation.h b/source/blender/compositor/operations/COM_MixMultiplyOperation.h index 5d4468e7271..2c12854bfa6 100644 --- a/source/blender/compositor/operations/COM_MixMultiplyOperation.h +++ b/source/blender/compositor/operations/COM_MixMultiplyOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixMultiplyOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixMultiplyOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixOverlayOperation.h b/source/blender/compositor/operations/COM_MixOverlayOperation.h index dd1d16a53d3..48d1d10a697 100644 --- a/source/blender/compositor/operations/COM_MixOverlayOperation.h +++ b/source/blender/compositor/operations/COM_MixOverlayOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixOverlayOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixOverlayOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixSaturationOperation.h b/source/blender/compositor/operations/COM_MixSaturationOperation.h index 7e746c02e09..ccb95e2f00f 100644 --- a/source/blender/compositor/operations/COM_MixSaturationOperation.h +++ b/source/blender/compositor/operations/COM_MixSaturationOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixSaturationOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixSaturationOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixScreenOperation.h b/source/blender/compositor/operations/COM_MixScreenOperation.h index 6522907f295..6b9fa302325 100644 --- a/source/blender/compositor/operations/COM_MixScreenOperation.h +++ b/source/blender/compositor/operations/COM_MixScreenOperation.h @@ -26,19 +26,19 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixScreenOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixScreenOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixSoftLightOperation.h b/source/blender/compositor/operations/COM_MixSoftLightOperation.h index fcbd8dab8b8..4189066de2c 100644 --- a/source/blender/compositor/operations/COM_MixSoftLightOperation.h +++ b/source/blender/compositor/operations/COM_MixSoftLightOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixSoftLightOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixSoftLightOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixSubtractOperation.h b/source/blender/compositor/operations/COM_MixSubtractOperation.h index 441857a8aca..b820fb1e5e1 100644 --- a/source/blender/compositor/operations/COM_MixSubtractOperation.h +++ b/source/blender/compositor/operations/COM_MixSubtractOperation.h @@ -26,20 +26,20 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixSubtractOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixSubtractOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixValueOperation.h b/source/blender/compositor/operations/COM_MixValueOperation.h index 89461b3ba40..d12a2d2b3d6 100644 --- a/source/blender/compositor/operations/COM_MixValueOperation.h +++ b/source/blender/compositor/operations/COM_MixValueOperation.h @@ -26,19 +26,19 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MixValueOperation : public MixBaseOperation { public: /** - * Default constructor - */ + * Default constructor + */ MixValueOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h index aca2ec2eff7..b6e89fa345c 100644 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h @@ -32,30 +32,30 @@ typedef enum MovieClipAttribute { MCA_ANGLE } MovieClipAttribute; /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class MovieClipAttributeOperation : public NodeOperation { private: - MovieClip * clip; + MovieClip *clip; float value; bool valueSet; int framenumber; MovieClipAttribute attribute; public: /** - * Default constructor - */ + * Default constructor + */ MovieClipAttributeOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); - void setMovieClip(MovieClip *clip) {this->clip = clip;} - void setFramenumber(int framenumber) {this->framenumber = framenumber;} - void setAttribute(MovieClipAttribute attribute) {this->attribute = attribute;} + void setMovieClip(MovieClip *clip) { this->clip = clip; } + void setFramenumber(int framenumber) { this->framenumber = framenumber; } + void setAttribute(MovieClipAttribute attribute) { this->attribute = attribute; } }; #endif diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.h b/source/blender/compositor/operations/COM_MovieClipOperation.h index f52a9973fc5..454c442a167 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipOperation.h @@ -31,10 +31,10 @@ #include "IMB_imbuf_types.h" /** - * Base class for all renderlayeroperations - * - * @todo: rename to operation. - */ + * Base class for all renderlayeroperations + * + * @todo: rename to operation. + */ class MovieClipOperation : public NodeOperation { protected: MovieClip *movieClip; @@ -45,8 +45,8 @@ protected: int framenumber; /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ + * Determine the output resolution. The resolution is retrieved from the Renderer + */ void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); public: @@ -54,11 +54,11 @@ public: void initExecution(); void deinitExecution(); - void setMovieClip(MovieClip *image) {this->movieClip = image;} - void setMovieClipUser(MovieClipUser *imageuser) {this->movieClipUser = imageuser;} - - void setFramenumber(int framenumber) {this->framenumber = framenumber;} - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void setMovieClip(MovieClip *image) { this->movieClip = image; } + void setMovieClipUser(MovieClipUser *imageuser) { this->movieClipUser = imageuser; } + + void setFramenumber(int framenumber) { this->framenumber = framenumber; } + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index 5792248464a..9c7050e1da0 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -57,28 +57,28 @@ public: this->calibration_width = calibration_width; this->calibration_height = calibration_height; this->inverted = inverted; - this->bufferCalculated = new int[this->width*this->height]; - this->buffer = new float[this->width*this->height*2]; - for (int i = 0 ; i < this->width*this->height ; i ++) { + this->bufferCalculated = new int[this->width * this->height]; + this->buffer = new float[this->width * this->height * 2]; + for (int i = 0; i < this->width * this->height; i++) { this->bufferCalculated[i] = 0; } } bool isCacheFor(MovieClip *movieclip, int width, int height, int calibration_width, int claibration_height, bool inverted) { return this->k1 == movieclip->tracking.camera.k1 && - this->k2 == movieclip->tracking.camera.k2 && - this->k3 == movieclip->tracking.camera.k3 && - this->principal_x == movieclip->tracking.camera.principal[0] && - this->principal_y == movieclip->tracking.camera.principal[1] && - this->pixel_aspect == movieclip->tracking.camera.pixel_aspect && - this->inverted == inverted && - this->width == width && - this->height == height && - this->calibration_width == calibration_width && - this->calibration_height == calibration_height; + this->k2 == movieclip->tracking.camera.k2 && + this->k3 == movieclip->tracking.camera.k3 && + this->principal_x == movieclip->tracking.camera.principal[0] && + this->principal_y == movieclip->tracking.camera.principal[1] && + this->pixel_aspect == movieclip->tracking.camera.pixel_aspect && + this->inverted == inverted && + this->width == width && + this->height == height && + this->calibration_width == calibration_width && + this->calibration_height == calibration_height; } - void getUV(MovieTracking *trackingData, int x, int y, float *u, float*v) { - if (x<0 || x >= this->width || y <0 || y >= this->height) { + void getUV(MovieTracking *trackingData, int x, int y, float *u, float *v) { + if (x < 0 || x >= this->width || y < 0 || y >= this->height) { *u = x; *v = y; } @@ -88,8 +88,8 @@ public: if (!bufferCalculated[offset]) { //float overscan = 0.0f; - float w = (float)this->width/* / (1 + overscan) */; - float h = (float)this->height/* / (1 + overscan) */; + float w = (float)this->width /* / (1 + overscan) */; + float h = (float)this->height /* / (1 + overscan) */; float aspx = (float)w / this->calibration_width; float aspy = (float)h / this->calibration_height; float in[2]; @@ -106,21 +106,21 @@ public: } buffer[offset2] = out[0] * aspx /* + 0.5 * overscan * w */; - buffer[offset2+1] = (out[1] * aspy /* + 0.5 * overscan * h */) * this->pixel_aspect; + buffer[offset2 + 1] = (out[1] * aspy /* + 0.5 * overscan * h */) * this->pixel_aspect; bufferCalculated[offset] = 1; } *u = buffer[offset2]; - *v = buffer[offset2+1]; + *v = buffer[offset2 + 1]; } } }; -class MovieDistortionOperation: public NodeOperation { +class MovieDistortionOperation : public NodeOperation { private: DistortionCache *cache; SocketReader *inputOperation; - MovieClip * movieClip; + MovieClip *movieClip; protected: bool distortion; @@ -129,13 +129,13 @@ protected: public: MovieDistortionOperation(bool distortion); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); - void setMovieClip(MovieClip *clip) {this->movieClip = clip;} - void setFramenumber(int framenumber) {this->framenumber = framenumber;} + void setMovieClip(MovieClip *clip) { this->movieClip = clip; } + void setFramenumber(int framenumber) { this->framenumber = framenumber; } }; #endif diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.h b/source/blender/compositor/operations/COM_MultilayerImageOperation.h index 809253e532a..c33e65fc55b 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.h +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.h @@ -27,7 +27,7 @@ #include "COM_ImageOperation.h" -class MultilayerBaseOperation: public BaseImageOperation { +class MultilayerBaseOperation : public BaseImageOperation { private: int passId; RenderLayer *renderlayer; @@ -35,34 +35,34 @@ protected: ImBuf *getImBuf(); public: /** - * Constructor - */ + * Constructor + */ MultilayerBaseOperation(int pass); - void setRenderLayer(RenderLayer *renderlayer) {this->renderlayer = renderlayer;} + void setRenderLayer(RenderLayer *renderlayer) { this->renderlayer = renderlayer; } }; -class MultilayerColorOperation: public MultilayerBaseOperation { +class MultilayerColorOperation : public MultilayerBaseOperation { public: - MultilayerColorOperation(int pass): MultilayerBaseOperation(pass) { + MultilayerColorOperation(int pass) : MultilayerBaseOperation(pass) { this->addOutputSocket(COM_DT_COLOR); } - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MultilayerValueOperation: public MultilayerBaseOperation { +class MultilayerValueOperation : public MultilayerBaseOperation { public: - MultilayerValueOperation(int pass): MultilayerBaseOperation(pass) { + MultilayerValueOperation(int pass) : MultilayerBaseOperation(pass) { this->addOutputSocket(COM_DT_VALUE); } - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class MultilayerVectorOperation: public MultilayerBaseOperation { +class MultilayerVectorOperation : public MultilayerBaseOperation { public: - MultilayerVectorOperation(int pass): MultilayerBaseOperation(pass) { + MultilayerVectorOperation(int pass) : MultilayerBaseOperation(pass) { this->addOutputSocket(COM_DT_VECTOR); } - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.h b/source/blender/compositor/operations/COM_NormalizeOperation.h index 765b8847384..de1c4d67bba 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.h +++ b/source/blender/compositor/operations/COM_NormalizeOperation.h @@ -25,41 +25,41 @@ #include "DNA_node_types.h" /** - * @brief base class of normalize, implementing the simple normalize - * @ingroup operation - */ + * @brief base class of normalize, implementing the simple normalize + * @ingroup operation + */ class NormalizeOperation : public NodeOperation { protected: /** - * @brief Cached reference to the reader - */ - SocketReader * imageReader; + * @brief Cached reference to the reader + */ + SocketReader *imageReader; /** - * @brief temporarily cache of the execution storage - * it stores x->min and y->mult - */ - NodeTwoFloats * cachedInstance; + * @brief temporarily cache of the execution storage + * it stores x->min and y->mult + */ + NodeTwoFloats *cachedInstance; public: NormalizeOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); void deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h index 9b9fb023467..cfc5f7e41f2 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileOperation.h @@ -45,18 +45,18 @@ private: public: OutputSingleLayerOperation(const Scene *scene, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path); - void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); - bool isOutputOperation(bool rendering) const {return true;} + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers); + bool isOutputOperation(bool rendering) const { return true; } void initExecution(); void deinitExecution(); - const CompositorPriority getRenderPriority() const {return COM_PRIORITY_LOW;} + const CompositorPriority getRenderPriority() const { return COM_PRIORITY_LOW; } }; /* extra info for OpenEXR layers */ struct OutputOpenExrLayer { OutputOpenExrLayer(const char *name, DataType datatype); - char name[EXR_TOT_MAXNAME-2]; + char name[EXR_TOT_MAXNAME - 2]; float *outputBuffer; DataType datatype; SocketReader *imageInput; @@ -79,11 +79,11 @@ public: void add_layer(const char *name, DataType datatype); - void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); - bool isOutputOperation(bool rendering) const {return true;} + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers); + bool isOutputOperation(bool rendering) const { return true; } void initExecution(); void deinitExecution(); - const CompositorPriority getRenderPriority() const {return COM_PRIORITY_LOW;} + const CompositorPriority getRenderPriority() const { return COM_PRIORITY_LOW; } }; #endif diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h index 32c0b6ecc77..f9ce0c644a1 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.h +++ b/source/blender/compositor/operations/COM_PreviewOperation.h @@ -31,24 +31,24 @@ protected: unsigned char *outputBuffer; /** - * @brief holds reference to the SDNA bNode, where this nodes will render the preview image for - */ + * @brief holds reference to the SDNA bNode, where this nodes will render the preview image for + */ bNode *node; SocketReader *input; float divider; public: PreviewOperation(); - bool isOutputOperation(bool rendering) const {return true;} + bool isOutputOperation(bool rendering) const { return true; } void initExecution(); void deinitExecution(); const CompositorPriority getRenderPriority() const; void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers); void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); - void setbNode(bNode *node) { this->node = node;} + void setbNode(bNode *node) { this->node = node; } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - bool isPreviewOperation() {return true;} + bool isPreviewOperation() { return true; } }; #endif diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h index c8788e100c8..2e188617ab5 100644 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h @@ -28,11 +28,11 @@ class ProjectorLensDistortionOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputProgram; - NodeLensDist * data; + NodeLensDist *data; float dispersion; float kr, kr2; @@ -40,23 +40,23 @@ public: ProjectorLensDistortionOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setData(NodeLensDist *data) {this->data = data;} - void setDispertion(float dispersion) {this->dispersion = dispersion;} + void setData(NodeLensDist *data) { this->data = data; } + void setDispertion(float dispersion) { this->dispersion = dispersion; } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); diff --git a/source/blender/compositor/operations/COM_QualityStepHelper.h b/source/blender/compositor/operations/COM_QualityStepHelper.h index 80b25684c5e..aef80e22e38 100644 --- a/source/blender/compositor/operations/COM_QualityStepHelper.h +++ b/source/blender/compositor/operations/COM_QualityStepHelper.h @@ -37,17 +37,17 @@ private: protected: /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(QualityHelper helper); - inline int getStep() const {return this->step;} - inline int getOffsetAdd() const {return this->offsetadd;} + inline int getStep() const { return this->step; } + inline int getOffsetAdd() const { return this->offsetadd; } public: QualityStepHelper(); - void setQuality(CompositorQuality quality) {this->quality = quality;} + void setQuality(CompositorQuality quality) { this->quality = quality; } }; #endif diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.h b/source/blender/compositor/operations/COM_ReadBufferOperation.h index 449b4a82618..576aa194bc5 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.h +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.h @@ -26,25 +26,25 @@ #include "COM_NodeOperation.h" #include "COM_MemoryProxy.h" -class ReadBufferOperation: public NodeOperation { +class ReadBufferOperation : public NodeOperation { private: MemoryProxy *memoryProxy; unsigned int offset; public: ReadBufferOperation(); - int isBufferOperation() {return true;} - void setMemoryProxy(MemoryProxy *memoryProxy) {this->memoryProxy = memoryProxy;} - MemoryProxy *getMemoryProxy() {return this->memoryProxy;} + int isBufferOperation() { return true; } + void setMemoryProxy(MemoryProxy *memoryProxy) { this->memoryProxy = memoryProxy; } + MemoryProxy *getMemoryProxy() { return this->memoryProxy; } void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); - void executePixel(float *color, float x, float y, float dx, float dy, MemoryBuffer *inputBuffers[]); - const bool isReadBufferOperation() const {return true;} - void setOffset(unsigned int offset) {this->offset = offset;} - unsigned int getOffset() {return this->offset;} - bool determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti *output); - MemoryBuffer *getInputMemoryBuffer(MemoryBuffer** memoryBuffers) {return memoryBuffers[offset];} + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); + void executePixel(float *color, float x, float y, float dx, float dy, MemoryBuffer * inputBuffers[]); + const bool isReadBufferOperation() const { return true; } + void setOffset(unsigned int offset) { this->offset = offset; } + unsigned int getOffset() { return this->offset; } + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + MemoryBuffer *getInputMemoryBuffer(MemoryBuffer **memoryBuffers) { return memoryBuffers[offset]; } void readResolutionFromWriteBuffer(); }; diff --git a/source/blender/compositor/operations/COM_RenderLayersAlphaProg.h b/source/blender/compositor/operations/COM_RenderLayersAlphaProg.h index da808f49fdf..846e337c572 100644 --- a/source/blender/compositor/operations/COM_RenderLayersAlphaProg.h +++ b/source/blender/compositor/operations/COM_RenderLayersAlphaProg.h @@ -28,7 +28,7 @@ class RenderLayersAlphaProg : public RenderLayersBaseProg { public: RenderLayersAlphaProg(); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; diff --git a/source/blender/compositor/operations/COM_RenderLayersBaseProg.h b/source/blender/compositor/operations/COM_RenderLayersBaseProg.h index 64e2496621f..ce2b8f767b6 100644 --- a/source/blender/compositor/operations/COM_RenderLayersBaseProg.h +++ b/source/blender/compositor/operations/COM_RenderLayersBaseProg.h @@ -36,64 +36,63 @@ extern "C" { } /** - * Base class for all renderlayeroperations - * - * @todo: rename to operation. - */ + * Base class for all renderlayeroperations + * + * @todo: rename to operation. + */ class RenderLayersBaseProg : public NodeOperation { private: /** - * Reference to the scene object. - */ + * Reference to the scene object. + */ Scene *scene; /** - * layerId of the layer where this operation needs to get its data from - */ + * layerId of the layer where this operation needs to get its data from + */ short layerId; /** - * cached instance to the float buffer inside the layer - */ + * cached instance to the float buffer inside the layer + */ float *inputBuffer; /** - * renderpass where this operation needs to get its data from - */ + * renderpass where this operation needs to get its data from + */ int renderpass; int elementsize; protected: /** - * Constructor - */ + * Constructor + */ RenderLayersBaseProg(int renderpass, int elementsize); /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ + * Determine the output resolution. The resolution is retrieved from the Renderer + */ void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); /** - * retrieve the reference to the float buffer of the renderer. - */ - inline float *getInputBuffer() {return this->inputBuffer;} + * retrieve the reference to the float buffer of the renderer. + */ + inline float *getInputBuffer() { return this->inputBuffer; } public: /** - * setter for the scene field. Will be called from - * @see RenderLayerNode to set the actual scene where - * the data will be retrieved from. - */ - void setScene(Scene *scene) {this->scene = scene;} - Scene *getScene() {return this->scene;} - void setLayerId(short layerId) {this->layerId = layerId;} - short getLayerId() {return this->layerId;} + * setter for the scene field. Will be called from + * @see RenderLayerNode to set the actual scene where + * the data will be retrieved from. + */ + void setScene(Scene *scene) { this->scene = scene; } + Scene *getScene() { return this->scene; } + void setLayerId(short layerId) { this->layerId = layerId; } + short getLayerId() { return this->layerId; } void initExecution(); void deinitExecution(); void executePixel(float *output, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); - }; #endif diff --git a/source/blender/compositor/operations/COM_RotateOperation.h b/source/blender/compositor/operations/COM_RotateOperation.h index 6afed39908b..bf7355da80e 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.h +++ b/source/blender/compositor/operations/COM_RotateOperation.h @@ -25,7 +25,7 @@ #include "COM_NodeOperation.h" -class RotateOperation: public NodeOperation { +class RotateOperation : public NodeOperation { private: SocketReader *imageSocket; SocketReader *degreeSocket; @@ -38,10 +38,10 @@ private: public: RotateOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); - void setDoDegree2RadConversion(bool abool) {this->doDegree2RadConversion = abool;} + void setDoDegree2RadConversion(bool abool) { this->doDegree2RadConversion = abool; } void ensureDegree(); }; diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h index 2c99cb63978..9e24ab3d1ca 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -70,8 +70,8 @@ public: void initExecution(); void deinitExecution(); - void setNewWidth(int width) {this->newWidth = width;} - void setNewHeight(int height) {this->newHeight = height;} + void setNewWidth(int width) { this->newWidth = width; } + void setNewHeight(int height) { this->newHeight = height; } }; #endif diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h index d2db55ea214..34656f38a09 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h @@ -28,11 +28,11 @@ class ScreenLensDistortionOperation : public NodeOperation { private: /** - * Cached reference to the inputProgram - */ + * Cached reference to the inputProgram + */ SocketReader *inputProgram; - NodeLensDist * data; + NodeLensDist *data; float dispersion; float distortion; @@ -46,24 +46,24 @@ public: ScreenLensDistortionOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setData(NodeLensDist *data) {this->data = data;} - void setDispertion(float dispersion) {this->dispersion = dispersion;} - void setDistortion(float distortion) {this->distortion = distortion;} + void setData(NodeLensDist *data) { this->data = data; } + void setDispertion(float dispersion) { this->dispersion = dispersion; } + void setDistortion(float distortion) { this->distortion = distortion; } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); diff --git a/source/blender/compositor/operations/COM_SeparateChannelOperation.h b/source/blender/compositor/operations/COM_SeparateChannelOperation.h index 3c1eed4bdd9..b1a38fd8294 100644 --- a/source/blender/compositor/operations/COM_SeparateChannelOperation.h +++ b/source/blender/compositor/operations/COM_SeparateChannelOperation.h @@ -25,18 +25,18 @@ #include "COM_NodeOperation.h" -class SeparateChannelOperation: public NodeOperation { +class SeparateChannelOperation : public NodeOperation { private: SocketReader *inputOperation; int channel; public: SeparateChannelOperation(); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); - void setChannel(int channel) {this->channel = channel;} + void setChannel(int channel) { this->channel = channel; } }; #endif diff --git a/source/blender/compositor/operations/COM_SetAlphaOperation.h b/source/blender/compositor/operations/COM_SetAlphaOperation.h index 3d9caabf880..231b41f1697 100644 --- a/source/blender/compositor/operations/COM_SetAlphaOperation.h +++ b/source/blender/compositor/operations/COM_SetAlphaOperation.h @@ -26,9 +26,9 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class SetAlphaOperation : public NodeOperation { private: SocketReader *inputColor; @@ -36,14 +36,14 @@ private: public: /** - * Default constructor - */ + * Default constructor + */ SetAlphaOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_SetColorOperation.h b/source/blender/compositor/operations/COM_SetColorOperation.h index dad3cfd7fc9..9d28f1757db 100644 --- a/source/blender/compositor/operations/COM_SetColorOperation.h +++ b/source/blender/compositor/operations/COM_SetColorOperation.h @@ -26,9 +26,9 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class SetColorOperation : public NodeOperation { private: float channel1; @@ -38,8 +38,8 @@ private: public: /** - * Default constructor - */ + * Default constructor + */ SetColorOperation(); const float getChannel1() {return this->channel1;} @@ -53,12 +53,12 @@ public: void setChannels(float value[4]) {this->channel1 = value[0];this->channel2 = value[1];this->channel3 = value[2];this->channel4 = value[3];} /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); - const bool isSetOperation() const {return true;} + const bool isSetOperation() const { return true; } }; #endif diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.h b/source/blender/compositor/operations/COM_SetSamplerOperation.h index 49bbae7e4ff..5dba0b3703f 100644 --- a/source/blender/compositor/operations/COM_SetSamplerOperation.h +++ b/source/blender/compositor/operations/COM_SetSamplerOperation.h @@ -26,25 +26,25 @@ /** - * this program converts an input colour to an output Sampler. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output Sampler. + * it assumes we are in sRGB colour space. + */ class SetSamplerOperation : public NodeOperation { private: PixelSampler sampler; SocketReader *reader; public: /** - * Default constructor - */ + * Default constructor + */ SetSamplerOperation(); - void setSampler(PixelSampler sampler) {this->sampler = sampler;} + void setSampler(PixelSampler sampler) { this->sampler = sampler; } /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); }; diff --git a/source/blender/compositor/operations/COM_SetValueOperation.h b/source/blender/compositor/operations/COM_SetValueOperation.h index 25810cd7ee5..2f4a6ec0dc8 100644 --- a/source/blender/compositor/operations/COM_SetValueOperation.h +++ b/source/blender/compositor/operations/COM_SetValueOperation.h @@ -26,29 +26,29 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class SetValueOperation : public NodeOperation { private: float value; public: /** - * Default constructor - */ + * Default constructor + */ SetValueOperation(); - const float getValue() {return this->value;} - void setValue(float value) {this->value = value;} + const float getValue() { return this->value; } + void setValue(float value) { this->value = value; } /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); - const bool isSetOperation() const {return true;} + const bool isSetOperation() const { return true; } }; #endif diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.h b/source/blender/compositor/operations/COM_SetVectorOperation.h index 9b5dd3ce674..49088027762 100644 --- a/source/blender/compositor/operations/COM_SetVectorOperation.h +++ b/source/blender/compositor/operations/COM_SetVectorOperation.h @@ -26,9 +26,9 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class SetVectorOperation : public NodeOperation { private: float x; @@ -38,26 +38,26 @@ private: public: /** - * Default constructor - */ + * Default constructor + */ SetVectorOperation(); - const float getX() {return this->x;} - void setX(float value) {this->x = value;} - const float getY() {return this->y;} - void setY(float value) {this->y = value;} - const float getZ() {return this->z;} - void setZ(float value) {this->z = value;} - const float getW() {return this->w;} - void setW(float value) {this->w = value;} + const float getX() { return this->x; } + void setX(float value) { this->x = value; } + const float getY() { return this->y; } + void setY(float value) { this->y = value; } + const float getZ() { return this->z; } + void setZ(float value) { this->z = value; } + const float getW() { return this->w; } + void setW(float value) { this->w = value; } /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); - const bool isSetOperation() const {return true;} + const bool isSetOperation() const { return true; } void setVector(float vector[3]) { setX(vector[0]); diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.h b/source/blender/compositor/operations/COM_SocketProxyOperation.h index a86134c1ea9..701a5a8f693 100644 --- a/source/blender/compositor/operations/COM_SocketProxyOperation.h +++ b/source/blender/compositor/operations/COM_SocketProxyOperation.h @@ -25,12 +25,12 @@ #include "COM_NodeOperation.h" -class SocketProxyOperation: public NodeOperation { +class SocketProxyOperation : public NodeOperation { private: SocketReader *inputOperation; public: SocketProxyOperation(); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_SplitViewerOperation.h b/source/blender/compositor/operations/COM_SplitViewerOperation.h index 2c3163f0b0a..aba63ff190b 100644 --- a/source/blender/compositor/operations/COM_SplitViewerOperation.h +++ b/source/blender/compositor/operations/COM_SplitViewerOperation.h @@ -35,10 +35,10 @@ private: bool xSplit; public: SplitViewerOperation(); - void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers); void initExecution(); void deinitExecution(); - void setSplitPercentage(float splitPercentage) {this->splitPercentage = splitPercentage;} - void setXSplit(bool xsplit) {this->xSplit = xsplit;} + void setSplitPercentage(float splitPercentage) { this->splitPercentage = splitPercentage; } + void setXSplit(bool xsplit) { this->xSplit = xsplit; } }; #endif diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h index de42b144730..e862a1f1910 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.h +++ b/source/blender/compositor/operations/COM_TextureOperation.h @@ -36,10 +36,10 @@ extern "C" { } /** - * Base class for all renderlayeroperations - * - * @todo: rename to operation. - */ + * Base class for all renderlayeroperations + * + * @todo: rename to operation. + */ class TextureBaseOperation : public NodeOperation { private: Tex *texture; @@ -50,33 +50,33 @@ private: protected: /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ + * Determine the output resolution. The resolution is retrieved from the Renderer + */ void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); /** - * Constructor - */ + * Constructor + */ TextureBaseOperation(); public: - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); - void setTexture(Tex *texture) {this->texture = texture;} + void setTexture(Tex *texture) { this->texture = texture; } void initExecution(); void deinitExecution(); - void setScene(const Scene *scene) {this->scene = scene;} + void setScene(const Scene *scene) { this->scene = scene; } }; -class TextureOperation:public TextureBaseOperation { +class TextureOperation : public TextureBaseOperation { public: TextureOperation(); }; -class TextureAlphaOperation:public TextureBaseOperation { +class TextureAlphaOperation : public TextureBaseOperation { public: TextureAlphaOperation(); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; diff --git a/source/blender/compositor/operations/COM_TonemapOperation.h b/source/blender/compositor/operations/COM_TonemapOperation.h index e7ea4f039f2..005f0862443 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.h +++ b/source/blender/compositor/operations/COM_TonemapOperation.h @@ -26,9 +26,9 @@ #include "DNA_node_types.h" /** - * @brief temporarily storage during execution of Tonemap - * @ingroup operation - */ + * @brief temporarily storage during execution of Tonemap + * @ingroup operation + */ typedef struct AvgLogLum { float al; float auto_key; @@ -38,48 +38,48 @@ typedef struct AvgLogLum { } AvgLogLum; /** - * @brief base class of tonemap, implementing the simple tonemap - * @ingroup operation - */ + * @brief base class of tonemap, implementing the simple tonemap + * @ingroup operation + */ class TonemapOperation : public NodeOperation { protected: /** - * @brief Cached reference to the reader - */ - SocketReader * imageReader; + * @brief Cached reference to the reader + */ + SocketReader *imageReader; /** - * @brief settings of the Tonemap - */ - NodeTonemap * data; + * @brief settings of the Tonemap + */ + NodeTonemap *data; /** - * @brief temporarily cache of the execution storage - */ - AvgLogLum * cachedInstance; + * @brief temporarily cache of the execution storage + */ + AvgLogLum *cachedInstance; public: TonemapOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); void deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); - void setData(NodeTonemap *data) {this->data = data;} + void setData(NodeTonemap *data) { this->data = data; } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); @@ -87,17 +87,17 @@ public: }; /** - * @brief class of tonemap, implementing the photoreceptor tonemap - * most parts have already been done in TonemapOperation - * @ingroup operation - */ + * @brief class of tonemap, implementing the photoreceptor tonemap + * most parts have already been done in TonemapOperation + * @ingroup operation + */ class PhotoreceptorTonemapOperation : public TonemapOperation { public: /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); }; #endif diff --git a/source/blender/compositor/operations/COM_TranslateOperation.h b/source/blender/compositor/operations/COM_TranslateOperation.h index 63d6ee0d0b5..e512bd9318e 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.h +++ b/source/blender/compositor/operations/COM_TranslateOperation.h @@ -25,24 +25,24 @@ #include "COM_NodeOperation.h" -class TranslateOperation: public NodeOperation { +class TranslateOperation : public NodeOperation { private: SocketReader *inputOperation; - SocketReader*inputXOperation; - SocketReader*inputYOperation; + SocketReader *inputXOperation; + SocketReader *inputYOperation; float deltaX; float deltaY; float isDeltaSet; public: TranslateOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); void deinitExecution(); - float getDeltaX() {return this->deltaX;} - float getDeltaY() {return this->deltaY;} + float getDeltaX() { return this->deltaX; } + float getDeltaY() { return this->deltaY; } inline void ensureDelta() { if (!isDeltaSet) { diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h index 9c2c4b4bf68..ede8f0333b4 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h @@ -37,25 +37,25 @@ public: VariableSizeBokehBlurOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void setMaxBlur(int maxRadius) {this->maxBlur = maxRadius;} - - void setThreshold(float threshold) {this->threshold = threshold;} + void setMaxBlur(int maxRadius) { this->maxBlur = maxRadius; } + + void setThreshold(float threshold) { this->threshold = threshold; } }; diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.h b/source/blender/compositor/operations/COM_VectorBlurOperation.h index 2c45628726d..30821cdd8b2 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.h +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.h @@ -29,16 +29,16 @@ class VectorBlurOperation : public NodeOperation, public QualityStepHelper { private: /** - * @brief Cached reference to the inputProgram - */ - SocketReader * inputImageProgram; - SocketReader * inputSpeedProgram; - SocketReader * inputZProgram; + * @brief Cached reference to the inputProgram + */ + SocketReader *inputImageProgram; + SocketReader *inputSpeedProgram; + SocketReader *inputZProgram; /** - * @brief settings of the glare node. - */ - NodeBlurData * settings; + * @brief settings of the glare node. + */ + NodeBlurData *settings; float *cachedInstance; @@ -46,23 +46,23 @@ public: VectorBlurOperation(); /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); - void setVectorBlurSettings(NodeBlurData * settings) {this->settings = settings;} + void setVectorBlurSettings(NodeBlurData *settings) { this->settings = settings; } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); protected: diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.h b/source/blender/compositor/operations/COM_VectorCurveOperation.h index 759e265220f..41faee7acf6 100644 --- a/source/blender/compositor/operations/COM_VectorCurveOperation.h +++ b/source/blender/compositor/operations/COM_VectorCurveOperation.h @@ -28,25 +28,25 @@ class VectorCurveOperation : public CurveBaseOperation { private: /** - * Cached reference to the inputProgram - */ - SocketReader * inputProgram; + * Cached reference to the inputProgram + */ + SocketReader *inputProgram; public: VectorCurveOperation(); /** - * the inner loop of this program - */ - void executePixel(float *Vector, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *Vector, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); /** - * Initialize the execution - */ + * Initialize the execution + */ void initExecution(); /** - * Deinitialize the execution - */ + * Deinitialize the execution + */ void deinitExecution(); }; #endif diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.h b/source/blender/compositor/operations/COM_ViewerBaseOperation.h index 8864894f0ed..2aaa7d20966 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.h +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.h @@ -30,8 +30,8 @@ class ViewerBaseOperation : public NodeOperation { protected: float *outputBuffer; unsigned char *outputBufferDisplay; - Image * image; - ImageUser * imageUser; + Image *image; + ImageUser *imageUser; void *lock; bool active; float centerX; @@ -41,27 +41,27 @@ protected: bool doColorPredivide; public: - bool isOutputOperation(bool rendering) const {return isActiveViewerOutput();} + bool isOutputOperation(bool rendering) const { return isActiveViewerOutput(); } void initExecution(); void deinitExecution(); - void setImage(Image *image) {this->image = image;} - void setImageUser(ImageUser *imageUser) {this->imageUser = imageUser;} - const bool isActiveViewerOutput() const {return active;} - void setActive(bool active) {this->active = active;} - void setCenterX(float centerX) {this->centerX = centerX;} - void setCenterY(float centerY) {this->centerY = centerY;} - void setChunkOrder(OrderOfChunks tileOrder) {this->chunkOrder = tileOrder;} + void setImage(Image *image) { this->image = image; } + void setImageUser(ImageUser *imageUser) { this->imageUser = imageUser; } + const bool isActiveViewerOutput() const { return active; } + void setActive(bool active) { this->active = active; } + void setCenterX(float centerX) { this->centerX = centerX;} + void setCenterY(float centerY) { this->centerY = centerY;} + void setChunkOrder(OrderOfChunks tileOrder) { this->chunkOrder = tileOrder; } float getCenterX() { return this->centerX; } float getCenterY() { return this->centerY; } OrderOfChunks getChunkOrder() { return this->chunkOrder; } const CompositorPriority getRenderPriority() const; - void setColorManagement(bool doColorManagement) {this->doColorManagement = doColorManagement;} - void setColorPredivide(bool doColorPredivide) {this->doColorPredivide = doColorPredivide;} - bool isViewerOperation() {return true;} + void setColorManagement(bool doColorManagement) { this->doColorManagement = doColorManagement; } + void setColorPredivide(bool doColorPredivide) { this->doColorPredivide = doColorPredivide; } + bool isViewerOperation() { return true; } protected: ViewerBaseOperation(); - void updateImage(rcti*rect); + void updateImage(rcti *rect); private: void initImage(); diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h index 4ffae31c131..49ef5ad4bb7 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.h +++ b/source/blender/compositor/operations/COM_ViewerOperation.h @@ -34,7 +34,7 @@ private: public: ViewerOperation(); - void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers); void initExecution(); void deinitExecution(); }; diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h index fff3212b410..321eed7240a 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.h +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h @@ -27,24 +27,24 @@ #include "COM_MemoryProxy.h" #include "COM_SocketReader.h" /** - * @brief Operation to write to a tile - * @ingroup Operation - */ -class WriteBufferOperation: public NodeOperation { + * @brief Operation to write to a tile + * @ingroup Operation + */ +class WriteBufferOperation : public NodeOperation { MemoryProxy *memoryProxy; NodeOperation *input; public: WriteBufferOperation(); ~WriteBufferOperation(); - int isBufferOperation() {return true;} - MemoryProxy *getMemoryProxy() {return this->memoryProxy;} - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); - const bool isWriteBufferOperation() const {return true;} + int isBufferOperation() { return true; } + MemoryProxy *getMemoryProxy() { return this->memoryProxy; } + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); + const bool isWriteBufferOperation() const { return true; } - void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers); void initExecution(); void deinitExecution(); - void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers, MemoryBuffer* outputBuffer); + void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer **memoryBuffers, MemoryBuffer *outputBuffer); void readResolutionFromInputSocket(); }; diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.h b/source/blender/compositor/operations/COM_ZCombineOperation.h index f9de916fce0..56ad950a3aa 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.h +++ b/source/blender/compositor/operations/COM_ZCombineOperation.h @@ -26,9 +26,9 @@ /** - * this program converts an input colour to an output value. - * it assumes we are in sRGB colour space. - */ + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ class ZCombineOperation : public NodeOperation { protected: SocketReader *image1Reader; @@ -37,21 +37,21 @@ protected: SocketReader *depth2Reader; public: /** - * Default constructor - */ + * Default constructor + */ ZCombineOperation(); void initExecution(); void deinitExecution(); /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; -class ZCombineAlphaOperation: public ZCombineOperation { - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +class ZCombineAlphaOperation : public ZCombineOperation { + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); }; #endif From cc82653b728408d5e30524549a419fe20fa6a967 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 14 Jun 2012 01:32:45 +0000 Subject: [PATCH 291/360] Matched FogGlow with old implementation --- source/blender/compositor/CMakeLists.txt | 4 +- .../compositor/nodes/COM_GlareNode.cpp | 35 +- .../compositor/nodes/COM_VectorBlurNode.cpp | 4 - .../operations/COM_FogGlowImageOperation.cpp | 51 --- .../operations/COM_GlareFogGlowOperation.cpp | 405 ++++++++++++++++++ ...peration.h => COM_GlareFogGlowOperation.h} | 25 +- 6 files changed, 431 insertions(+), 93 deletions(-) delete mode 100644 source/blender/compositor/operations/COM_FogGlowImageOperation.cpp create mode 100644 source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp rename source/blender/compositor/operations/{COM_FogGlowImageOperation.h => COM_GlareFogGlowOperation.h} (65%) diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index bc2aeaefc83..20d110dd2a8 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -557,8 +557,6 @@ set(SRC operations/COM_ConvolutionEdgeFilterOperation.cpp operations/COM_DilateErodeOperation.cpp operations/COM_DilateErodeOperation.h - operations/COM_FogGlowImageOperation.cpp - operations/COM_FogGlowImageOperation.h operations/COM_GlareThresholdOperation.cpp operations/COM_GlareThresholdOperation.h operations/COM_GlareBaseOperation.cpp @@ -569,6 +567,8 @@ set(SRC operations/COM_GlareStreaksOperation.h operations/COM_GlareGhostOperation.cpp operations/COM_GlareGhostOperation.h + operations/COM_GlareFogGlowOperation.cpp + operations/COM_GlareFogGlowOperation.h operations/COM_SetSamplerOperation.cpp operations/COM_SetSamplerOperation.h diff --git a/source/blender/compositor/nodes/COM_GlareNode.cpp b/source/blender/compositor/nodes/COM_GlareNode.cpp index dc367040c9a..6e8e66c83ac 100644 --- a/source/blender/compositor/nodes/COM_GlareNode.cpp +++ b/source/blender/compositor/nodes/COM_GlareNode.cpp @@ -22,7 +22,6 @@ #include "COM_GlareNode.h" #include "DNA_node_types.h" -#include "COM_FogGlowImageOperation.h" #include "COM_GlareThresholdOperation.h" #include "COM_GlareSimpleStarOperation.h" #include "COM_GlareStreaksOperation.h" @@ -30,6 +29,7 @@ #include "COM_MixBlendOperation.h" #include "COM_FastGaussianBlurOperation.h" #include "COM_GlareGhostOperation.h" +#include "COM_GlareFogGlowOperation.h" GlareNode::GlareNode(bNode *editorNode): Node(editorNode) { @@ -95,34 +95,25 @@ void GlareNode::convertToOperations(ExecutionSystem *system, CompositorContext * case 1: // fog glow { GlareThresholdOperation *thresholdOperation = new GlareThresholdOperation(); - FastGaussianBlurOperation* bluroperation = new FastGaussianBlurOperation(); - SetValueOperation * valueoperation = new SetValueOperation(); + GlareFogGlowOperation * glareoperation = new GlareFogGlowOperation(); SetValueOperation * mixvalueoperation = new SetValueOperation(); MixBlendOperation * mixoperation = new MixBlendOperation(); - mixoperation->setResolutionInputSocketIndex(1); - this->getInputSocket(0)->relinkConnections(thresholdOperation->getInputSocket(0), 0, system); - addLink(system, thresholdOperation->getOutputSocket(), bluroperation->getInputSocket(0)); - addLink(system, valueoperation->getOutputSocket(), bluroperation->getInputSocket(1)); - addLink(system, mixvalueoperation->getOutputSocket(), mixoperation->getInputSocket(0)); - addLink(system, bluroperation->getOutputSocket(), mixoperation->getInputSocket(2)); - addLink(system, thresholdOperation->getInputSocket(0)->getConnection()->getFromSocket(), mixoperation->getInputSocket(1)); - thresholdOperation->setThreshold(glare->threshold); - NodeBlurData * data = new NodeBlurData(); - data->relative = 0; - data->sizex = glare->size; - data->sizey = glare->size; - bluroperation->setData(data); - bluroperation->deleteDataWhenFinished(); - bluroperation->setQuality(context->getQuality()); - valueoperation->setValue(1.0f); - mixvalueoperation->setValue(0.5f+glare->mix*0.5f); + this->getInputSocket(0)->relinkConnections(thresholdOperation->getInputSocket(0), 0, system); + addLink(system, thresholdOperation->getOutputSocket(), glareoperation->getInputSocket(0)); + addLink(system, mixvalueoperation->getOutputSocket(), mixoperation->getInputSocket(0)); + addLink(system, glareoperation->getOutputSocket(), mixoperation->getInputSocket(2)); + addLink(system, thresholdOperation->getInputSocket(0)->getConnection()->getFromSocket(), mixoperation->getInputSocket(1)); this->getOutputSocket()->relinkConnections(mixoperation->getOutputSocket()); - system->addOperation(bluroperation); + thresholdOperation->setThreshold(glare->threshold); + glareoperation->setGlareSettings(glare); + mixvalueoperation->setValue(0.5f+glare->mix*0.5f); + mixoperation->setResolutionInputSocketIndex(1); + + system->addOperation(glareoperation); system->addOperation(thresholdOperation); system->addOperation(mixvalueoperation); - system->addOperation(valueoperation); system->addOperation(mixoperation); } break; diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.cpp b/source/blender/compositor/nodes/COM_VectorBlurNode.cpp index 596256eb6af..98096c3de7b 100644 --- a/source/blender/compositor/nodes/COM_VectorBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_VectorBlurNode.cpp @@ -22,11 +22,7 @@ #include "COM_VectorBlurNode.h" #include "DNA_node_types.h" -#include "COM_FogGlowImageOperation.h" -#include "COM_BokehBlurOperation.h" #include "COM_VectorBlurOperation.h" -#include "COM_SetValueOperation.h" -#include "COM_MixBlendOperation.h" VectorBlurNode::VectorBlurNode(bNode *editorNode): Node(editorNode) { diff --git a/source/blender/compositor/operations/COM_FogGlowImageOperation.cpp b/source/blender/compositor/operations/COM_FogGlowImageOperation.cpp deleted file mode 100644 index 05a758aca7f..00000000000 --- a/source/blender/compositor/operations/COM_FogGlowImageOperation.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2011, Blender Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributor: - * Jeroen Bakker - * Monique Dewanchand - */ - -#include "COM_FogGlowImageOperation.h" -#include "BLI_math.h" - -FogGlowImageOperation::FogGlowImageOperation(): NodeOperation() -{ - this->addOutputSocket(COM_DT_COLOR); -} -void FogGlowImageOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) -{ - const float cs_r = 1.f, cs_g = 1.f, cs_b = 1.f; - - float u, v, w, d, r; - - v = 2.f*(y / (float)512) - 1.f; - u = 2.f*(x / (float)512) - 1.f; - r = (u*u + v*v)*256; - d = -sqrtf(sqrtf(sqrtf(r))); - w = (0.5f + 0.5f * cosf(u * (float)M_PI)) * (0.5f + 0.5f * cosf(v * (float)M_PI)); - color[0] = expf(d*cs_r) * w; - color[1] = expf(d*cs_g) * w; - color[2] = expf(d*cs_b) * w; - color[3] = 1.0f; -} - -void FogGlowImageOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) -{ - resolution[0] = 512; - resolution[1] = 512; -} diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp new file mode 100644 index 00000000000..4acc8aa17f0 --- /dev/null +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp @@ -0,0 +1,405 @@ +/* + * Copyright 2011, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_GlareFogGlowOperation.h" +#include "MEM_guardedalloc.h" + +/* + * 2D Fast Hartley Transform, used for convolution + */ + +typedef float fREAL; + +// returns next highest power of 2 of x, as well it's log2 in L2 +static unsigned int nextPow2(unsigned int x, unsigned int* L2) +{ + unsigned int pw, x_notpow2 = x & (x-1); + *L2 = 0; + while (x>>=1) ++(*L2); + pw = 1 << (*L2); + if (x_notpow2) { (*L2)++; pw<<=1; } + return pw; +} + +//------------------------------------------------------------------------------ + +// from FXT library by Joerg Arndt, faster in order bitreversal +// use: r = revbin_upd(r, h) where h = N>>1 +static unsigned int revbin_upd(unsigned int r, unsigned int h) +{ + while (!((r^=h)&h)) h >>= 1; + return r; +} +//------------------------------------------------------------------------------ +static void FHT(fREAL* data, unsigned int M, unsigned int inverse) +{ + double tt, fc, dc, fs, ds, a = M_PI; + fREAL t1, t2; + int n2, bd, bl, istep, k, len = 1 << M, n = 1; + + int i, j = 0; + unsigned int Nh = len >> 1; + for (i=1;i<(len-1);++i) { + j = revbin_upd(j, Nh); + if (j>i) { + t1 = data[i]; + data[i] = data[j]; + data[j] = t1; + } + } + + do { + fREAL* data_n = &data[n]; + + istep = n << 1; + for (k=0; k> 1; + if (n>2) { + fc = dc = cos(a); + fs = ds = sqrt(1.0 - fc*fc); //sin(a); + bd = n-2; + for (bl=1; bl1) { + for (k=n2; k log2 of width/height, + nzp -> the row where zero pad data starts, + inverse -> see above */ +static void FHT2D(fREAL *data, unsigned int Mx, unsigned int My, + unsigned int nzp, unsigned int inverse) +{ + unsigned int i, j, Nx, Ny, maxy; + fREAL t; + + Nx = 1 << Mx; + Ny = 1 << My; + + // rows (forward transform skips 0 pad data) + maxy = inverse ? Ny : nzp; + for (j=0; j0; i++) { + #define PRED(k) (((k & Nym) << Mx) + (k >> My)) + for (j=PRED(i); j>i; j=PRED(j)); + if (j < i) continue; + for (k=i, j=PRED(i); j!=i; k=j, j=PRED(j), stm--) { + t=data[j], data[j]=data[k], data[k]=t; + } + #undef PRED + stm--; + } + } + // swap Mx/My & Nx/Ny + i = Nx, Nx = Ny, Ny = i; + i = Mx, Mx = My, My = i; + + // now columns == transposed rows + for (j=0; j> 1); j++) { + unsigned int jm = (Ny - j) & (Ny-1); + unsigned int ji = j << Mx; + unsigned int jmi = jm << Mx; + for (i=0; i<=(Nx >> 1); i++) { + unsigned int im = (Nx - i) & (Nx-1); + fREAL A = data[ji + i]; + fREAL B = data[jmi + i]; + fREAL C = data[ji + im]; + fREAL D = data[jmi + im]; + fREAL E = (fREAL)0.5*((A + D) - (B + C)); + data[ji + i] = A - E; + data[jmi + i] = B + E; + data[ji + im] = C + E; + data[jmi + im] = D - E; + } + } + +} + +//------------------------------------------------------------------------------ + +/* 2D convolution calc, d1 *= d2, M/N - > log2 of width/height */ +static void fht_convolve(fREAL* d1, fREAL* d2, unsigned int M, unsigned int N) +{ + fREAL a, b; + unsigned int i, j, k, L, mj, mL; + unsigned int m = 1 << M, n = 1 << N; + unsigned int m2 = 1 << (M-1), n2 = 1 << (N-1); + unsigned int mn2 = m << (N-1); + + d1[0] *= d2[0]; + d1[mn2] *= d2[mn2]; + d1[m2] *= d2[m2]; + d1[m2 + mn2] *= d2[m2 + mn2]; + for (i=1; igetWidth(); + const unsigned int kernelHeight = in2->getHeight(); + const unsigned int imageWidth = in1->getWidth(); + const unsigned int imageHeight = in1->getHeight(); + float * kernelBuffer = in2->getBuffer(); + float * imageBuffer = in1->getBuffer(); + + MemoryBuffer* rdst = new MemoryBuffer(NULL, in1->getRect()); + + // convolution result width & height + w2 = 2*kernelWidth - 1; + h2 = 2*kernelHeight - 1; + // FFT pow2 required size & log2 + w2 = nextPow2(w2, &log2_w); + h2 = nextPow2(h2, &log2_h); + + // alloc space + data1 = (fREAL*)MEM_callocN(3*w2*h2*sizeof(fREAL), "convolve_fast FHT data1"); + data2 = (fREAL*)MEM_callocN(w2*h2*sizeof(fREAL), "convolve_fast FHT data2"); + + // normalize convolutor + wt[0] = wt[1] = wt[2] = 0.f; + for (y=0; y> 1; + hh = kernelHeight >> 1; + xbsz = (w2 + 1) - kernelWidth; + ybsz = (h2 + 1) - kernelHeight; + nxb = imageWidth / xbsz; + if (imageWidth % xbsz) nxb++; + nyb = imageHeight / ybsz; + if (imageHeight % ybsz) nyb++; + for (ybl=0; ybl data1 + for (y=0; y data2 + memset(data2, 0, w2*h2*sizeof(fREAL)); + for (y=0; y= kernelHeight) continue; + fp = &data2[y*w2]; + colp = (fRGB*)&imageBuffer[yy*imageWidth*COM_NUMBER_OF_CHANNELS]; + for (x=0; x= imageWidth) continue; + fp[x] = colp[xx][ch]; + } + } + + // forward FHT + // zero pad data start is different for each == height+1 + if (!in2done) FHT2D(data1ch, log2_w, log2_h, kernelHeight+1, 0); + FHT2D(data2, log2_w, log2_h, kernelHeight+1, 0); + + // FHT2D transposed data, row/col now swapped + // convolve & inverse FHT + fht_convolve(data2, data1ch, log2_h, log2_w); + FHT2D(data2, log2_h, log2_w, 0, 1); + // data again transposed, so in order again + + // overlap-add result + for (y=0; y<(int)h2; y++) { + const int yy = ybl*ybsz + y - hh; + if ((yy < 0) || (yy >= imageHeight)) continue; + fp = &data2[y*w2]; + colp = (fRGB*)&rdst->getBuffer()[yy*imageWidth*COM_NUMBER_OF_CHANNELS]; + for (x=0; x<(int)w2; x++) { + const int xx = xbl*xbsz + x - hw; + if ((xx < 0) || (xx >= imageWidth)) continue; + colp[xx][ch] += fp[x]; + } + } + + } + in2done = TRUE; + } + } + + MEM_freeN(data2); + MEM_freeN(data1); + memcpy(dst, rdst->getBuffer(), sizeof(float)*imageWidth*imageHeight*COM_NUMBER_OF_CHANNELS); + delete(rdst); +} + +void GlareFogGlowOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) +{ + int x, y; + float scale, u, v, r, w, d; + fRGB fcol; + MemoryBuffer *ckrn; + unsigned int sz = 1 << settings->size; + const float cs_r = 1.f, cs_g = 1.f, cs_b = 1.f; + + // temp. src image + // make the convolution kernel + rcti kernelRect; + BLI_init_rcti(&kernelRect, 0, sz, 0, sz); + ckrn = new MemoryBuffer(NULL, &kernelRect); + + scale = 0.25f*sqrtf(sz*sz); + + for (y=0; ywritePixel(x, y, fcol); + } + } + + convolve(data, inputTile, ckrn); + delete ckrn; +} diff --git a/source/blender/compositor/operations/COM_FogGlowImageOperation.h b/source/blender/compositor/operations/COM_GlareFogGlowOperation.h similarity index 65% rename from source/blender/compositor/operations/COM_FogGlowImageOperation.h rename to source/blender/compositor/operations/COM_GlareFogGlowOperation.h index 8330115718f..5737a6a1ff0 100644 --- a/source/blender/compositor/operations/COM_FogGlowImageOperation.h +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.h @@ -15,25 +15,22 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ -#ifndef _COM_FogGlowOperation_h -#define _COM_FogGlowOperation_h +#ifndef _COM_GlareFogGlowOperation_h +#define _COM_GlareFogGlowOperation_h #include "COM_NodeOperation.h" -#include "DNA_lamp_types.h" +#include "DNA_node_types.h" +#include "COM_GlareBaseOperation.h" -class FogGlowImageOperation : public NodeOperation { +class GlareFogGlowOperation : public GlareBaseOperation { public: - FogGlowImageOperation(); - - /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); - - void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + GlareFogGlowOperation() : GlareBaseOperation() { + } +protected: + void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings); }; #endif From fac417a3baf132e7d04540e1fbdefe7d3a1fa17b Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 14 Jun 2012 03:11:36 +0000 Subject: [PATCH 292/360] Fixed glares --- source/blender/compositor/CMakeLists.txt | 2 + .../compositor/intern/COM_MemoryBuffer.cpp | 10 ++ .../compositor/intern/COM_MemoryBuffer.h | 1 + .../compositor/nodes/COM_GlareNode.cpp | 125 +++++------------- .../operations/COM_GlareFogGlowOperation.cpp | 2 +- .../operations/COM_GlareGhostOperation.cpp | 2 +- .../COM_GlareThresholdOperation.cpp | 12 +- .../operations/COM_GlareThresholdOperation.h | 12 +- .../operations/COM_MixGlareOperation.cpp | 46 +++++++ .../operations/COM_MixGlareOperation.h | 45 +++++++ 10 files changed, 155 insertions(+), 102 deletions(-) create mode 100644 source/blender/compositor/operations/COM_MixGlareOperation.cpp create mode 100644 source/blender/compositor/operations/COM_MixGlareOperation.h diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 20d110dd2a8..aa428c2b8d0 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -461,6 +461,8 @@ set(SRC operations/COM_MixBaseOperation.cpp operations/COM_MixBlendOperation.cpp operations/COM_MixBlendOperation.h + operations/COM_MixGlareOperation.cpp + operations/COM_MixGlareOperation.h operations/COM_MixAddOperation.h operations/COM_MixAddOperation.cpp operations/COM_MixMultiplyOperation.h diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp index b88d42ea8d0..90f6d4a738d 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp @@ -141,6 +141,16 @@ void MemoryBuffer::writePixel(int x, int y, const float color[4]) } } +void MemoryBuffer::addPixel(int x, int y, const float color[4]) +{ + if (x >= this->rect.xmin && x < this->rect.xmax && + y >= this->rect.ymin && y < this->rect.ymax) + { + const int offset = (this->chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS; + add_v4_v4(&this->buffer[offset], color); + } +} + void MemoryBuffer::readCubic(float result[4], float x, float y) { int x1 = floor(x); diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h index dee2c9b771f..dd24a30e85e 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.h +++ b/source/blender/compositor/intern/COM_MemoryBuffer.h @@ -126,6 +126,7 @@ public: void read(float result[4], int x, int y); void writePixel(int x, int y, const float color[4]); + void addPixel(int x, int y, const float color[4]); void readCubic(float result[4], float x, float y); void readEWA(float result[4], float fx, float fy, float dx, float dy); diff --git a/source/blender/compositor/nodes/COM_GlareNode.cpp b/source/blender/compositor/nodes/COM_GlareNode.cpp index 6e8e66c83ac..dcb8f3a3a4c 100644 --- a/source/blender/compositor/nodes/COM_GlareNode.cpp +++ b/source/blender/compositor/nodes/COM_GlareNode.cpp @@ -26,7 +26,7 @@ #include "COM_GlareSimpleStarOperation.h" #include "COM_GlareStreaksOperation.h" #include "COM_SetValueOperation.h" -#include "COM_MixBlendOperation.h" +#include "COM_MixGlareOperation.h" #include "COM_FastGaussianBlurOperation.h" #include "COM_GlareGhostOperation.h" #include "COM_GlareFogGlowOperation.h" @@ -40,109 +40,44 @@ void GlareNode::convertToOperations(ExecutionSystem *system, CompositorContext * bNode *node = this->getbNode(); NodeGlare *glare = (NodeGlare*)node->storage; + GlareBaseOperation * glareoperation = NULL; + switch (glare->type) { default: case 3: - { - GlareThresholdOperation *thresholdOperation = new GlareThresholdOperation(); - GlareGhostOperation * glareoperation = new GlareGhostOperation(); - SetValueOperation * mixvalueoperation = new SetValueOperation(); - MixBlendOperation * mixoperation = new MixBlendOperation(); - - this->getInputSocket(0)->relinkConnections(thresholdOperation->getInputSocket(0), 0, system); - addLink(system, thresholdOperation->getOutputSocket(), glareoperation->getInputSocket(0)); - addLink(system, mixvalueoperation->getOutputSocket(), mixoperation->getInputSocket(0)); - addLink(system, glareoperation->getOutputSocket(), mixoperation->getInputSocket(2)); - addLink(system, thresholdOperation->getInputSocket(0)->getConnection()->getFromSocket(), mixoperation->getInputSocket(1)); - this->getOutputSocket()->relinkConnections(mixoperation->getOutputSocket()); - - thresholdOperation->setThreshold(glare->threshold); - glareoperation->setGlareSettings(glare); - mixvalueoperation->setValue(0.5f+glare->mix*0.5f); - mixoperation->setResolutionInputSocketIndex(1); - - system->addOperation(glareoperation); - system->addOperation(thresholdOperation); - system->addOperation(mixvalueoperation); - system->addOperation(mixoperation); - } + glareoperation = new GlareGhostOperation(); + break; case 2: // streaks - { - GlareThresholdOperation *thresholdOperation = new GlareThresholdOperation(); - GlareStreaksOperation * glareoperation = new GlareStreaksOperation(); - SetValueOperation * mixvalueoperation = new SetValueOperation(); - MixBlendOperation * mixoperation = new MixBlendOperation(); - - this->getInputSocket(0)->relinkConnections(thresholdOperation->getInputSocket(0), 0, system); - addLink(system, thresholdOperation->getOutputSocket(), glareoperation->getInputSocket(0)); - addLink(system, mixvalueoperation->getOutputSocket(), mixoperation->getInputSocket(0)); - addLink(system, glareoperation->getOutputSocket(), mixoperation->getInputSocket(2)); - addLink(system, thresholdOperation->getInputSocket(0)->getConnection()->getFromSocket(), mixoperation->getInputSocket(1)); - this->getOutputSocket()->relinkConnections(mixoperation->getOutputSocket()); - - thresholdOperation->setThreshold(glare->threshold); - glareoperation->setGlareSettings(glare); - mixvalueoperation->setValue(0.5f+glare->mix*0.5f); - mixoperation->setResolutionInputSocketIndex(1); - - system->addOperation(glareoperation); - system->addOperation(thresholdOperation); - system->addOperation(mixvalueoperation); - system->addOperation(mixoperation); - } + glareoperation = new GlareStreaksOperation(); break; case 1: // fog glow - { - GlareThresholdOperation *thresholdOperation = new GlareThresholdOperation(); - GlareFogGlowOperation * glareoperation = new GlareFogGlowOperation(); - SetValueOperation * mixvalueoperation = new SetValueOperation(); - MixBlendOperation * mixoperation = new MixBlendOperation(); - - this->getInputSocket(0)->relinkConnections(thresholdOperation->getInputSocket(0), 0, system); - addLink(system, thresholdOperation->getOutputSocket(), glareoperation->getInputSocket(0)); - addLink(system, mixvalueoperation->getOutputSocket(), mixoperation->getInputSocket(0)); - addLink(system, glareoperation->getOutputSocket(), mixoperation->getInputSocket(2)); - addLink(system, thresholdOperation->getInputSocket(0)->getConnection()->getFromSocket(), mixoperation->getInputSocket(1)); - this->getOutputSocket()->relinkConnections(mixoperation->getOutputSocket()); - - thresholdOperation->setThreshold(glare->threshold); - glareoperation->setGlareSettings(glare); - mixvalueoperation->setValue(0.5f+glare->mix*0.5f); - mixoperation->setResolutionInputSocketIndex(1); - - system->addOperation(glareoperation); - system->addOperation(thresholdOperation); - system->addOperation(mixvalueoperation); - system->addOperation(mixoperation); - } + glareoperation = new GlareFogGlowOperation(); break; - case 0: // simple star - { - GlareThresholdOperation *thresholdOperation = new GlareThresholdOperation(); - GlareSimpleStarOperation * glareoperation = new GlareSimpleStarOperation(); - SetValueOperation * mixvalueoperation = new SetValueOperation(); - MixBlendOperation * mixoperation = new MixBlendOperation(); - - this->getInputSocket(0)->relinkConnections(thresholdOperation->getInputSocket(0), 0, system); - addLink(system, thresholdOperation->getOutputSocket(), glareoperation->getInputSocket(0)); - addLink(system, mixvalueoperation->getOutputSocket(), mixoperation->getInputSocket(0)); - addLink(system, glareoperation->getOutputSocket(), mixoperation->getInputSocket(2)); - addLink(system, thresholdOperation->getInputSocket(0)->getConnection()->getFromSocket(), mixoperation->getInputSocket(1)); - this->getOutputSocket()->relinkConnections(mixoperation->getOutputSocket()); - - thresholdOperation->setThreshold(glare->threshold); - glareoperation->setGlareSettings(glare); - mixvalueoperation->setValue(0.5f+glare->mix*0.5f); - mixoperation->setResolutionInputSocketIndex(1); - - - system->addOperation(glareoperation); - system->addOperation(thresholdOperation); - system->addOperation(mixvalueoperation); - system->addOperation(mixoperation); - } + glareoperation = new GlareSimpleStarOperation(); break; } + GlareThresholdOperation *thresholdOperation = new GlareThresholdOperation(); + SetValueOperation * mixvalueoperation = new SetValueOperation(); + MixGlareOperation * mixoperation = new MixGlareOperation(); + mixoperation->getInputSocket(2)->setResizeMode(COM_SC_FIT); + + this->getInputSocket(0)->relinkConnections(thresholdOperation->getInputSocket(0), 0, system); + addLink(system, thresholdOperation->getOutputSocket(), glareoperation->getInputSocket(0)); + addLink(system, mixvalueoperation->getOutputSocket(), mixoperation->getInputSocket(0)); + addLink(system, glareoperation->getOutputSocket(), mixoperation->getInputSocket(2)); + addLink(system, thresholdOperation->getInputSocket(0)->getConnection()->getFromSocket(), mixoperation->getInputSocket(1)); + this->getOutputSocket()->relinkConnections(mixoperation->getOutputSocket()); + + thresholdOperation->setGlareSettings(glare); + glareoperation->setGlareSettings(glare); + mixvalueoperation->setValue(0.5f+glare->mix*0.5f); + mixoperation->setResolutionInputSocketIndex(1); + + system->addOperation(glareoperation); + system->addOperation(thresholdOperation); + system->addOperation(mixvalueoperation); + system->addOperation(mixoperation); + } diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp index 4acc8aa17f0..1bdbdf71bdc 100644 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp @@ -322,7 +322,7 @@ void convolve(float* dst, MemoryBuffer* in1, MemoryBuffer* in2) memset(data2, 0, w2*h2*sizeof(fREAL)); for (y=0; y= kernelHeight) continue; + if (yy >= imageHeight) continue; fp = &data2[y*w2]; colp = (fRGB*)&imageBuffer[yy*imageWidth*COM_NUMBER_OF_CHANNELS]; for (x=0; xwritePixel(x, y, tc); + tbuf1->addPixel(x, y, tc); } if (isBreaked()) breaked = true; } diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp index ea76e7551ad..f9b2ec2b32d 100644 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp @@ -25,10 +25,18 @@ GlareThresholdOperation::GlareThresholdOperation() : NodeOperation() { - this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR, COM_SC_FIT); this->addOutputSocket(COM_DT_COLOR); this->inputProgram = NULL; } + +void GlareThresholdOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) +{ + NodeOperation::determineResolution(resolution, preferredResolution); + resolution[0] = resolution[0] / (1 << settings->quality); + resolution[1] = resolution[1] / (1 << settings->quality); +} + void GlareThresholdOperation::initExecution() { this->inputProgram = this->getInputSocketReader(0); @@ -36,6 +44,8 @@ void GlareThresholdOperation::initExecution() void GlareThresholdOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + const float threshold = settings->threshold; + this->inputProgram->read(color, x, y, sampler, inputBuffers); if (rgb_to_luma_y(color) >= threshold) { color[0] -= threshold, color[1] -= threshold, color[2] -= threshold; diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.h b/source/blender/compositor/operations/COM_GlareThresholdOperation.h index d5ec8ba93a6..70692565e27 100644 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.h +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.h @@ -32,8 +32,10 @@ private: */ SocketReader *inputProgram; - float threshold; - + /** + * @brief settings of the glare node. + */ + NodeGlare *settings; public: GlareThresholdOperation(); @@ -52,8 +54,10 @@ public: */ void deinitExecution(); - void setThreshold(float threshold) { - this->threshold = threshold; + void setGlareSettings(NodeGlare *settings) { + this->settings = settings; } + + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); }; #endif diff --git a/source/blender/compositor/operations/COM_MixGlareOperation.cpp b/source/blender/compositor/operations/COM_MixGlareOperation.cpp new file mode 100644 index 00000000000..229fc1e5313 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixGlareOperation.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2011, Glareer Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixGlareOperation.h" + +MixGlareOperation::MixGlareOperation(): MixBaseOperation() +{ +} + +void MixGlareOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +{ + float inputColor1[4]; + float inputColor2[4]; + float inputValue[4]; + float value; + + inputValueOperation->read(inputValue, x, y, sampler, inputBuffers); + inputColor1Operation->read(inputColor1, x, y, sampler, inputBuffers); + inputColor2Operation->read(inputColor2, x, y, sampler, inputBuffers); + value = inputValue[0]; + float mf = 2.f - 2.f*fabsf(value - 0.5f); + + outputValue[0] = mf*((inputColor1[0])+value*(inputColor2[0]-inputColor1[0])); + outputValue[1] = mf*((inputColor1[1])+value*(inputColor2[1]-inputColor1[1])); + outputValue[2] = mf*((inputColor1[2])+value*(inputColor2[2]-inputColor1[2])); + outputValue[3] = inputColor1[3]; +} diff --git a/source/blender/compositor/operations/COM_MixGlareOperation.h b/source/blender/compositor/operations/COM_MixGlareOperation.h new file mode 100644 index 00000000000..1a025eb3edd --- /dev/null +++ b/source/blender/compositor/operations/COM_MixGlareOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Glareer Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixGlareOperation_h +#define _COM_MixGlareOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixGlareOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixGlareOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); + +}; +#endif From cae6873bc69ab8590ca6f4d2bbf2eb3d189ab13a Mon Sep 17 00:00:00 2001 From: Dan Eicher Date: Thu, 14 Jun 2012 04:57:42 +0000 Subject: [PATCH 293/360] Sequencer Drag & Drop -- disallow dropping on sequences for the current drop_poll functions --- .../editors/space_sequencer/space_sequencer.c | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index dbfc554007a..b8bf764fabc 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -325,27 +325,43 @@ static void sequencer_main_area_draw(const bContext *C, ARegion *ar) /* ************* dropboxes ************* */ -static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) +static int image_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) { + ARegion *ar = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + int hand; + if (drag->type == WM_DRAG_PATH) if (ELEM(drag->icon, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */ - return 1; + if (find_nearest_seq(scene, &ar->v2d, &hand, event->mval) == NULL) + return 1; + return 0; } -static int movie_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) +static int movie_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) { + ARegion *ar = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + int hand; + if (drag->type == WM_DRAG_PATH) if (ELEM3(drag->icon, 0, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */ - return 1; + if (find_nearest_seq(scene, &ar->v2d, &hand, event->mval) == NULL) + return 1; return 0; } -static int sound_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) +static int sound_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) { + ARegion *ar = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + int hand; + if (drag->type == WM_DRAG_PATH) if (ELEM(drag->icon, ICON_FILE_SOUND, ICON_FILE_BLANK)) /* rule might not work? */ - return 1; + if (find_nearest_seq(scene, &ar->v2d, &hand, event->mval) == NULL) + return 1; return 0; } From c07c57237398fbd214c329f2be0d88cc255e26eb Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Thu, 14 Jun 2012 08:01:20 +0000 Subject: [PATCH 294/360] Fix for [#31813] "bge.types.KX_RadarSensor incorrect attributes" reported by Monster. KX_RadarSensor.angle was returning the angle that was used to construct Bullet's physics shape, which is calculated from the logic brick gui. KX_RadarSensor.angle now recalculates the original value from the gui. However, m_coneradius isn't actually used by KX_RadarSensor that I can see, so it might be better to just assign the original angle to m_coneradius instead of the calculated value. I've also made KX_RadarSensor.angle read-only, since setting m_coneradius does not appear to have any affect, which means writing to KX_RadarSensor.angle never worked properly. --- doc/python_api/rst/bge.types.rst | 2 +- source/gameengine/Ketsji/KX_RadarSensor.cpp | 12 +++++++++++- source/gameengine/Ketsji/KX_RadarSensor.h | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst index bcef816dc9d..1d9f84fbcac 100644 --- a/doc/python_api/rst/bge.types.rst +++ b/doc/python_api/rst/bge.types.rst @@ -2692,7 +2692,7 @@ Game Types (bge.types) The angle of the cone (in degrees) with which to test. - :type: float from 0 to 360 + :type: float .. attribute:: axis diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index 678794f2beb..978944c20e8 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -212,9 +212,19 @@ PyAttributeDef KX_RadarSensor::Attributes[] = { KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneOrigin", KX_RadarSensor, m_cone_origin, 3), KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneTarget", KX_RadarSensor, m_cone_target, 3), KX_PYATTRIBUTE_FLOAT_RO("distance", KX_RadarSensor, m_coneheight), - KX_PYATTRIBUTE_FLOAT_RW("angle", 0, 360, KX_RadarSensor, m_coneradius), + KX_PYATTRIBUTE_RO_FUNCTION("angle", KX_RadarSensor, pyattr_get_angle), KX_PYATTRIBUTE_INT_RW("axis", 0, 5, true, KX_RadarSensor, m_axis), {NULL} //Sentinel }; +PyObject* KX_RadarSensor::pyattr_get_angle(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_RadarSensor* self= static_cast(self_v); + + // The original angle from the gui was converted, so we recalculate the value here to maintain + // consistency between Python and the gui + return PyFloat_FromDouble(MT_degrees(atan(self->m_coneradius / self->m_coneheight)) * 2); + +} + #endif // WITH_PYTHON diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index 903413ca89b..f1ed5b3c982 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -93,6 +93,7 @@ public: /* python */ virtual sensortype GetSensorType() { return ST_RADAR; } + static PyObject* pyattr_get_angle(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); }; #endif //__KX_RADARSENSOR_H__ From 418451fa034209eaed25e49cf7f97e07df2e09d7 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Thu, 14 Jun 2012 08:02:45 +0000 Subject: [PATCH 295/360] KX_RadarSensor.getConeHeight() not longer exists, removing it from the docs. --- doc/python_api/rst/bge.types.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst index 1d9f84fbcac..ff85df1f68b 100644 --- a/doc/python_api/rst/bge.types.rst +++ b/doc/python_api/rst/bge.types.rst @@ -2703,11 +2703,6 @@ Game Types (bge.types) KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z, KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z - .. method:: getConeHeight() - - :return: The height of the cone with which to test. - :rtype: float - .. class:: KX_RaySensor(SCA_ISensor) A ray sensor detects the first object in a given direction. From e8d48b187b83acb6fad6fbb244bbf8c8bbe51e89 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 14 Jun 2012 08:53:37 +0000 Subject: [PATCH 296/360] Compositor Compile Fix (Windows): * sqrtf only takes floats as arguments. --- .../blender/compositor/operations/COM_GlareFogGlowOperation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp index 1bdbdf71bdc..aa847c2d10d 100644 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp @@ -382,7 +382,7 @@ void GlareFogGlowOperation::generateGlare(float *data, MemoryBuffer *inputTile, BLI_init_rcti(&kernelRect, 0, sz, 0, sz); ckrn = new MemoryBuffer(NULL, &kernelRect); - scale = 0.25f*sqrtf(sz*sz); + scale = 0.25f*sqrtf((float)sz*sz); for (y=0; y Date: Thu, 14 Jun 2012 08:58:23 +0000 Subject: [PATCH 297/360] Cyles UI: * Alignment fix for the "Samples" panel, this way both columns are aligned nicely. --- intern/cycles/blender/addon/ui.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 6f2b33b2815..bda8249c17e 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -57,7 +57,7 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel): split = layout.split() col = split.column() - sub = col.column(align=True) + sub = col.column() sub.active = cscene.device == 'CPU' sub.prop(cscene, "progressive") @@ -66,23 +66,24 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel): sub.prop(cscene, "sample_clamp") if cscene.progressive or cscene.device != 'CPU': - col = split.column(align=True) + col = split.column() col.label(text="Samples:") - col.prop(cscene, "samples", text="Render") - col.prop(cscene, "preview_samples", text="Preview") - else: sub = col.column(align=True) + sub.prop(cscene, "samples", text="Render") + sub.prop(cscene, "preview_samples", text="Preview") + else: sub.label(text="AA Samples:") sub.prop(cscene, "aa_samples", text="Render") sub.prop(cscene, "preview_aa_samples", text="Preview") - col = split.column(align=True) + col = split.column() col.label(text="Samples:") - col.prop(cscene, "diffuse_samples", text="Diffuse") - col.prop(cscene, "glossy_samples", text="Glossy") - col.prop(cscene, "transmission_samples", text="Transmission") - col.prop(cscene, "ao_samples", text="AO") - col.prop(cscene, "mesh_light_samples", text="Mesh Light") + sub = col.column(align=True) + sub.prop(cscene, "diffuse_samples", text="Diffuse") + sub.prop(cscene, "glossy_samples", text="Glossy") + sub.prop(cscene, "transmission_samples", text="Transmission") + sub.prop(cscene, "ao_samples", text="AO") + sub.prop(cscene, "mesh_light_samples", text="Mesh Light") class CyclesRender_PT_light_paths(CyclesButtonsPanel, Panel): bl_label = "Light Paths" From ee65cd7685f3a2334bf47dbfeff5f0d576e082fd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 09:40:36 +0000 Subject: [PATCH 298/360] style cleanup --- .../operations/COM_GlareFogGlowOperation.cpp | 254 +++++++++--------- 1 file changed, 127 insertions(+), 127 deletions(-) diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp index aa847c2d10d..0c2ae96aa51 100644 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp @@ -30,13 +30,13 @@ typedef float fREAL; // returns next highest power of 2 of x, as well it's log2 in L2 -static unsigned int nextPow2(unsigned int x, unsigned int* L2) +static unsigned int nextPow2(unsigned int x, unsigned int *L2) { - unsigned int pw, x_notpow2 = x & (x-1); + unsigned int pw, x_notpow2 = x & (x - 1); *L2 = 0; - while (x>>=1) ++(*L2); + while (x >>= 1) ++(*L2); pw = 1 << (*L2); - if (x_notpow2) { (*L2)++; pw<<=1; } + if (x_notpow2) { (*L2)++; pw <<= 1; } return pw; } @@ -46,11 +46,11 @@ static unsigned int nextPow2(unsigned int x, unsigned int* L2) // use: r = revbin_upd(r, h) where h = N>>1 static unsigned int revbin_upd(unsigned int r, unsigned int h) { - while (!((r^=h)&h)) h >>= 1; + while (!((r ^= h) & h)) h >>= 1; return r; } //------------------------------------------------------------------------------ -static void FHT(fREAL* data, unsigned int M, unsigned int inverse) +static void FHT(fREAL *data, unsigned int M, unsigned int inverse) { double tt, fc, dc, fs, ds, a = M_PI; fREAL t1, t2; @@ -58,9 +58,9 @@ static void FHT(fREAL* data, unsigned int M, unsigned int inverse) int i, j = 0; unsigned int Nh = len >> 1; - for (i=1;i<(len-1);++i) { + for (i = 1; i < (len - 1); ++i) { j = revbin_upd(j, Nh); - if (j>i) { + if (j > i) { t1 = data[i]; data[i] = data[j]; data[j] = t1; @@ -68,40 +68,40 @@ static void FHT(fREAL* data, unsigned int M, unsigned int inverse) } do { - fREAL* data_n = &data[n]; + fREAL *data_n = &data[n]; istep = n << 1; - for (k=0; k> 1; - if (n>2) { + if (n > 2) { fc = dc = cos(a); - fs = ds = sqrt(1.0 - fc*fc); //sin(a); - bd = n-2; - for (bl=1; bl1) { - for (k=n2; k 1) { + for (k = n2; k < len; k += istep) { t1 = data_n[k]; data_n[k] = data[k] - t1; data[k] += t1; @@ -110,20 +110,20 @@ static void FHT(fREAL* data, unsigned int M, unsigned int inverse) n = istep; a *= 0.5; - } while (n log2 of width/height, - nzp -> the row where zero pad data starts, - inverse -> see above */ + nzp -> the row where zero pad data starts, + inverse -> see above */ static void FHT2D(fREAL *data, unsigned int Mx, unsigned int My, - unsigned int nzp, unsigned int inverse) + unsigned int nzp, unsigned int inverse) { unsigned int i, j, Nx, Ny, maxy; fREAL t; @@ -133,25 +133,25 @@ static void FHT2D(fREAL *data, unsigned int Mx, unsigned int My, // rows (forward transform skips 0 pad data) maxy = inverse ? Ny : nzp; - for (j=0; j0; i++) { + unsigned int k, Nym = Ny - 1, stm = 1 << (Mx + My); + for (i = 0; stm > 0; i++) { #define PRED(k) (((k & Nym) << Mx) + (k >> My)) - for (j=PRED(i); j>i; j=PRED(j)); + for (j = PRED(i); j > i; j = PRED(j)) ; if (j < i) continue; - for (k=i, j=PRED(i); j!=i; k=j, j=PRED(j), stm--) { - t=data[j], data[j]=data[k], data[k]=t; + for (k = i, j = PRED(i); j != i; k = j, j = PRED(j), stm--) { + t = data[j], data[j] = data[k], data[k] = t; } #undef PRED stm--; @@ -162,21 +162,21 @@ static void FHT2D(fREAL *data, unsigned int Mx, unsigned int My, i = Mx, Mx = My, My = i; // now columns == transposed rows - for (j=0; j> 1); j++) { - unsigned int jm = (Ny - j) & (Ny-1); + for (j = 0; j <= (Ny >> 1); j++) { + unsigned int jm = (Ny - j) & (Ny - 1); unsigned int ji = j << Mx; unsigned int jmi = jm << Mx; - for (i=0; i<=(Nx >> 1); i++) { - unsigned int im = (Nx - i) & (Nx-1); + for (i = 0; i <= (Nx >> 1); i++) { + unsigned int im = (Nx - i) & (Nx - 1); fREAL A = data[ji + i]; fREAL B = data[jmi + i]; fREAL C = data[ji + im]; fREAL D = data[jmi + im]; - fREAL E = (fREAL)0.5*((A + D) - (B + C)); + fREAL E = (fREAL)0.5 * ((A + D) - (B + C)); data[ji + i] = A - E; data[jmi + i] = B + E; data[ji + im] = C + E; @@ -189,62 +189,62 @@ static void FHT2D(fREAL *data, unsigned int Mx, unsigned int My, //------------------------------------------------------------------------------ /* 2D convolution calc, d1 *= d2, M/N - > log2 of width/height */ -static void fht_convolve(fREAL* d1, fREAL* d2, unsigned int M, unsigned int N) +static void fht_convolve(fREAL *d1, fREAL *d2, unsigned int M, unsigned int N) { fREAL a, b; unsigned int i, j, k, L, mj, mL; unsigned int m = 1 << M, n = 1 << N; - unsigned int m2 = 1 << (M-1), n2 = 1 << (N-1); - unsigned int mn2 = m << (N-1); + unsigned int m2 = 1 << (M - 1), n2 = 1 << (N - 1); + unsigned int mn2 = m << (N - 1); d1[0] *= d2[0]; d1[mn2] *= d2[mn2]; d1[m2] *= d2[m2]; d1[m2 + mn2] *= d2[m2 + mn2]; - for (i=1; igetHeight(); const unsigned int imageWidth = in1->getWidth(); const unsigned int imageHeight = in1->getHeight(); - float * kernelBuffer = in2->getBuffer(); - float * imageBuffer = in1->getBuffer(); + float *kernelBuffer = in2->getBuffer(); + float *imageBuffer = in1->getBuffer(); - MemoryBuffer* rdst = new MemoryBuffer(NULL, in1->getRect()); + MemoryBuffer *rdst = new MemoryBuffer(NULL, in1->getRect()); // convolution result width & height - w2 = 2*kernelWidth - 1; - h2 = 2*kernelHeight - 1; + w2 = 2 * kernelWidth - 1; + h2 = 2 * kernelHeight - 1; // FFT pow2 required size & log2 w2 = nextPow2(w2, &log2_w); h2 = nextPow2(h2, &log2_h); // alloc space - data1 = (fREAL*)MEM_callocN(3*w2*h2*sizeof(fREAL), "convolve_fast FHT data1"); - data2 = (fREAL*)MEM_callocN(w2*h2*sizeof(fREAL), "convolve_fast FHT data2"); + data1 = (fREAL *)MEM_callocN(3 * w2 * h2 * sizeof(fREAL), "convolve_fast FHT data1"); + data2 = (fREAL *)MEM_callocN(w2 * h2 * sizeof(fREAL), "convolve_fast FHT data2"); // normalize convolutor wt[0] = wt[1] = wt[2] = 0.f; - for (y=0; y data1 - for (y=0; y data2 - memset(data2, 0, w2*h2*sizeof(fREAL)); - for (y=0; y= imageHeight) continue; - fp = &data2[y*w2]; - colp = (fRGB*)&imageBuffer[yy*imageWidth*COM_NUMBER_OF_CHANNELS]; - for (x=0; x= imageWidth) continue; fp[x] = colp[xx][ch]; } @@ -334,8 +334,8 @@ void convolve(float* dst, MemoryBuffer* in1, MemoryBuffer* in2) // forward FHT // zero pad data start is different for each == height+1 - if (!in2done) FHT2D(data1ch, log2_w, log2_h, kernelHeight+1, 0); - FHT2D(data2, log2_w, log2_h, kernelHeight+1, 0); + if (!in2done) FHT2D(data1ch, log2_w, log2_h, kernelHeight + 1, 0); + FHT2D(data2, log2_w, log2_h, kernelHeight + 1, 0); // FHT2D transposed data, row/col now swapped // convolve & inverse FHT @@ -344,13 +344,13 @@ void convolve(float* dst, MemoryBuffer* in1, MemoryBuffer* in2) // data again transposed, so in order again // overlap-add result - for (y=0; y<(int)h2; y++) { - const int yy = ybl*ybsz + y - hh; + for (y = 0; y < (int)h2; y++) { + const int yy = ybl * ybsz + y - hh; if ((yy < 0) || (yy >= imageHeight)) continue; - fp = &data2[y*w2]; - colp = (fRGB*)&rdst->getBuffer()[yy*imageWidth*COM_NUMBER_OF_CHANNELS]; - for (x=0; x<(int)w2; x++) { - const int xx = xbl*xbsz + x - hw; + fp = &data2[y * w2]; + colp = (fRGB *)&rdst->getBuffer()[yy * imageWidth * COM_NUMBER_OF_CHANNELS]; + for (x = 0; x < (int)w2; x++) { + const int xx = xbl * xbsz + x - hw; if ((xx < 0) || (xx >= imageWidth)) continue; colp[xx][ch] += fp[x]; } @@ -363,7 +363,7 @@ void convolve(float* dst, MemoryBuffer* in1, MemoryBuffer* in2) MEM_freeN(data2); MEM_freeN(data1); - memcpy(dst, rdst->getBuffer(), sizeof(float)*imageWidth*imageHeight*COM_NUMBER_OF_CHANNELS); + memcpy(dst, rdst->getBuffer(), sizeof(float) * imageWidth * imageHeight * COM_NUMBER_OF_CHANNELS); delete(rdst); } @@ -382,19 +382,19 @@ void GlareFogGlowOperation::generateGlare(float *data, MemoryBuffer *inputTile, BLI_init_rcti(&kernelRect, 0, sz, 0, sz); ckrn = new MemoryBuffer(NULL, &kernelRect); - scale = 0.25f*sqrtf((float)sz*sz); + scale = 0.25f * sqrtf((float)sz * sz); - for (y=0; ywritePixel(x, y, fcol); } From 8ebec02df6e58fe02bd33c236601a3209f9818cd Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 14 Jun 2012 09:41:41 +0000 Subject: [PATCH 299/360] Removed the actual data type concept as it was never used. --- source/blender/compositor/COM_defines.h | 6 +- .../compositor/intern/COM_Converter.cpp | 4 +- .../compositor/intern/COM_ExecutionSystem.cpp | 26 +------ .../intern/COM_ExecutionSystemHelper.cpp | 15 +--- .../compositor/intern/COM_InputSocket.cpp | 78 +------------------ .../compositor/intern/COM_InputSocket.h | 15 ---- .../compositor/intern/COM_NodeBase.cpp | 52 ------------- .../blender/compositor/intern/COM_NodeBase.h | 28 ------- .../compositor/intern/COM_OutputSocket.cpp | 57 -------------- .../compositor/intern/COM_OutputSocket.h | 24 +----- .../blender/compositor/intern/COM_Socket.cpp | 7 -- source/blender/compositor/intern/COM_Socket.h | 22 +----- .../blender/compositor/nodes/COM_MuteNode.cpp | 3 - .../compositor/nodes/COM_OutputFileNode.cpp | 2 +- .../compositor/nodes/COM_SocketProxyNode.cpp | 7 +- .../compositor/nodes/COM_SwitchNode.cpp | 2 +- .../operations/COM_SocketProxyOperation.cpp | 6 +- .../operations/COM_SocketProxyOperation.h | 2 +- 18 files changed, 20 insertions(+), 336 deletions(-) diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h index d072b4ca727..42015035f73 100644 --- a/source/blender/compositor/COM_defines.h +++ b/source/blender/compositor/COM_defines.h @@ -28,8 +28,6 @@ * @ingroup Model */ typedef enum DataType { - /** @brief Unknown data type (or not yet known) */ - COM_DT_UNKNOWN = 0, /** @brief Value data type */ COM_DT_VALUE = 1, /** @brief Vector data type */ @@ -69,8 +67,8 @@ typedef enum CompositorPriority { // chunk size determination #define COM_PREVIEW_SIZE 140.0f -//#define COM_OPENCL_ENABLED -//#define COM_DEBUG +#define COM_OPENCL_ENABLED +#define COM_DEBUG // workscheduler threading models /** diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index dc6409e7b86..f4bb89969ff 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -362,8 +362,8 @@ void Converter::convertDataType(SocketConnection *connection, ExecutionSystem *s { OutputSocket *outputSocket = connection->getFromSocket(); InputSocket *inputSocket = connection->getToSocket(); - DataType fromDatatype = outputSocket->getActualDataType(); - DataType toDatatype = inputSocket->getActualDataType(); + DataType fromDatatype = outputSocket->getDataType(); + DataType toDatatype = inputSocket->getDataType(); NodeOperation * converter = NULL; if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_COLOR) { converter = new ConvertValueToColourProg(); diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 9681996c74d..b84e9d0d3f7 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -229,19 +229,15 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) void ExecutionSystem::convertToOperations() { unsigned int index; - // first determine data types of the nodes, this can be used by the node to convert to a different operation system - this->determineActualSocketDataTypes((vector&)this->nodes); for (index = 0; index < this->nodes.size(); index++) { Node *node = (Node*)this->nodes[index]; node->convertToOperations(this, &this->context); } - // update the socket types of the operations. this will be used to add conversion operations in the system - this->determineActualSocketDataTypes((vector&)this->operations); for (index = 0 ; index < this->connections.size(); index ++) { SocketConnection *connection = this->connections[index]; if (connection->isValid()) { - if (connection->getFromSocket()->getActualDataType() != connection->getToSocket()->getActualDataType()) { + if (connection->getFromSocket()->getDataType() != connection->getToSocket()->getDataType()) { Converter::convertDataType(connection, this); } } @@ -307,26 +303,6 @@ void ExecutionSystem::addSocketConnection(SocketConnection *connection) } -void ExecutionSystem::determineActualSocketDataTypes(vector &nodes) -{ - unsigned int index; - /* first do all input nodes */ - for (index = 0; index < nodes.size(); index++) { - NodeBase *node = nodes[index]; - if (node->isInputNode()) { - node->determineActualSocketDataTypes(); - } - } - - /* then all other nodes */ - for (index = 0; index < nodes.size(); index++) { - NodeBase *node = nodes[index]; - if (!node->isInputNode()) { - node->determineActualSocketDataTypes(); - } - } -} - void ExecutionSystem::findOutputExecutionGroup(vector *result, CompositorPriority priority) const { unsigned int index; diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp index d5ca2ec619a..2d889e269e0 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp @@ -218,7 +218,7 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) printf("|"); } printf("", socket); - switch (socket->getActualDataType()) { + switch (socket->getDataType()) { case COM_DT_VALUE: printf("Value"); break; @@ -228,9 +228,6 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) case COM_DT_COLOR: printf("Color"); break; - case COM_DT_UNKNOWN: - printf("Unknown"); - break; } } printf("}"); @@ -270,7 +267,7 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) printf("|"); } printf("", socket); - switch (socket->getActualDataType()) { + switch (socket->getDataType()) { case COM_DT_VALUE: printf("Value"); break; @@ -280,9 +277,6 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) case COM_DT_COLOR: printf("Color"); break; - case COM_DT_UNKNOWN: - printf("Unknown"); - break; } } printf("}"); @@ -317,7 +311,7 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) printf(" [color=red]"); } else { - switch (connection->getFromSocket()->getActualDataType()) { + switch (connection->getFromSocket()->getDataType()) { case COM_DT_VALUE: printf(" [color=grey]"); break; @@ -327,9 +321,6 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) case COM_DT_COLOR: printf(" [color=orange]"); break; - case COM_DT_UNKNOWN: - printf(" [color=black]"); - break; } } printf("\r\n"); diff --git a/source/blender/compositor/intern/COM_InputSocket.cpp b/source/blender/compositor/intern/COM_InputSocket.cpp index 4d96d077901..c9705ad69fb 100644 --- a/source/blender/compositor/intern/COM_InputSocket.cpp +++ b/source/blender/compositor/intern/COM_InputSocket.cpp @@ -64,68 +64,6 @@ void InputSocket::determineResolution(unsigned int resolution[],unsigned int pre } } -DataType InputSocket::convertToSupportedDataType(DataType datatype) -{ - int supportedDataTypes = getDataType(); - if (supportedDataTypes&datatype) { - return datatype; - } - bool candoValue = supportedDataTypes&COM_DT_VALUE; - bool candoVector = supportedDataTypes&COM_DT_VECTOR; - bool candoColor = supportedDataTypes&COM_DT_COLOR; - - if (datatype == COM_DT_VALUE) { - if (candoColor) { - return COM_DT_COLOR; - } - else if (candoVector) { - return COM_DT_VECTOR; - } - } - else if (datatype == COM_DT_VECTOR) { - if (candoColor) { - return COM_DT_COLOR; - } - else if (candoValue) { - return COM_DT_VALUE; - } - } - else if (datatype == COM_DT_COLOR) { - if (candoVector) { - return COM_DT_VECTOR; - } - else if (candoValue) { - return COM_DT_VALUE; - } - } - return this->getDataType(); -} - -void InputSocket::determineActualDataType() -{ - /// @note: this method is only called for inputsocket that are not connected. - /// @note: passes COM_DT_COLOR, the convertToSupportedDataType converts this to a capable DataType - this->setActualDataType(this->convertToSupportedDataType(COM_DT_COLOR)); - #if 0 // XXX TODO check for proxy node and use output data type? - if (this->getGroupOutputSocket()) { - if (!this->isInsideOfGroupNode()) { - this->getGroupOutputSocket()->determineActualDataType(); - } - } - #endif -} - -void InputSocket::notifyActualInputType(DataType datatype) -{ - DataType supportedDataType = convertToSupportedDataType(datatype); - this->setActualDataType(supportedDataType); - this->fireActualDataTypeSet(); -} - -void InputSocket::fireActualDataTypeSet() -{ - this->getNode()->notifyActualDataTypeSet(this, this->getActualDataType()); -} void InputSocket::relinkConnections(InputSocket *relinkToSocket) { if (!isConnected()) { @@ -141,8 +79,7 @@ void InputSocket::relinkConnectionsDuplicate(InputSocket *relinkToSocket, int ed { if (!this->isConnected()) { Node *node = (Node*)this->getNode(); - switch (this->getActualDataType()) { - case COM_DT_UNKNOWN: + switch (this->getDataType()) { case COM_DT_COLOR: node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex); break; @@ -171,8 +108,7 @@ void InputSocket::relinkConnections(InputSocket *relinkToSocket, int editorNode } else { Node *node = (Node*)this->getNode(); - switch (this->getActualDataType()) { - case COM_DT_UNKNOWN: + switch (this->getDataType()) { case COM_DT_COLOR: node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex); break; @@ -186,16 +122,6 @@ void InputSocket::relinkConnections(InputSocket *relinkToSocket, int editorNode } } -const ChannelInfo *InputSocket::getChannelInfo(const int channelnumber) -{ - if (this->isConnected() && this->connection->getFromSocket()) { - return this->connection->getFromSocket()->getChannelInfo(channelnumber); - } - else { - return NULL; - } -} - bool InputSocket::isStatic() { if (isConnected()) { diff --git a/source/blender/compositor/intern/COM_InputSocket.h b/source/blender/compositor/intern/COM_InputSocket.h index 6ac6ad09126..c066b5d8303 100644 --- a/source/blender/compositor/intern/COM_InputSocket.h +++ b/source/blender/compositor/intern/COM_InputSocket.h @@ -73,19 +73,6 @@ private: InputSocketResizeMode resizeMode; - /** - * @brief convert a data type to a by the socket supported data type. - * - * @param datatype the datatype that needs to be checked - * @section data-conversion - */ - DataType convertToSupportedDataType(DataType datatype); - - /** - * @brief called when the ActualDataType is set. notifies other parties - */ - void fireActualDataTypeSet(); - public: InputSocket(DataType datatype); InputSocket(DataType datatype, InputSocketResizeMode resizeMode); @@ -104,8 +91,6 @@ public: */ void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); - void determineActualDataType(); - /** * @brief Notifies the Input of the data type (via a SocketConnection) * @param datatype the datatype to evaluate diff --git a/source/blender/compositor/intern/COM_NodeBase.cpp b/source/blender/compositor/intern/COM_NodeBase.cpp index 17a623c9c81..5ffe9bdd26a 100644 --- a/source/blender/compositor/intern/COM_NodeBase.cpp +++ b/source/blender/compositor/intern/COM_NodeBase.cpp @@ -89,55 +89,3 @@ InputSocket *NodeBase::getInputSocket(int index) { return this->inputsockets[index]; } - - -void NodeBase::determineActualSocketDataTypes() -{ - unsigned int index; - for (index = 0 ; index < this->outputsockets.size() ; index ++) { - OutputSocket *socket = this->outputsockets[index]; - if (socket->getActualDataType() ==COM_DT_UNKNOWN && socket->isConnected()) { - socket->determineActualDataType(); - } - } - for (index = 0 ; index < this->inputsockets.size() ; index ++) { - InputSocket *socket = this->inputsockets[index]; - if (socket->getActualDataType() ==COM_DT_UNKNOWN) { - socket->determineActualDataType(); - } - } -} - -DataType NodeBase::determineActualDataType(OutputSocket *outputsocket) -{ - const int inputIndex = outputsocket->getInputSocketDataTypeDeterminatorIndex(); - if (inputIndex != -1) { - return this->getInputSocket(inputIndex)->getActualDataType(); - } - else { - return outputsocket->getDataType(); - } -} - -void NodeBase::notifyActualDataTypeSet(InputSocket *socket, DataType actualType) -{ - unsigned int index; - int socketIndex = -1; - for (index = 0 ; index < this->inputsockets.size() ; index ++) { - if (this->inputsockets[index] == socket) { - socketIndex = (int)index; - break; - } - } - if (socketIndex == -1) return; - - for (index = 0 ; index < this->outputsockets.size() ; index ++) { - OutputSocket *socket = this->outputsockets[index]; - if (socket->isActualDataTypeDeterminedByInputSocket() && - socket->getInputSocketDataTypeDeterminatorIndex() == socketIndex) - { - socket->setActualDataType(actualType); - socket->fireActualDataType(); - } - } -} diff --git a/source/blender/compositor/intern/COM_NodeBase.h b/source/blender/compositor/intern/COM_NodeBase.h index 3917904afe3..5e3a4fa5531 100644 --- a/source/blender/compositor/intern/COM_NodeBase.h +++ b/source/blender/compositor/intern/COM_NodeBase.h @@ -73,24 +73,6 @@ public: */ virtual ~NodeBase(); - /** - * @brief determine the actual socket data types that will go through the system - */ - virtual void determineActualSocketDataTypes(); - - /** - * @brief determine the actual socket data types of a specific outputsocket - * - * @param outputsocket - * a reference to the actual outputsocket where the datatype must be determined from - * - * @return - * COM_DT_VALUE if it is a value (1 float buffer) - * COM_DT_COLOR if it is a value (4 float buffer) - * COM_DT_VECTOR if it is a value (3 float buffer) - */ - virtual DataType determineActualDataType(OutputSocket *outputsocket); - /** * @brief is this node an operation? * This is true when the instance is of the subclass NodeOperation. @@ -116,16 +98,6 @@ public: */ const unsigned int getNumberOfOutputSockets() const { return this->outputsockets.size(); } - /** - * after the data has been determined of an outputsocket that has a connection with an inputsocket this method is called on the - * node that contains the inputsocket. - * @param socket - * the reference of the inputsocket where connected data type is found - * @param actualType [COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR] - * the actual data type that is coming from the connected output socket - */ - virtual void notifyActualDataTypeSet(InputSocket *socket, const DataType actualType); - /** * get the reference to a certain outputsocket * @param index diff --git a/source/blender/compositor/intern/COM_OutputSocket.cpp b/source/blender/compositor/intern/COM_OutputSocket.cpp index 708b2d65d46..77bad3c006f 100644 --- a/source/blender/compositor/intern/COM_OutputSocket.cpp +++ b/source/blender/compositor/intern/COM_OutputSocket.cpp @@ -27,16 +27,6 @@ OutputSocket::OutputSocket(DataType datatype) :Socket(datatype) { - this->inputSocketDataTypeDeterminatorIndex = -1; -} -OutputSocket::OutputSocket(DataType datatype, int inputSocketDataTypeDeterminatorIndex) :Socket(datatype) -{ - this->inputSocketDataTypeDeterminatorIndex = inputSocketDataTypeDeterminatorIndex; -} - -OutputSocket::OutputSocket(OutputSocket *from): Socket(from->getDataType()) -{ - this->inputSocketDataTypeDeterminatorIndex = from->getInputSocketDataTypeDeterminatorIndex(); } int OutputSocket::isOutputSocket() const { return true; } @@ -57,51 +47,11 @@ void OutputSocket::determineResolution(unsigned int resolution[], unsigned int p } } -void OutputSocket::determineActualDataType() -{ - DataType actualDatatype = this->getNode()->determineActualDataType(this); - - /** @todo: set the channel info needs to be moved after integration with OCIO */ - this->channelinfo[0].setNumber(0); - this->channelinfo[1].setNumber(1); - this->channelinfo[2].setNumber(2); - this->channelinfo[3].setNumber(3); - switch (actualDatatype) { - case COM_DT_VALUE: - this->channelinfo[0].setType(COM_CT_Value); - break; - case COM_DT_VECTOR: - this->channelinfo[0].setType(COM_CT_X); - this->channelinfo[1].setType(COM_CT_Y); - this->channelinfo[2].setType(COM_CT_Z); - break; - case COM_DT_COLOR: - this->channelinfo[0].setType(COM_CT_ColorComponent); - this->channelinfo[1].setType(COM_CT_ColorComponent); - this->channelinfo[2].setType(COM_CT_ColorComponent); - this->channelinfo[3].setType(COM_CT_Alpha); - break; - default: - break; - } - - this->setActualDataType(actualDatatype); - this->fireActualDataType(); -} - void OutputSocket::addConnection(SocketConnection *connection) { this->connections.push_back(connection); } -void OutputSocket::fireActualDataType() -{ - unsigned int index; - for (index = 0 ; index < this->connections.size();index ++) { - SocketConnection *connection = this->connections[index]; - connection->getToSocket()->notifyActualInputType(this->getActualDataType()); - } -} void OutputSocket::relinkConnections(OutputSocket *relinkToSocket, bool single) { if (isConnected()) { @@ -109,7 +59,6 @@ void OutputSocket::relinkConnections(OutputSocket *relinkToSocket, bool single) SocketConnection *connection = this->connections[0]; connection->setFromSocket(relinkToSocket); relinkToSocket->addConnection(connection); -// relinkToSocket->setActualDataType(this->getActualDataType()); this->connections.erase(this->connections.begin()); } else { @@ -119,7 +68,6 @@ void OutputSocket::relinkConnections(OutputSocket *relinkToSocket, bool single) connection->setFromSocket(relinkToSocket); relinkToSocket->addConnection(connection); } -// relinkToSocket->setActualDataType(this->getActualDataType()); this->connections.clear(); } } @@ -157,8 +105,3 @@ WriteBufferOperation *OutputSocket::findAttachedWriteBufferOperation() const return NULL; } -ChannelInfo *OutputSocket::getChannelInfo(const int channelnumber) -{ - return &this->channelinfo[channelnumber]; -} - diff --git a/source/blender/compositor/intern/COM_OutputSocket.h b/source/blender/compositor/intern/COM_OutputSocket.h index e008d651046..c073703c423 100644 --- a/source/blender/compositor/intern/COM_OutputSocket.h +++ b/source/blender/compositor/intern/COM_OutputSocket.h @@ -43,15 +43,7 @@ class WriteBufferOperation; class OutputSocket : public Socket { private: vector connections; - - /** - * @brief index of the inputsocket that determines the datatype of this outputsocket - * -1 will not use any inputsocket to determine the datatype, but use the outputsocket - * default datatype. - */ - int inputSocketDataTypeDeterminatorIndex; - - ChannelInfo channelinfo[4]; + void removeFirstConnection(); public: OutputSocket(DataType datatype); @@ -72,18 +64,10 @@ public: /** * @brief determine the actual data type and channel info. */ - void determineActualDataType(); void relinkConnections(OutputSocket *relinkToSocket) { this->relinkConnections(relinkToSocket, false); }; void relinkConnections(OutputSocket *relinkToSocket, bool single); - bool isActualDataTypeDeterminedByInputSocket() { - return this->inputSocketDataTypeDeterminatorIndex > -1; - } const int getNumberOfConnections() { return connections.size(); } - /** - * @brief get the index of the inputsocket that determines the datatype of this outputsocket - */ - int getInputSocketDataTypeDeterminatorIndex() { return this->inputSocketDataTypeDeterminatorIndex; } void clearConnections(); /** @@ -93,12 +77,6 @@ public: WriteBufferOperation *findAttachedWriteBufferOperation() const; ChannelInfo *getChannelInfo(const int channelnumber); - /** - * @brief trigger determine actual data type to all connected sockets - * @note will only be triggered just after the actual data type is set. - */ - void fireActualDataType(); - private: }; diff --git a/source/blender/compositor/intern/COM_Socket.cpp b/source/blender/compositor/intern/COM_Socket.cpp index a5336ac1202..af9ad1967a5 100644 --- a/source/blender/compositor/intern/COM_Socket.cpp +++ b/source/blender/compositor/intern/COM_Socket.cpp @@ -27,7 +27,6 @@ Socket::Socket(DataType datatype) { this->datatype = datatype; - this->actualType = COM_DT_UNKNOWN; this->editorSocket = NULL; this->node = NULL; } @@ -42,9 +41,3 @@ int Socket::isOutputSocket() const { return false; } const int Socket::isConnected() const {return false;} void Socket::setNode(NodeBase *node) {this->node = node;} NodeBase *Socket::getNode() const {return this->node;} - -DataType Socket::getActualDataType() const {return this->actualType;} -void Socket::setActualDataType(DataType actualType) -{ - this->actualType = actualType; -} diff --git a/source/blender/compositor/intern/COM_Socket.h b/source/blender/compositor/intern/COM_Socket.h index 0be21a6b1b8..7c5c2198a16 100644 --- a/source/blender/compositor/intern/COM_Socket.h +++ b/source/blender/compositor/intern/COM_Socket.h @@ -57,12 +57,6 @@ private: */ DataType datatype; - /** - * the actual data type during execution. This can be different than the field datatype, based on the conversion rules of the node - * @section data-conversion - */ - DataType actualType; - bNodeSocket *editorSocket; public: Socket(DataType datatype); @@ -71,25 +65,11 @@ public: void setNode(NodeBase *node); NodeBase *getNode() const; - /** - * @brief get the actual data type - * - * @note The actual data type can differ from the data type this socket expects. - * @return actual DataType - */ - DataType getActualDataType() const; - - /** - * @brief set the actual data type - * @param actualType the new actual type - */ - void setActualDataType(DataType actualType); - + const virtual int isConnected() const; int isInputSocket() const; int isOutputSocket() const; virtual void determineResolution(int resolution[], unsigned int preferredResolution[]) {} - virtual void determineActualDataType() {} void setEditorSocket(bNodeSocket *editorSocket) { this->editorSocket = editorSocket; } bNodeSocket *getbNodeSocket() const { return this->editorSocket; } diff --git a/source/blender/compositor/nodes/COM_MuteNode.cpp b/source/blender/compositor/nodes/COM_MuteNode.cpp index 93e352cfede..57b7871318b 100644 --- a/source/blender/compositor/nodes/COM_MuteNode.cpp +++ b/source/blender/compositor/nodes/COM_MuteNode.cpp @@ -72,9 +72,6 @@ void MuteNode::reconnect(ExecutionSystem * graph, OutputSocket * output) operation = coloroperation; break; } - /* quiet warnings */ - case COM_DT_UNKNOWN: - break; } if (operation) { diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cpp b/source/blender/compositor/nodes/COM_OutputFileNode.cpp index ca18ea5fbf7..e5deb595d78 100644 --- a/source/blender/compositor/nodes/COM_OutputFileNode.cpp +++ b/source/blender/compositor/nodes/COM_OutputFileNode.cpp @@ -77,7 +77,7 @@ void OutputFileNode::convertToOperations(ExecutionSystem *graph, CompositorConte BLI_join_dirfile(path, FILE_MAX, storage->base_path, sockdata->path); OutputSingleLayerOperation *outputOperation = new OutputSingleLayerOperation( - context->getScene(), context->getbNodeTree(), input->getActualDataType(), format, path); + context->getScene(), context->getbNodeTree(), input->getDataType(), format, path); input->relinkConnections(outputOperation->getInputSocket(0)); graph->addOperation(outputOperation); if (!previewAdded) { diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp index fbb25afe266..cdb844cad54 100644 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp +++ b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp @@ -49,14 +49,14 @@ void SocketProxyNode::convertToOperations(ExecutionSystem *graph, CompositorCont InputSocket * inputsocket = this->getInputSocket(0); if (outputsocket->isConnected()) { if (inputsocket->isConnected()) { - SocketProxyOperation *operation = new SocketProxyOperation(); + SocketProxyOperation *operation = new SocketProxyOperation(this->getOutputSocket()->getDataType()); inputsocket->relinkConnections(operation->getInputSocket(0)); outputsocket->relinkConnections(operation->getOutputSocket(0)); graph->addOperation(operation); } else { /* If input is not connected, add a constant value operation instead */ - switch (outputsocket->getActualDataType()) { + switch (outputsocket->getDataType()) { case COM_DT_VALUE: { SetValueOperation *operation = new SetValueOperation(); @@ -84,9 +84,6 @@ void SocketProxyNode::convertToOperations(ExecutionSystem *graph, CompositorCont graph->addOperation(operation); break; } - /* quiet warnings */ - case COM_DT_UNKNOWN: - break; } } } diff --git a/source/blender/compositor/nodes/COM_SwitchNode.cpp b/source/blender/compositor/nodes/COM_SwitchNode.cpp index 58c60a96de8..bb1a9c119f8 100644 --- a/source/blender/compositor/nodes/COM_SwitchNode.cpp +++ b/source/blender/compositor/nodes/COM_SwitchNode.cpp @@ -31,7 +31,7 @@ SwitchNode::SwitchNode(bNode *editorNode): Node(editorNode) void SwitchNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) { - SocketProxyOperation * operation = new SocketProxyOperation(); + SocketProxyOperation * operation = new SocketProxyOperation(COM_DT_COLOR); int switchFrame = this->getbNode()->custom1; if (!switchFrame) { diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp index 51b16506dd9..5f86d6bd7c7 100644 --- a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp +++ b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp @@ -22,10 +22,10 @@ #include "COM_SocketProxyOperation.h" -SocketProxyOperation::SocketProxyOperation() : NodeOperation() +SocketProxyOperation::SocketProxyOperation(DataType type) : NodeOperation() { - this->addInputSocket(COM_DT_COLOR/*|COM_DT_VECTOR|COM_DT_VALUE*/); - this->addOutputSocket(COM_DT_COLOR); + this->addInputSocket(type); + this->addOutputSocket(type); this->inputOperation = NULL; } diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.h b/source/blender/compositor/operations/COM_SocketProxyOperation.h index 701a5a8f693..5dc8f3d6f8f 100644 --- a/source/blender/compositor/operations/COM_SocketProxyOperation.h +++ b/source/blender/compositor/operations/COM_SocketProxyOperation.h @@ -29,7 +29,7 @@ class SocketProxyOperation : public NodeOperation { private: SocketReader *inputOperation; public: - SocketProxyOperation(); + SocketProxyOperation(DataType type); void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); void initExecution(); From 4f607bf162130bb5360650921bfcc5aac38efcc3 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 14 Jun 2012 09:42:17 +0000 Subject: [PATCH 300/360] disabled some flags :) --- source/blender/compositor/COM_defines.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h index 42015035f73..d59388c9206 100644 --- a/source/blender/compositor/COM_defines.h +++ b/source/blender/compositor/COM_defines.h @@ -67,8 +67,8 @@ typedef enum CompositorPriority { // chunk size determination #define COM_PREVIEW_SIZE 140.0f -#define COM_OPENCL_ENABLED -#define COM_DEBUG +//#define COM_OPENCL_ENABLED +//#define COM_DEBUG // workscheduler threading models /** From 47950325a412e40a6d9ed89f7cef849f0d136a29 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 10:03:23 +0000 Subject: [PATCH 301/360] minor change to r47872, multiply both values as unsigned ints before converting to float. --- .../compositor/operations/COM_GlareFogGlowOperation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp index 0c2ae96aa51..a91445be4b5 100644 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp @@ -382,14 +382,14 @@ void GlareFogGlowOperation::generateGlare(float *data, MemoryBuffer *inputTile, BLI_init_rcti(&kernelRect, 0, sz, 0, sz); ckrn = new MemoryBuffer(NULL, &kernelRect); - scale = 0.25f * sqrtf((float)sz * sz); + scale = 0.25f * sqrtf((float)(sz * sz)); for (y = 0; y < sz; ++y) { - v = 2.f * (y / (float)sz) - 1.f; + v = 2.f * (y / (float)sz) - 1.0f; for (x = 0; x < sz; ++x) { - u = 2.f * (x / (float)sz) - 1.f; + u = 2.f * (x / (float)sz) - 1.0f; r = (u * u + v * v) * scale; - d = -sqrtf(sqrtf(sqrtf(r))) * 9.f; + d = -sqrtf(sqrtf(sqrtf(r))) * 9.0f; fcol[0] = expf(d * cs_r), fcol[1] = expf(d * cs_g), fcol[2] = expf(d * cs_b); // linear window good enough here, visual result counts, not scientific analysis //w = (1.f-fabs(u))*(1.f-fabs(v)); From 68386ef23a2b48f4a0ece2da1d8e5f66e0ef4bf6 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 14 Jun 2012 10:21:53 +0000 Subject: [PATCH 302/360] resolutions were not propagated correctly. --- source/blender/compositor/intern/COM_ExecutionSystem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index b84e9d0d3f7..7ea97b3fa39 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -212,7 +212,9 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) writeOperation = new WriteBufferOperation(); writeOperation->setbNodeTree(this->getContext().getbNodeTree()); this->addOperation(writeOperation); - for (index = 0 ; index < outputsocket->getNumberOfConnections();index ++) { + ExecutionSystemHelper::addLink(this->getConnections(), outputsocket, writeOperation->getInputSocket(0)); + writeOperation->readResolutionFromInputSocket(); + for (index = 0 ; index < outputsocket->getNumberOfConnections()-1;index ++) { SocketConnection * connection = outputsocket->getConnection(index); ReadBufferOperation *readoperation = new ReadBufferOperation(); readoperation->setMemoryProxy(writeOperation->getMemoryProxy()); @@ -221,8 +223,6 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) readoperation->readResolutionFromWriteBuffer(); this->addOperation(readoperation); } - ExecutionSystemHelper::addLink(this->getConnections(), outputsocket, writeOperation->getInputSocket(0)); - writeOperation->readResolutionFromInputSocket(); } } From 05a1a3169336380b51947451ebdabdf5455fe38f Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Thu, 14 Jun 2012 10:38:39 +0000 Subject: [PATCH 303/360] Collada: Added export Option 'sort by object name' to fix an issue with Second Life import --- source/blender/collada/ExportSettings.h | 1 + source/blender/collada/collada.cpp | 5 ++++ source/blender/collada/collada.h | 1 + source/blender/collada/collada_utils.cpp | 28 +++++++++++++++++++ source/blender/collada/collada_utils.h | 2 ++ .../blender/makesrna/intern/rna_scene_api.c | 4 ++- .../windowmanager/intern/wm_operators.c | 6 ++++ 7 files changed, 46 insertions(+), 1 deletion(-) diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h index 97ea6873856..e856eefab99 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -39,6 +39,7 @@ struct ExportSettings bool include_armatures; bool include_children; bool use_object_instantiation; + bool sort_by_name; bool second_life; char *filepath; LinkNode *export_set; diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index bc03bdc970c..9a4fd44b9e9 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -59,6 +59,7 @@ int collada_export( int include_children, int use_object_instantiation, + int sort_by_name, int second_life) { ExportSettings export_settings; @@ -79,6 +80,7 @@ int collada_export( export_settings.include_children = include_children != 0; export_settings.second_life = second_life != 0; export_settings.use_object_instantiation = use_object_instantiation != 0; + export_settings.sort_by_name = sort_by_name != 0; export_settings.filepath = (char *)filepath; int includeFilter = OB_REL_NONE; @@ -88,6 +90,9 @@ int collada_export( eObjectSet objectSet = (export_settings.selected) ? OB_SET_SELECTED : OB_SET_ALL; export_settings.export_set = BKE_object_relational_superset(sce, objectSet, (eObRelationTypes)includeFilter); + if (export_settings.sort_by_name) + bc_bubble_sort_by_Object_name(export_settings.export_set); + DocumentExporter exporter(&export_settings); exporter.exportCurrentScene(sce); diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index da2179ca135..8daf2b65fe2 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -47,6 +47,7 @@ extern "C" { int include_children, int use_object_instantiation, + int sort_by_name, int second_life); diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index f481de994a3..3d9aa8e542d 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -226,3 +226,31 @@ void bc_remove_mark(Object *ob) { ob->id.flag &= ~LIB_DOIT; } + +// Use bubble sort algorithm for sorting the export set +void bc_bubble_sort_by_Object_name(LinkNode *export_set) +{ + int i, j; // loop indices + bool unsorted = true; + + LinkNode *current; + int set_size = BLI_linklist_length(export_set); + for(i = 0; (i < set_size) && unsorted; i++) { + unsorted = false; + + for (current=export_set; current->next; current = current->next) { + Object *a = (Object *)current->link; + Object *b = (Object *)current->next->link; + + std::string str_a (a->id.name); + std::string str_b (b->id.name); + + if (str_a.compare(str_b) > 0) { + current->link = b; + current->next->link = a; + unsorted = true; + } + + } + } +} \ No newline at end of file diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 71365ffb8d0..139a2cb93bd 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -71,4 +71,6 @@ extern void bc_remove_mark(Object *ob); extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n); extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); +extern void bc_bubble_sort_by_Object_name(LinkNode *export_set); + #endif diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 76fe5a656b6..76366efe0d1 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -93,11 +93,12 @@ static void rna_Scene_collada_export( int include_armatures, int include_children, int use_object_instantiation, + int sort_by_name, int second_life) { collada_export(scene, filepath, selected, apply_modifiers, include_armatures, include_children, - use_object_instantiation, second_life); + use_object_instantiation, sort_by_name, second_life); } #endif @@ -130,6 +131,7 @@ void RNA_api_scene(StructRNA *srna) parm = RNA_def_boolean(func, "include_armatures", 0, "Include Armatures", "Include armature(s) used by the exported objects"); parm = RNA_def_boolean(func, "include_children", 0, "Include Children", "Include all children even if not selected"); parm = RNA_def_boolean(func, "use_object_instantiation", 1, "Use Object Instantiation", "Instantiate multiple Objects from same Data"); + parm = RNA_def_boolean(func, "sort_by_name", 0, "Sort by Object name", "Sort exported data by Object name"); parm = RNA_def_boolean(func, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life"); RNA_def_function_ui_description(func, "Export to collada file"); #endif diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index e16a7befdd5..b4bec014b9c 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2167,6 +2167,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) int apply_modifiers; int include_children; int use_object_instantiation; + int sort_by_name; if (!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); @@ -2182,6 +2183,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) include_armatures = RNA_boolean_get(op->ptr, "include_armatures"); include_children = RNA_boolean_get(op->ptr, "include_children"); use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation"); + sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name"); second_life = RNA_boolean_get(op->ptr, "second_life"); /* get editmode results */ @@ -2195,6 +2197,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) include_armatures, include_children, use_object_instantiation, + sort_by_name, second_life)) { return OPERATOR_FINISHED; } @@ -2232,6 +2235,9 @@ static void WM_OT_collada_export(wmOperatorType *ot) RNA_def_boolean(ot->srna, "use_object_instantiation", 1, "Use Object Instantiation", "Instantiate multiple Objects from same Data"); + RNA_def_boolean(ot->srna, "sort_by_name", 0, "Sort by Object name", + "Sort exported data by Object name"); + RNA_def_boolean(ot->srna, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life"); } From 17d5ac0abf00a46d39b84ae17806042011bd11d6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 10:54:14 +0000 Subject: [PATCH 304/360] quiet compiler warning --- extern/recastnavigation/Recast/Include/RecastAssert.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/recastnavigation/Recast/Include/RecastAssert.h b/extern/recastnavigation/Recast/Include/RecastAssert.h index b58b8fcd286..45cb01fb595 100644 --- a/extern/recastnavigation/Recast/Include/RecastAssert.h +++ b/extern/recastnavigation/Recast/Include/RecastAssert.h @@ -24,7 +24,7 @@ #ifdef NDEBUG // From http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/ -# define rcAssert(x) do { (void)sizeof(x); } while(__LINE__==-1,false) +# define rcAssert(x) do { (void)sizeof(x); } while((void)(__LINE__ == -1), false) #else # include # define rcAssert assert From a57c8a37a10168fc4335c167c71939474be81e8c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 11:05:15 +0000 Subject: [PATCH 305/360] comment unused vars --- intern/raskter/raskter.c | 6 +++--- .../gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h | 2 +- source/gameengine/Rasterizer/RAS_2DFilterManager.h | 4 ++-- source/gameengine/Rasterizer/RAS_MeshObject.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index 0574d985d0c..910cd4c6a3d 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -810,9 +810,9 @@ int PLX_antialias_buffer(float *buf, int buf_x, int buf_y) { buf[i] *= 0.5f; } #endif - buf_x = buf_x; - buf_y = buf_y; - buf[0] = buf[0]; + (void)buf_x; + (void)buf_y; + (void)buf; return 1; #else /*XXX - TODO: THIS IS NOT FINAL CODE - IT DOES NOT WORK - DO NOT ENABLE IT */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h index 84991b9a9ad..43296fc9760 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h @@ -51,7 +51,7 @@ public: virtual void NextFrame(); virtual void HookEscape(); private: - short m_exit_key; + /* short m_exit_key; */ /* UNUSED */ #ifdef WITH_CXX_GUARDEDALLOC diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.h b/source/gameengine/Rasterizer/RAS_2DFilterManager.h index d3b23deab52..c9af48fe516 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.h +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.h @@ -57,14 +57,14 @@ private: float canvascoord[4]; float textureoffsets[18]; - float view[4]; + /* float view[4]; */ /* UNUSED */ /* texname[0] contains render to texture, texname[1] contains depth texture, texname[2] contains luminance texture*/ unsigned int texname[3]; int texturewidth; int textureheight; int canvaswidth; int canvasheight; - int numberoffilters; + /* int numberoffilters; */ /* UNUSED */ /* bit 0: enable/disable depth texture * bit 1: enable/disable luminance texture*/ short texflag[MAX_RENDER_PASS]; diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index b3e84c4656b..ffe2964c058 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -57,7 +57,7 @@ class RAS_Deformer; class RAS_MeshObject { private: - unsigned int m_debugcolor; + /* unsigned int m_debugcolor; */ /* UNUSED */ bool m_bModified; bool m_bMeshModified; From a164b7ed25fc6be5805b45ee8a6f2e91d5ff7627 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 14 Jun 2012 11:26:46 +0000 Subject: [PATCH 306/360] Comment numberoffilters in constructor too. Otherwise it'll for sure give compilation error. --- source/gameengine/Rasterizer/RAS_2DFilterManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index 95a2dc59c5e..0a1958e509a 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -53,7 +53,7 @@ RAS_2DFilterManager::RAS_2DFilterManager(): texturewidth(-1), textureheight(-1), canvaswidth(-1), canvasheight(-1), -numberoffilters(0), need_tex_update(true) +/* numberoffilters(0), */ /* UNUSED */ need_tex_update(true) { isshadersupported = GLEW_ARB_shader_objects && GLEW_ARB_fragment_shader && GLEW_ARB_multitexture; From d3c8cdc1c3fb4f24cfcdbe5f211c505349f76a61 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 11:44:05 +0000 Subject: [PATCH 307/360] code cleanup: zbuf/alpha exr writing --- .../imbuf/intern/openexr/openexr_api.cpp | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index c3c7b7fa34c..f2beb045dfa 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -194,10 +194,11 @@ static void openexr_header_metadata(Header *header, struct ImBuf *ibuf) static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags) { - int channels = ibuf->channels; - int width = ibuf->x; - int height = ibuf->y; - int write_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; // summarize + const int channels = ibuf->channels; + const int is_alpha = (channels >= 4) && (ibuf->planes == 32); + const int is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; /* summarize */ + const int width = ibuf->x; + const int height = ibuf->y; try { @@ -209,9 +210,9 @@ static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags header.channels().insert("R", Channel(HALF)); header.channels().insert("G", Channel(HALF)); header.channels().insert("B", Channel(HALF)); - if (ibuf->planes == 32 && channels >= 4) + if (is_alpha) header.channels().insert("A", Channel(HALF)); - if (write_zbuf) // z we do as float always + if (is_zbuf) // z we do as float always header.channels().insert("Z", Channel(Imf::FLOAT)); FrameBuffer frameBuffer; @@ -220,16 +221,16 @@ static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags /* we store first everything in half array */ RGBAZ *pixels = new RGBAZ[height * width]; RGBAZ *to = pixels; - int xstride = sizeof (RGBAZ); + int xstride = sizeof(RGBAZ); int ystride = xstride * width; /* indicate used buffers */ frameBuffer.insert("R", Slice(HALF, (char *) &pixels[0].r, xstride, ystride)); frameBuffer.insert("G", Slice(HALF, (char *) &pixels[0].g, xstride, ystride)); frameBuffer.insert("B", Slice(HALF, (char *) &pixels[0].b, xstride, ystride)); - if (ibuf->planes == 32 && channels >= 4) + if (is_alpha) frameBuffer.insert("A", Slice(HALF, (char *) &pixels[0].a, xstride, ystride)); - if (write_zbuf) + if (is_zbuf) frameBuffer.insert("Z", Slice(Imf::FLOAT, (char *)(ibuf->zbuf_float + (height - 1) * width), sizeof(float), sizeof(float) * -width)); if (ibuf->rect_float) { @@ -298,10 +299,11 @@ static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags static int imb_save_openexr_float(struct ImBuf *ibuf, const char *name, int flags) { - int channels = ibuf->channels; - int width = ibuf->x; - int height = ibuf->y; - int write_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; // summarize + const int channels = ibuf->channels; + const int is_alpha = (channels >= 4) && (ibuf->planes == 32); + const int is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; /* summarize */ + const int width = ibuf->x; + const int height = ibuf->y; try { @@ -313,9 +315,9 @@ static int imb_save_openexr_float(struct ImBuf *ibuf, const char *name, int flag header.channels().insert("R", Channel(Imf::FLOAT)); header.channels().insert("G", Channel(Imf::FLOAT)); header.channels().insert("B", Channel(Imf::FLOAT)); - if (ibuf->planes == 32 && channels >= 4) + if (is_alpha) header.channels().insert("A", Channel(Imf::FLOAT)); - if (write_zbuf) + if (is_zbuf) header.channels().insert("Z", Channel(Imf::FLOAT)); FrameBuffer frameBuffer; @@ -333,9 +335,9 @@ static int imb_save_openexr_float(struct ImBuf *ibuf, const char *name, int flag frameBuffer.insert("R", Slice(Imf::FLOAT, (char *)rect[0], xstride, ystride)); frameBuffer.insert("G", Slice(Imf::FLOAT, (char *)rect[1], xstride, ystride)); frameBuffer.insert("B", Slice(Imf::FLOAT, (char *)rect[2], xstride, ystride)); - if (ibuf->planes == 32 && channels >= 4) + if (is_alpha) frameBuffer.insert("A", Slice(Imf::FLOAT, (char *)rect[3], xstride, ystride)); - if (write_zbuf) + if (is_zbuf) frameBuffer.insert("Z", Slice(Imf::FLOAT, (char *) (ibuf->zbuf_float + (height - 1) * width), sizeof(float), sizeof(float) * -width)); file->setFrameBuffer(frameBuffer); From e2cda811ac2b8bd054afe2d7e0a0c760de96080c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 12:05:38 +0000 Subject: [PATCH 308/360] fix for years old bug - OpenEXR always adding alpha channel on load (how did nobody notice this?). --- .../imbuf/intern/openexr/openexr_api.cpp | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index f2beb045dfa..18957cb8260 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -945,13 +945,16 @@ static const char *exr_rgba_channelname(InputFile *file, const char *chan) return chan; } - - static int exr_has_zbuffer(InputFile *file) { return !(file->header().channels().findChannel("Z") == NULL); } +static int exr_has_alpha(InputFile *file) +{ + return !(file->header().channels().findChannel("A") == NULL); +} + static int exr_is_multilayer(InputFile *file) { const StringAttribute *comments = file->header().findTypedAttribute("BlenderMultiChannel"); @@ -966,7 +969,8 @@ static int exr_is_multilayer(InputFile *file) return 0; } -struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags){ +struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags) +{ struct ImBuf *ibuf = NULL; InputFile *file = NULL; @@ -979,8 +983,8 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags){ file = new InputFile(*membuf); Box2i dw = file->header().dataWindow(); - int width = dw.max.x - dw.min.x + 1; - int height = dw.max.y - dw.min.y + 1; + const int width = dw.max.x - dw.min.x + 1; + const int height = dw.max.y - dw.min.y + 1; //printf("OpenEXR-load: image data window %d %d %d %d\n", // dw.min.x, dw.min.y, dw.max.x, dw.max.y); @@ -995,8 +999,9 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags){ printf("Error: can't process EXR multilayer file\n"); } else { + const int is_alpha = exr_has_alpha(file); - ibuf = IMB_allocImBuf(width, height, 32, 0); + ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, 0); ibuf->ftype = OPENEXR; /* openEXR is linear as per EXR spec */ @@ -1031,8 +1036,9 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags){ frameBuffer.insert(exr_rgba_channelname(file, "B"), Slice(Imf::FLOAT, (char *) (first + 2), xstride, ystride)); + /* 1.0 is fill value, this still neesd to be assigned even when (is_alpha == 0) */ frameBuffer.insert(exr_rgba_channelname(file, "A"), - Slice(Imf::FLOAT, (char *) (first + 3), xstride, ystride, 1, 1, 1.0f)); /* 1.0 is fill value */ + Slice(Imf::FLOAT, (char *) (first + 3), xstride, ystride, 1, 1, 1.0f)); if (exr_has_zbuffer(file)) { float *firstz; From d56e77ada59050d02a03b44e9d5a7b122683615f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 14 Jun 2012 12:18:42 +0000 Subject: [PATCH 309/360] Keying Screen node from tomato branch Merge Keying Screen node developed in tomato branch into trunk. This node is aimed to make dealing with non-even greenscreens better by generating gradiented image which could be used a input for keyer nodes. Based on building voronoi diagram using motion tracking markers as sites position and average pattern color as color for that site. Pretty straignforward node, some documentation is there http://wiki.blender.org/index.php/User:Nazg-gul/Keying#Screen_color --- source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/intern/node.c | 1 + source/blender/blenlib/BLI_voronoi.h | 70 ++ source/blender/blenlib/CMakeLists.txt | 1 + source/blender/blenlib/intern/voronoi.c | 833 ++++++++++++++++++ source/blender/compositor/CMakeLists.txt | 7 + .../compositor/intern/COM_Converter.cpp | 4 + .../compositor/nodes/COM_KeyingScreenNode.cpp | 57 ++ .../compositor/nodes/COM_KeyingScreenNode.h | 36 + .../operations/COM_KeyingScreenOperation.cpp | 220 +++++ .../operations/COM_KeyingScreenOperation.h | 79 ++ source/blender/editors/space_node/drawnode.c | 21 + source/blender/makesdna/DNA_node_types.h | 4 + source/blender/makesrna/intern/rna_nodetree.c | 18 + .../makesrna/intern/rna_nodetree_types.h | 1 + source/blender/nodes/CMakeLists.txt | 1 + source/blender/nodes/NOD_composite.h | 1 + .../nodes/node_composite_keyingscreen.c | 202 +++++ 18 files changed, 1557 insertions(+) create mode 100644 source/blender/blenlib/BLI_voronoi.h create mode 100644 source/blender/blenlib/intern/voronoi.c create mode 100644 source/blender/compositor/nodes/COM_KeyingScreenNode.cpp create mode 100644 source/blender/compositor/nodes/COM_KeyingScreenNode.h create mode 100644 source/blender/compositor/operations/COM_KeyingScreenOperation.cpp create mode 100644 source/blender/compositor/operations/COM_KeyingScreenOperation.h create mode 100644 source/blender/nodes/composite/nodes/node_composite_keyingscreen.c diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index e8f863fbbfd..bf708fc550d 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -658,6 +658,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); #define CMP_NODE_DOUBLEEDGEMASK 266 #define CMP_NODE_OUTPUT_MULTI_FILE__DEPRECATED 267 /* DEPRECATED multi file node has been merged into regular CMP_NODE_OUTPUT_FILE */ #define CMP_NODE_MASK 268 +#define CMP_NODE_KEYINGSCREEN 269 #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 c48c0231aa0..20c9344a870 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1900,6 +1900,7 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_cmp_color_spill(ttype); register_node_type_cmp_luma_matte(ttype); register_node_type_cmp_doubleedgemask(ttype); + register_node_type_cmp_keyingscreen(ttype); register_node_type_cmp_translate(ttype); register_node_type_cmp_rotate(ttype); diff --git a/source/blender/blenlib/BLI_voronoi.h b/source/blender/blenlib/BLI_voronoi.h new file mode 100644 index 00000000000..a67b01c5175 --- /dev/null +++ b/source/blender/blenlib/BLI_voronoi.h @@ -0,0 +1,70 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_VORONOI_H__ +#define __BLI_VORONOI_H__ + +struct ListBase; + +/** \file BLI_voronoi.h + * \ingroup bli + */ + +typedef struct VoronoiSite { + float co[2]; + float color[3]; +} VoronoiSite; + +typedef struct VoronoiEdge { + struct VoronoiEdge *next, *prev; + + float start[2], end[2]; /* start and end points */ + + /* this fields are used during diagram computation only */ + + float direction[2]; /* directional vector, from "start", points to "end", normal of |left, right| */ + + float left[2]; /* point on Voronoi place on the left side of edge */ + float right[2]; /* point on Voronoi place on the right side of edge */ + + float f, g; /* directional coeffitients satisfying equation y = f*x + g (edge lies on this line) */ + + /* some edges consist of two parts, so we add the pointer to another part to connect them at the end of an algorithm */ + struct VoronoiEdge *neighbour; +} VoronoiEdge; + +typedef struct VoronoiTriangulationPoint { + float co[2]; + float color[3]; + int power; +} VoronoiTriangulationPoint; + +void BLI_voronoi_compute(const VoronoiSite *sites, int sites_total, int width, int height, struct ListBase *edges); + +void BLI_voronoi_triangulate(const VoronoiSite *sites, int sites_total, struct ListBase *edges, int width, int height, + VoronoiTriangulationPoint **triangulated_points_r, int *triangulated_points_total_r, + int (**triangles_r)[3], int *triangles_total_r); + +#endif /* __BLI_VORONOI_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index d535e190314..ac7681e3be7 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -89,6 +89,7 @@ set(SRC intern/time.c intern/uvproject.c intern/voxel.c + intern/voronoi.c intern/winstuff.c BLI_args.h diff --git a/source/blender/blenlib/intern/voronoi.c b/source/blender/blenlib/intern/voronoi.c new file mode 100644 index 00000000000..0088d24d741 --- /dev/null +++ b/source/blender/blenlib/intern/voronoi.c @@ -0,0 +1,833 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/* + * Fortune's algorithm implemented using explanation and some code snippets from + * http://blog.ivank.net/fortunes-algorithm-and-implementation.html + */ + +/** \file blender/blenkernel/intern/tracking.c + * \ingroup bli + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_voronoi.h" +#include "BLI_utildefines.h" + +#define VORONOI_EPS 1e-3 + +enum { + voronoiEventType_Site = 0, + voronoiEventType_Circle = 1 +} voronoiEventType; + +typedef struct VoronoiEvent { + struct VoronoiEvent *next, *prev; + + int type; /* type of event (site or circle) */ + float site[2]; /* site for which event was generated */ + + struct VoronoiParabola *parabola; /* parabola for which event was generated */ +} VoronoiEvent; + +typedef struct VoronoiParabola { + struct VoronoiParabola *left, *right, *parent; + VoronoiEvent *event; + int is_leaf; + float site[2]; + VoronoiEdge *edge; +} VoronoiParabola; + +typedef struct VoronoiProcess { + ListBase queue, edges; + VoronoiParabola *root; + int width, height; + float current_y; +} VoronoiProcess; + +/* event */ + +static void voronoi_insertEvent(VoronoiProcess *process, VoronoiEvent *event) +{ + VoronoiEvent *current_event = process->queue.first; + + while (current_event) { + if (current_event->site[1] < event->site[1]) { + break; + } + if (current_event->site[1] == event->site[1]) { + event->site[1] -= VORONOI_EPS; + } + + current_event = current_event->next; + } + + BLI_insertlinkbefore(&process->queue, current_event, event); +} + +/* edge */ +static VoronoiEdge *voronoiEdge_new(float start[2], float left[2], float right[2]) +{ + VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "voronoi edge"); + + copy_v2_v2(edge->start, start); + copy_v2_v2(edge->left, left); + copy_v2_v2(edge->right, right); + + edge->neighbour = NULL; + edge->end[0] = 0; + edge->end[1] = 0; + + edge->f = (right[0] - left[0]) / (left[1] - right[1]); + edge->g = start[1] - edge->f * start[0]; + + edge->direction[0] = right[1] - left[1]; + edge->direction[1] = -(right[0] - left[0]); + + return edge; +} + +/* parabola */ + +static VoronoiParabola *voronoiParabola_new(void) +{ + VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola"); + + parabola->is_leaf = FALSE; + parabola->event = NULL; + parabola->edge = NULL; + parabola->parent = 0; + + return parabola; +} + +static VoronoiParabola *voronoiParabola_newSite(float site[2]) +{ + VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola site"); + + copy_v2_v2(parabola->site, site); + parabola->is_leaf = TRUE; + parabola->event = NULL; + parabola->edge = NULL; + parabola->parent = 0; + + return parabola; +} + +/* returns the closest leave which is on the left of current node */ +static VoronoiParabola *voronoiParabola_getLeftChild(VoronoiParabola *parabola) +{ + VoronoiParabola *current_parabola; + + if (!parabola) + return NULL; + + current_parabola = parabola->left; + while (!current_parabola->is_leaf) { + current_parabola = current_parabola->right; + } + + return current_parabola; +} + +/* returns the closest leave which is on the right of current node */ +static VoronoiParabola *voronoiParabola_getRightChild(VoronoiParabola *parabola) +{ + VoronoiParabola *current_parabola; + + if (!parabola) + return NULL; + + current_parabola = parabola->right; + while (!current_parabola->is_leaf) { + current_parabola = current_parabola->left; + } + + return current_parabola; +} + +/* returns the closest parent which is on the left */ +static VoronoiParabola *voronoiParabola_getLeftParent(VoronoiParabola *parabola) +{ + VoronoiParabola *current_par = parabola->parent; + VoronoiParabola *last_parabola = parabola; + + while (current_par->left == last_parabola) { + if (!current_par->parent) + return NULL; + + last_parabola = current_par; + current_par = current_par->parent; + } + + return current_par; +} + +/* returns the closest parent which is on the right */ +static VoronoiParabola *voronoiParabola_getRightParent(VoronoiParabola *parabola) +{ + VoronoiParabola *current_parabola = parabola->parent; + VoronoiParabola *last_parabola = parabola; + + while (current_parabola->right == last_parabola) { + if (!current_parabola->parent) + return NULL; + + last_parabola = current_parabola; + current_parabola = current_parabola->parent; + } + + return current_parabola; +} + +static void voronoiParabola_setLeft(VoronoiParabola *parabola, VoronoiParabola *left) +{ + parabola->left = left; + left->parent = parabola; +} + +static void voronoiParabola_setRight(VoronoiParabola *parabola, VoronoiParabola *right) +{ + parabola->right = right; + right->parent = parabola; +} + +static float voronoi_getY(VoronoiProcess *process, float p[2], float x) +{ + float ly = process->current_y; + + float dp = 2 * (p[1] - ly); + float a1 = 1 / dp; + float b1 = -2 * p[0] / dp; + float c1 = ly + dp / 4 + p[0] * p[0] / dp; + + return a1 * x * x + b1 * x + c1; +} + +static float voronoi_getXOfEdge(VoronoiProcess *process, VoronoiParabola *par, float y) +{ + VoronoiParabola *left = voronoiParabola_getLeftChild(par); + VoronoiParabola *right = voronoiParabola_getRightChild(par); + float p[2], r[2]; + float dp, a1, b1, c1, a2, b2, c2, a, b, c, disc, ry, x1, x2; + float ly = process->current_y; + + copy_v2_v2(p, left->site); + copy_v2_v2(r, right->site); + + dp = 2.0f * (p[1] - y); + a1 = 1.0f / dp; + b1 = -2.0f * p[0] / dp; + c1 = y + dp / 4 + p[0] * p[0] / dp; + + dp = 2.0f * (r[1] - y); + a2 = 1.0f / dp; + b2 = -2.0f * r[0] / dp; + c2 = ly + dp / 4 + r[0] * r[0] / dp; + + a = a1 - a2; + b = b1 - b2; + c = c1 - c2; + + disc = b*b - 4 * a * c; + x1 = (-b + sqrtf(disc)) / (2*a); + x2 = (-b - sqrtf(disc)) / (2*a); + + if (p[1] < r[1]) + ry = MAX2(x1, x2); + else + ry = MIN2(x1, x2); + + return ry; +} + +static VoronoiParabola *voronoi_getParabolaByX(VoronoiProcess *process, float xx) +{ + VoronoiParabola * par = process->root; + float x = 0.0f; + float ly = process->current_y; + + while (!par->is_leaf) { + x = voronoi_getXOfEdge(process, par, ly); + + if (x > xx) + par = par->left; + else + par = par->right; + } + + return par; +} + +static int voronoi_getEdgeIntersection(VoronoiEdge *a, VoronoiEdge *b, float p[2]) +{ + float x = (b->g - a->g) / (a->f - b->f); + float y = a->f * x + a->g; + + if ((x - a->start[0]) / a->direction[0] < 0) + return 0; + + if ((y - a->start[1]) / a->direction[1] < 0) + return 0; + + if ((x - b->start[0]) / b->direction[0] < 0) + return 0; + + if ((y - b->start[1]) / b->direction[1] < 0) + return 0; + + p[0] = x; + p[1] = y; + + return 1; +} + +static void voronoi_checkCircle(VoronoiProcess *process, VoronoiParabola *b) +{ + VoronoiParabola *lp = voronoiParabola_getLeftParent(b); + VoronoiParabola *rp = voronoiParabola_getRightParent(b); + + VoronoiParabola *a = voronoiParabola_getLeftChild(lp); + VoronoiParabola *c = voronoiParabola_getRightChild(rp); + + VoronoiEvent *event; + + float ly = process->current_y; + float s[2], dx, dy, d; + + if (!a || !c || len_squared_v2v2(a->site, c->site) < VORONOI_EPS) + return; + + if (!voronoi_getEdgeIntersection(lp->edge, rp->edge, s)) + return; + + dx = a->site[0] - s[0]; + dy = a->site[1] - s[1]; + + d = sqrtf((dx * dx) + (dy * dy)); + + if (s[1] - d >= ly) + return; + + event = MEM_callocN(sizeof(VoronoiEvent), "voronoi circle event"); + + event->type = voronoiEventType_Circle; + + event->site[0] = s[0]; + event->site[1] = s[1] - d; + + b->event = event; + event->parabola = b; + + voronoi_insertEvent(process, event); +} + +static void voronoi_addParabola(VoronoiProcess *process, float site[2]) +{ + VoronoiParabola *root = process->root; + VoronoiParabola *par, *p0, *p1, *p2; + VoronoiEdge *el, *er; + float start[2]; + + if (!process->root) { + process->root = voronoiParabola_newSite(site); + + return; + } + + if (root->is_leaf && root->site[1] - site[1] < 0) { + float *fp = root->site; + float s[2]; + + root->is_leaf = FALSE; + voronoiParabola_setLeft(root, voronoiParabola_newSite(fp)); + voronoiParabola_setRight(root, voronoiParabola_newSite(site)); + + s[0] = (site[0] + fp[0]) / 2.0f; + s[1] = process->height; + + if(site[0] > fp[0]) + root->edge = voronoiEdge_new(s, fp, site); + else + root->edge = voronoiEdge_new(s, site, fp); + + BLI_addtail(&process->edges, root->edge); + + return; + } + + par = voronoi_getParabolaByX(process, site[0]); + + if (par->event) { + BLI_freelinkN(&process->queue, par->event); + + par->event = NULL; + } + + start[0] = site[0]; + start[1] = voronoi_getY(process, par->site, site[0]); + + el = voronoiEdge_new(start, par->site, site); + er = voronoiEdge_new(start, site, par->site); + + el->neighbour = er; + BLI_addtail(&process->edges, el); + + par->edge = er; + par->is_leaf = FALSE; + + p0 = voronoiParabola_newSite(par->site); + p1 = voronoiParabola_newSite(site); + p2 = voronoiParabola_newSite(par->site); + + voronoiParabola_setRight(par, p2); + voronoiParabola_setLeft(par, voronoiParabola_new()); + par->left->edge = el; + + voronoiParabola_setLeft(par->left, p0); + voronoiParabola_setRight(par->left, p1); + + voronoi_checkCircle(process, p0); + voronoi_checkCircle(process, p2); +} + +static void voronoi_removeParabola(VoronoiProcess *process, VoronoiEvent *event) +{ + VoronoiParabola *p1 = event->parabola; + + VoronoiParabola *xl = voronoiParabola_getLeftParent(p1); + VoronoiParabola *xr = voronoiParabola_getRightParent(p1); + + VoronoiParabola *p0 = voronoiParabola_getLeftChild(xl); + VoronoiParabola *p2 = voronoiParabola_getRightChild(xr); + + VoronoiParabola *higher = NULL, *par, *gparent; + + float p[2]; + + if (p0->event) { + BLI_freelinkN(&process->queue, p0->event); + p0->event = NULL; + } + + if (p2->event) { + BLI_freelinkN(&process->queue, p2->event); + p2->event = NULL; + } + + p[0] = event->site[0]; + p[1] = voronoi_getY(process, p1->site, event->site[0]); + + copy_v2_v2(xl->edge->end, p); + copy_v2_v2(xr->edge->end, p); + + par = p1; + while (par != process->root) { + par = par->parent; + + if (par == xl) + higher = xl; + if (par == xr) + higher = xr; + } + + higher->edge = voronoiEdge_new(p, p0->site, p2->site); + BLI_addtail(&process->edges, higher->edge); + + gparent = p1->parent->parent; + if (p1->parent->left == p1) { + if (gparent->left == p1->parent) + voronoiParabola_setLeft(gparent, p1->parent->right); + if (gparent->right == p1->parent) + voronoiParabola_setRight(gparent, p1->parent->right); + } + else { + if (gparent->left == p1->parent) + voronoiParabola_setLeft(gparent, p1->parent->left); + if (gparent->right == p1->parent) + voronoiParabola_setRight(gparent, p1->parent->left); + } + + MEM_freeN(p1->parent); + MEM_freeN(p1); + + voronoi_checkCircle(process, p0); + voronoi_checkCircle(process, p2); +} + +void voronoi_finishEdge(VoronoiProcess *process, VoronoiParabola *parabola) +{ + float mx; + + if (parabola->is_leaf) { + MEM_freeN(parabola); + return; + } + + if (parabola->edge->direction[0] > 0.0f) + mx = MAX2(process->width, parabola->edge->start[0] + 10); + else + mx = MIN2(0.0, parabola->edge->start[0] - 10); + + parabola->edge->end[0] = mx; + parabola->edge->end[1] = mx * parabola->edge->f + parabola->edge->g; + + voronoi_finishEdge(process, parabola->left); + voronoi_finishEdge(process, parabola->right); + + MEM_freeN(parabola); +} + +void voronoi_clampEdgeVertex(int width, int height, float *coord, float *other_coord) +{ + const float corners[4][2] = {{0.0f, 0.0f}, + {width - 1, 0.0f}, + {width - 1, height - 1}, + {0.0f, height - 1}}; + int i; + + if (IN_RANGE_INCL(coord[0], 0, width-1) && IN_RANGE_INCL(coord[1], 0, height-1)) { + return; + } + + for (i = 0; i < 4; i++) { + float v1[2], v2[2]; + float p[2]; + + copy_v2_v2(v1, corners[i]); + + if (i == 3) + copy_v2_v2(v2, corners[0]); + else + copy_v2_v2(v2, corners[i + 1]); + + if (isect_seg_seg_v2_point(v1, v2, coord, other_coord, p) == 1) { + if (i == 0 && coord[1] > p[1]) + continue; + if (i == 1 && coord[0] < p[0]) + continue; + if (i == 2 && coord[1] < p[1]) + continue; + if (i == 3 && coord[0] > p[0]) + continue; + + copy_v2_v2(coord, p); + } + } +} + +void voronoi_clampEdges(ListBase *edges, int width, int height, ListBase *clamped_edges) +{ + VoronoiEdge *edge; + + edge = edges->first; + while (edge) { + VoronoiEdge *new_edge = MEM_callocN(sizeof(VoronoiEdge), "clamped edge"); + + *new_edge = *edge; + BLI_addtail(clamped_edges, new_edge); + + voronoi_clampEdgeVertex(width, height, new_edge->start, new_edge->end); + voronoi_clampEdgeVertex(width, height, new_edge->end, new_edge->start); + + edge = edge->next; + } +} + +static int voronoi_getNextSideCoord(ListBase *edges, float coord[2], int dim, int dir, float next_coord[2]) +{ + VoronoiEdge *edge = edges->first; + float distance = FLT_MAX; + int other_dim = dim ? 0 : 1; + + while (edge) { + int ok = FALSE; + float co[2], cur_distance; + + if (fabsf(edge->start[other_dim] - coord[other_dim]) < VORONOI_EPS && + len_squared_v2v2(coord, edge->start) > VORONOI_EPS) + { + copy_v2_v2(co, edge->start); + ok = TRUE; + } + + if (fabsf(edge->end[other_dim] - coord[other_dim]) < VORONOI_EPS && + len_squared_v2v2(coord, edge->end) > VORONOI_EPS) + { + copy_v2_v2(co, edge->end); + ok = TRUE; + } + + if (ok) { + if (dir > 0 && coord[dim] > co[dim]) { + ok = FALSE; + } + else if (dir < 0 && coord[dim] < co[dim]) { + ok = FALSE; + } + } + + if (ok) { + cur_distance = len_squared_v2v2(coord, co); + if (cur_distance < distance) { + copy_v2_v2(next_coord, co); + distance = cur_distance; + } + } + + edge = edge->next; + } + + return distance < FLT_MAX; +} + +static void voronoi_createBoundaryEdges(ListBase *edges, int width, int height) +{ + const float corners[4][2] = {{width - 1, 0.0f}, + {width - 1, height - 1}, + {0.0f, height - 1}, + {0.0f, 0.0f}}; + int i, dim = 0, dir = 1; + + float coord[2] = {0.0f, 0.0f}; + float next_coord[2] = {0.0f, 0.0f}; + + for (i = 0; i < 4; i++) { + while (voronoi_getNextSideCoord(edges, coord, dim, dir, next_coord)) { + VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "boundary edge"); + + copy_v2_v2(edge->start, coord); + copy_v2_v2(edge->end, next_coord); + BLI_addtail(edges, edge); + + copy_v2_v2(coord, next_coord); + } + + if (len_squared_v2v2(coord, corners[i]) > VORONOI_EPS) { + VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "boundary edge"); + + copy_v2_v2(edge->start, coord); + copy_v2_v2(edge->end, corners[i]); + BLI_addtail(edges, edge); + copy_v2_v2(coord, corners[i]); + } + + dim = dim ? 0 : 1; + if (i == 1) + dir = -1; + } +} + +void BLI_voronoi_compute(const VoronoiSite *sites, int sites_total, int width, int height, ListBase *edges) +{ + VoronoiProcess process; + VoronoiEdge *edge; + int i; + + memset(&process, 0, sizeof(VoronoiProcess)); + + process.width = width; + process.height = height; + + for (i = 0; i < sites_total; i++) { + VoronoiEvent *event = MEM_callocN(sizeof(VoronoiEvent), "voronoi site event"); + + event->type = voronoiEventType_Site; + copy_v2_v2(event->site, sites[i].co); + + voronoi_insertEvent(&process, event); + } + + while (process.queue.first) { + VoronoiEvent *event = process.queue.first; + + process.current_y = event->site[1]; + + if (event->type == voronoiEventType_Site) { + voronoi_addParabola(&process, event->site); + } + else { + voronoi_removeParabola(&process, event); + } + + BLI_freelinkN(&process.queue, event); + } + + voronoi_finishEdge(&process, process.root); + + edge = process.edges.first; + while (edge) { + if (edge->neighbour) { + copy_v2_v2(edge->start, edge->neighbour->end); + MEM_freeN(edge->neighbour); + } + + edge = edge->next; + } + + BLI_movelisttolist(edges, &process.edges); +} + +static int testVoronoiEdge(const float site[2], const float point[2], const VoronoiEdge *edge) +{ + float p[2]; + + if (isect_seg_seg_v2_point(site, point, edge->start, edge->end, p) == 1) { + if (len_squared_v2v2(p, edge->start) > VORONOI_EPS && + len_squared_v2v2(p, edge->end) > VORONOI_EPS) + { + return FALSE; + } + } + + return TRUE; +} + +static int voronoi_addTriangulationPoint(const float coord[2], const float color[3], + VoronoiTriangulationPoint **triangulated_points, + int *triangulated_points_total) +{ + VoronoiTriangulationPoint *triangulation_point; + int i; + + for (i = 0; i < *triangulated_points_total; i++) { + if (equals_v2v2(coord, (*triangulated_points)[i].co)) { + triangulation_point = &(*triangulated_points)[i]; + + add_v3_v3(triangulation_point->color, color); + triangulation_point->power++; + + return i; + } + } + + if (*triangulated_points) { + *triangulated_points = MEM_reallocN(*triangulated_points, + sizeof(VoronoiTriangulationPoint) * (*triangulated_points_total + 1)); + } + else { + *triangulated_points = MEM_callocN(sizeof(VoronoiTriangulationPoint), "triangulation points"); + } + + triangulation_point = &(*triangulated_points)[(*triangulated_points_total)]; + copy_v2_v2(triangulation_point->co, coord); + copy_v3_v3(triangulation_point->color, color); + + triangulation_point->power = 1; + + (*triangulated_points_total)++; + + return (*triangulated_points_total) - 1; +} + +static void voronoi_addTriangle(int v1, int v2, int v3, int (**triangles)[3], int *triangles_total) +{ + int *triangle; + + if (*triangles) { + *triangles = MEM_reallocN(*triangles, sizeof(int[3]) * (*triangles_total + 1)); + } + else { + *triangles = MEM_callocN(sizeof(int[3]), "trianglulation triangles"); + } + + triangle = (int*)&(*triangles)[(*triangles_total)]; + + triangle[0] = v1; + triangle[1] = v2; + triangle[2] = v3; + + (*triangles_total)++; +} + +void BLI_voronoi_triangulate(const VoronoiSite *sites, int sites_total, ListBase *edges, int width, int height, + VoronoiTriangulationPoint **triangulated_points_r, int *triangulated_points_total_r, + int (**triangles_r)[3], int *triangles_total_r) +{ + VoronoiTriangulationPoint *triangulated_points = NULL; + int (*triangles)[3] = NULL; + int triangulated_points_total = 0, triangles_total = 0; + int i; + ListBase boundary_edges = {NULL, NULL}; + + voronoi_clampEdges(edges, width, height, &boundary_edges); + voronoi_createBoundaryEdges(&boundary_edges, width, height); + + for (i = 0; i < sites_total; i++) { + VoronoiEdge *edge; + int v1; + + v1 = voronoi_addTriangulationPoint(sites[i].co, sites[i].color, &triangulated_points, &triangulated_points_total); + + edge = boundary_edges.first; + while (edge) { + VoronoiEdge *test_edge = boundary_edges.first; + int ok_start = TRUE, ok_end = TRUE; + + while (test_edge) { + float v1[2], v2[2]; + + sub_v2_v2v2(v1, edge->start, sites[i].co); + sub_v2_v2v2(v2, edge->end, sites[i].co); + + if (ok_start && !testVoronoiEdge(sites[i].co, edge->start, test_edge)) + ok_start = FALSE; + + if (ok_end && !testVoronoiEdge(sites[i].co, edge->end, test_edge)) + ok_end = FALSE; + + test_edge = test_edge->next; + } + + if (ok_start && ok_end) { + int v2, v3; + + v2 = voronoi_addTriangulationPoint(edge->start, sites[i].color, &triangulated_points, &triangulated_points_total); + v3 = voronoi_addTriangulationPoint(edge->end, sites[i].color, &triangulated_points, &triangulated_points_total); + + voronoi_addTriangle(v1, v2, v3, &triangles, &triangles_total); + } + + edge = edge->next; + } + } + + for (i = 0; i < triangulated_points_total; i++) { + VoronoiTriangulationPoint *triangulation_point = &triangulated_points[i]; + + mul_v3_fl(triangulation_point->color, 1.0f / triangulation_point->power); + } + + *triangulated_points_r = triangulated_points; + *triangulated_points_total_r = triangulated_points_total; + + *triangles_r = triangles; + *triangles_total_r = triangles_total; + + BLI_freelistN(&boundary_edges); +} diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index aa428c2b8d0..cfaf11c4400 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -323,6 +323,13 @@ set(SRC operations/COM_DoubleEdgeMaskOperation.cpp operations/COM_DoubleEdgeMaskOperation.h + + + nodes/COM_KeyingScreenNode.cpp + nodes/COM_KeyingScreenNode.h + operations/COM_KeyingScreenOperation.cpp + operations/COM_KeyingScreenOperation.h + operations/COM_ColorSpillOperation.cpp operations/COM_ColorSpillOperation.h operations/COM_RenderLayersBaseProg.cpp diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index f4bb89969ff..082e2fe5d04 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -112,6 +112,7 @@ #include "COM_DoubleEdgeMaskNode.h" #include "COM_CropNode.h" #include "COM_MaskNode.h" +#include "COM_KeyingScreenNode.h" Node *Converter::convert(bNode *bNode) { @@ -351,6 +352,9 @@ case CMP_NODE_OUTPUT_FILE: case CMP_NODE_MASK: node = new MaskNode(bNode); break; + case CMP_NODE_KEYINGSCREEN: + node = new KeyingScreenNode(bNode); + break; /* not inplemented yet */ default: node = new MuteNode(bNode); diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp new file mode 100644 index 00000000000..ad58adae48b --- /dev/null +++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_KeyingScreenNode.h" +#include "COM_ExecutionSystem.h" +#include "COM_KeyingScreenOperation.h" + +extern "C" { + #include "DNA_movieclip_types.h" +} + +KeyingScreenNode::KeyingScreenNode(bNode *editorNode): Node(editorNode) +{ +} + +void KeyingScreenNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +{ + OutputSocket *outputScreen = this->getOutputSocket(0); + + bNode *editorNode = this->getbNode(); + MovieClip *clip = (MovieClip *) editorNode->id; + + NodeKeyingScreenData *keyingscreen_data = (NodeKeyingScreenData *) editorNode->storage; + + // always connect the output image + KeyingScreenOperation *operation = new KeyingScreenOperation(); + + if (outputScreen->isConnected()) { + outputScreen->relinkConnections(operation->getOutputSocket()); + } + + operation->setMovieClip(clip); + operation->setTrackingObject(keyingscreen_data->tracking_object); + operation->setFramenumber(context->getFramenumber()); + + graph->addOperation(operation); +} diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.h b/source/blender/compositor/nodes/COM_KeyingScreenNode.h new file mode 100644 index 00000000000..7c87219ef6e --- /dev/null +++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.h @@ -0,0 +1,36 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_Node.h" +#include "DNA_node_types.h" + +/** + * @brief KeyingScreenNode + * @ingroup Node + */ +class KeyingScreenNode : public Node { +public: + KeyingScreenNode(bNode *editorNode); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); + +}; diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp new file mode 100644 index 00000000000..757afe7b394 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -0,0 +1,220 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_KeyingScreenOperation.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_math_color.h" + +#include "DNA_scene_types.h" + +extern "C" { + #include "BKE_movieclip.h" + #include "BKE_tracking.h" + + #include "IMB_imbuf.h" + #include "IMB_imbuf_types.h" +} + +KeyingScreenOperation::KeyingScreenOperation(): NodeOperation() +{ + this->addOutputSocket(COM_DT_COLOR); + this->movieClip = NULL; + this->framenumber = 0; + this->trackingObject[0] = 0; + setComplex(true); +} + +void KeyingScreenOperation::initExecution() +{ + initMutex(); + this->cachedTriangulation = NULL; +} + +void KeyingScreenOperation::deinitExecution() +{ + if (this->cachedTriangulation) { + TriangulationData *triangulation = cachedTriangulation; + + if (triangulation->triangulated_points) + MEM_freeN(triangulation->triangulated_points); + + if (triangulation->triangles) + MEM_freeN(triangulation->triangles); + + MEM_freeN(this->cachedTriangulation); + + this->cachedTriangulation = NULL; + } +} + +KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTriangulation() +{ + MovieClipUser user = {0}; + TriangulationData *triangulation; + MovieTracking *tracking = &movieClip->tracking; + MovieTrackingTrack *track; + VoronoiSite *sites; + ImBuf *ibuf; + ListBase *tracksbase; + ListBase edges = {NULL, NULL}; + int sites_total; + int i; + int width = this->getWidth(); + int height = this->getHeight(); + + if (this->trackingObject[0]) { + MovieTrackingObject *object = BKE_tracking_named_object(tracking, this->trackingObject); + + if (!object) + return NULL; + + tracksbase = BKE_tracking_object_tracks(tracking, object); + } + else + tracksbase = BKE_tracking_get_tracks(tracking); + + sites_total = BLI_countlist(tracksbase); + + if (!sites_total) + return NULL; + + BKE_movieclip_user_set_frame(&user, framenumber); + ibuf = BKE_movieclip_get_ibuf(movieClip, &user); + + if (!ibuf) + return NULL; + + triangulation = (TriangulationData *) MEM_callocN(sizeof(TriangulationData), "keying screen triangulation data"); + + sites = (VoronoiSite *) MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites"); + track = (MovieTrackingTrack *) tracksbase->first; + i = 0; + while (track) { + VoronoiSite *site = &sites[i]; + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenumber); + ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE); + int j; + + zero_v3(site->color); + for (j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) { + if (pattern_ibuf->rect_float) { + add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]); + } + else { + unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect; + + site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f); + site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f); + site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f); + } + } + + mul_v3_fl(site->color, 1.0f / (pattern_ibuf->x * pattern_ibuf->y)); + IMB_freeImBuf(pattern_ibuf); + + site->co[0] = marker->pos[0] * width; + site->co[1] = marker->pos[1] * height; + + track = track->next; + i++; + } + + IMB_freeImBuf(ibuf); + + BLI_voronoi_compute(sites, sites_total, width, height, &edges); + + BLI_voronoi_triangulate(sites, sites_total, &edges, width, height, + &triangulation->triangulated_points, &triangulation->triangulated_points_total, + &triangulation->triangles, &triangulation->triangles_total); + + MEM_freeN(sites); + BLI_freelistN(&edges); + + return triangulation; +} + +void *KeyingScreenOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + if (this->movieClip == NULL) + return NULL; + + if (this->cachedTriangulation) + return this->cachedTriangulation; + + lockMutex(); + if (this->cachedTriangulation == NULL) { + this->cachedTriangulation = buildVoronoiTriangulation(); + } + unlockMutex(); + + return this->cachedTriangulation; +} + +void KeyingScreenOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) +{ + resolution[0] = 0; + resolution[1] = 0; + + if (this->movieClip) { + MovieClipUser user = {0}; + int width, height; + + BKE_movieclip_user_set_frame(&user, framenumber); + BKE_movieclip_get_size(this->movieClip, &user, &width, &height); + + resolution[0] = width; + resolution[1] = height; + } +} + +void KeyingScreenOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + color[0] = 0.0f; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 1.0f; + + if (this->movieClip && data) { + TriangulationData *triangulation = (TriangulationData *) data; + int i; + for (i = 0; i < triangulation->triangles_total; i++) { + int *triangle = triangulation->triangles[i]; + VoronoiTriangulationPoint *a = &triangulation->triangulated_points[triangle[0]], + *b = &triangulation->triangulated_points[triangle[1]], + *c = &triangulation->triangulated_points[triangle[2]]; + float co[2] = {(float) x, (float) y}, w[3]; + + if (barycentric_coords_v2(a->co, b->co, c->co, co, w)) { + if (barycentric_inside_triangle_v2(w)) { + color[0] += a->color[0] * w[0] + b->color[0] * w[1] + c->color[0] * w[2]; + color[1] += a->color[1] * w[0] + b->color[1] * w[1] + c->color[1] * w[2]; + color[2] += a->color[2] * w[0] + b->color[2] * w[1] + c->color[2] * w[2]; + } + } + } + } +} diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h new file mode 100644 index 00000000000..9d3f44f6be2 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h @@ -0,0 +1,79 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + + +#ifndef _COM_KeyingScreenOperation_h +#define _COM_KeyingScreenOperation_h + +#include + +#include "COM_NodeOperation.h" + +#include "DNA_scene_types.h" +#include "DNA_movieclip_types.h" + +#include "BLI_listbase.h" + +extern "C" { + #include "BLI_voronoi.h" +} + +/** + * Class with implementation of green screen gradient rasterization + */ +class KeyingScreenOperation : public NodeOperation { +protected: + typedef struct TriangulationData { + VoronoiTriangulationPoint *triangulated_points; + int (*triangles)[3]; + int triangulated_points_total, triangles_total; + } TriangulationData; + + MovieClip *movieClip; + int framenumber; + TriangulationData *cachedTriangulation; + char trackingObject[64]; + + /** + * Determine the output resolution. The resolution is retrieved from the Renderer + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + TriangulationData *buildVoronoiTriangulation(); + + public: + KeyingScreenOperation(); + + void initExecution(); + void deinitExecution(); + + void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + void setMovieClip(MovieClip *clip) {this->movieClip = clip;} + void setTrackingObject(char *object) {strncpy(this->trackingObject, object, sizeof(this->trackingObject));} + void setFramenumber(int framenumber) {this->framenumber = framenumber;} + + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); +}; + +#endif diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index e6549034a85..a42bf062b12 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2425,6 +2425,24 @@ static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *p } +static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + bNode *node= ptr->data; + + uiTemplateID(layout, C, ptr, "clip", NULL, NULL, NULL); + + if (node->id) { + MovieClip *clip = (MovieClip *) node->id; + uiLayout *col; + PointerRNA tracking_ptr; + + RNA_pointer_create(&clip->id, &RNA_MovieTracking, &clip->tracking, &tracking_ptr); + + col = uiLayoutColumn(layout, 1); + uiItemPointerR(col, ptr, "tracking_object", &tracking_ptr, "objects", "", ICON_OBJECT_DATA); + } +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -2617,6 +2635,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_MASK: ntype->uifunc= node_composit_buts_mask; break; + case CMP_NODE_KEYINGSCREEN: + ntype->uifunc = node_composit_buts_keyingscreen; + break; default: ntype->uifunc = NULL; } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 5be7688d714..a81d3f5b6cd 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -628,6 +628,10 @@ typedef struct TexNodeOutput { char name[64]; } TexNodeOutput; +typedef struct NodeKeyingScreenData { + char tracking_object[64]; +} NodeKeyingScreenData; + /* frame node flags */ #define NODE_FRAME_SHRINK 1 /* keep the bounding box minimal */ #define NODE_FRAME_RESIZEABLE 2 /* test flag, if frame can be resized by user */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 73e2b5da4f0..b43fca26748 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3101,6 +3101,24 @@ static void def_cmp_mask(StructRNA *srna) RNA_def_property_ui_text(prop, "Mask", ""); } +static void def_cmp_keyingscreen(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "MovieClip"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Movie Clip", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + RNA_def_struct_sdna_from(srna, "NodeKeyingScreenData", "storage"); + + prop = RNA_def_property(srna, "tracking_object", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "tracking_object"); + RNA_def_property_ui_text(prop, "Tracking Object", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); +} static void dev_cmd_transform(StructRNA *srna) { diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index 3981afe5349..98170cc4d67 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -168,6 +168,7 @@ DefNode( CompositorNode, CMP_NODE_BOKEHBLUR, def_cmp_bokehblur, "BOKEH DefNode( CompositorNode, CMP_NODE_SWITCH, def_cmp_switch, "SWITCH" ,Switch, "Switch", "" ) DefNode( CompositorNode, CMP_NODE_COLORCORRECTION,def_cmp_colorcorrection,"COLORCORRECTION",ColorCorrection, "ColorCorrection", "" ) DefNode( CompositorNode, CMP_NODE_MASK, def_cmp_mask, "MASK", Mask, "Mask", "" ) +DefNode( CompositorNode, CMP_NODE_KEYINGSCREEN, def_cmp_keyingscreen, "KEYINGSCREEN", KeyingScreen, "KeyingScreen", "" ) DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" ) DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" ) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 8b2a5ebd263..7b0feab2bc1 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -76,6 +76,7 @@ set(SRC composite/nodes/node_composite_idMask.c composite/nodes/node_composite_image.c composite/nodes/node_composite_invert.c + composite/nodes/node_composite_keyingscreen.c composite/nodes/node_composite_lensdist.c composite/nodes/node_composite_levels.c composite/nodes/node_composite_lummaMatte.c diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index f850ea91f12..fd4918a32b5 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -105,6 +105,7 @@ void register_node_type_cmp_channel_matte(struct bNodeTreeType *ttype); void register_node_type_cmp_color_spill(struct bNodeTreeType *ttype); void register_node_type_cmp_luma_matte(struct bNodeTreeType *ttype); void register_node_type_cmp_doubleedgemask(struct bNodeTreeType *ttype); +void register_node_type_cmp_keyingscreen(struct bNodeTreeType *ttype); void register_node_type_cmp_translate(struct bNodeTreeType *ttype); void register_node_type_cmp_rotate(struct bNodeTreeType *ttype); diff --git a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c new file mode 100644 index 00000000000..6149285fdbc --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c @@ -0,0 +1,202 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_keyingscreen.c + * \ingroup cmpnodes + */ + +#include "BLF_translation.h" + +#include "DNA_movieclip_types.h" + +#include "BKE_movieclip.h" + +#include "BLI_listbase.h" +#include "BLI_math_base.h" +#include "BLI_math_color.h" +#include "BLI_voronoi.h" + +#include "node_composite_util.h" + +/* **************** Translate ******************** */ + +static bNodeSocketTemplate cmp_node_keyingscreen_out[] = { + { SOCK_RGBA, 0, "Screen"}, + { -1, 0, "" } +}; + + +static void compute_gradient_screen(RenderData *rd, NodeKeyingScreenData *keyingscreen_data, MovieClip *clip, CompBuf *screenbuf) +{ + MovieClipUser user = {0}; + MovieTracking *tracking = &clip->tracking; + MovieTrackingTrack *track; + VoronoiTriangulationPoint *triangulated_points; + VoronoiSite *sites; + ImBuf *ibuf; + ListBase *tracksbase; + ListBase edges = {NULL, NULL}; + int sites_total, triangulated_points_total, triangles_total; + int (*triangles)[3]; + int i, x, y; + float *rect = screenbuf->rect; + + if (keyingscreen_data->tracking_object[0]) { + MovieTrackingObject *object = BKE_tracking_named_object(tracking, keyingscreen_data->tracking_object); + + if (!object) + return; + + tracksbase = BKE_tracking_object_tracks(tracking, object); + } + else + tracksbase = BKE_tracking_get_tracks(tracking); + + sites_total = BLI_countlist(tracksbase); + + if (!sites_total) + return; + + BKE_movieclip_user_set_frame(&user, rd->cfra); + ibuf = BKE_movieclip_get_ibuf(clip, &user); + + sites = MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites"); + track = tracksbase->first; + i = 0; + while (track) { + VoronoiSite *site = &sites[i]; + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, rd->cfra); + ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE); + int j; + + zero_v3(site->color); + for (j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) { + if (pattern_ibuf->rect_float) { + add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]); + } + else { + unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect; + + site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f); + site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f); + site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f); + } + } + + mul_v3_fl(site->color, 1.0f / (pattern_ibuf->x * pattern_ibuf->y)); + IMB_freeImBuf(pattern_ibuf); + + site->co[0] = marker->pos[0] * screenbuf->x; + site->co[1] = marker->pos[1] * screenbuf->y; + + track = track->next; + i++; + } + + IMB_freeImBuf(ibuf); + + BLI_voronoi_compute(sites, sites_total, screenbuf->x, screenbuf->y, &edges); + + BLI_voronoi_triangulate(sites, sites_total, &edges, screenbuf->x, screenbuf->y, + &triangulated_points, &triangulated_points_total, + &triangles, &triangles_total); + + for (y = 0; y < screenbuf->y; y++) { + for (x = 0; x < screenbuf->x; x++) { + int index = 4 * (y * screenbuf->x + x); + + rect[index + 0] = rect[index + 1] = rect[index + 2] = 0.0f; + rect[index + 3] = 1.0f; + + for (i = 0; i < triangles_total; i++) { + int *triangle = triangles[i]; + VoronoiTriangulationPoint *a = &triangulated_points[triangle[0]], + *b = &triangulated_points[triangle[1]], + *c = &triangulated_points[triangle[2]]; + float co[2] = {x, y}, w[3]; + + if (barycentric_coords_v2(a->co, b->co, c->co, co, w)) { + if (barycentric_inside_triangle_v2(w)) { + rect[index + 0] += a->color[0] * w[0] + b->color[0] * w[1] + c->color[0] * w[2]; + rect[index + 1] += a->color[1] * w[0] + b->color[1] * w[1] + c->color[1] * w[2]; + rect[index + 2] += a->color[2] * w[0] + b->color[2] * w[1] + c->color[2] * w[2]; + } + } + } + } + } + + MEM_freeN(triangulated_points); + MEM_freeN(triangles); + MEM_freeN(sites); + BLI_freelistN(&edges); +} + +static void exec(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) +{ + NodeKeyingScreenData *keyingscreen_data = node->storage; + RenderData *rd = data; + CompBuf *screenbuf = NULL; + + if (node->id) { + MovieClip *clip = (MovieClip *) node->id; + MovieClipUser user = {0}; + int width, height; + + BKE_movieclip_user_set_frame(&user, rd->cfra); + BKE_movieclip_get_size(clip, &user, &width, &height); + + screenbuf = alloc_compbuf(width, height, CB_RGBA, TRUE); + compute_gradient_screen(rd, keyingscreen_data, clip, screenbuf); + } + + out[0]->data = screenbuf; +} + +static void node_composit_init_keyingscreen(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +{ + NodeKeyingScreenData *data; + + data = MEM_callocN(sizeof(NodeKeyingScreenData), "node keyingscreen data"); + + node->storage = data; +} + +void register_node_type_cmp_keyingscreen(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, CMP_NODE_KEYINGSCREEN, "Keying Screen", NODE_CLASS_MATTE, NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, cmp_node_keyingscreen_out); + node_type_size(&ntype, 140, 100, 320); + node_type_init(&ntype, node_composit_init_keyingscreen); + node_type_storage(&ntype, "NodeKeyingScreenData", node_free_standard_storage, node_copy_standard_storage); + node_type_exec(&ntype, exec); + + nodeRegisterType(ttype, &ntype); +} From 554107b6a1c4a89288e77fbf3e0d11c4ec777bfe Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 14 Jun 2012 13:33:37 +0000 Subject: [PATCH 310/360] Disable fixed-sized specializations for schur solver As far as i remember Keir, this should be safe for our usages of ceres and it should save noticeable amount of time and used memory when compiling blender with libmv support. Quick tests with tracking went smooth after this. --- extern/libmv/third_party/ceres/CMakeLists.txt | 36 +++++++++++-------- extern/libmv/third_party/ceres/SConscript | 4 ++- extern/libmv/third_party/ceres/bundle.sh | 20 ++++++++++- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/extern/libmv/third_party/ceres/CMakeLists.txt b/extern/libmv/third_party/ceres/CMakeLists.txt index 5207bddec12..e6a9e430c47 100644 --- a/extern/libmv/third_party/ceres/CMakeLists.txt +++ b/extern/libmv/third_party/ceres/CMakeLists.txt @@ -58,21 +58,6 @@ set(SRC internal/ceres/detect_structure.cc internal/ceres/evaluator.cc internal/ceres/file.cc - internal/ceres/generated/schur_eliminator_2_2_2.cc - internal/ceres/generated/schur_eliminator_2_2_3.cc - internal/ceres/generated/schur_eliminator_2_2_4.cc - internal/ceres/generated/schur_eliminator_2_2_d.cc - internal/ceres/generated/schur_eliminator_2_3_3.cc - internal/ceres/generated/schur_eliminator_2_3_4.cc - internal/ceres/generated/schur_eliminator_2_3_9.cc - internal/ceres/generated/schur_eliminator_2_3_d.cc - internal/ceres/generated/schur_eliminator_2_4_3.cc - internal/ceres/generated/schur_eliminator_2_4_4.cc - internal/ceres/generated/schur_eliminator_2_4_d.cc - internal/ceres/generated/schur_eliminator_4_4_2.cc - internal/ceres/generated/schur_eliminator_4_4_3.cc - internal/ceres/generated/schur_eliminator_4_4_4.cc - internal/ceres/generated/schur_eliminator_4_4_d.cc internal/ceres/generated/schur_eliminator_d_d_d.cc internal/ceres/gradient_checking_cost_function.cc internal/ceres/implicit_schur_complement.cc @@ -191,6 +176,26 @@ set(SRC internal/ceres/visibility.h ) +#if(FALSE) +# list(APPEND SRC +# internal/ceres/generated/schur_eliminator_2_2_2.cc +# internal/ceres/generated/schur_eliminator_2_2_3.cc +# internal/ceres/generated/schur_eliminator_2_2_4.cc +# internal/ceres/generated/schur_eliminator_2_2_d.cc +# internal/ceres/generated/schur_eliminator_2_3_3.cc +# internal/ceres/generated/schur_eliminator_2_3_4.cc +# internal/ceres/generated/schur_eliminator_2_3_9.cc +# internal/ceres/generated/schur_eliminator_2_3_d.cc +# internal/ceres/generated/schur_eliminator_2_4_3.cc +# internal/ceres/generated/schur_eliminator_2_4_4.cc +# internal/ceres/generated/schur_eliminator_2_4_d.cc +# internal/ceres/generated/schur_eliminator_4_4_2.cc +# internal/ceres/generated/schur_eliminator_4_4_3.cc +# internal/ceres/generated/schur_eliminator_4_4_4.cc +# internal/ceres/generated/schur_eliminator_4_4_d.cc +# ) +#endif() + if(WIN32) list(APPEND INC ../glog/src/windows @@ -213,6 +218,7 @@ add_definitions( -D"CERES_HASH_NAMESPACE_END=}}" -DCERES_NO_SUITESPARSE -DCERES_DONT_HAVE_PROTOCOL_BUFFERS + -DCERES_RESTRICT_SCHUR_SPECIALIZATION ) blender_add_lib(extern_ceres "${SRC}" "${INC}" "${INC_SYS}") diff --git a/extern/libmv/third_party/ceres/SConscript b/extern/libmv/third_party/ceres/SConscript index d8b2b8520d7..6b5f1b8d64d 100644 --- a/extern/libmv/third_party/ceres/SConscript +++ b/extern/libmv/third_party/ceres/SConscript @@ -13,13 +13,15 @@ src = [] defs = [] src += env.Glob('internal/ceres/*.cc') -src += env.Glob('internal/ceres/generated/*.cc') +src += env.Glob('internal/ceres/generated/schur_eliminator_d_d_d.cc') +#src += env.Glob('internal/ceres/generated/*.cc') defs.append('CERES_HAVE_PTHREAD') defs.append('CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {') defs.append('CERES_HASH_NAMESPACE_END=}}') defs.append('CERES_NO_SUITESPARSE') defs.append('CERES_DONT_HAVE_PROTOCOL_BUFFERS') +defs.append('CERES_RESTRICT_SCHUR_SPECIALIZATION') incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags' diff --git a/extern/libmv/third_party/ceres/bundle.sh b/extern/libmv/third_party/ceres/bundle.sh index f54342180db..99aaadd8d87 100755 --- a/extern/libmv/third_party/ceres/bundle.sh +++ b/extern/libmv/third_party/ceres/bundle.sh @@ -1,5 +1,6 @@ #!/bin/sh +if false; then if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then echo Proceeding as requested by command line ... else @@ -36,7 +37,10 @@ done rm -rf $tmp -sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | sort -d` +fi + +sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | grep -v -E 'schur_eliminator_[0-9]_[0-9]_[0-9d].cc' | sort -d` +generated_sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//#\t\t/' | grep -E 'schur_eliminator_[0-9]_[0-9]_[0-9d].cc' | sort -d` headers=`find ./include ./internal -type f -iname '*.h' | sed -r 's/^\.\//\t/' | sort -d` src_dir=`find ./internal -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort -d | uniq` @@ -48,6 +52,10 @@ for x in $src_dir $src_third_dir; do continue; fi + if test `echo "$x" | grep -c generated` -eq 1; then + continue; + fi + if stat $x/*.cpp > /dev/null 2>&1; then t="src += env.Glob('`echo $x'/*.cpp'`')" fi @@ -121,6 +129,12 @@ ${sources} ${headers} ) +#if(FALSE) +# list(APPEND SRC +${generated_sources} +# ) +#endif() + if(WIN32) list(APPEND INC ../glog/src/windows @@ -143,6 +157,7 @@ add_definitions( -D"CERES_HASH_NAMESPACE_END=}}" -DCERES_NO_SUITESPARSE -DCERES_DONT_HAVE_PROTOCOL_BUFFERS + -DCERES_RESTRICT_SCHUR_SPECIALIZATION ) blender_add_lib(extern_ceres "\${SRC}" "\${INC}" "\${INC_SYS}") @@ -164,12 +179,15 @@ src = [] defs = [] $src +src += env.Glob('internal/ceres/generated/schur_eliminator_d_d_d.cc') +#src += env.Glob('internal/ceres/generated/*.cc') defs.append('CERES_HAVE_PTHREAD') defs.append('CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {') defs.append('CERES_HASH_NAMESPACE_END=}}') defs.append('CERES_NO_SUITESPARSE') defs.append('CERES_DONT_HAVE_PROTOCOL_BUFFERS') +defs.append('CERES_RESTRICT_SCHUR_SPECIALIZATION') incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags' From a2c862570e52e2488ae894d0e265a759fdb5f022 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 14 Jun 2012 13:48:04 +0000 Subject: [PATCH 311/360] Blender is using tabs, not spaces for indentation --- source/blender/makesrna/intern/rna_nodetree.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 509e20949c2..762e5ef0dfa 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3089,10 +3089,10 @@ static void def_cmp_mask(StructRNA *srna) { PropertyRNA *prop; - prop = RNA_def_property(srna, "smooth_mask", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom1", 0); - RNA_def_property_ui_text(prop, "Anti-Alias", "Apply an anti-aliasing filter to the mask"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + prop = RNA_def_property(srna, "smooth_mask", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "custom1", 0); + RNA_def_property_ui_text(prop, "Anti-Alias", "Apply an anti-aliasing filter to the mask"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "id"); From 201e9d815a2f200f22a0dae7f885a568049a279d Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 14 Jun 2012 13:54:55 +0000 Subject: [PATCH 312/360] Bugfix for [#31829] Add lamp icons missing. Patch by Philipp Oeser. Note: If you do code cleanups, and revert make sure you revert it correct and not halfway. ;-) r47034 --- source/blender/editors/object/object_add.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 159f75b60e6..ba26b92f354 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -108,13 +108,14 @@ #include "object_intern.h" /* this is an exact copy of the define in rna_lamp.c - * kept here because of linking order */ + * kept here because of linking order. + * Icons are only defined here */ EnumPropertyItem lamp_type_items[] = { - {LA_LOCAL, "POINT", 0, "Point", "Omnidirectional point light source"}, - {LA_SUN, "SUN", 0, "Sun", "Constant direction parallel ray light source"}, - {LA_SPOT, "SPOT", 0, "Spot", "Directional cone light source"}, - {LA_HEMI, "HEMI", 0, "Hemi", "180 degree constant light source"}, - {LA_AREA, "AREA", 0, "Area", "Directional area light source"}, + {LA_LOCAL, "POINT", ICON_LAMP_POINT, "Point", "Omnidirectional point light source"}, + {LA_SUN, "SUN", ICON_LAMP_SUN, "Sun", "Constant direction parallel ray light source"}, + {LA_SPOT, "SPOT", ICON_LAMP_SPOT, "Spot", "Directional cone light source"}, + {LA_HEMI, "HEMI", ICON_LAMP_HEMI, "Hemi", "180 degree constant light source"}, + {LA_AREA, "AREA", ICON_LAMP_AREA, "Area", "Directional area light source"}, {0, NULL, 0, NULL, NULL} }; From 29e5f72395fc4caad621815aa66bc3eda583c848 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 14 Jun 2012 14:02:15 +0000 Subject: [PATCH 313/360] Interface: * Rename "Clear Game Property" to "Rename Game Properties", because the operator deletes all game properties from all selected object(s), not only one. This fixes [#31828], patch by Philipp Oeser. --- source/blender/editors/object/object_edit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 3d7dd01bf30..5ad663b92d3 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1770,7 +1770,7 @@ static int game_property_clear_exec(bContext *C, wmOperator *UNUSED(op)) void OBJECT_OT_game_property_clear(wmOperatorType *ot) { /* identifiers */ - ot->name = "Clear Game Property"; + ot->name = "Clear Game Properties"; ot->idname = "OBJECT_OT_game_property_clear"; ot->description = "Remove all game properties from all selected objects"; From 931aeeb1f22d06e47357866139ff9c578b64bf7b Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 14 Jun 2012 14:04:55 +0000 Subject: [PATCH 314/360] * Add RNA comment for Lamp icon defines. --- source/blender/makesrna/intern/rna_lamp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index fdad91165c4..9d63e0e687d 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -180,7 +180,7 @@ static void rna_Lamp_use_nodes_update(Main *blain, Scene *scene, PointerRNA *ptr } #else - +/* Don't define icons here, so they don't show up in the Lamp UI (properties Editor) - DingTo */ EnumPropertyItem lamp_type_items[] = { {LA_LOCAL, "POINT", 0, "Point", "Omnidirectional point light source"}, {LA_SUN, "SUN", 0, "Sun", "Constant direction parallel ray light source"}, From 43864f9103d726fa3c425afb87d38433a2c01ba6 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Thu, 14 Jun 2012 14:47:41 +0000 Subject: [PATCH 315/360] fix a nullpointer exception when data missing in dae file --- source/blender/collada/ArmatureImporter.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index c58b6f3101d..115f129cb88 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -654,11 +654,17 @@ void ArmatureImporter::make_armatures(bContext *C) create_armature_bones(skin); // link armature with a mesh object - Object *ob = mesh_importer->get_object_by_geom_uid(*get_geometry_uid(skin.get_controller_uid())); - if (ob) - skin.link_armature(C, ob, joint_by_uid, this); + const COLLADAFW::UniqueId &uid = skin.get_controller_uid(); + const COLLADAFW::UniqueId *guid = get_geometry_uid(uid); + if (guid != NULL) { + Object *ob = mesh_importer->get_object_by_geom_uid(*guid); + if (ob) + skin.link_armature(C, ob, joint_by_uid, this); + else + fprintf(stderr, "Cannot find object to link armature with.\n"); + } else - fprintf(stderr, "Cannot find object to link armature with.\n"); + fprintf(stderr, "Cannot find geometry to link armature with.\n"); // set armature parent if any Object *par = skin.get_parent(); From 91eed57e62f2c820a9d1b4764ff3d4c7adafd51c Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Thu, 14 Jun 2012 14:48:52 +0000 Subject: [PATCH 316/360] Collada: cleanup sort function for --- source/blender/collada/collada_utils.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index 3d9aa8e542d..c4e336f3bc6 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -230,14 +230,13 @@ void bc_remove_mark(Object *ob) // Use bubble sort algorithm for sorting the export set void bc_bubble_sort_by_Object_name(LinkNode *export_set) { - int i, j; // loop indices - bool unsorted = true; + bool sorted = false; + LinkNode *node; + for(node=export_set; node->next && !sorted; node=node->next) { - LinkNode *current; - int set_size = BLI_linklist_length(export_set); - for(i = 0; (i < set_size) && unsorted; i++) { - unsorted = false; + sorted = true; + LinkNode *current; for (current=export_set; current->next; current = current->next) { Object *a = (Object *)current->link; Object *b = (Object *)current->next->link; @@ -248,7 +247,7 @@ void bc_bubble_sort_by_Object_name(LinkNode *export_set) if (str_a.compare(str_b) > 0) { current->link = b; current->next->link = a; - unsorted = true; + sorted = false; } } From 0b2fcf43680eb0c6877bd111580fa98ae7ccb7e7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 15:04:40 +0000 Subject: [PATCH 317/360] change to scale node - multiply scale by scene size, without this theres no reliable way to match different scaled footage to an output and still have useful preview's at <100 percentage. --- source/blender/compositor/nodes/COM_ScaleNode.cpp | 5 +++++ .../compositor/operations/COM_ScaleOperation.cpp | 7 +++++++ .../blender/compositor/operations/COM_ScaleOperation.h | 10 ++++++++++ source/blender/makesdna/DNA_scene_types.h | 5 ++++- .../nodes/composite/nodes/node_composite_scale.c | 9 +++++++-- 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp index fd4e4331fca..09fd40be31e 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.cpp +++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp @@ -77,6 +77,11 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c case CMP_SCALE_ABSOLUTE: { ScaleAbsoluteOperation *operation = new ScaleAbsoluteOperation(); // TODO: what is the use of this one.... perhaps some issues when the ui was updated.... +#ifdef USE_SCENE_COMPO_SCALE + const RenderData *data = &context->getScene()->r; + operation->setRenderPercentage(data->size / 100.0f); +#endif + inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); inputXSocket->relinkConnections(operation->getInputSocket(1), 1, graph); inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph); diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp index 341bcdd1b62..ae640bf7057 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cpp +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -136,8 +136,14 @@ void ScaleAbsoluteOperation::executePixel(float *color, float x, float y, PixelS this->inputXOperation->read(scaleX, x, y, sampler, inputBuffers); this->inputYOperation->read(scaleY, x, y, sampler, inputBuffers); +#ifdef USE_SCENE_COMPO_SCALE + const float scx = scaleX[0] * this->render_perc; // target absolute scale * render_percentage + const float scy = scaleY[0] * this->render_perc; // target absolute scale * render_percentage +#else const float scx = scaleX[0]; // target absolute scale const float scy = scaleY[0]; // target absolute scale +#endif + const float width = this->getWidth(); const float height = this->getHeight(); //div @@ -146,6 +152,7 @@ void ScaleAbsoluteOperation::executePixel(float *color, float x, float y, PixelS float nx = this->centerX + (x - this->centerX) / relativeXScale; float ny = this->centerY + (y - this->centerY) / relativeYScale; + this->inputOperation->read(color, nx, ny, sampler, inputBuffers); } diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h index 9e24ab3d1ca..cc666187f36 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -47,6 +47,12 @@ class ScaleAbsoluteOperation : public NodeOperation { SocketReader *inputYOperation; float centerX; float centerY; + +#ifdef USE_SCENE_COMPO_SCALE + /* scene->r.size / 100.0f */ /* added after 2.63, this may be done differently/better */ + float render_perc; +#endif + public: ScaleAbsoluteOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); @@ -54,6 +60,10 @@ public: void initExecution(); void deinitExecution(); + +#ifdef USE_SCENE_COMPO_SCALE + void setRenderPercentage(float render_perc) { this->render_perc = render_perc; } +#endif }; class ScaleFixedSizeOperation : public NodeOperation { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 75b0b18879d..33b28a6abff 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -34,9 +34,12 @@ #include "DNA_defs.h" -// XXX, temp feature - campbell +/* XXX, temp feature - campbell */ #define DURIAN_CAMERA_SWITCH +/* XXX - We cant agree on this and it might get deprecated - campbell */ +#define USE_SCENE_COMPO_SCALE + #ifdef __cplusplus extern "C" { #endif diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c index a36919ba553..90ab485af75 100644 --- a/source/blender/nodes/composite/nodes/node_composite_scale.c +++ b/source/blender/nodes/composite/nodes/node_composite_scale.c @@ -49,11 +49,12 @@ static bNodeSocketTemplate cmp_node_scale_out[]= { /* node->custom1 stores if input values are absolute or relative scale */ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { + RenderData *rd = data; + if (out[0]->hasoutput==0) return; if (in[0]->data) { - RenderData *rd= data; CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); ImBuf *ibuf; int newx, newy; @@ -114,9 +115,13 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b int a, x, y; float *fp; +#ifdef USE_SCENE_COMPO_SCALE + x = MAX2((int)in[1]->vec[0], 1) * (rd->size / 100.0f); + y = MAX2((int)in[2]->vec[0], 1) * (rd->size / 100.0f); +#else x = MAX2((int)in[1]->vec[0], 1); y = MAX2((int)in[2]->vec[0], 1); - +#endif stackbuf = alloc_compbuf(x, y, CB_RGBA, 1); fp = stackbuf->rect; From 1a39e74131b9dc30cb5daf4dffe3bb17c74f44fc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 16:13:09 +0000 Subject: [PATCH 318/360] revert own commits 47907, 47908 after some discussion this is really bad and needs some different solution. --- source/blender/compositor/nodes/COM_ScaleNode.cpp | 5 ----- .../blender/compositor/operations/COM_ScaleOperation.cpp | 5 ----- .../blender/compositor/operations/COM_ScaleOperation.h | 9 --------- source/blender/makesdna/DNA_scene_types.h | 3 --- .../blender/nodes/composite/nodes/node_composite_scale.c | 9 ++------- 5 files changed, 2 insertions(+), 29 deletions(-) diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp index 09fd40be31e..fd4e4331fca 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.cpp +++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp @@ -77,11 +77,6 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c case CMP_SCALE_ABSOLUTE: { ScaleAbsoluteOperation *operation = new ScaleAbsoluteOperation(); // TODO: what is the use of this one.... perhaps some issues when the ui was updated.... -#ifdef USE_SCENE_COMPO_SCALE - const RenderData *data = &context->getScene()->r; - operation->setRenderPercentage(data->size / 100.0f); -#endif - inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); inputXSocket->relinkConnections(operation->getInputSocket(1), 1, graph); inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph); diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp index ae640bf7057..f0c3b41b61a 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cpp +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -136,13 +136,8 @@ void ScaleAbsoluteOperation::executePixel(float *color, float x, float y, PixelS this->inputXOperation->read(scaleX, x, y, sampler, inputBuffers); this->inputYOperation->read(scaleY, x, y, sampler, inputBuffers); -#ifdef USE_SCENE_COMPO_SCALE - const float scx = scaleX[0] * this->render_perc; // target absolute scale * render_percentage - const float scy = scaleY[0] * this->render_perc; // target absolute scale * render_percentage -#else const float scx = scaleX[0]; // target absolute scale const float scy = scaleY[0]; // target absolute scale -#endif const float width = this->getWidth(); const float height = this->getHeight(); diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h index cc666187f36..cf2f878e8bc 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -48,11 +48,6 @@ class ScaleAbsoluteOperation : public NodeOperation { float centerX; float centerY; -#ifdef USE_SCENE_COMPO_SCALE - /* scene->r.size / 100.0f */ /* added after 2.63, this may be done differently/better */ - float render_perc; -#endif - public: ScaleAbsoluteOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); @@ -60,10 +55,6 @@ public: void initExecution(); void deinitExecution(); - -#ifdef USE_SCENE_COMPO_SCALE - void setRenderPercentage(float render_perc) { this->render_perc = render_perc; } -#endif }; class ScaleFixedSizeOperation : public NodeOperation { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 33b28a6abff..3bceb0277d5 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -37,9 +37,6 @@ /* XXX, temp feature - campbell */ #define DURIAN_CAMERA_SWITCH -/* XXX - We cant agree on this and it might get deprecated - campbell */ -#define USE_SCENE_COMPO_SCALE - #ifdef __cplusplus extern "C" { #endif diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c index 90ab485af75..9a25a62b981 100644 --- a/source/blender/nodes/composite/nodes/node_composite_scale.c +++ b/source/blender/nodes/composite/nodes/node_composite_scale.c @@ -49,12 +49,11 @@ static bNodeSocketTemplate cmp_node_scale_out[]= { /* node->custom1 stores if input values are absolute or relative scale */ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - RenderData *rd = data; - if (out[0]->hasoutput==0) return; if (in[0]->data) { + RenderData *rd = data; CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); ImBuf *ibuf; int newx, newy; @@ -115,13 +114,9 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b int a, x, y; float *fp; -#ifdef USE_SCENE_COMPO_SCALE - x = MAX2((int)in[1]->vec[0], 1) * (rd->size / 100.0f); - y = MAX2((int)in[2]->vec[0], 1) * (rd->size / 100.0f); -#else x = MAX2((int)in[1]->vec[0], 1); y = MAX2((int)in[2]->vec[0], 1); -#endif + stackbuf = alloc_compbuf(x, y, CB_RGBA, 1); fp = stackbuf->rect; From 550824968ce4ecea3718e5744b48812be6c5d554 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 16:15:37 +0000 Subject: [PATCH 319/360] style cleanup --- .../compositor/nodes/COM_ScaleNode.cpp | 4 +- .../composite/nodes/node_composite_scale.c | 84 +++++++++---------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp index fd4e4331fca..5b2d6851f9f 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.cpp +++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp @@ -15,8 +15,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand */ diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c index 9a25a62b981..69d76ed03e0 100644 --- a/source/blender/nodes/composite/nodes/node_composite_scale.c +++ b/source/blender/nodes/composite/nodes/node_composite_scale.c @@ -4,7 +4,7 @@ * 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. + * 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 @@ -34,82 +34,82 @@ /* **************** Scale ******************** */ -static bNodeSocketTemplate cmp_node_scale_in[]= { - { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("X"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX, PROP_FACTOR}, - { SOCK_FLOAT, 1, N_("Y"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX, PROP_FACTOR}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_scale_in[] = { + { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_FLOAT, 1, N_("X"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Y"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX, PROP_FACTOR}, + { -1, 0, "" } }; -static bNodeSocketTemplate cmp_node_scale_out[]= { - { SOCK_RGBA, 0, N_("Image")}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_scale_out[] = { + { SOCK_RGBA, 0, N_("Image")}, + { -1, 0, "" } }; /* only supports RGBA nodes now */ /* node->custom1 stores if input values are absolute or relative scale */ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - if (out[0]->hasoutput==0) + if (out[0]->hasoutput == 0) return; - + if (in[0]->data) { RenderData *rd = data; - CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); + CompBuf *stackbuf, *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA); ImBuf *ibuf; int newx, newy; - - if (node->custom1==CMP_SCALE_RELATIVE) { - newx= MAX2((int)(in[1]->vec[0]*cbuf->x), 1); - newy= MAX2((int)(in[2]->vec[0]*cbuf->y), 1); + + if (node->custom1 == CMP_SCALE_RELATIVE) { + newx = MAX2((int)(in[1]->vec[0] * cbuf->x), 1); + newy = MAX2((int)(in[2]->vec[0] * cbuf->y), 1); } - else if (node->custom1==CMP_SCALE_SCENEPERCENT) { + else if (node->custom1 == CMP_SCALE_SCENEPERCENT) { newx = cbuf->x * (rd->size / 100.0f); newy = cbuf->y * (rd->size / 100.0f); } - else if (node->custom1==CMP_SCALE_RENDERPERCENT) { - newx= (rd->xsch * rd->size)/100; - newy= (rd->ysch * rd->size)/100; + else if (node->custom1 == CMP_SCALE_RENDERPERCENT) { + newx = (rd->xsch * rd->size) / 100; + newy = (rd->ysch * rd->size) / 100; } - else { /* CMP_SCALE_ABSOLUTE */ - newx= MAX2((int)in[1]->vec[0], 1); - newy= MAX2((int)in[2]->vec[0], 1); + else { /* CMP_SCALE_ABSOLUTE */ + newx = MAX2((int)in[1]->vec[0], 1); + newy = MAX2((int)in[2]->vec[0], 1); } - newx= MIN2(newx, CMP_SCALE_MAX); - newy= MIN2(newy, CMP_SCALE_MAX); + newx = MIN2(newx, CMP_SCALE_MAX); + newy = MIN2(newy, CMP_SCALE_MAX); - ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0); + ibuf = IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0); if (ibuf) { - ibuf->rect_float= cbuf->rect; + ibuf->rect_float = cbuf->rect; IMB_scaleImBuf(ibuf, newx, newy); - + if (ibuf->rect_float == cbuf->rect) { /* no scaling happened. */ - stackbuf= pass_on_compbuf(in[0]->data); + stackbuf = pass_on_compbuf(in[0]->data); } else { - stackbuf= alloc_compbuf(newx, newy, CB_RGBA, 0); - stackbuf->rect= ibuf->rect_float; - stackbuf->malloc= 1; + stackbuf = alloc_compbuf(newx, newy, CB_RGBA, 0); + stackbuf->rect = ibuf->rect_float; + stackbuf->malloc = 1; } - ibuf->rect_float= NULL; + ibuf->rect_float = NULL; ibuf->mall &= ~IB_rectfloat; IMB_freeImBuf(ibuf); - + /* also do the translation vector */ - stackbuf->xof = (int)(((float)newx/(float)cbuf->x) * (float)cbuf->xof); - stackbuf->yof = (int)(((float)newy/(float)cbuf->y) * (float)cbuf->yof); + stackbuf->xof = (int)(((float)newx / (float)cbuf->x) * (float)cbuf->xof); + stackbuf->yof = (int)(((float)newy / (float)cbuf->y) * (float)cbuf->yof); } else { - stackbuf= dupalloc_compbuf(cbuf); + stackbuf = dupalloc_compbuf(cbuf); printf("Scaling to %dx%d failed\n", newx, newy); } - - out[0]->data= stackbuf; - if (cbuf!=in[0]->data) + + out[0]->data = stackbuf; + if (cbuf != in[0]->data) free_compbuf(cbuf); } - else if (node->custom1==CMP_SCALE_ABSOLUTE) { + else if (node->custom1 == CMP_SCALE_ABSOLUTE) { CompBuf *stackbuf; int a, x, y; float *fp; @@ -126,7 +126,7 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b fp += 4; } - out[0]->data= stackbuf; + out[0]->data = stackbuf; } } From ffc9e340b12ffbebbf193f573a3bbe072b9f5df6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 16:55:55 +0000 Subject: [PATCH 320/360] new scaling options to scale footage without stretching - add stretch/fit/crop to compositor scale node, default behavior isnt changed. this is only added for the old compositor, will add to the new compositor next. --- source/blender/blenkernel/BKE_node.h | 3 ++ source/blender/editors/space_node/drawnode.c | 4 ++ .../editors/space_view3d/view3d_draw.c | 3 +- source/blender/makesrna/intern/rna_nodetree.c | 25 +++++++++--- .../composite/nodes/node_composite_scale.c | 40 ++++++++++++++++++- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index c856d407f05..b3f17c06d5c 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -693,6 +693,9 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); #define CMP_SCALE_ABSOLUTE 1 #define CMP_SCALE_SCENEPERCENT 2 #define CMP_SCALE_RENDERPERCENT 3 +/* custom2 */ +#define CMP_SCALE_RENDERSIZE_FRAME_ASPECT (1 << 0) +#define CMP_SCALE_RENDERSIZE_FRAME_CROP (1 << 1) /* API */ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 033bfd165c2..e48dd39022e 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2018,6 +2018,10 @@ static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C static void node_composit_buts_scale(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "space", 0, "", ICON_NONE); + + if (RNA_enum_get(ptr, "space") == CMP_SCALE_RENDERPERCENT) { + uiItemR(layout, ptr, "frame_method", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + } } static void node_composit_buts_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 5073eca96ad..1f7dfef3871 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1632,8 +1632,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, } /* aspect correction */ - if (bgpic->flag & V3D_BGPIC_CAMERA_ASPECT) - { + if (bgpic->flag & V3D_BGPIC_CAMERA_ASPECT) { /* apply aspect from clip */ const float w_src = ibuf->x * image_aspect[0]; const float h_src = ibuf->y * image_aspect[1]; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 762e5ef0dfa..9567226f722 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2077,20 +2077,35 @@ static void def_cmp_dilate_erode(StructRNA *srna) static void def_cmp_scale(StructRNA *srna) { PropertyRNA *prop; - + static EnumPropertyItem space_items[] = { - {0, "RELATIVE", 0, "Relative", ""}, - {1, "ABSOLUTE", 0, "Absolute", ""}, - {2, "SCENE_SIZE", 0, "Scene Size", ""}, - {3, "RENDER_SIZE", 0, "Render Size", ""}, + {CMP_SCALE_RELATIVE, "RELATIVE", 0, "Relative", ""}, + {CMP_SCALE_ABSOLUTE, "ABSOLUTE", 0, "Absolute", ""}, + {CMP_SCALE_SCENEPERCENT, "SCENE_SIZE", 0, "Scene Size", ""}, + {CMP_SCALE_RENDERPERCENT, "RENDER_SIZE", 0, "Render Size", ""}, {0, NULL, 0, NULL, NULL} }; + /* matching bgpic_camera_frame_items[] */ + static const EnumPropertyItem space_frame_items[] = { + {0, "STRETCH", 0, "Stretch", ""}, + {CMP_SCALE_RENDERSIZE_FRAME_ASPECT, "FIT", 0, "Fit", ""}, + {CMP_SCALE_RENDERSIZE_FRAME_ASPECT | CMP_SCALE_RENDERSIZE_FRAME_CROP, "CROP", 0, "Crop", ""}, + {0, NULL, 0, NULL, NULL} + }; + prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom1"); RNA_def_property_enum_items(prop, space_items); RNA_def_property_ui_text(prop, "Space", "Coordinate space to scale relative to"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + /* expose 2 flags as a enum of 3 items */ + prop = RNA_def_property(srna, "frame_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "custom2"); + RNA_def_property_enum_items(prop, space_frame_items); + RNA_def_property_ui_text(prop, "Frame Method", "How the image fits in the camera frame"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } static void def_cmp_rotate(StructRNA *srna) diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c index 69d76ed03e0..fd4bd643126 100644 --- a/source/blender/nodes/composite/nodes/node_composite_scale.c +++ b/source/blender/nodes/composite/nodes/node_composite_scale.c @@ -67,8 +67,44 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b newy = cbuf->y * (rd->size / 100.0f); } else if (node->custom1 == CMP_SCALE_RENDERPERCENT) { - newx = (rd->xsch * rd->size) / 100; - newy = (rd->ysch * rd->size) / 100; + /* supports framing options */ + if (node->custom2 & CMP_SCALE_RENDERSIZE_FRAME_ASPECT) { + /* apply aspect from clip */ + const float w_src = cbuf->x; + const float h_src = cbuf->y; + + /* destination aspect is already applied from the camera frame */ + const float w_dst = (rd->xsch * rd->size) / 100; + const float h_dst = (rd->ysch * rd->size) / 100; + + const float asp_src = w_src / h_src; + const float asp_dst = w_dst / h_dst; + + if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) { + if ((asp_src > asp_dst) == ((node->custom2 & CMP_SCALE_RENDERSIZE_FRAME_CROP) != 0)) { + /* fit X */ + const float div = asp_src / asp_dst; + newx = w_dst * div; + newy = h_dst; + } + else { + /* fit Y */ + const float div = asp_dst / asp_src; + newx = w_dst; + newy = h_dst * div; + } + } + else { + /* same as below - no aspect correction needed */ + newx = w_dst; + newy = h_dst; + } + } + else { + /* stretch */ + newx = (rd->xsch * rd->size) / 100; + newy = (rd->ysch * rd->size) / 100; + } } else { /* CMP_SCALE_ABSOLUTE */ newx = MAX2((int)in[1]->vec[0], 1); From 2cc9ecad553f1154a72efce9f73f9cac80797dfd Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Thu, 14 Jun 2012 18:29:29 +0000 Subject: [PATCH 321/360] fix for exporting armature, when it is explicitly selected --- source/blender/collada/SceneExporter.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp index 63bf94923d4..bd746e241ca 100644 --- a/source/blender/collada/SceneExporter.cpp +++ b/source/blender/collada/SceneExporter.cpp @@ -84,10 +84,16 @@ void SceneExporter::exportHierarchy(Scene *sce) void SceneExporter::writeNodes(Object *ob, Scene *sce) { // Add associated armature first if available + bool armature_exported = false; Object *ob_arm = bc_get_assigned_armature(ob); - if (ob_arm != NULL && bc_is_marked(ob_arm)) { - bc_remove_mark(ob_arm); - writeNodes(ob_arm, sce); + if (ob_arm != NULL) + { + armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm); + if (armature_exported && bc_is_marked(ob_arm)) { + bc_remove_mark(ob_arm); + writeNodes(ob_arm, sce); + armature_exported = true; + } } COLLADASW::Node colladaNode(mSW); @@ -97,12 +103,11 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) colladaNode.start(); - bool is_skinned_mesh = arm_exporter->is_skinned_mesh(ob); std::list child_objects; // list child objects - LinkNode *node = this->export_settings->export_set; - while (node) { + LinkNode *node; + for (node=this->export_settings->export_set; node; node=node->next) { // cob - child object Object *cob = (Object *)node->link; @@ -118,10 +123,9 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) break; } } - node = node->next; } - if (ob->type == OB_MESH && this->export_settings->include_armatures && is_skinned_mesh) + if (ob->type == OB_MESH && armature_exported) // for skinned mesh we write obmat in TransformWriter::add_node_transform_identity(colladaNode); else @@ -130,7 +134,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) // if (ob->type == OB_MESH) { bool instance_controller_created = false; - if (this->export_settings->include_armatures && is_skinned_mesh) { + if (armature_exported) { instance_controller_created = arm_exporter->add_instance_controller(ob); } if (!instance_controller_created) { From 91d0ef0a7eaa74df92f1e30299ba0e1720658eb6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 18:55:35 +0000 Subject: [PATCH 322/360] scale node for new compositor now supports framing option. --- .../compositor/nodes/COM_ScaleNode.cpp | 2 + .../operations/COM_ScaleOperation.cpp | 41 ++++++++++++++++++- .../operations/COM_ScaleOperation.h | 8 ++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp index 5b2d6851f9f..85d5644484b 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.cpp +++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp @@ -65,6 +65,8 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c case CMP_SCALE_RENDERPERCENT: { const RenderData *data = &context->getScene()->r; ScaleFixedSizeOperation *operation = new ScaleFixedSizeOperation(); + operation->setIsAspect((bnode->custom2 & CMP_SCALE_RENDERSIZE_FRAME_ASPECT) != 0); + operation->setIsCrop((bnode->custom2 & CMP_SCALE_RENDERSIZE_FRAME_CROP) != 0); operation->setNewWidth(data->xsch * data->size / 100.0f); operation->setNewHeight(data->ysch * data->size / 100.0f); inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp index f0c3b41b61a..aea4da920a0 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cpp +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -190,6 +190,38 @@ void ScaleFixedSizeOperation::initExecution() this->inputOperation = this->getInputSocketReader(0); this->relX = inputOperation->getWidth() / (float)this->newWidth; this->relY = inputOperation->getHeight() / (float)this->newHeight; + + if (this->is_aspect) { + /* apply aspect from clip */ + const float w_src = inputOperation->getWidth(); + const float h_src = inputOperation->getHeight(); + + /* destination aspect is already applied from the camera frame */ + const float w_dst = this->newWidth; + const float h_dst = this->newHeight; + + const float asp_src = w_src / h_src; + const float asp_dst = w_dst / h_dst; + + this->offsetX = 0.0f; + this->offsetY = 0.0f; + + if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) { + if ((asp_src > asp_dst) == (this->is_crop == true)) { + /* fit X */ + const float div = asp_src / asp_dst; + this->relX /= div; + this->offsetX = ((w_src - (w_src * div)) / (w_src / w_dst)) / 2.0f; + } + else { + /* fit Y */ + const float div = asp_dst / asp_src; + this->relY /= div; + this->offsetY = ((h_src - (h_src * div)) / (h_src / h_dst)) / 2.0f; + } + } + + } } void ScaleFixedSizeOperation::deinitExecution() @@ -204,7 +236,14 @@ void ScaleFixedSizeOperation::executePixel(float *color, float x, float y, Pixel sampler = COM_PS_BICUBIC; #endif - this->inputOperation->read(color, x * relX, y * relY, sampler, inputBuffers); + if (this->is_aspect) { + float nx = ((x - this->offsetX) * relX); + float ny = ((y - this->offsetY) * relY); + this->inputOperation->read(color, nx, ny, sampler, inputBuffers); + } + else { + this->inputOperation->read(color, x * relX, y * relY, sampler, inputBuffers); + } } bool ScaleFixedSizeOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h index cf2f878e8bc..3964a5e2f71 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -63,6 +63,12 @@ class ScaleFixedSizeOperation : public NodeOperation { int newHeight; float relX; float relY; + + /* center is only used for aspect correction */ + float offsetX; + float offsetY; + bool is_aspect; + bool is_crop; public: ScaleFixedSizeOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); @@ -73,6 +79,8 @@ public: void deinitExecution(); void setNewWidth(int width) { this->newWidth = width; } void setNewHeight(int height) { this->newHeight = height; } + void setIsAspect(int is_aspect) { this->is_aspect = is_aspect; } + void setIsCrop(int is_crop) { this->is_crop = is_crop; } }; #endif From c42d4b101ba01d71e49321d7c82e0edf794a1bcd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 19:09:00 +0000 Subject: [PATCH 323/360] remove unused fRGB defines and change float member to bool. --- .../compositor/operations/COM_GlareBaseOperation.h | 12 ------------ .../compositor/operations/COM_TranslateOperation.h | 2 +- source/blender/nodes/composite/node_composite_util.h | 12 ------------ 3 files changed, 1 insertion(+), 25 deletions(-) diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h index 2ef413a936b..dc708044d31 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.h +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.h @@ -32,30 +32,18 @@ typedef float fRGB[4]; /* TODO - replace with BLI_math_vector */ -/* clear color */ -#define fRGB_clear(c) { c[0] = c[1] = c[2] = 0.f; } (void)0 /* copy c2 to c1 */ #define fRGB_copy(c1, c2) { c1[0] = c2[0]; c1[1] = c2[1]; c1[2] = c2[2]; c1[3] = c2[3]; } (void)0 /* add c2 to c1 */ #define fRGB_add(c1, c2) { c1[0] += c2[0]; c1[1] += c2[1]; c1[2] += c2[2]; } (void)0 -/* subtract c2 from c1 */ -#define fRGB_sub(c1, c2) { c1[0] -= c2[0]; c1[1] -= c2[1]; c1[2] -= c2[2]; } (void)0 /* multiply c by float value s */ #define fRGB_mult(c, s) { c[0] *= s; c[1] *= s; c[2] *= s; } (void)0 /* multiply c2 by s and add to c1 */ #define fRGB_madd(c1, c2, s) { c1[0] += c2[0] * s; c1[1] += c2[1] * s; c1[2] += c2[2] * s; } (void)0 /* multiply c2 by color c1 */ #define fRGB_colormult(c, cs) { c[0] *= cs[0]; c[1] *= cs[1]; c[2] *= cs[2]; } (void)0 -/* multiply c2 by color c3 and add to c1 */ -#define fRGB_colormadd(c1, c2, c3) { c1[0] += c2[0] * c3[0]; c1[1] += c2[1] * c3[1]; c1[2] += c2[2] * c3[2]; } (void)0 /* multiply c2 by color rgb, rgb as separate arguments */ #define fRGB_rgbmult(c, r, g, b) { c[0] *= (r); c[1] *= (g); c[2] *= (b); } (void)0 -/* swap colors c1 & c2 */ -#define fRGB_swap(c1, c2) { float _t = c1[0]; c1[0] = c2[0]; c2[0] = _t; \ - _t = c1[1]; c1[1] = c2[1]; c2[1] = _t; \ - _t = c1[2]; c1[2] = c2[2]; c2[2] = _t; \ - _t = c1[3]; c1[3] = c2[3]; c3[3] = _t; \ - } (void)0 class GlareBaseOperation : public SingleThreadedNodeOperation { diff --git a/source/blender/compositor/operations/COM_TranslateOperation.h b/source/blender/compositor/operations/COM_TranslateOperation.h index e512bd9318e..bf3121bec11 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.h +++ b/source/blender/compositor/operations/COM_TranslateOperation.h @@ -32,7 +32,7 @@ private: SocketReader *inputYOperation; float deltaX; float deltaY; - float isDeltaSet; + bool isDeltaSet; public: TranslateOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h index cab60caaae7..42e6ea6bd20 100644 --- a/source/blender/nodes/composite/node_composite_util.h +++ b/source/blender/nodes/composite/node_composite_util.h @@ -182,30 +182,18 @@ extern void node_ID_title_cb(void *node_v, void *unused_v); /* utility functions used by glare, tonemap and lens distortion */ /* soms macros for color handling */ typedef float fRGB[4]; -/* clear color */ -#define fRGB_clear(c) { c[0]=c[1]=c[2]=0.f; } (void)0 /* copy c2 to c1 */ #define fRGB_copy(c1, c2) { c1[0]=c2[0]; c1[1]=c2[1]; c1[2]=c2[2]; c1[3]=c2[3]; } (void)0 /* add c2 to c1 */ #define fRGB_add(c1, c2) { c1[0]+=c2[0]; c1[1]+=c2[1]; c1[2]+=c2[2]; } (void)0 -/* subtract c2 from c1 */ -#define fRGB_sub(c1, c2) { c1[0]-=c2[0]; c1[1]-=c2[1]; c1[2]-=c2[2]; } (void)0 /* multiply c by float value s */ #define fRGB_mult(c, s) { c[0]*=s; c[1]*=s; c[2]*=s; } (void)0 /* multiply c2 by s and add to c1 */ #define fRGB_madd(c1, c2, s) { c1[0]+=c2[0]*s; c1[1]+=c2[1]*s; c1[2]+=c2[2]*s; } (void)0 /* multiply c2 by color c1 */ #define fRGB_colormult(c, cs) { c[0]*=cs[0]; c[1]*=cs[1]; c[2]*=cs[2]; } (void)0 -/* multiply c2 by color c3 and add to c1 */ -#define fRGB_colormadd(c1, c2, c3) { c1[0]+=c2[0]*c3[0]; c1[1]+=c2[1]*c3[1]; c1[2]+=c2[2]*c3[2]; } (void)0 /* multiply c2 by color rgb, rgb as separate arguments */ #define fRGB_rgbmult(c, r, g, b) { c[0]*=(r); c[1]*=(g); c[2]*=(b); } (void)0 -/* swap colors c1 & c2 */ -#define fRGB_swap(c1, c2) { float _t=c1[0]; c1[0]=c2[0]; c2[0]=_t;\ - _t=c1[1]; c1[1]=c2[1]; c2[1]=_t;\ - _t=c1[2]; c1[2]=c2[2]; c2[2]=_t;\ - _t=c1[3]; c1[3]=c2[3]; c3[3]=_t;\ - } (void)0 void qd_getPixel(CompBuf* src, int x, int y, float* col); void qd_setPixel(CompBuf* src, int x, int y, float* col); From 8ae116fbbb505be7055046eb15ba82ced203ced2 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Thu, 14 Jun 2012 19:19:11 +0000 Subject: [PATCH 324/360] Collada: (Exporter) fix Operator preset --- .../scripts/presets/operator/wm.collada_export/second_life.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/release/scripts/presets/operator/wm.collada_export/second_life.py b/release/scripts/presets/operator/wm.collada_export/second_life.py index 151c4e55652..be9656428ab 100644 --- a/release/scripts/presets/operator/wm.collada_export/second_life.py +++ b/release/scripts/presets/operator/wm.collada_export/second_life.py @@ -3,6 +3,8 @@ op = bpy.context.active_operator op.selected = True op.apply_modifiers = True -op.include_bone_children = False +op.include_armatures = False +op.include_children = False op.use_object_instantiation = False +op.sort_by_name = True op.second_life = True From 813348a4eeeb97536cc47a9eb30605cdb68ca781 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 19:22:55 +0000 Subject: [PATCH 325/360] code cleanup: replace most fRGB functions with inline vector functions --- .../operations/COM_GlareBaseOperation.h | 10 ---- .../operations/COM_GlareFogGlowOperation.cpp | 6 +-- .../operations/COM_GlareGhostOperation.cpp | 8 ++-- .../nodes/composite/node_composite_util.c | 12 ++--- .../nodes/composite/node_composite_util.h | 10 ---- .../composite/nodes/node_composite_glare.c | 48 +++++++++---------- .../composite/nodes/node_composite_tonemap.c | 8 ++-- 7 files changed, 41 insertions(+), 61 deletions(-) diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h index dc708044d31..ac67ac055e9 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.h +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.h @@ -32,16 +32,6 @@ typedef float fRGB[4]; /* TODO - replace with BLI_math_vector */ -/* copy c2 to c1 */ -#define fRGB_copy(c1, c2) { c1[0] = c2[0]; c1[1] = c2[1]; c1[2] = c2[2]; c1[3] = c2[3]; } (void)0 -/* add c2 to c1 */ -#define fRGB_add(c1, c2) { c1[0] += c2[0]; c1[1] += c2[1]; c1[2] += c2[2]; } (void)0 -/* multiply c by float value s */ -#define fRGB_mult(c, s) { c[0] *= s; c[1] *= s; c[2] *= s; } (void)0 -/* multiply c2 by s and add to c1 */ -#define fRGB_madd(c1, c2, s) { c1[0] += c2[0] * s; c1[1] += c2[1] * s; c1[2] += c2[2] * s; } (void)0 -/* multiply c2 by color c1 */ -#define fRGB_colormult(c, cs) { c[0] *= cs[0]; c[1] *= cs[1]; c[2] *= cs[2]; } (void)0 /* multiply c2 by color rgb, rgb as separate arguments */ #define fRGB_rgbmult(c, r, g, b) { c[0] *= (r); c[1] *= (g); c[2] *= (b); } (void)0 diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp index a91445be4b5..694aa26bcde 100644 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp @@ -277,7 +277,7 @@ void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) for (y = 0; y < kernelHeight; y++) { colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS]; for (x = 0; x < kernelWidth; x++) - fRGB_add(wt, colp[x]); + add_v3_v3(wt, colp[x]); } if (wt[0] != 0.f) wt[0] = 1.f / wt[0]; if (wt[1] != 0.f) wt[1] = 1.f / wt[1]; @@ -285,7 +285,7 @@ void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) for (y = 0; y < kernelHeight; y++) { colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS]; for (x = 0; x < kernelWidth; x++) - fRGB_colormult(colp[x], wt); + mul_v3_v3(colp[x], wt); } // copy image data, unpacking interleaved RGBA into separate channels @@ -395,7 +395,7 @@ void GlareFogGlowOperation::generateGlare(float *data, MemoryBuffer *inputTile, //w = (1.f-fabs(u))*(1.f-fabs(v)); // actually, Hanning window is ok, cos^2 for some reason is slower w = (0.5f + 0.5f * cos((double)u * M_PI)) * (0.5f + 0.5f * cos((double)v * M_PI)); - fRGB_mult(fcol, w); + mul_v3_fl(fcol, w); ckrn->writePixel(x, y, fcol); } } diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp index 2d5fe57b817..39fffd6ac64 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp @@ -85,11 +85,11 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No s = (u - 0.5f) * sc + 0.5f, t = (v - 0.5f) * sc + 0.5f; tbuf1->read(c, s * gbuf->getWidth(), t * gbuf->getHeight()); sm = smoothMask(s, t); - fRGB_mult(c, sm); + mul_v3_fl(c, sm); s = (u - 0.5f) * isc + 0.5f, t = (v - 0.5f) * isc + 0.5f; tbuf2->read(tc, s * gbuf->getWidth() - 0.5f, t * gbuf->getHeight() - 0.5f); sm = smoothMask(s, t); - fRGB_madd(c, tc, sm); + madd_v3_v3fl(c, tc, sm); gbuf->writePixel(x, y, c); } @@ -109,9 +109,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No s = (u - 0.5f) * scalef[np] + 0.5f; t = (v - 0.5f) * scalef[np] + 0.5f; gbuf->read(c, s * gbuf->getWidth() - 0.5f, t * gbuf->getHeight() - 0.5f); - fRGB_colormult(c, cm[np]); + mul_v3_v3(c, cm[np]); sm = smoothMask(s, t) * 0.25f; - fRGB_madd(tc, c, sm); + madd_v3_v3fl(tc, c, sm); } tbuf1->addPixel(x, y, tc); } diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c index ff223ac83cf..afd10d96e99 100644 --- a/source/blender/nodes/composite/node_composite_util.c +++ b/source/blender/nodes/composite/node_composite_util.c @@ -1022,7 +1022,7 @@ void convolve(CompBuf* dst, CompBuf* in1, CompBuf* in2) for (y=0; yy; y++) { colp = (fRGB*)&in2->rect[y*in2->x*in2->type]; for (x=0; xx; x++) - fRGB_add(wt, colp[x]); + add_v3_v3(wt, colp[x]); } if (wt[0] != 0.f) wt[0] = 1.f/wt[0]; if (wt[1] != 0.f) wt[1] = 1.f/wt[1]; @@ -1030,7 +1030,7 @@ void convolve(CompBuf* dst, CompBuf* in1, CompBuf* in2) for (y=0; yy; y++) { colp = (fRGB*)&in2->rect[y*in2->x*in2->type]; for (x=0; xx; x++) - fRGB_colormult(colp[x], wt); + mul_v3_v3(colp[x], wt); } // copy image data, unpacking interleaved RGBA into separate channels @@ -1279,14 +1279,14 @@ CompBuf* qd_downScaledCopy(CompBuf* src, int scale) xx = x*scale; mx = xx + scale; if (mx > src->x) mx = src->x; - colsum[0] = colsum[1] = colsum[2] = 0.f; + zero_v3(colsum); for (sy=yy; syrect[sy*src->x*src->type]; for (sx=xx; sxrect[y*dst->x*dst->type]; scolp = (fRGB*)&src->rect[y*dst->x*dst->type]; for (x=0; xx; x++) { - fRGB_copy(c1, dcolp[x]); - fRGB_copy(c2, scolp[x]); + copy_v3_v3(c1, dcolp[x]); + copy_v3_v3(c2, scolp[x]); c1[0] += mix*(c2[0] - c1[0]); c1[1] += mix*(c2[1] - c1[1]); c1[2] += mix*(c2[2] - c1[2]); if (c1[0] < 0.f) c1[0] = 0.f; if (c1[1] < 0.f) c1[1] = 0.f; if (c1[2] < 0.f) c1[2] = 0.f; - fRGB_mult(c1, mf); - fRGB_copy(dcolp[x], c1); + mul_v3_fl(c1, mf); + copy_v3_v3(dcolp[x], c1); } } } @@ -72,7 +72,7 @@ static void mixImages(CompBuf *dst, CompBuf *src, float mix) for (y=0; yy; y++) { dcolp = (fRGB*)&dst->rect[y*dst->x*dst->type]; for (x=0; xx; x++) { - fRGB_copy(c1, dcolp[x]); + copy_v3_v3(c1, dcolp[x]); qd_getPixelLerp(src, (x + 0.5f)*xr - 0.5f, (y + 0.5f)*yr - 0.5f, c2); c1[0] += mix*(c2[0] - c1[0]); c1[1] += mix*(c2[1] - c1[1]); @@ -80,8 +80,8 @@ static void mixImages(CompBuf *dst, CompBuf *src, float mix) if (c1[0] < 0.f) c1[0] = 0.f; if (c1[1] < 0.f) c1[1] = 0.f; if (c1[2] < 0.f) c1[2] = 0.f; - fRGB_mult(c1, mf); - fRGB_copy(dcolp[x], c1); + mul_v3_fl(c1, mf); + copy_v3_v3(dcolp[x], c1); } } } @@ -146,11 +146,11 @@ static void star4(NodeGlare* ndg, CompBuf* dst, CompBuf* src) xm = x - i; xp = x + i; qd_getPixel(tbuf1, x, y, c); - fRGB_mult(c, f1); + mul_v3_fl(c, f1); qd_getPixel(tbuf1, (ndg->angle ? xm : x), ym, tc); - fRGB_madd(c, tc, f2); + madd_v3_v3fl(c, tc, f2); qd_getPixel(tbuf1, (ndg->angle ? xp : x), yp, tc); - fRGB_madd(c, tc, f2); + madd_v3_v3fl(c, tc, f2); qd_setPixel(tbuf1, x, y, c); } } @@ -162,11 +162,11 @@ static void star4(NodeGlare* ndg, CompBuf* dst, CompBuf* src) xm = x - i; xp = x + i; qd_getPixel(tbuf1, x, y, c); - fRGB_mult(c, f1); + mul_v3_fl(c, f1); qd_getPixel(tbuf1, (ndg->angle ? xm : x), ym, tc); - fRGB_madd(c, tc, f2); + madd_v3_v3fl(c, tc, f2); qd_getPixel(tbuf1, (ndg->angle ? xp : x), yp, tc); - fRGB_madd(c, tc, f2); + madd_v3_v3fl(c, tc, f2); qd_setPixel(tbuf1, x, y, c); } } @@ -179,11 +179,11 @@ static void star4(NodeGlare* ndg, CompBuf* dst, CompBuf* src) xm = x - i; xp = x + i; qd_getPixel(tbuf2, x, y, c); - fRGB_mult(c, f1); + mul_v3_fl(c, f1); qd_getPixel(tbuf2, xm, (ndg->angle ? yp : y), tc); - fRGB_madd(c, tc, f2); + madd_v3_v3fl(c, tc, f2); qd_getPixel(tbuf2, xp, (ndg->angle ? ym : y), tc); - fRGB_madd(c, tc, f2); + madd_v3_v3fl(c, tc, f2); qd_setPixel(tbuf2, x, y, c); } } @@ -195,11 +195,11 @@ static void star4(NodeGlare* ndg, CompBuf* dst, CompBuf* src) xm = x - i; xp = x + i; qd_getPixel(tbuf2, x, y, c); - fRGB_mult(c, f1); + mul_v3_fl(c, f1); qd_getPixel(tbuf2, xm, (ndg->angle ? yp : y), tc); - fRGB_madd(c, tc, f2); + madd_v3_v3fl(c, tc, f2); qd_getPixel(tbuf2, xp, (ndg->angle ? ym : y), tc); - fRGB_madd(c, tc, f2); + madd_v3_v3fl(c, tc, f2); qd_setPixel(tbuf2, x, y, c); } } @@ -342,11 +342,11 @@ static void ghosts(NodeGlare* ndg, CompBuf* dst, CompBuf* src) s = (u-0.5f)*sc + 0.5f, t = (v-0.5f)*sc + 0.5f; qd_getPixelLerp(tbuf1, s*gbuf->x, t*gbuf->y, c); sm = smoothMask(s, t); - fRGB_mult(c, sm); + mul_v3_fl(c, sm); s = (u-0.5f)*isc + 0.5f, t = (v-0.5f)*isc + 0.5f; qd_getPixelLerp(tbuf2, s*gbuf->x - 0.5f, t*gbuf->y - 0.5f, tc); sm = smoothMask(s, t); - fRGB_madd(c, tc, sm); + madd_v3_v3fl(c, tc, sm); qd_setPixel(gbuf, x, y, c); } } @@ -363,9 +363,9 @@ static void ghosts(NodeGlare* ndg, CompBuf* dst, CompBuf* src) s = (u-0.5f)*scalef[np] + 0.5f; t = (v-0.5f)*scalef[np] + 0.5f; qd_getPixelLerp(gbuf, s*gbuf->x - 0.5f, t*gbuf->y - 0.5f, c); - fRGB_colormult(c, cm[np]); + mul_v3_v3(c, cm[np]); sm = smoothMask(s, t)*0.25f; - fRGB_madd(tc, c, sm); + madd_v3_v3fl(tc, c, sm); } p = (x + y*tbuf1->x)*tbuf1->type; tbuf1->rect[p] += tc[0]; @@ -413,7 +413,7 @@ static void fglow(NodeGlare* ndg, CompBuf* dst, CompBuf* src) //w = (1.f-fabs(u))*(1.f-fabs(v)); // actually, Hanning window is ok, cos^2 for some reason is slower w = (0.5f + 0.5f*cos((double)u*M_PI))*(0.5f + 0.5f*cos((double)v*M_PI)); - fRGB_mult(fcol, w); + mul_v3_fl(fcol, w); qd_setPixel(ckrn, x, y, fcol); } } diff --git a/source/blender/nodes/composite/nodes/node_composite_tonemap.c b/source/blender/nodes/composite/nodes/node_composite_tonemap.c index 6196825c9b3..50006e599e5 100644 --- a/source/blender/nodes/composite/nodes/node_composite_tonemap.c +++ b/source/blender/nodes/composite/nodes/node_composite_tonemap.c @@ -53,14 +53,14 @@ static float avgLogLum(CompBuf *src, float* auto_key, float* Lav, float* Cav) while (p--) { float L = rgb_to_luma_y(bc[0]); *Lav += L; - fRGB_add(Cav, bc[0]); + add_v3_v3(Cav, bc[0]); lsum += (float)log((double)MAX2(L, 0.0) + 1e-5); maxl = (L > maxl) ? L : maxl; minl = (L < minl) ? L : minl; bc++; } *Lav *= sc; - fRGB_mult(Cav, sc); + mul_v3_fl(Cav, sc); maxl = log((double)maxl + 1e-5); minl = log((double)minl + 1e-5f); avl = lsum*sc; *auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.f; return exp((double)avl); @@ -109,8 +109,8 @@ static void tonemap(NodeTonemap* ntm, CompBuf* dst, CompBuf* src) fRGB* sp = (fRGB*)&src->rect[y*src->x*src->type]; fRGB* dp = (fRGB*)&dst->rect[y*src->x*src->type]; for (x=0; xx; x++) { - fRGB_copy(dp[x], sp[x]); - fRGB_mult(dp[x], al); + copy_v4_v4(dp[x], sp[x]); + mul_v3_fl(dp[x], al); dr = dp[x][0] + ntm->offset; dg = dp[x][1] + ntm->offset; db = dp[x][2] + ntm->offset; From 9355bece599582358d8ed7b39bdf376446ba7018 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 22:48:40 +0000 Subject: [PATCH 326/360] click dragging with the eye dropper now averages out colors - useful when you have grainy footage of a green screen. --- .../blender/editors/interface/interface_ops.c | 114 ++++++++++++++---- .../editors/interface/interface_utils.c | 8 +- 2 files changed, 97 insertions(+), 25 deletions(-) diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index dfd2d0cc4d0..3900e0f01f2 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -40,6 +40,7 @@ #include "BLI_blenlib.h" #include "BLI_math_color.h" +#include "BLI_math_vector.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -69,22 +70,42 @@ /* ********************************************************** */ typedef struct Eyedropper { + short do_color_management; + PointerRNA ptr; PropertyRNA *prop; int index; + + int accum_start; /* has mouse been presed */ + float accum_col[4]; + int accum_tot; } Eyedropper; static int eyedropper_init(bContext *C, wmOperator *op) { + Scene *scene = CTX_data_scene(C); + const int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; + Eyedropper *eye; op->customdata = eye = MEM_callocN(sizeof(Eyedropper), "Eyedropper"); uiContextActiveProperty(C, &eye->ptr, &eye->prop, &eye->index); - - return (eye->ptr.data && eye->prop && RNA_property_editable(&eye->ptr, eye->prop)); + + if ((eye->ptr.data == NULL) || + (eye->prop == NULL) || + (RNA_property_editable(&eye->ptr, eye->prop) == FALSE) || + (RNA_property_array_length(&eye->ptr, eye->prop) < 3) || + (RNA_property_type(eye->prop) != PROP_FLOAT)) + { + return FALSE; + } + + eye->do_color_management = (color_manage && RNA_property_subtype(eye->prop) == PROP_COLOR); + + return TRUE; } - + static void eyedropper_exit(bContext *C, wmOperator *op) { WM_cursor_restore(CTX_wm_window(C)); @@ -100,29 +121,57 @@ static int eyedropper_cancel(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } -static void eyedropper_sample(bContext *C, Eyedropper *eye, int mx, int my) +/* *** eyedropper_color_ helper functions *** */ +static void eyedropper_color_sample_fl(Eyedropper *UNUSED(eye), int mx, int my, + float r_col[4]) { - if (RNA_property_type(eye->prop) == PROP_FLOAT) { - Scene *scene = CTX_data_scene(C); - const int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; - float col[4]; - - RNA_property_float_get_array(&eye->ptr, eye->prop, col); - - glReadBuffer(GL_FRONT); - glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, col); - glReadBuffer(GL_BACK); - - if (RNA_property_array_length(&eye->ptr, eye->prop) < 3) return; + glReadBuffer(GL_FRONT); + glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col); + glReadBuffer(GL_BACK); +} - /* convert from screen (srgb) space to linear rgb space */ - if (color_manage && RNA_property_subtype(eye->prop) == PROP_COLOR) - srgb_to_linearrgb_v3_v3(col, col); - - RNA_property_float_set_array(&eye->ptr, eye->prop, col); - - RNA_property_update(C, &eye->ptr, eye->prop); +static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[4]) +{ + float col_linear[4]; + /* convert from screen (srgb) space to linear rgb space */ + if (eye->do_color_management) { + srgb_to_linearrgb_v3_v3(col_linear, col); } + else { + copy_v3_v3(col_linear, col); + } + col_linear[3] = col[3]; + + RNA_property_float_set_array(&eye->ptr, eye->prop, col_linear); + + RNA_property_update(C, &eye->ptr, eye->prop); +} + +static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye) +{ + float col[4]; + mul_v4_v4fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot); + eyedropper_color_set(C, eye, col); +} + +static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my) +{ + float col[4]; + + RNA_property_float_get_array(&eye->ptr, eye->prop, col); + + eyedropper_color_sample_fl(eye, mx, my, col); + + eyedropper_color_set(C, eye, col); +} + +static void eyedropper_color_sample_accum(Eyedropper *eye, int mx, int my) +{ + float col[4]; + eyedropper_color_sample_fl(eye, mx, my, col); + /* delay linear conversion */ + add_v4_v4(eye->accum_col, col); + eye->accum_tot++; } /* main modal status check */ @@ -136,10 +185,27 @@ static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event) return eyedropper_cancel(C, op); case LEFTMOUSE: if (event->val == KM_RELEASE) { - eyedropper_sample(C, eye, event->x, event->y); + if (eye->accum_tot == 0) { + eyedropper_color_sample(C, eye, event->x, event->y); + } + else { + eyedropper_color_set_accum(C, eye); + } eyedropper_exit(C, op); return OPERATOR_FINISHED; } + else if (event->val == KM_PRESS) { + /* enable accum and make first sample */ + eye->accum_start = TRUE; + eyedropper_color_sample_accum(eye, event->x, event->y); + } + break; + case MOUSEMOVE: + if (eye->accum_start) { + /* button is pressed so keep sampling */ + eyedropper_color_sample_accum(eye, event->x, event->y); + eyedropper_color_set_accum(C, eye); + } break; } diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index a0b83b5fef4..9773918e508 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -130,7 +130,13 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind return but; } -int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int (*check_prop)(PointerRNA *, PropertyRNA *), const char label_align) +/** + * \a check_prop callback filters functions to avoid drawing certain properties, + * in cases where PROP_HIDDEN flag can't be used for a property. + */ +int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, + int (*check_prop)(PointerRNA *, PropertyRNA *), + const char label_align) { uiLayout *split, *col; int flag; From bd9192670bf7922f2e12fe586bf8b376000412ff Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Fri, 15 Jun 2012 01:43:01 +0000 Subject: [PATCH 327/360] Added option in shift-g to select verts by number of connected edges (valence). --- source/blender/bmesh/intern/bmesh_operators.h | 3 ++- source/blender/bmesh/operators/bmo_utils.c | 11 +++++++++++ source/blender/editors/mesh/editmesh_select.c | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 3c6c3004e3a..b1da8ecb275 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -72,7 +72,8 @@ enum { enum { SIMVERT_NORMAL = 0, SIMVERT_FACE, - SIMVERT_VGROUP + SIMVERT_VGROUP, + SIMVERT_EDGE }; enum { diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index 3ebc7b04aa4..e0cd3e2ba90 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -873,6 +873,7 @@ typedef struct SimSel_VertExt { BMVert *v; union { int num_faces; /* adjacent faces */ + int num_edges; /* adjacent edges */ MDeformVert *dvert; /* deform vertex */ }; } SimSel_VertExt; @@ -928,6 +929,9 @@ void bmo_similarverts_exec(BMesh *bm, BMOperator *op) v_ext[i].dvert = NULL; } break; + case SIMVERT_EDGE: + v_ext[i].num_edges = BM_vert_edge_count(v); + break; } i++; @@ -970,6 +974,13 @@ void bmo_similarverts_exec(BMesh *bm, BMOperator *op) } } break; + case SIMVERT_EDGE: + /* number of adjacent edges */ + if (v_ext[i].num_edges == v_ext[indices[idx]].num_edges) { + BMO_elem_flag_enable(bm, v, VERT_MARK); + cont = FALSE; + } + break; } } } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 57bce6b9de4..44ec8bd6aaa 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -676,6 +676,7 @@ static EnumPropertyItem prop_similar_types[] = { {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""}, {SIMVERT_FACE, "FACE", 0, "Amount of Adjacent Faces", ""}, {SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""}, + {SIMVERT_EDGE, "EDGE", 0, "Amount of connecting edges", ""}, {SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""}, {SIMEDGE_DIR, "DIR", 0, "Direction", ""}, From 4e4e5bb7ffe97b9f2db1b91bae0abf2fc58153ea Mon Sep 17 00:00:00 2001 From: Nicholas Rishel Date: Fri, 15 Jun 2012 01:43:07 +0000 Subject: [PATCH 328/360] Comment no longer accurate. --- source/blender/windowmanager/intern/wm_event_system.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 5f2d9c6fb54..c46c382c37f 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2716,7 +2716,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U case GHOST_kEventButtonUp: { GHOST_TEventButtonData *bd = customdata; - /* Note!, this starts as 0/1 but later is converted to KM_PRESS/KM_RELEASE by tweak */ event.val = (type == GHOST_kEventButtonDown) ? KM_PRESS : KM_RELEASE; if (bd->button == GHOST_kButtonMaskLeft) From e879ee1798151301765bcdf6b2e6c67718a782a8 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Fri, 15 Jun 2012 02:21:07 +0000 Subject: [PATCH 329/360] SVN maintenance. --- source/blender/collada/collada_utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index c4e336f3bc6..aa6f0b3c515 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -252,4 +252,4 @@ void bc_bubble_sort_by_Object_name(LinkNode *export_set) } } -} \ No newline at end of file +} From 46ea5670db378048fc1339b5e355523842fa82a2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 07:50:27 +0000 Subject: [PATCH 330/360] scale node - framing offset: compatible with camera shiftX/Y and the viewport option. --- release/scripts/startup/bl_ui/space_view3d.py | 6 ++--- .../compositor/nodes/COM_ScaleNode.cpp | 4 ++++ .../operations/COM_ScaleOperation.cpp | 24 +++++++++++++++---- .../operations/COM_ScaleOperation.h | 8 +++++-- source/blender/editors/space_node/drawnode.c | 4 ++++ source/blender/makesrna/intern/rna_nodetree.c | 10 ++++++++ 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index d7fe7ebbbf7..b525ab922d2 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2584,13 +2584,13 @@ class VIEW3D_PT_background_image(Panel): rowsub = col.row() rowsub.prop(bg, "frame_method", expand=True) - if bg.view_axis != 'CAMERA': - col.prop(bg, "size") - row = col.row(align=True) row.prop(bg, "offset_x", text="X") row.prop(bg, "offset_y", text="Y") + if bg.view_axis != 'CAMERA': + col.prop(bg, "size") + class VIEW3D_PT_transform_orientations(Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp index 85d5644484b..870ed8f2484 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.cpp +++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp @@ -65,8 +65,12 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c case CMP_SCALE_RENDERPERCENT: { const RenderData *data = &context->getScene()->r; ScaleFixedSizeOperation *operation = new ScaleFixedSizeOperation(); + + /* framing options */ operation->setIsAspect((bnode->custom2 & CMP_SCALE_RENDERSIZE_FRAME_ASPECT) != 0); operation->setIsCrop((bnode->custom2 & CMP_SCALE_RENDERSIZE_FRAME_CROP) != 0); + operation->setOffset(bnode->custom3, bnode->custom4); + operation->setNewWidth(data->xsch * data->size / 100.0f); operation->setNewHeight(data->ysch * data->size / 100.0f); inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp index aea4da920a0..45e846998af 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cpp +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -191,6 +191,21 @@ void ScaleFixedSizeOperation::initExecution() this->relX = inputOperation->getWidth() / (float)this->newWidth; this->relY = inputOperation->getHeight() / (float)this->newHeight; + + /* *** all the options below are for a fairly special case - camera framing *** */ + if (this->offsetX != 0.0f || this->offsetY != 0.0f) { + this->is_offset = true; + + if (this->newWidth > this->newHeight) { + this->offsetX *= this->newWidth; + this->offsetY *= this->newWidth; + } + else { + this->offsetX *= this->newHeight; + this->offsetY *= this->newHeight; + } + } + if (this->is_aspect) { /* apply aspect from clip */ const float w_src = inputOperation->getWidth(); @@ -203,9 +218,6 @@ void ScaleFixedSizeOperation::initExecution() const float asp_src = w_src / h_src; const float asp_dst = w_dst / h_dst; - this->offsetX = 0.0f; - this->offsetY = 0.0f; - if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) { if ((asp_src > asp_dst) == (this->is_crop == true)) { /* fit X */ @@ -219,9 +231,11 @@ void ScaleFixedSizeOperation::initExecution() this->relY /= div; this->offsetY = ((h_src - (h_src * div)) / (h_src / h_dst)) / 2.0f; } - } + this->is_offset = true; + } } + /* *** end framing options *** */ } void ScaleFixedSizeOperation::deinitExecution() @@ -236,7 +250,7 @@ void ScaleFixedSizeOperation::executePixel(float *color, float x, float y, Pixel sampler = COM_PS_BICUBIC; #endif - if (this->is_aspect) { + if (this->is_offset) { float nx = ((x - this->offsetX) * relX); float ny = ((y - this->offsetY) * relY); this->inputOperation->read(color, nx, ny, sampler, inputBuffers); diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h index 3964a5e2f71..7089f6c10a4 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -69,6 +69,9 @@ class ScaleFixedSizeOperation : public NodeOperation { float offsetY; bool is_aspect; bool is_crop; + /* set from other properties on initialization, + * check if we need to apply offset */ + bool is_offset; public: ScaleFixedSizeOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); @@ -79,8 +82,9 @@ public: void deinitExecution(); void setNewWidth(int width) { this->newWidth = width; } void setNewHeight(int height) { this->newHeight = height; } - void setIsAspect(int is_aspect) { this->is_aspect = is_aspect; } - void setIsCrop(int is_crop) { this->is_crop = is_crop; } + void setIsAspect(bool is_aspect) { this->is_aspect = is_aspect; } + void setIsCrop(bool is_crop) { this->is_crop = is_crop; } + void setOffset(float x, float y) { this->offsetX = x; this->offsetY = y; } }; #endif diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index e48dd39022e..8aa56823baf 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2020,7 +2020,11 @@ static void node_composit_buts_scale(uiLayout *layout, bContext *UNUSED(C), Poin uiItemR(layout, ptr, "space", 0, "", ICON_NONE); if (RNA_enum_get(ptr, "space") == CMP_SCALE_RENDERPERCENT) { + uiLayout *row; uiItemR(layout, ptr, "frame_method", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + row = uiLayoutRow(layout, TRUE); + uiItemR(row, ptr, "offset_x", 0, "X", ICON_NONE); + uiItemR(row, ptr, "offset_y", 0, "Y", ICON_NONE); } } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 9567226f722..683a49a7690 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2106,6 +2106,16 @@ static void def_cmp_scale(StructRNA *srna) RNA_def_property_enum_items(prop, space_frame_items); RNA_def_property_ui_text(prop, "Frame Method", "How the image fits in the camera frame"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "custom3"); + RNA_def_property_ui_text(prop, "X Offset", "Offset image horizontally (factor of image size)"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "custom4"); + RNA_def_property_ui_text(prop, "Y Offset", "Offset image vertically (factor of image size)"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } static void def_cmp_rotate(StructRNA *srna) From 9c55e7b9956313bbaf034925e49abbd0260fe457 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 08:01:41 +0000 Subject: [PATCH 331/360] add node scale offset for old compositor too - also fix for error in last commit. --- .../operations/COM_ScaleOperation.cpp | 4 ++-- .../composite/nodes/node_composite_scale.c | 20 +++++++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp index 45e846998af..2e23df73b67 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cpp +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -223,13 +223,13 @@ void ScaleFixedSizeOperation::initExecution() /* fit X */ const float div = asp_src / asp_dst; this->relX /= div; - this->offsetX = ((w_src - (w_src * div)) / (w_src / w_dst)) / 2.0f; + this->offsetX += ((w_src - (w_src * div)) / (w_src / w_dst)) / 2.0f; } else { /* fit Y */ const float div = asp_dst / asp_src; this->relY /= div; - this->offsetY = ((h_src - (h_src * div)) / (h_src / h_dst)) / 2.0f; + this->offsetY += ((h_src - (h_src * div)) / (h_src / h_dst)) / 2.0f; } this->is_offset = true; diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c index fd4bd643126..1df67724762 100644 --- a/source/blender/nodes/composite/nodes/node_composite_scale.c +++ b/source/blender/nodes/composite/nodes/node_composite_scale.c @@ -57,6 +57,7 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b CompBuf *stackbuf, *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA); ImBuf *ibuf; int newx, newy; + float ofsx = 0.0f, ofsy = 0.0f; if (node->custom1 == CMP_SCALE_RELATIVE) { newx = MAX2((int)(in[1]->vec[0] * cbuf->x), 1); @@ -67,6 +68,21 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b newy = cbuf->y * (rd->size / 100.0f); } else if (node->custom1 == CMP_SCALE_RENDERPERCENT) { + + if (node->custom3 != 0.0f || node->custom4 != 0.0f) { + const float w_dst = (rd->xsch * rd->size) / 100; + const float h_dst = (rd->ysch * rd->size) / 100; + + if (w_dst > h_dst) { + ofsx = node->custom3 * w_dst; + ofsy = node->custom4 * w_dst; + } + else { + ofsx = node->custom3 * h_dst; + ofsy = node->custom4 * h_dst; + } + } + /* supports framing options */ if (node->custom2 & CMP_SCALE_RENDERSIZE_FRAME_ASPECT) { /* apply aspect from clip */ @@ -133,8 +149,8 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b IMB_freeImBuf(ibuf); /* also do the translation vector */ - stackbuf->xof = (int)(((float)newx / (float)cbuf->x) * (float)cbuf->xof); - stackbuf->yof = (int)(((float)newy / (float)cbuf->y) * (float)cbuf->yof); + stackbuf->xof = (int)(ofsx + (((float)newx / (float)cbuf->x) * (float)cbuf->xof)); + stackbuf->yof = (int)(ofsy + (((float)newy / (float)cbuf->y) * (float)cbuf->yof)); } else { stackbuf = dupalloc_compbuf(cbuf); From c9f1477fb07a89be657b5ca5d2fd29b29b556e5d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 08:26:49 +0000 Subject: [PATCH 332/360] Garbage mate input for keying node This adds garbage matte input to new keying node which is used to force occluding things which can not be eliminated by color operations. White areas defines areas which should be removed from final result. --- source/blender/compositor/nodes/COM_KeyingNode.cpp | 2 ++ .../blender/compositor/operations/COM_KeyingOperation.cpp | 8 ++++++++ .../blender/compositor/operations/COM_KeyingOperation.h | 2 ++ .../blender/nodes/composite/nodes/node_composite_keying.c | 5 +++-- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index 74af25b8e5f..b1bde9643df 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -156,6 +156,7 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext * { InputSocket *inputImage = this->getInputSocket(0); InputSocket *inputScreen = this->getInputSocket(1); + InputSocket *inputGarbageMatte = this->getInputSocket(2); OutputSocket *outputImage = this->getOutputSocket(0); OutputSocket *outputMatte = this->getOutputSocket(1); OutputSocket *outputEdges = this->getOutputSocket(2); @@ -170,6 +171,7 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext * keyingOperation->setScreenBalance(keying_data->screen_balance); inputScreen->relinkConnections(keyingOperation->getInputSocket(1), 1, graph); + inputGarbageMatte->relinkConnections(keyingOperation->getInputSocket(2), 2, graph); if (keying_data->blur_pre) { /* chroma preblur operation for input of keying operation */ diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp index fba4dc65faf..599989d52dc 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp @@ -56,33 +56,39 @@ KeyingOperation::KeyingOperation(): NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); this->screenBalance = 0.5f; this->pixelReader = NULL; this->screenReader = NULL; + this->garbageReader = NULL; } void KeyingOperation::initExecution() { this->pixelReader = this->getInputSocketReader(0); this->screenReader = this->getInputSocketReader(1); + this->garbageReader = this->getInputSocketReader(2); } void KeyingOperation::deinitExecution() { this->pixelReader = NULL; this->screenReader = NULL; + this->garbageReader = NULL; } void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { float pixelColor[4]; float screenColor[4]; + float garbageValue[4]; this->pixelReader->read(pixelColor, x, y, sampler, inputBuffers); this->screenReader->read(screenColor, x, y, sampler, inputBuffers); + this->garbageReader->read(garbageValue, x, y, sampler, inputBuffers); int primary_channel = get_pixel_primary_channel(screenColor); @@ -100,6 +106,8 @@ void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler color[0] = distance; } + + color[0] *= (1.0f - garbageValue[0]); } bool KeyingOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h index 0fc13407d14..657a1ff807c 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.h +++ b/source/blender/compositor/operations/COM_KeyingOperation.h @@ -38,6 +38,8 @@ class KeyingOperation : public NodeOperation { protected: SocketReader *pixelReader; SocketReader *screenReader; + SocketReader *garbageReader; + float screenBalance; public: diff --git a/source/blender/nodes/composite/nodes/node_composite_keying.c b/source/blender/nodes/composite/nodes/node_composite_keying.c index e5bf3b7ae62..31a8a0d67a6 100644 --- a/source/blender/nodes/composite/nodes/node_composite_keying.c +++ b/source/blender/nodes/composite/nodes/node_composite_keying.c @@ -46,8 +46,9 @@ /* **************** Translate ******************** */ static bNodeSocketTemplate cmp_node_keying_in[] = { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Key Color", 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Key Color", 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_FLOAT, 1, "Garbage Matte", 0.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; From 35d1a1cbd81c6ed152ff517344364370746d65f5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 08:33:33 +0000 Subject: [PATCH 333/360] fix for own mistake - sampling was adjusting alpha when it shouldn't, also make spacebar reset the accumulated color while eyedropping. --- .../blender/editors/interface/interface_ops.c | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 3900e0f01f2..1c3b642b63b 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -77,7 +77,7 @@ typedef struct Eyedropper { int index; int accum_start; /* has mouse been presed */ - float accum_col[4]; + float accum_col[3]; int accum_tot; } Eyedropper; @@ -122,55 +122,58 @@ static int eyedropper_cancel(bContext *C, wmOperator *op) } /* *** eyedropper_color_ helper functions *** */ -static void eyedropper_color_sample_fl(Eyedropper *UNUSED(eye), int mx, int my, - float r_col[4]) + +/* simply get the color from the screen */ +static void eyedropper_color_sample_fl(Eyedropper *UNUSED(eye), int mx, int my, float r_col[3]) { glReadBuffer(GL_FRONT); glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col); glReadBuffer(GL_BACK); } -static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[4]) +/* sets the sample color RGB, maintaining A */ +static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3]) { - float col_linear[4]; + float col_conv[4]; + + /* to maintain alpha */ + RNA_property_float_get_array(&eye->ptr, eye->prop, col_conv); + /* convert from screen (srgb) space to linear rgb space */ if (eye->do_color_management) { - srgb_to_linearrgb_v3_v3(col_linear, col); + srgb_to_linearrgb_v3_v3(col_conv, col); } else { - copy_v3_v3(col_linear, col); + copy_v3_v3(col_conv, col); } - col_linear[3] = col[3]; - RNA_property_float_set_array(&eye->ptr, eye->prop, col_linear); + RNA_property_float_set_array(&eye->ptr, eye->prop, col_conv); RNA_property_update(C, &eye->ptr, eye->prop); } +/* set sample from accumulated values */ static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye) { float col[4]; - mul_v4_v4fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot); + mul_v3_v3fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot); eyedropper_color_set(C, eye, col); } +/* single point sample & set */ static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my) { - float col[4]; - - RNA_property_float_get_array(&eye->ptr, eye->prop, col); - + float col[3]; eyedropper_color_sample_fl(eye, mx, my, col); - eyedropper_color_set(C, eye, col); } static void eyedropper_color_sample_accum(Eyedropper *eye, int mx, int my) { - float col[4]; + float col[3]; eyedropper_color_sample_fl(eye, mx, my, col); /* delay linear conversion */ - add_v4_v4(eye->accum_col, col); + add_v3_v3(eye->accum_col, col); eye->accum_tot++; } @@ -207,6 +210,14 @@ static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event) eyedropper_color_set_accum(C, eye); } break; + case SPACEKEY: + if (event->val == KM_RELEASE) { + eye->accum_tot = 0; + zero_v3(eye->accum_col); + eyedropper_color_sample_accum(eye, event->x, event->y); + eyedropper_color_set_accum(C, eye); + } + break; } return OPERATOR_RUNNING_MODAL; From e95e2419f848116c0b74dc9cb30b410bbd682551 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Fri, 15 Jun 2012 09:51:27 +0000 Subject: [PATCH 334/360] Collada (Exporter) improved export panel layout --- .../windowmanager/intern/wm_operators.c | 66 +++++++++++++++++-- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b4bec014b9c..458ed43d489 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2206,6 +2206,58 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) } } + +void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr) +{ + ID *id = imfptr->id.data; + + uiLayout *box, *row; + + // Export Options: + box = uiLayoutBox(layout); + row = uiLayoutRow(box, 0); + uiItemL(row, IFACE_("Export Data Options:"), ICON_MESH_DATA); + + row = uiLayoutRow(box, 0); + uiItemR(row, imfptr, "apply_modifiers", 0, NULL, ICON_NONE); + + row = uiLayoutRow(box, 0); + uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE); + + row = uiLayoutRow(box, 0); + uiItemR(row, imfptr, "include_armatures", 0, NULL, ICON_NONE); + uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected")); + + row = uiLayoutRow(box, 0); + uiItemR(row, imfptr, "include_children", 0, NULL, ICON_NONE); + uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected")); + + + // Collada options: + box = uiLayoutBox(layout); + row = uiLayoutRow(box, 0); + uiItemL(row, IFACE_("Collada Options:"), ICON_MODIFIER); + + row = uiLayoutRow(box, 0); + uiItemR(row, imfptr, "use_object_instantiation", 0, NULL, ICON_NONE); + row = uiLayoutRow(box, 0); + uiItemR(row, imfptr, "sort_by_name", 0, IFACE_("Sort by Object name"), ICON_NONE); + row = uiLayoutRow(box, 0); + uiItemR(row, imfptr, "second_life", 0, IFACE_("Export for Second Life"), ICON_NONE); + +} + +static void wm_collada_export_draw(bContext *C, wmOperator *op) +{ + uiLayout *layout = op->layout; + PointerRNA ptr; + + /* image template */ + RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); + uiCollada_exportSettings(layout, &ptr); + +} + static void WM_OT_collada_export(wmOperatorType *ot) { ot->name = "Export COLLADA"; @@ -2217,22 +2269,25 @@ static void WM_OT_collada_export(wmOperatorType *ot) ot->poll = WM_operator_winactive; ot->flag |= OPTYPE_PRESET; + + ot->ui = wm_collada_export_draw; WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); + RNA_def_boolean(ot->srna, "selected", 0, "Selection Only", "Export only selected elements"); - RNA_def_boolean(ot->srna, "apply_modifiers", 0, "Apply Modifiers", - "Apply modifiers (Preview Resolution)"); - RNA_def_boolean(ot->srna, "include_armatures", 0, "Include Armatures", - "Include armature(s) used by the exported objects"); + "Include armature(s) even if not selected"); RNA_def_boolean(ot->srna, "include_children", 0, "Include Children", "Include all children even if not selected"); - RNA_def_boolean(ot->srna, "use_object_instantiation", 1, "Use Object Instantiation", + RNA_def_boolean(ot->srna, "apply_modifiers", 0, "Apply Modifiers", + "Apply modifiers (Preview Resolution)"); + + RNA_def_boolean(ot->srna, "use_object_instantiation", 1, "Use Object Instances", "Instantiate multiple Objects from same Data"); RNA_def_boolean(ot->srna, "sort_by_name", 0, "Sort by Object name", @@ -2242,6 +2297,7 @@ static void WM_OT_collada_export(wmOperatorType *ot) "Compatibility mode for Second Life"); } + /* function used for WM_OT_save_mainfile too */ static int wm_collada_import_exec(bContext *C, wmOperator *op) { From 3264db37972877184ead9785181722e5cf65f164 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Fri, 15 Jun 2012 09:56:06 +0000 Subject: [PATCH 335/360] Collada (Exporter) improved export panel layout minor code cleanup --- source/blender/windowmanager/intern/wm_operators.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 458ed43d489..f39b8f267a5 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2241,21 +2241,18 @@ void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr) row = uiLayoutRow(box, 0); uiItemR(row, imfptr, "use_object_instantiation", 0, NULL, ICON_NONE); row = uiLayoutRow(box, 0); - uiItemR(row, imfptr, "sort_by_name", 0, IFACE_("Sort by Object name"), ICON_NONE); + uiItemR(row, imfptr, "sort_by_name", 0, NULL, ICON_NONE); row = uiLayoutRow(box, 0); - uiItemR(row, imfptr, "second_life", 0, IFACE_("Export for Second Life"), ICON_NONE); + uiItemR(row, imfptr, "second_life", 0, NULL, ICON_NONE); } static void wm_collada_export_draw(bContext *C, wmOperator *op) { - uiLayout *layout = op->layout; PointerRNA ptr; - /* image template */ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); - uiCollada_exportSettings(layout, &ptr); - + uiCollada_exportSettings(op->layout, &ptr); } static void WM_OT_collada_export(wmOperatorType *ot) From ec755bdfa7920c9db4dd771c065e85539b00d140 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 09:58:52 +0000 Subject: [PATCH 336/360] style cleanup: composite/blur --- .../nodes/COM_BilateralBlurNode.cpp | 6 +- .../blender/compositor/nodes/COM_BlurNode.cpp | 10 +- .../compositor/nodes/COM_BokehBlurNode.cpp | 6 +- .../nodes/COM_DirectionalBlurNode.cpp | 6 +- .../compositor/nodes/COM_VectorBlurNode.cpp | 6 +- .../operations/COM_BilateralBlurOperation.cpp | 8 +- .../operations/COM_BlurBaseOperation.cpp | 38 +- .../operations/COM_BokehBlurOperation.cpp | 38 +- .../COM_DirectionalBlurOperation.cpp | 8 +- .../COM_FastGaussianBlurOperation.cpp | 126 ++-- .../COM_FastGaussianBlurOperation.h | 2 +- .../COM_GaussianBokehBlurOperation.cpp | 48 +- .../operations/COM_GaussianXBlurOperation.cpp | 20 +- .../operations/COM_GaussianYBlurOperation.cpp | 20 +- .../operations/COM_KeyingBlurOperation.cpp | 4 +- .../operations/COM_KeyingBlurOperation.h | 4 +- .../COM_VariableSizeBokehBlurOperation.cpp | 18 +- .../operations/COM_VectorBlurOperation.cpp | 24 +- .../nodes/node_composite_bilateralblur.c | 146 ++--- .../composite/nodes/node_composite_blur.c | 618 +++++++++--------- .../nodes/node_composite_bokehblur.c | 20 +- .../nodes/node_composite_directionalblur.c | 74 +-- .../composite/nodes/node_composite_vecBlur.c | 48 +- 23 files changed, 650 insertions(+), 648 deletions(-) diff --git a/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp b/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp index fa654d35785..6baa04ff7c2 100644 --- a/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp @@ -26,13 +26,13 @@ #include "COM_ExecutionSystem.h" #include "COM_BilateralBlurOperation.h" -BilateralBlurNode::BilateralBlurNode(bNode *editorNode): Node(editorNode) +BilateralBlurNode::BilateralBlurNode(bNode *editorNode) : Node(editorNode) { } -void BilateralBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void BilateralBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { - NodeBilateralBlurData *data = (NodeBilateralBlurData*)this->getbNode()->storage; + NodeBilateralBlurData *data = (NodeBilateralBlurData *)this->getbNode()->storage; BilateralBlurOperation *operation = new BilateralBlurOperation(); operation->setQuality(context->getQuality()); operation->setData(data); diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index b27b6323f49..fe93768161c 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -29,19 +29,19 @@ #include "COM_GaussianBokehBlurOperation.h" #include "COM_FastGaussianBlurOperation.h" -BlurNode::BlurNode(bNode *editorNode): Node(editorNode) +BlurNode::BlurNode(bNode *editorNode) : Node(editorNode) { } -void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { bNode *editorNode = this->getbNode(); - NodeBlurData * data = (NodeBlurData*)editorNode->storage; - InputSocket * inputSizeSocket = this->getInputSocket(1); + NodeBlurData *data = (NodeBlurData *)editorNode->storage; + InputSocket *inputSizeSocket = this->getInputSocket(1); bool connectedSizeSocket = inputSizeSocket->isConnected(); const bNodeSocket *sock = this->getInputSocket(1)->getbNodeSocket(); - const float size = ((const bNodeSocketValueFloat*)sock->default_value)->value; + const float size = ((const bNodeSocketValueFloat *)sock->default_value)->value; CompositorQuality quality = context->getQuality(); diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp index abae1b88890..ee0119230f4 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp @@ -30,11 +30,11 @@ #include "COM_VariableSizeBokehBlurOperation.h" #include "COM_ConvertDepthToRadiusOperation.h" -BokehBlurNode::BokehBlurNode(bNode *editorNode): Node(editorNode) +BokehBlurNode::BokehBlurNode(bNode *editorNode) : Node(editorNode) { } -void BokehBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void BokehBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { Object *camob = context->getScene()->camera; @@ -58,7 +58,7 @@ void BokehBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContex this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); this->getInputSocket(3)->relinkConnections(operation->getInputSocket(2), 3, graph); - operation->setSize(((bNodeSocketValueFloat*)this->getInputSocket(2)->getbNodeSocket()->default_value)->value); + operation->setSize(((bNodeSocketValueFloat *)this->getInputSocket(2)->getbNodeSocket()->default_value)->value); operation->setQuality(context->getQuality()); graph->addOperation(operation); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); diff --git a/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp b/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp index d63fbbdb092..d096ef977f8 100644 --- a/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp @@ -26,13 +26,13 @@ #include "COM_ExecutionSystem.h" #include "COM_DirectionalBlurOperation.h" -DirectionalBlurNode::DirectionalBlurNode(bNode *editorNode): Node(editorNode) +DirectionalBlurNode::DirectionalBlurNode(bNode *editorNode) : Node(editorNode) { } -void DirectionalBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void DirectionalBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { - NodeDBlurData *data = (NodeDBlurData*)this->getbNode()->storage; + NodeDBlurData *data = (NodeDBlurData *)this->getbNode()->storage; DirectionalBlurOperation *operation = new DirectionalBlurOperation(); operation->setQuality(context->getQuality()); operation->setData(data); diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.cpp b/source/blender/compositor/nodes/COM_VectorBlurNode.cpp index 98096c3de7b..78b9065b4da 100644 --- a/source/blender/compositor/nodes/COM_VectorBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_VectorBlurNode.cpp @@ -24,14 +24,14 @@ #include "DNA_node_types.h" #include "COM_VectorBlurOperation.h" -VectorBlurNode::VectorBlurNode(bNode *editorNode): Node(editorNode) +VectorBlurNode::VectorBlurNode(bNode *editorNode) : Node(editorNode) { } -void VectorBlurNode::convertToOperations(ExecutionSystem *system, CompositorContext * context) +void VectorBlurNode::convertToOperations(ExecutionSystem *system, CompositorContext *context) { bNode *node = this->getbNode(); - NodeBlurData *vectorBlurSettings = (NodeBlurData*)node->storage; + NodeBlurData *vectorBlurSettings = (NodeBlurData *)node->storage; VectorBlurOperation *operation = new VectorBlurOperation(); operation->setVectorBlurSettings(vectorBlurSettings); operation->setQuality(context->getQuality()); diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp b/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp index 7129e7c140a..3628c399581 100644 --- a/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp @@ -65,14 +65,14 @@ void BilateralBlurOperation::executePixel(float *color, int x, int y, MemoryBuff zero_v4(blurColor); blurDivider = 0.0f; - for (int yi = miny ; yi < maxy ; yi+=QualityStepHelper::getStep()) { - for (int xi = minx ; xi < maxx ; xi+=QualityStepHelper::getStep()) { + for (int yi = miny; yi < maxy; yi += QualityStepHelper::getStep()) { + for (int xi = minx; xi < maxx; xi += QualityStepHelper::getStep()) { // read determinator this->inputDeterminatorProgram->read(determinator, xi, yi, inputBuffers, data); deltaColor = (fabsf(determinatorReferenceColor[0] - determinator[0]) + fabsf(determinatorReferenceColor[1] - determinator[1]) + fabsf(determinatorReferenceColor[2] - determinator[2])); // do not take the alpha channel into account - if (deltaColor< sigmacolor) { + if (deltaColor < sigmacolor) { // add this to the blur this->inputColorProgram->read(tempColor, xi, yi, inputBuffers, data); add_v4_v4(blurColor, tempColor); @@ -101,7 +101,7 @@ void BilateralBlurOperation::deinitExecution() bool BilateralBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { rcti newInput; - int add = ceil(this->space)+1; + int add = ceil(this->space) + 1; newInput.xmax = input->xmax + (add); newInput.xmin = input->xmin - (add); diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp index 2280ee3a435..bb915fec590 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp @@ -27,7 +27,7 @@ extern "C" { #include "RE_pipeline.h" } -BlurBaseOperation::BlurBaseOperation(): NodeOperation() +BlurBaseOperation::BlurBaseOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); @@ -37,7 +37,7 @@ BlurBaseOperation::BlurBaseOperation(): NodeOperation() this->data = NULL; this->size = 1.0f; this->deleteData = false; - this->sizeavailable=false; + this->sizeavailable = false; } void BlurBaseOperation::initExecution() { @@ -47,18 +47,18 @@ void BlurBaseOperation::initExecution() this->data->image_in_height = this->getHeight(); if (this->data->relative) { switch (this->data->aspect) { - case CMP_NODE_BLUR_ASPECT_NONE: - this->data->sizex = (int)(this->data->percentx*0.01f*this->data->image_in_width); - this->data->sizey = (int)(this->data->percenty*0.01f*this->data->image_in_height); - break; - case CMP_NODE_BLUR_ASPECT_Y: - this->data->sizex = (int)(this->data->percentx*0.01f*this->data->image_in_width); - this->data->sizey = (int)(this->data->percenty*0.01f*this->data->image_in_width); - break; - case CMP_NODE_BLUR_ASPECT_X: - this->data->sizex = (int)(this->data->percentx*0.01f*this->data->image_in_height); - this->data->sizey = (int)(this->data->percenty*0.01f*this->data->image_in_height); - break; + case CMP_NODE_BLUR_ASPECT_NONE: + this->data->sizex = (int)(this->data->percentx * 0.01f * this->data->image_in_width); + this->data->sizey = (int)(this->data->percenty * 0.01f * this->data->image_in_height); + break; + case CMP_NODE_BLUR_ASPECT_Y: + this->data->sizex = (int)(this->data->percentx * 0.01f * this->data->image_in_width); + this->data->sizey = (int)(this->data->percenty * 0.01f * this->data->image_in_width); + break; + case CMP_NODE_BLUR_ASPECT_X: + this->data->sizex = (int)(this->data->percentx * 0.01f * this->data->image_in_height); + this->data->sizey = (int)(this->data->percenty * 0.01f * this->data->image_in_height); + break; } } @@ -77,14 +77,14 @@ float *BlurBaseOperation::make_gausstab(int rad) sum = 0.0f; for (i = -rad; i <= rad; i++) { - val = RE_filter_value(this->data->filtertype, (float)i/(float)rad); + val = RE_filter_value(this->data->filtertype, (float)i / (float)rad); sum += val; - gausstab[i+rad] = val; + gausstab[i + rad] = val; } - sum = 1.0f/sum; - for (i=0; igetHeight(); float dimension; - if (widthbokehMidX = width/2.0f; - this->bokehMidY = height/2.0f; - this->bokehDimension = dimension/2.0f; + this->bokehMidX = width / 2.0f; + this->bokehMidY = height / 2.0f; + this->bokehDimension = dimension / 2.0f; QualityStepHelper::initExecution(COM_QH_INCREASE); } @@ -78,14 +78,14 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer * float bokeh[4]; inputBoundingBoxReader->read(tempBoundingBox, x, y, COM_PS_NEAREST, inputBuffers); - if (tempBoundingBox[0] >0.0f) { + if (tempBoundingBox[0] > 0.0f) { float overallmultiplyer[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); int bufferwidth = inputBuffer->getWidth(); int bufferstartx = inputBuffer->getRect()->xmin; int bufferstarty = inputBuffer->getRect()->ymin; - int pixelSize = this->size*this->getWidth()/100.0f; + int pixelSize = this->size * this->getWidth() / 100.0f; int miny = y - pixelSize; int maxy = y + pixelSize; @@ -101,16 +101,16 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer * int step = getStep(); int offsetadd = getOffsetAdd(); - float m = this->bokehDimension/pixelSize; - for (int ny = miny ; ny < maxy ; ny +=step) { - int bufferindex = ((minx - bufferstartx)*4)+((ny-bufferstarty)*4*bufferwidth); - for (int nx = minx ; nx < maxx ; nx +=step) { - float u = this->bokehMidX - (nx-x) *m; - float v = this->bokehMidY - (ny-y) *m; + float m = this->bokehDimension / pixelSize; + for (int ny = miny; ny < maxy; ny += step) { + int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth); + for (int nx = minx; nx < maxx; nx += step) { + float u = this->bokehMidX - (nx - x) * m; + float v = this->bokehMidY - (ny - y) * m; inputBokehProgram->read(bokeh, u, v, COM_PS_NEAREST, inputBuffers); madd_v4_v4v4(tempColor, bokeh, &buffer[bufferindex]); add_v4_v4(overallmultiplyer, bokeh); - bufferindex +=offsetadd; + bufferindex += offsetadd; } } color[0] = tempColor[0] * (1.0f / overallmultiplyer[0]); @@ -135,10 +135,10 @@ bool BokehBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe rcti newInput; rcti bokehInput; - newInput.xmax = input->xmax + (size*this->getWidth()/100.0f); - newInput.xmin = input->xmin - (size*this->getWidth()/100.0f); - newInput.ymax = input->ymax + (size*this->getWidth()/100.0f); - newInput.ymin = input->ymin - (size*this->getWidth()/100.0f); + newInput.xmax = input->xmax + (size * this->getWidth() / 100.0f); + newInput.xmin = input->xmin - (size * this->getWidth() / 100.0f); + newInput.ymax = input->ymax + (size * this->getWidth() / 100.0f); + newInput.ymin = input->ymin - (size * this->getWidth() / 100.0f); NodeOperation *operation = getInputOperation(1); bokehInput.xmax = operation->getWidth(); @@ -168,7 +168,7 @@ void BokehBlurOperation::executeOpenCL(cl_context context, cl_program program, c if (!kernel) { kernel = COM_clCreateKernel(program, "bokehBlurKernel", NULL); } - cl_int radius = this->getWidth()*this->size/100.0f; + cl_int radius = this->getWidth() * this->size / 100.0f; cl_int step = this->getStep(); COM_clAttachMemoryBufferToKernelParameter(context, kernel, 0, -1, clMemToCleanUp, inputMemoryBuffers, this->inputBoundingBoxReader); diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp index 60c31400eca..271a165f0ff 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp @@ -54,12 +54,12 @@ void DirectionalBlurOperation::initExecution() const float itsc = 1.0f / powf(2.0f, (float)iterations); float D; - D = distance * sqrtf(width*width + height*height); + D = distance * sqrtf(width * width + height * height); center_x_pix = center_x * width; center_y_pix = center_y * height; tx = itsc * D * cosf(a); - ty = -itsc * D * sinf(a); + ty = -itsc *D *sinf(a); sc = itsc * zoom; rot = itsc * spin; @@ -68,8 +68,8 @@ void DirectionalBlurOperation::initExecution() void DirectionalBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { const int iterations = pow(2.f, this->data->iter); - float col[4] = {0,0,0,0}; - float col2[4] = {0,0,0,0}; + float col[4] = {0, 0, 0, 0}; + float col2[4] = {0, 0, 0, 0}; this->inputProgram->read(col2, x, y, COM_PS_NEAREST, inputBuffers); float ltx = tx; float lty = ty; diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index 92e1aace9e2..7830eef829c 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -24,14 +24,14 @@ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" -FastGaussianBlurOperation::FastGaussianBlurOperation(): BlurBaseOperation() +FastGaussianBlurOperation::FastGaussianBlurOperation() : BlurBaseOperation() { this->iirgaus = NULL; } -void FastGaussianBlurOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data) +void FastGaussianBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { - MemoryBuffer *newData = (MemoryBuffer*)data; + MemoryBuffer *newData = (MemoryBuffer *)data; newData->read(color, x, y); } @@ -44,7 +44,7 @@ bool FastGaussianBlurOperation::determineDependingAreaOfInterest(rcti *input, Re sizeInput.xmax = 5; sizeInput.ymax = 5; - NodeOperation * operation = this->getInputOperation(1); + NodeOperation *operation = this->getInputOperation(1); if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { return true; } @@ -81,25 +81,25 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **m { lockMutex(); if (!iirgaus) { - MemoryBuffer *newBuf = (MemoryBuffer*)this->inputProgram->initializeTileData(rect, memoryBuffers); + MemoryBuffer *newBuf = (MemoryBuffer *)this->inputProgram->initializeTileData(rect, memoryBuffers); MemoryBuffer *copy = newBuf->duplicate(); updateSize(memoryBuffers); int c; - sx = data->sizex * this->size/2.0f; - sy = data->sizey * this->size/2.0f; + sx = data->sizex * this->size / 2.0f; + sy = data->sizey * this->size / 2.0f; if ((sx == sy) && (sx > 0.f)) { - for (c=0; c 0.f) { - for (c=0; c 0.f) { - for (c=0; c ~200 if (sigma >= 3.556f) - q = 0.9804f*(sigma - 3.556f) + 2.5091f; + q = 0.9804f * (sigma - 3.556f) + 2.5091f; else // sigma >= 0.5 - q = (0.0561f*sigma + 0.5784f)*sigma - 0.2568f; - q2 = q*q; - sc = (1.1668 + q)*(3.203729649 + (2.21566 + q)*q); + q = (0.0561f * sigma + 0.5784f) * sigma - 0.2568f; + q2 = q * q; + sc = (1.1668 + q) * (3.203729649 + (2.21566 + q) * q); // no gabor filtering here, so no complex multiplies, just the regular coefs. // all negated here, so as not to have to recalc Triggs/Sdika matrix - cf[1] = q*(5.788961737 + (6.76492 + 3.0*q)*q)/ sc; - cf[2] = -q2*(3.38246 + 3.0*q)/sc; + cf[1] = q * (5.788961737 + (6.76492 + 3.0 * q) * q) / sc; + cf[2] = -q2 * (3.38246 + 3.0 * q) / sc; // 0 & 3 unchanged - cf[3] = q2*q/sc; + cf[3] = q2 * q / sc; cf[0] = 1.0 - cf[1] - cf[2] - cf[3]; // Triggs/Sdika border corrections, @@ -150,59 +150,61 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, int ch // but neither seem to be quite the same, result seems to be ok so far anyway. // Extra scale factor here to not have to do it in filter, // though maybe this had something to with the precision errors - sc = cf[0]/((1.0 + cf[1] - cf[2] + cf[3])*(1.0 - cf[1] - cf[2] - cf[3])*(1.0 + cf[2] + (cf[1] - cf[3])*cf[3])); - tsM[0] = sc*(-cf[3]*cf[1] + 1.0 - cf[3]*cf[3] - cf[2]); - tsM[1] = sc*((cf[3] + cf[1])*(cf[2] + cf[3]*cf[1])); - tsM[2] = sc*(cf[3]*(cf[1] + cf[3]*cf[2])); - tsM[3] = sc*(cf[1] + cf[3]*cf[2]); - tsM[4] = sc*(-(cf[2] - 1.0)*(cf[2] + cf[3]*cf[1])); - tsM[5] = sc*(-(cf[3]*cf[1] + cf[3]*cf[3] + cf[2] - 1.0)*cf[3]); - tsM[6] = sc*(cf[3]*cf[1] + cf[2] + cf[1]*cf[1] - cf[2]*cf[2]); - tsM[7] = sc*(cf[1]*cf[2] + cf[3]*cf[2]*cf[2] - cf[1]*cf[3]*cf[3] - cf[3]*cf[3]*cf[3] - cf[3]*cf[2] + cf[3]); - tsM[8] = sc*(cf[3]*(cf[1] + cf[3]*cf[2])); + sc = cf[0] / ((1.0 + cf[1] - cf[2] + cf[3]) * (1.0 - cf[1] - cf[2] - cf[3]) * (1.0 + cf[2] + (cf[1] - cf[3]) * cf[3])); + tsM[0] = sc * (-cf[3] * cf[1] + 1.0 - cf[3] * cf[3] - cf[2]); + tsM[1] = sc * ((cf[3] + cf[1]) * (cf[2] + cf[3] * cf[1])); + tsM[2] = sc * (cf[3] * (cf[1] + cf[3] * cf[2])); + tsM[3] = sc * (cf[1] + cf[3] * cf[2]); + tsM[4] = sc * (-(cf[2] - 1.0) * (cf[2] + cf[3] * cf[1])); + tsM[5] = sc * (-(cf[3] * cf[1] + cf[3] * cf[3] + cf[2] - 1.0) * cf[3]); + tsM[6] = sc * (cf[3] * cf[1] + cf[2] + cf[1] * cf[1] - cf[2] * cf[2]); + tsM[7] = sc * (cf[1] * cf[2] + cf[3] * cf[2] * cf[2] - cf[1] * cf[3] * cf[3] - cf[3] * cf[3] * cf[3] - cf[3] * cf[2] + cf[3]); + tsM[8] = sc * (cf[3] * (cf[1] + cf[3] * cf[2])); -#define YVV(L) \ -{ \ -W[0] = cf[0]*X[0] + cf[1]*X[0] + cf[2]*X[0] + cf[3]*X[0]; \ -W[1] = cf[0]*X[1] + cf[1]*W[0] + cf[2]*X[0] + cf[3]*X[0]; \ -W[2] = cf[0]*X[2] + cf[1]*W[1] + cf[2]*W[0] + cf[3]*X[0]; \ -for (i=3; i=0; i--) \ -Y[i] = cf[0]*W[i] + cf[1]*Y[i+1] + cf[2]*Y[i+2] + cf[3]*Y[i+3]; \ -} +#define YVV(L) \ +{ \ + W[0] = cf[0] * X[0] + cf[1] * X[0] + cf[2] * X[0] + cf[3] * X[0]; \ + W[1] = cf[0] * X[1] + cf[1] * W[0] + cf[2] * X[0] + cf[3] * X[0]; \ + W[2] = cf[0] * X[2] + cf[1] * W[1] + cf[2] * W[0] + cf[3] * X[0]; \ + for (i = 3; i < L; i++) { \ + W[i] = cf[0] * X[i] + cf[1] * W[i - 1] + cf[2] * W[i - 2] + cf[3] * W[i - 3]; \ + } \ + tsu[0] = W[L - 1] - X[L - 1]; \ + tsu[1] = W[L - 2] - X[L - 1]; \ + tsu[2] = W[L - 3] - X[L - 1]; \ + tsv[0] = tsM[0] * tsu[0] + tsM[1] * tsu[1] + tsM[2] * tsu[2] + X[L - 1]; \ + tsv[1] = tsM[3] * tsu[0] + tsM[4] * tsu[1] + tsM[5] * tsu[2] + X[L - 1]; \ + tsv[2] = tsM[6] * tsu[0] + tsM[7] * tsu[1] + tsM[8] * tsu[2] + X[L - 1]; \ + Y[L - 1] = cf[0] * W[L - 1] + cf[1] * tsv[0] + cf[2] * tsv[1] + cf[3] * tsv[2]; \ + Y[L - 2] = cf[0] * W[L - 2] + cf[1] * Y[L - 1] + cf[2] * tsv[0] + cf[3] * tsv[1]; \ + Y[L - 3] = cf[0] * W[L - 3] + cf[1] * Y[L - 2] + cf[2] * Y[L - 1] + cf[3] * tsv[0]; \ + for (i = L - 4; i >= 0; i--) { \ + Y[i] = cf[0] * W[i] + cf[1] * Y[i + 1] + cf[2] * Y[i + 2] + cf[3] * Y[i + 3]; \ + } \ +} (void)0 // intermediate buffers sz = MAX2(src->getWidth(), src->getHeight()); - X = (double*)MEM_callocN(sz*sizeof(double), "IIR_gauss X buf"); - Y = (double*)MEM_callocN(sz*sizeof(double), "IIR_gauss Y buf"); - W = (double*)MEM_callocN(sz*sizeof(double), "IIR_gauss W buf"); - if (xy & 1) { // H - for (y=0; ygetHeight(); ++y) { - const int yx = y*src->getWidth(); - for (x=0; xgetWidth(); ++x) - X[x] = buffer[(x + yx)*COM_NUMBER_OF_CHANNELS + chan]; + X = (double *)MEM_callocN(sz * sizeof(double), "IIR_gauss X buf"); + Y = (double *)MEM_callocN(sz * sizeof(double), "IIR_gauss Y buf"); + W = (double *)MEM_callocN(sz * sizeof(double), "IIR_gauss W buf"); + if (xy & 1) { // H + for (y = 0; y < src->getHeight(); ++y) { + const int yx = y * src->getWidth(); + for (x = 0; x < src->getWidth(); ++x) + X[x] = buffer[(x + yx) * COM_NUMBER_OF_CHANNELS + chan]; YVV(src->getWidth()); - for (x=0; xgetWidth(); ++x) - buffer[(x + yx)*COM_NUMBER_OF_CHANNELS + chan] = Y[x]; + for (x = 0; x < src->getWidth(); ++x) + buffer[(x + yx) * COM_NUMBER_OF_CHANNELS + chan] = Y[x]; } } - if (xy & 2) { // V - for (x=0; xgetWidth(); ++x) { - for (y=0; ygetHeight(); ++y) - X[y] = buffer[(x + y*src->getWidth())*COM_NUMBER_OF_CHANNELS + chan]; + if (xy & 2) { // V + for (x = 0; x < src->getWidth(); ++x) { + for (y = 0; y < src->getHeight(); ++y) + X[y] = buffer[(x + y * src->getWidth()) * COM_NUMBER_OF_CHANNELS + chan]; YVV(src->getHeight()); - for (y=0; ygetHeight(); ++y) - buffer[(x + y*src->getWidth())*COM_NUMBER_OF_CHANNELS + chan] = Y[y]; + for (y = 0; y < src->getHeight(); ++y) + buffer[(x + y * src->getWidth()) * COM_NUMBER_OF_CHANNELS + chan] = Y[y]; } } diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h index 9c8973f6a3a..f92e3dc68a5 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h @@ -34,7 +34,7 @@ private: public: FastGaussianBlurOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); static void IIR_gauss(MemoryBuffer *src, float sigma, int channel, int xy); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index 80e35f63ac5..b5ae54299eb 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -27,7 +27,7 @@ extern "C" { #include "RE_pipeline.h" } -GaussianBokehBlurOperation::GaussianBokehBlurOperation(): BlurBaseOperation() +GaussianBokehBlurOperation::GaussianBokehBlurOperation() : BlurBaseOperation() { this->gausstab = NULL; } @@ -65,42 +65,42 @@ void GaussianBokehBlurOperation::updateGauss(MemoryBuffer **memoryBuffers) if (!sizeavailable) { updateSize(memoryBuffers); } - radxf = size*(float)this->data->sizex; - if (radxf>width/2.0f) - radxf = width/2.0f; - else if (radxf<1.0f) + radxf = size * (float)this->data->sizex; + if (radxf > width / 2.0f) + radxf = width / 2.0f; + else if (radxf < 1.0f) radxf = 1.0f; /* vertical */ - radyf = size*(float)this->data->sizey; - if (radyf>height/2.0f) - radyf = height/2.0f; - else if (radyf<1.0f) + radyf = size * (float)this->data->sizey; + if (radyf > height / 2.0f) + radyf = height / 2.0f; + else if (radyf < 1.0f) radyf = 1.0f; radx = ceil(radxf); rady = ceil(radyf); - n = (2*radx+1)*(2*rady+1); + n = (2 * radx + 1) * (2 * rady + 1); /* create a full filter image */ ddgauss = new float[n]; dgauss = ddgauss; val = 0.0f; - for (j=-rady; j<=rady; j++) { - for (i=-radx; i<=radx; i++, dgauss++) { + for (j = -rady; j <= rady; j++) { + for (i = -radx; i <= radx; i++, dgauss++) { float fj = (float)j / radyf; float fi = (float)i / radxf; float dist = sqrt(fj * fj + fi * fi); *dgauss = RE_filter_value(this->data->filtertype, dist); - val+= *dgauss; + val += *dgauss; } } - if (val!=0.0f) { - val = 1.0f/val; - for (j = n - 1; j>=0; j--) - ddgauss[j]*= val; + if (val != 0.0f) { + val = 1.0f / val; + for (j = n - 1; j >= 0; j--) + ddgauss[j] *= val; } else ddgauss[4] = 1.0f; @@ -116,7 +116,7 @@ void GaussianBokehBlurOperation::executePixel(float *color, int x, int y, Memory tempColor[2] = 0; tempColor[3] = 0; float overallmultiplyer = 0; - MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); int bufferwidth = inputBuffer->getWidth(); int bufferstartx = inputBuffer->getRect()->xmin; @@ -134,15 +134,15 @@ void GaussianBokehBlurOperation::executePixel(float *color, int x, int y, Memory int index; int step = QualityStepHelper::getStep(); int offsetadd = QualityStepHelper::getOffsetAdd(); - for (int ny = miny ; ny < maxy ; ny +=step) { - index = ((ny-y)+this->rady) * (this->radx*2+1) + (minx-x+this->radx); - int bufferindex = ((minx - bufferstartx)*4)+((ny-bufferstarty)*4*bufferwidth); - for (int nx = minx ; nx < maxx ; nx +=step) { + for (int ny = miny; ny < maxy; ny += step) { + index = ((ny - y) + this->rady) * (this->radx * 2 + 1) + (minx - x + this->radx); + int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth); + for (int nx = minx; nx < maxx; nx += step) { const float multiplyer = gausstab[index]; madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplyer); overallmultiplyer += multiplyer; index += step; - bufferindex +=offsetadd; + bufferindex += offsetadd; } } @@ -164,7 +164,7 @@ bool GaussianBokehBlurOperation::determineDependingAreaOfInterest(rcti *input, R sizeInput.ymin = 0; sizeInput.xmax = 5; sizeInput.ymax = 5; - NodeOperation * operation = this->getInputOperation(1); + NodeOperation *operation = this->getInputOperation(1); if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { return true; diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp index e30cbfeff7e..8edbf8f0617 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp @@ -27,7 +27,7 @@ extern "C" { #include "RE_pipeline.h" } -GaussianXBlurOperation::GaussianXBlurOperation(): BlurBaseOperation() +GaussianXBlurOperation::GaussianXBlurOperation() : BlurBaseOperation() { this->gausstab = NULL; this->rad = 0; @@ -48,8 +48,8 @@ void GaussianXBlurOperation::initExecution() BlurBaseOperation::initExecution(); if (this->sizeavailable) { - float rad = size*this->data->sizex; - if (rad<1) + float rad = size * this->data->sizex; + if (rad < 1) rad = 1; this->rad = rad; @@ -61,8 +61,8 @@ void GaussianXBlurOperation::updateGauss(MemoryBuffer **memoryBuffers) { if (this->gausstab == NULL) { updateSize(memoryBuffers); - float rad = size*this->data->sizex; - if (rad<1) + float rad = size * this->data->sizex; + if (rad < 1) rad = 1; this->rad = rad; @@ -78,7 +78,7 @@ void GaussianXBlurOperation::executePixel(float *color, int x, int y, MemoryBuff tempColor[2] = 0; tempColor[3] = 0; float overallmultiplyer = 0.0f; - MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); int bufferwidth = inputBuffer->getWidth(); int bufferstartx = inputBuffer->getRect()->xmin; @@ -96,9 +96,9 @@ void GaussianXBlurOperation::executePixel(float *color, int x, int y, MemoryBuff int index; int step = getStep(); int offsetadd = getOffsetAdd(); - int bufferindex = ((minx - bufferstartx)*4)+((miny-bufferstarty)*4*bufferwidth); - for (int nx = minx ; nx < maxx ; nx +=step) { - index = (nx-x)+this->rad; + int bufferindex = ((minx - bufferstartx) * 4) + ((miny - bufferstarty) * 4 * bufferwidth); + for (int nx = minx; nx < maxx; nx += step) { + index = (nx - x) + this->rad; const float multiplyer = gausstab[index]; madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplyer); overallmultiplyer += multiplyer; @@ -123,7 +123,7 @@ bool GaussianXBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadB sizeInput.xmax = 5; sizeInput.ymax = 5; - NodeOperation * operation = this->getInputOperation(1); + NodeOperation *operation = this->getInputOperation(1); if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { return true; } diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp index c0561704596..7143cc02615 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -27,7 +27,7 @@ extern "C" { #include "RE_pipeline.h" } -GaussianYBlurOperation::GaussianYBlurOperation(): BlurBaseOperation() +GaussianYBlurOperation::GaussianYBlurOperation() : BlurBaseOperation() { this->gausstab = NULL; this->rad = 0; @@ -45,8 +45,8 @@ void *GaussianYBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memo void GaussianYBlurOperation::initExecution() { if (this->sizeavailable) { - float rad = size*this->data->sizey; - if (rad<1) + float rad = size * this->data->sizey; + if (rad < 1) rad = 1; this->rad = rad; @@ -58,8 +58,8 @@ void GaussianYBlurOperation::updateGauss(MemoryBuffer **memoryBuffers) { if (this->gausstab == NULL) { updateSize(memoryBuffers); - float rad = size*this->data->sizey; - if (rad<1) + float rad = size * this->data->sizey; + if (rad < 1) rad = 1; this->rad = rad; @@ -75,7 +75,7 @@ void GaussianYBlurOperation::executePixel(float *color, int x, int y, MemoryBuff tempColor[2] = 0; tempColor[3] = 0; float overallmultiplyer = 0; - MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); int bufferwidth = inputBuffer->getWidth(); int bufferstartx = inputBuffer->getRect()->xmin; @@ -92,9 +92,9 @@ void GaussianYBlurOperation::executePixel(float *color, int x, int y, MemoryBuff int step = getStep(); int index; - for (int ny = miny ; ny < maxy ; ny +=step) { - index = (ny-y)+this->rad; - int bufferindex = ((minx - bufferstartx)*4)+((ny-bufferstarty)*4*bufferwidth); + for (int ny = miny; ny < maxy; ny += step) { + index = (ny - y) + this->rad; + int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth); const float multiplyer = gausstab[index]; madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplyer); overallmultiplyer += multiplyer; @@ -118,7 +118,7 @@ bool GaussianYBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadB sizeInput.xmax = 5; sizeInput.ymax = 5; - NodeOperation * operation = this->getInputOperation(1); + NodeOperation *operation = this->getInputOperation(1); if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { return true; } diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp index 3ed3921e0c1..9c7a33c1327 100644 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp @@ -28,7 +28,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" -KeyingBlurOperation::KeyingBlurOperation(): NodeOperation() +KeyingBlurOperation::KeyingBlurOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -47,7 +47,7 @@ void *KeyingBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryB void KeyingBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { - MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); int bufferWidth = inputBuffer->getWidth(); diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.h b/source/blender/compositor/operations/COM_KeyingBlurOperation.h index 8d7834c7265..2848f260cbd 100644 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.h +++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.h @@ -27,8 +27,8 @@ #include "COM_NodeOperation.h" /** - * Class with implementation of bluring for keying node - */ + * Class with implementation of bluring for keying node + */ class KeyingBlurOperation : public NodeOperation { protected: int size; diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 1544b1c8d06..7c9b0c75518 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -76,9 +76,9 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me add_v4_v4(tempColor, readColor); add_v3_fl(overallmultiplyer, 1.0f); - for (int ny = miny ; ny < maxy ; ny += QualityStepHelper::getStep()) { - for (int nx = minx ; nx < maxx ; nx += QualityStepHelper::getStep()) { - if (nx >=0 && nx < this->getWidth() && ny >= 0 && ny < getHeight()) { + for (int ny = miny; ny < maxy; ny += QualityStepHelper::getStep()) { + for (int nx = minx; nx < maxx; nx += QualityStepHelper::getStep()) { + if (nx >= 0 && nx < this->getWidth() && ny >= 0 && ny < getHeight()) { inputSizeProgram->read(tempSize, nx, ny, COM_PS_NEAREST, inputBuffers); float size = tempSize[0]; // size += this->threshold; @@ -88,8 +88,8 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me /* pass */ } else if (size >= fabsf(dx) && size >= fabsf(dy)) { - float u = 256 + dx*256/size; - float v = 256 + dy*256/size; + float u = 256 + dx * 256 / size; + float v = 256 + dy * 256 / size; inputBokehProgram->read(bokeh, u, v, COM_PS_NEAREST, inputBuffers); inputProgram->read(readColor, nx, ny, COM_PS_NEAREST, inputBuffers); madd_v4_v4v4(tempColor, bokeh, readColor); @@ -119,10 +119,10 @@ bool VariableSizeBokehBlurOperation::determineDependingAreaOfInterest(rcti *inpu rcti newInput; rcti bokehInput; - newInput.xmax = input->xmax + maxBlur+2; - newInput.xmin = input->xmin - maxBlur+2; - newInput.ymax = input->ymax + maxBlur-2; - newInput.ymin = input->ymin - maxBlur-2; + newInput.xmax = input->xmax + maxBlur + 2; + newInput.xmin = input->xmin - maxBlur + 2; + newInput.ymax = input->ymax + maxBlur - 2; + newInput.ymin = input->ymin - maxBlur - 2; bokehInput.xmax = 512; bokehInput.xmin = 0; bokehInput.ymax = 512; diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp index 3dac3547b8a..3efae2c4e3d 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp @@ -28,7 +28,7 @@ extern "C" { #include "RE_pipeline.h" } -VectorBlurOperation::VectorBlurOperation(): NodeOperation() +VectorBlurOperation::VectorBlurOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); // ZBUF @@ -54,12 +54,12 @@ void VectorBlurOperation::initExecution() void VectorBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { - float *buffer = (float*) data; - int index = (y*this->getWidth() + x) * COM_NUMBER_OF_CHANNELS; + float *buffer = (float *) data; + int index = (y * this->getWidth() + x) * COM_NUMBER_OF_CHANNELS; color[0] = buffer[index]; - color[1] = buffer[index+1]; - color[2] = buffer[index+2]; - color[3] = buffer[index+3]; + color[1] = buffer[index + 1]; + color[2] = buffer[index + 2]; + color[3] = buffer[index + 3]; } void VectorBlurOperation::deinitExecution() @@ -79,11 +79,11 @@ void *VectorBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryB lockMutex(); if (this->cachedInstance == NULL) { - MemoryBuffer *tile = (MemoryBuffer*)inputImageProgram->initializeTileData(rect, memoryBuffers); - MemoryBuffer *speed = (MemoryBuffer*)inputSpeedProgram->initializeTileData(rect, memoryBuffers); - MemoryBuffer *z = (MemoryBuffer*)inputZProgram->initializeTileData(rect, memoryBuffers); - float *data = new float[this->getWidth()*this->getHeight()*COM_NUMBER_OF_CHANNELS]; - memcpy(data, tile->getBuffer(),this->getWidth()*this->getHeight()*COM_NUMBER_OF_CHANNELS*sizeof(float)); + MemoryBuffer *tile = (MemoryBuffer *)inputImageProgram->initializeTileData(rect, memoryBuffers); + MemoryBuffer *speed = (MemoryBuffer *)inputSpeedProgram->initializeTileData(rect, memoryBuffers); + MemoryBuffer *z = (MemoryBuffer *)inputZProgram->initializeTileData(rect, memoryBuffers); + float *data = new float[this->getWidth() * this->getHeight() * COM_NUMBER_OF_CHANNELS]; + memcpy(data, tile->getBuffer(), this->getWidth() * this->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); this->generateVectorBlur(data, tile, speed, z); this->cachedInstance = data; } @@ -110,7 +110,7 @@ void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputIma { float *zbuf = inputZ->convertToValueBuffer(); NodeBlurData blurdata; - blurdata.samples = this->settings->samples/QualityStepHelper::getStep(); + blurdata.samples = this->settings->samples / QualityStepHelper::getStep(); blurdata.maxspeed = this->settings->maxspeed; blurdata.minspeed = this->settings->minspeed; blurdata.curved = this->settings->curved; diff --git a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c index 196234d658f..62e8138f5e1 100644 --- a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c @@ -32,71 +32,71 @@ #include "node_composite_util.h" /* **************** BILATERALBLUR ******************** */ -static bNodeSocketTemplate cmp_node_bilateralblur_in[]= { +static bNodeSocketTemplate cmp_node_bilateralblur_in[] = { { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_RGBA, 1, N_("Determinator"), 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; -static bNodeSocketTemplate cmp_node_bilateralblur_out[]= { +static bNodeSocketTemplate cmp_node_bilateralblur_out[] = { { SOCK_RGBA, 0, N_("Image")}, { -1, 0, "" } }; #define INIT_C3 \ - mean0 = 1; \ - mean1[0] = src[0]; \ - mean1[1] = src[1]; \ - mean1[2] = src[2]; \ - mean1[3] = src[3]; \ - (void)0 + mean0 = 1; \ + mean1[0] = src[0]; \ + mean1[1] = src[1]; \ + mean1[2] = src[2]; \ + mean1[3] = src[3]; \ + (void)0 /* 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])) + ((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 */ + 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] + \ - (double)COLOR_DISTANCE_C3(ref, ref_color ) * i2sigma_color; \ - w = 1.0/(w*w + 1); \ - mean0 += w; \ - mean1[0] += (double)temp_color[0] * w; \ - mean1[1] += (double)temp_color[1] * w; \ - mean1[2] += (double)temp_color[2] * w; \ - mean1[3] += (double)temp_color[3] * w; \ - (void)0 + temp_color = src + deltas[k]; \ + ref_color = ref + deltas[k]; \ + w = weight_tab[k] + \ + (double)COLOR_DISTANCE_C3(ref, ref_color) * i2sigma_color; \ + w = 1.0 / (w * w + 1); \ + mean0 += w; \ + mean1[0] += (double)temp_color[0] * w; \ + mean1[1] += (double)temp_color[1] * w; \ + mean1[2] += (double)temp_color[2] * w; \ + mean1[3] += (double)temp_color[3] * w; \ + (void)0 /* write blurred values to image */ #define UPDATE_OUTPUT_C3 \ - mean0 = 1.0/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; \ - (void)0 + mean0 = 1.0 / 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; \ + (void)0 /* initializes deltas for fast access to neighbor 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)); \ - (void)0 +#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)); \ + (void)0 /* 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 *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) { - NodeBilateralBlurData *nbbd= node->storage; - CompBuf *new, *source, *img= in[0]->data, *refimg= in[1]->data; + 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]; @@ -104,46 +104,46 @@ static void node_composit_exec_bilateralblur(void *UNUSED(data), bNode *node, bN float sigma_color, sigma_space; int imgx, imgy, x, y, pix, i, step; int deltas[8]; - short found_determinator= 0; + 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); + img = typecheck_compbuf(in[0]->data, CB_RGBA); } - imgx= img->x; - imgy= img->y; - pix= img->type; - step= pix * imgx; + imgx = img->x; + imgy = img->y; + pix = img->type; + step = pix * imgx; if (refimg) { if (refimg->x == imgx && refimg->y == imgy) { if (ELEM3(refimg->type, CB_VAL, CB_VEC2, CB_VEC3)) { - refimg= typecheck_compbuf(in[1]->data, CB_RGBA); - found_determinator= 1; + refimg = typecheck_compbuf(in[1]->data, CB_RGBA); + found_determinator = 1; } } } else { - refimg= img; + refimg = img; } /* allocs */ - source= dupalloc_compbuf(img); - new= alloc_compbuf(imgx, imgy, pix, 1); + 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; + new->xof = img->xof; + new->yof = img->yof; /* bilateral code properties */ - sigma_color= nbbd->sigma_color; - sigma_space= nbbd->sigma_space; + sigma_color = nbbd->sigma_color; + sigma_space = nbbd->sigma_space; - i2sigma_color= 1.0f / (sigma_color * sigma_color); - i2sigma_space= 1.0f / (sigma_space * sigma_space); + i2sigma_color = 1.0f / (sigma_color * sigma_color); + i2sigma_space = 1.0f / (sigma_space * sigma_space); INIT_3X3_DELTAS(deltas, step, pix); @@ -151,13 +151,13 @@ static void node_composit_exec_bilateralblur(void *UNUSED(data), bNode *node, bN 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; + 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) { + for (x = 0; x < imgx; x++, src += pix, ref += pix) { INIT_C3; KERNEL_ELEMENT_C3(6); @@ -175,10 +175,10 @@ static void node_composit_exec_bilateralblur(void *UNUSED(data), bNode *node, bN UPDATE_OUTPUT_C3; } - dest+= step; + dest += step; - for (y= 1; y < imgy - 1; y++, dest+= step, src+= pix, ref+= pix) { - x= 0; + for (y = 1; y < imgy - 1; y++, dest += step, src += pix, ref += pix) { + x = 0; INIT_C3; @@ -190,10 +190,10 @@ static void node_composit_exec_bilateralblur(void *UNUSED(data), bNode *node, bN UPDATE_OUTPUT_C3; - src+= pix; - ref+= pix; + src += pix; + ref += pix; - for (x= 1; x < imgx - 1; x++, src+= pix, ref+= pix) { + for (x = 1; x < imgx - 1; x++, src += pix, ref += pix) { INIT_C3; KERNEL_ELEMENT_C3(0); @@ -219,7 +219,7 @@ static void node_composit_exec_bilateralblur(void *UNUSED(data), bNode *node, bN UPDATE_OUTPUT_C3; } - for (x= 0; x < imgx; x++, src+= pix, ref+= pix) { + for (x = 0; x < imgx; x++, src += pix, ref += pix) { INIT_C3; KERNEL_ELEMENT_C3(2); @@ -249,17 +249,17 @@ static void node_composit_exec_bilateralblur(void *UNUSED(data), bNode *node, bN free_compbuf(refimg); } - out[0]->data= source; + out[0]->data = source; free_compbuf(new); } -static void node_composit_init_bilateralblur(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +static void node_composit_init_bilateralblur(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) { - NodeBilateralBlurData *nbbd= MEM_callocN(sizeof(NodeBilateralBlurData), "node bilateral blur data"); - node->storage= nbbd; - nbbd->sigma_color= 0.3; - nbbd->sigma_space= 5.0; + NodeBilateralBlurData *nbbd = MEM_callocN(sizeof(NodeBilateralBlurData), "node bilateral blur data"); + node->storage = nbbd; + nbbd->sigma_color = 0.3; + nbbd->sigma_space = 5.0; } void register_node_type_cmp_bilateralblur(bNodeTreeType *ttype) diff --git a/source/blender/nodes/composite/nodes/node_composite_blur.c b/source/blender/nodes/composite/nodes/node_composite_blur.c index f10e6bfe939..046623f5b26 100644 --- a/source/blender/nodes/composite/nodes/node_composite_blur.c +++ b/source/blender/nodes/composite/nodes/node_composite_blur.c @@ -34,14 +34,14 @@ #include "node_composite_util.h" /* **************** BLUR ******************** */ -static bNodeSocketTemplate cmp_node_blur_in[]= { - { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("Size"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_blur_in[] = { + { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_FLOAT, 1, N_("Size"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { -1, 0, "" } }; -static bNodeSocketTemplate cmp_node_blur_out[]= { - { SOCK_RGBA, 0, N_("Image")}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_blur_out[] = { + { SOCK_RGBA, 0, N_("Image")}, + { -1, 0, "" } }; static float *make_gausstab(int filtertype, int rad) @@ -55,14 +55,14 @@ static float *make_gausstab(int filtertype, int rad) sum = 0.0f; for (i = -rad; i <= rad; i++) { - val= RE_filter_value(filtertype, (float)i/(float)rad); + val = RE_filter_value(filtertype, (float)i / (float)rad); sum += val; - gausstab[i+rad] = val; + gausstab[i + rad] = val; } - sum= 1.0f/sum; - for (i=0; istorage; + NodeBlurData *nbd = node->storage; CompBuf *work; register float sum, val; float rval, gval, bval, aval; float *gausstab, *gausstabcent; - int rad, imgx= img->x, imgy= img->y; - int x, y, pix= img->type; + int rad, imgx = img->x, imgy = img->y; + int x, y, pix = img->type; int i, bigstep; float *src, *dest; /* helper image */ - work= alloc_compbuf(imgx, imgy, img->type, 1); /* allocs */ + work = alloc_compbuf(imgx, imgy, img->type, 1); /* allocs */ /* horizontal */ if (nbd->sizex == 0) { memcpy(work->rect, img->rect, sizeof(float) * img->type * imgx * imgy); } else { - rad = scale*(float)nbd->sizex; - if (rad>imgx/2) - rad= imgx/2; - else if (rad<1) - rad= 1; + rad = scale * (float)nbd->sizex; + if (rad > imgx / 2) + rad = imgx / 2; + else if (rad < 1) + rad = 1; - gausstab= make_gausstab(nbd->filtertype, rad); - gausstabcent= gausstab+rad; + gausstab = make_gausstab(nbd->filtertype, rad); + gausstabcent = gausstab + rad; for (y = 0; y < imgy; y++) { - float *srcd= img->rect + pix*(y*img->x); + float *srcd = img->rect + pix * (y * img->x); - dest = work->rect + pix*(y * img->x); + dest = work->rect + pix * (y * img->x); - for (x = 0; x < imgx ; x++) { - int minr= x-rad<0?-x:-rad; - int maxr= x+rad>imgx?imgx-x:rad; + for (x = 0; x < imgx; x++) { + int minr = x - rad < 0 ? -x : -rad; + int maxr = x + rad > imgx ? imgx - x : rad; - src= srcd + pix*(x+minr); + src = srcd + pix * (x + minr); - sum= gval = rval= bval= aval= 0.0f; - for (i= minr; i < maxr; i++) { - val= gausstabcent[i]; - sum+= val; + sum = gval = rval = bval = aval = 0.0f; + for (i = minr; i < maxr; i++) { + val = gausstabcent[i]; + sum += val; rval += val * (*src++); - if (pix==4) { + if (pix == 4) { gval += val * (*src++); bval += val * (*src++); aval += val * (*src++); } } - sum= 1.0f/sum; - *dest++ = rval*sum; - if (pix==4) { - *dest++ = gval*sum; - *dest++ = bval*sum; - *dest++ = aval*sum; + sum = 1.0f / sum; + *dest++ = rval * sum; + if (pix == 4) { + *dest++ = gval * sum; + *dest++ = bval * sum; + *dest++ = aval * sum; } } if (node->exec & NODE_BREAK) @@ -156,47 +156,47 @@ static void blur_single_image(bNode *node, CompBuf *new, CompBuf *img, float sca memcpy(new->rect, work->rect, sizeof(float) * img->type * imgx * imgy); } else { - rad = scale*(float)nbd->sizey; - if (rad>imgy/2) - rad= imgy/2; - else if (rad<1) - rad= 1; + rad = scale * (float)nbd->sizey; + if (rad > imgy / 2) + rad = imgy / 2; + else if (rad < 1) + rad = 1; - gausstab= make_gausstab(nbd->filtertype, rad); - gausstabcent= gausstab+rad; + gausstab = make_gausstab(nbd->filtertype, rad); + gausstabcent = gausstab + rad; - bigstep = pix*imgx; + bigstep = pix * imgx; for (x = 0; x < imgx; x++) { - float *srcd= work->rect + pix*x; + float *srcd = work->rect + pix * x; - dest = new->rect + pix*x; + dest = new->rect + pix * x; - for (y = 0; y < imgy ; y++) { - int minr= y-rad<0?-y:-rad; - int maxr= y+rad>imgy?imgy-y:rad; + for (y = 0; y < imgy; y++) { + int minr = y - rad < 0 ? -y : -rad; + int maxr = y + rad > imgy ? imgy - y : rad; - src= srcd + bigstep*(y+minr); + src = srcd + bigstep * (y + minr); - sum= gval = rval= bval= aval= 0.0f; - for (i= minr; i < maxr; i++) { - val= gausstabcent[i]; - sum+= val; + sum = gval = rval = bval = aval = 0.0f; + for (i = minr; i < maxr; i++) { + val = gausstabcent[i]; + sum += val; rval += val * src[0]; - if (pix==4) { + if (pix == 4) { gval += val * src[1]; bval += val * src[2]; aval += val * src[3]; } src += bigstep; } - sum= 1.0f/sum; - dest[0] = rval*sum; - if (pix==4) { - dest[1] = gval*sum; - dest[2] = bval*sum; - dest[3] = aval*sum; + sum = 1.0f / sum; + dest[0] = rval * sum; + if (pix == 4) { + dest[1] = gval * sum; + dest[2] = bval * sum; + dest[3] = aval * sum; } - dest+= bigstep; + dest += bigstep; } if (node->exec & NODE_BREAK) break; @@ -216,83 +216,83 @@ static void bloom_with_reference(CompBuf *new, CompBuf *img, CompBuf *UNUSED(ref float **maintabs; float *gausstabx, *gausstabcenty; float *gausstaby, *gausstabcentx; - int radx, rady, imgx= img->x, imgy= img->y; + int radx, rady, imgx = img->x, imgy = img->y; int x, y; int i, j; float *src, *dest, *wb; - wbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1); + wbuf = alloc_compbuf(imgx, imgy, CB_VAL, 1); /* horizontal */ radx = (float)nbd->sizex; - if (radx>imgx/2) - radx= imgx/2; - else if (radx<1) - radx= 1; + if (radx > imgx / 2) + radx = imgx / 2; + else if (radx < 1) + radx = 1; /* vertical */ rady = (float)nbd->sizey; - if (rady>imgy/2) - rady= imgy/2; - else if (rady<1) - rady= 1; - - x= MAX2(radx, rady); - maintabs= MEM_mallocN(x*sizeof(void *), "gauss array"); - for (i= 0; i imgy / 2) + rady = imgy / 2; + else if (rady < 1) + rady = 1; + + x = MAX2(radx, rady); + maintabs = MEM_mallocN(x * sizeof(void *), "gauss array"); + for (i = 0; i < x; i++) + maintabs[i] = make_bloomtab(i + 1); /* vars to store before we go */ // refd= ref->rect; - src= img->rect; + src = img->rect; - radxf= (float)radx; - radyf= (float)rady; + radxf = (float)radx; + radyf = (float)rady; for (y = 0; y < imgy; y++) { - for (x = 0; x < imgx ; x++, src+=4) {//, refd++) { + for (x = 0; x < imgx; x++, src += 4) { //, refd++) { // int refradx= (int)(refd[0]*radxf); // int refrady= (int)(refd[0]*radyf); - int refradx= (int)(radxf*0.3f*src[3]*(src[0]+src[1]+src[2])); - int refrady= (int)(radyf*0.3f*src[3]*(src[0]+src[1]+src[2])); + int refradx = (int)(radxf * 0.3f * src[3] * (src[0] + src[1] + src[2])); + int refrady = (int)(radyf * 0.3f * src[3] * (src[0] + src[1] + src[2])); - if (refradx>radx) refradx= radx; - else if (refradx<1) refradx= 1; - if (refrady>rady) refrady= rady; - else if (refrady<1) refrady= 1; - - if (refradx==1 && refrady==1) { - wb= wbuf->rect + ( y*imgx + x); - dest= new->rect + 4*( y*imgx + x); - wb[0]+= 1.0f; + if (refradx > radx) refradx = radx; + else if (refradx < 1) refradx = 1; + if (refrady > rady) refrady = rady; + else if (refrady < 1) refrady = 1; + + if (refradx == 1 && refrady == 1) { + wb = wbuf->rect + (y * imgx + x); + dest = new->rect + 4 * (y * imgx + x); + wb[0] += 1.0f; dest[0] += src[0]; dest[1] += src[1]; dest[2] += src[2]; dest[3] += src[3]; } else { - int minxr= x-refradx<0?-x:-refradx; - int maxxr= x+refradx>imgx?imgx-x:refradx; - int minyr= y-refrady<0?-y:-refrady; - int maxyr= y+refrady>imgy?imgy-y:refrady; - - float *destd= new->rect + 4*( (y + minyr)*imgx + x + minxr); - float *wbufd= wbuf->rect + ( (y + minyr)*imgx + x + minxr); - - gausstabx= maintabs[refradx-1]; - gausstabcentx= gausstabx+refradx; - gausstaby= maintabs[refrady-1]; - gausstabcenty= gausstaby+refrady; - - for (i= minyr; i < maxyr; i++, destd+= 4*imgx, wbufd+= imgx) { - dest= destd; - wb= wbufd; - for (j= minxr; j < maxxr; j++, dest+=4, wb++) { + int minxr = x - refradx < 0 ? -x : -refradx; + int maxxr = x + refradx > imgx ? imgx - x : refradx; + int minyr = y - refrady < 0 ? -y : -refrady; + int maxyr = y + refrady > imgy ? imgy - y : refrady; + + float *destd = new->rect + 4 * ( (y + minyr) * imgx + x + minxr); + float *wbufd = wbuf->rect + ( (y + minyr) * imgx + x + minxr); + + gausstabx = maintabs[refradx - 1]; + gausstabcentx = gausstabx + refradx; + gausstaby = maintabs[refrady - 1]; + gausstabcenty = gausstaby + refrady; + + for (i = minyr; i < maxyr; i++, destd += 4 * imgx, wbufd += imgx) { + dest = destd; + wb = wbufd; + for (j = minxr; j < maxxr; j++, dest += 4, wb++) { - val= gausstabcenty[i]*gausstabcentx[j]; - wb[0]+= val; + val = gausstabcenty[i] * gausstabcentx[j]; + wb[0] += val; dest[0] += val * src[0]; dest[1] += val * src[1]; dest[2] += val * src[2]; @@ -303,23 +303,23 @@ static void bloom_with_reference(CompBuf *new, CompBuf *img, CompBuf *UNUSED(ref } } - x= imgx*imgy; - dest= new->rect; - wb= wbuf->rect; + x = imgx * imgy; + dest = new->rect; + wb = wbuf->rect; while (x--) { - val= 1.0f/wb[0]; - dest[0]*= val; - dest[1]*= val; - dest[2]*= val; - dest[3]*= val; + val = 1.0f / wb[0]; + dest[0] *= val; + dest[1] *= val; + dest[2] *= val; + dest[3] *= val; wb++; - dest+= 4; + dest += 4; } free_compbuf(wbuf); - x= MAX2(radx, rady); - for (i= 0; i0.33f) { - fj= (fj-0.33f)/0.66f; - if (fi+fj>1.0f) + if (fj > 0.33f) { + fj = (fj - 0.33f) / 0.66f; + if (fi + fj > 1.0f) return 0.0f; else return 1.0f; @@ -346,85 +346,85 @@ static float hexagon_filter(float fi, float fj) /* both images same type, either 1 or 4 channels */ static void bokeh_single_image(bNode *node, CompBuf *new, CompBuf *img, float fac) { - NodeBlurData *nbd= node->storage; + NodeBlurData *nbd = node->storage; register float val; float radxf, radyf; float *gausstab, *dgauss; - int radx, rady, imgx= img->x, imgy= img->y; - int x, y, pix= img->type; + int radx, rady, imgx = img->x, imgy = img->y; + int x, y, pix = img->type; int i, j, n; - float *src= NULL, *dest, *srcd= NULL; + float *src = NULL, *dest, *srcd = NULL; /* horizontal */ - radxf = fac*(float)nbd->sizex; - if (radxf>imgx/2.0f) - radxf= imgx/2.0f; - else if (radxf<1.0f) - radxf= 1.0f; + radxf = fac * (float)nbd->sizex; + if (radxf > imgx / 2.0f) + radxf = imgx / 2.0f; + else if (radxf < 1.0f) + radxf = 1.0f; /* vertical */ - radyf = fac*(float)nbd->sizey; - if (radyf>imgy/2.0f) - radyf= imgy/2.0f; - else if (radyf<1.0f) - radyf= 1.0f; + radyf = fac * (float)nbd->sizey; + if (radyf > imgy / 2.0f) + radyf = imgy / 2.0f; + else if (radyf < 1.0f) + radyf = 1.0f; - radx= ceil(radxf); - rady= ceil(radyf); + radx = ceil(radxf); + rady = ceil(radyf); - n = (2*radx+1)*(2*rady+1); + n = (2 * radx + 1) * (2 * rady + 1); /* create a full filter image */ - gausstab= MEM_mallocN(sizeof(float)*n, "filter tab"); - dgauss= gausstab; - val= 0.0f; - for (j=-rady; j<=rady; j++) { - for (i=-radx; i<=radx; i++, dgauss++) { - float fj= (float)j/radyf; - float fi= (float)i/radxf; - float dist= sqrt(fj*fj + fi*fi); - - //*dgauss= hexagon_filter(fi, fj); - *dgauss= RE_filter_value(nbd->filtertype, dist); + gausstab = MEM_mallocN(sizeof(float) * n, "filter tab"); + dgauss = gausstab; + val = 0.0f; + for (j = -rady; j <= rady; j++) { + for (i = -radx; i <= radx; i++, dgauss++) { + float fj = (float)j / radyf; + float fi = (float)i / radxf; + float dist = sqrt(fj * fj + fi * fi); - val+= *dgauss; + //*dgauss= hexagon_filter(fi, fj); + *dgauss = RE_filter_value(nbd->filtertype, dist); + + val += *dgauss; } } - if (val!=0.0f) { - val= 1.0f/val; - for (j= n -1; j>=0; j--) - gausstab[j]*= val; + if (val != 0.0f) { + val = 1.0f / val; + for (j = n - 1; j >= 0; j--) + gausstab[j] *= val; } - else gausstab[4]= 1.0f; - - for (y = -rady+1; y < imgy+rady-1; y++) { - - if (y<=0) srcd= img->rect; - else if (yrect + pix*(imgy-1)*imgx; - - for (x = -radx+1; x < imgx+radx-1 ; x++) { - int minxr= x-radx<0?-x:-radx; - int maxxr= x+radx>=imgx?imgx-x-1:radx; - int minyr= y-rady<0?-y:-rady; - int maxyr= y+rady>imgy-1?imgy-y-1:rady; - - float *destd= new->rect + pix*( (y + minyr)*imgx + x + minxr); - float *dgausd= gausstab + (minyr+rady)*(2*radx+1) + minxr+radx; - - if (x<=0) src= srcd; - else if (xrect; + else if (y < imgy) srcd += pix * imgx; + else srcd = img->rect + pix * (imgy - 1) * imgx; + + for (x = -radx + 1; x < imgx + radx - 1; x++) { + int minxr = x - radx < 0 ? -x : -radx; + int maxxr = x + radx >= imgx ? imgx - x - 1 : radx; + int minyr = y - rady < 0 ? -y : -rady; + int maxyr = y + rady > imgy - 1 ? imgy - y - 1 : rady; + + float *destd = new->rect + pix * ( (y + minyr) * imgx + x + minxr); + float *dgausd = gausstab + (minyr + rady) * (2 * radx + 1) + minxr + radx; + + if (x <= 0) src = srcd; + else if (x < imgx) src += pix; + else src = srcd + pix * (imgx - 1); + + for (i = minyr; i <= maxyr; i++, destd += pix * imgx, dgausd += 2 * radx + 1) { + dest = destd; + dgauss = dgausd; + for (j = minxr; j <= maxxr; j++, dest += pix, dgauss++) { + val = *dgauss; + if (val != 0.0f) { dest[0] += val * src[0]; - if (pix>1) { + if (pix > 1) { dest[1] += val * src[1]; dest[2] += val * src[2]; dest[3] += val * src[3]; @@ -444,116 +444,116 @@ static void bokeh_single_image(bNode *node, CompBuf *new, CompBuf *img, float fa /* reference has to be mapped 0-1, and equal in size */ static void blur_with_reference(bNode *node, CompBuf *new, CompBuf *img, CompBuf *ref) { - NodeBlurData *nbd= node->storage; + NodeBlurData *nbd = node->storage; CompBuf *blurbuf, *ref_use; register float sum, val; float rval, gval, bval, aval, radxf, radyf; float **maintabs; float *gausstabx, *gausstabcenty; float *gausstaby, *gausstabcentx; - int radx, rady, imgx= img->x, imgy= img->y; - int x, y, pix= img->type; + int radx, rady, imgx = img->x, imgy = img->y; + int x, y, pix = img->type; int i, j; float *src, *dest, *refd, *blurd; - float defcol[4] = {1.0f, 1.0f, 1.0f, 1.0f}; /* default color for compbuf_get_pixel */ - float proccol[4]; /* local color if compbuf is procedural */ + float defcol[4] = {1.0f, 1.0f, 1.0f, 1.0f}; /* default color for compbuf_get_pixel */ + float proccol[4]; /* local color if compbuf is procedural */ int refradx, refrady; - if (ref->x!=img->x || ref->y!=img->y) + if (ref->x != img->x || ref->y != img->y) return; - ref_use= typecheck_compbuf(ref, CB_VAL); + ref_use = typecheck_compbuf(ref, CB_VAL); /* trick is; we blur the reference image... but only works with clipped values*/ - blurbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1); - blurbuf->xof= ref_use->xof; - blurbuf->yof= ref_use->yof; - blurd= blurbuf->rect; - refd= ref_use->rect; - for (x= imgx*imgy; x>0; x--, refd++, blurd++) { - if (refd[0]<0.0f) blurd[0]= 0.0f; - else if (refd[0]>1.0f) blurd[0]= 1.0f; - else blurd[0]= refd[0]; + blurbuf = alloc_compbuf(imgx, imgy, CB_VAL, 1); + blurbuf->xof = ref_use->xof; + blurbuf->yof = ref_use->yof; + blurd = blurbuf->rect; + refd = ref_use->rect; + for (x = imgx * imgy; x > 0; x--, refd++, blurd++) { + if (refd[0] < 0.0f) blurd[0] = 0.0f; + else if (refd[0] > 1.0f) blurd[0] = 1.0f; + else blurd[0] = refd[0]; } blur_single_image(node, blurbuf, blurbuf, 1.0f); /* horizontal */ radx = (float)nbd->sizex; - if (radx>imgx/2) - radx= imgx/2; - else if (radx<1) - radx= 1; + if (radx > imgx / 2) + radx = imgx / 2; + else if (radx < 1) + radx = 1; /* vertical */ rady = (float)nbd->sizey; - if (rady>imgy/2) - rady= imgy/2; - else if (rady<1) - rady= 1; - - x= MAX2(radx, rady); - maintabs= MEM_mallocN(x*sizeof(void *), "gauss array"); - for (i= 0; ifiltertype, i+1); - - dest= new->rect; - radxf= (float)radx; - radyf= (float)rady; + if (rady > imgy / 2) + rady = imgy / 2; + else if (rady < 1) + rady = 1; + + x = MAX2(radx, rady); + maintabs = MEM_mallocN(x * sizeof(void *), "gauss array"); + for (i = 0; i < x; i++) + maintabs[i] = make_gausstab(nbd->filtertype, i + 1); + + dest = new->rect; + radxf = (float)radx; + radyf = (float)rady; for (y = 0; y < imgy; y++) { - for (x = 0; x < imgx ; x++, dest+=pix) { - refd= compbuf_get_pixel(blurbuf, defcol, proccol, x-blurbuf->xrad, y-blurbuf->yrad, blurbuf->xrad, blurbuf->yrad); - refradx= (int)(refd[0]*radxf); - refrady= (int)(refd[0]*radyf); - - if (refradx>radx) refradx= radx; - else if (refradx<1) refradx= 1; - if (refrady>rady) refrady= rady; - else if (refrady<1) refrady= 1; + for (x = 0; x < imgx; x++, dest += pix) { + refd = compbuf_get_pixel(blurbuf, defcol, proccol, x - blurbuf->xrad, y - blurbuf->yrad, blurbuf->xrad, blurbuf->yrad); + refradx = (int)(refd[0] * radxf); + refrady = (int)(refd[0] * radyf); - if (refradx==1 && refrady==1) { - src= img->rect + pix*( y*imgx + x); - if (pix==1) - dest[0]= src[0]; + if (refradx > radx) refradx = radx; + else if (refradx < 1) refradx = 1; + if (refrady > rady) refrady = rady; + else if (refrady < 1) refrady = 1; + + if (refradx == 1 && refrady == 1) { + src = img->rect + pix * (y * imgx + x); + if (pix == 1) + dest[0] = src[0]; else copy_v4_v4(dest, src); } else { - int minxr= x-refradx<0?-x:-refradx; - int maxxr= x+refradx>imgx?imgx-x:refradx; - int minyr= y-refrady<0?-y:-refrady; - int maxyr= y+refrady>imgy?imgy-y:refrady; - - float *srcd= img->rect + pix*( (y + minyr)*imgx + x + minxr); - - gausstabx= maintabs[refradx-1]; - gausstabcentx= gausstabx+refradx; - gausstaby= maintabs[refrady-1]; - gausstabcenty= gausstaby+refrady; + int minxr = x - refradx < 0 ? -x : -refradx; + int maxxr = x + refradx > imgx ? imgx - x : refradx; + int minyr = y - refrady < 0 ? -y : -refrady; + int maxyr = y + refrady > imgy ? imgy - y : refrady; - sum= gval = rval= bval= aval= 0.0f; - - for (i= minyr; i < maxyr; i++, srcd+= pix*imgx) { - src= srcd; - for (j= minxr; j < maxxr; j++, src+=pix) { + float *srcd = img->rect + pix * ( (y + minyr) * imgx + x + minxr); + + gausstabx = maintabs[refradx - 1]; + gausstabcentx = gausstabx + refradx; + gausstaby = maintabs[refrady - 1]; + gausstabcenty = gausstaby + refrady; + + sum = gval = rval = bval = aval = 0.0f; + + for (i = minyr; i < maxyr; i++, srcd += pix * imgx) { + src = srcd; + for (j = minxr; j < maxxr; j++, src += pix) { - val= gausstabcenty[i]*gausstabcentx[j]; - sum+= val; + val = gausstabcenty[i] * gausstabcentx[j]; + sum += val; rval += val * src[0]; - if (pix>1) { + if (pix > 1) { gval += val * src[1]; bval += val * src[2]; aval += val * src[3]; } } } - sum= 1.0f/sum; - dest[0] = rval*sum; - if (pix>1) { - dest[1] = gval*sum; - dest[2] = bval*sum; - dest[3] = aval*sum; + sum = 1.0f / sum; + dest[0] = rval * sum; + if (pix > 1) { + dest[1] = gval * sum; + dest[2] = bval * sum; + dest[3] = aval * sum; } } } @@ -563,46 +563,46 @@ static void blur_with_reference(bNode *node, CompBuf *new, CompBuf *img, CompBuf free_compbuf(blurbuf); - x= MAX2(radx, rady); - for (i= 0; idata; - NodeBlurData *nbd= node->storage; + CompBuf *new, *img = in[0]->data; + NodeBlurData *nbd = node->storage; - if (img==NULL) return; + if (img == NULL) return; /* store image in size that is needed for absolute/relative conversions on ui level */ - nbd->image_in_width= img->x; - nbd->image_in_height= img->y; + nbd->image_in_width = img->x; + nbd->image_in_height = img->y; - if (out[0]->hasoutput==0) return; + if (out[0]->hasoutput == 0) return; if (nbd->relative) { - if (nbd->aspect==CMP_NODE_BLUR_ASPECT_NONE) { - nbd->sizex= (int)(nbd->percentx*0.01f*nbd->image_in_width); - nbd->sizey= (int)(nbd->percenty*0.01f*nbd->image_in_height); + if (nbd->aspect == CMP_NODE_BLUR_ASPECT_NONE) { + nbd->sizex = (int)(nbd->percentx * 0.01f * nbd->image_in_width); + nbd->sizey = (int)(nbd->percenty * 0.01f * nbd->image_in_height); } - else if (nbd->aspect==CMP_NODE_BLUR_ASPECT_Y) { - nbd->sizex= (int)(nbd->percentx*0.01f*nbd->image_in_width); - nbd->sizey= (int)(nbd->percenty*0.01f*nbd->image_in_width); + else if (nbd->aspect == CMP_NODE_BLUR_ASPECT_Y) { + nbd->sizex = (int)(nbd->percentx * 0.01f * nbd->image_in_width); + nbd->sizey = (int)(nbd->percenty * 0.01f * nbd->image_in_width); } - else if (nbd->aspect==CMP_NODE_BLUR_ASPECT_X) { - nbd->sizex= (int)(nbd->percentx*0.01f*nbd->image_in_height); - nbd->sizey= (int)(nbd->percenty*0.01f*nbd->image_in_height); + else if (nbd->aspect == CMP_NODE_BLUR_ASPECT_X) { + nbd->sizex = (int)(nbd->percentx * 0.01f * nbd->image_in_height); + nbd->sizey = (int)(nbd->percenty * 0.01f * nbd->image_in_height); } } - if (nbd->sizex==0 && nbd->sizey==0) { - new= pass_on_compbuf(img); - out[0]->data= new; + if (nbd->sizex == 0 && nbd->sizey == 0) { + new = pass_on_compbuf(img); + out[0]->data = new; } else if (nbd->filtertype == R_FILTER_FAST_GAUSS) { if (in[1]->vec[0] < 0.001f) { /* time node inputs can be a tiny value */ @@ -610,10 +610,10 @@ static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bN } else { // TODO: can this be mapped with reference, too? - const float sx = ((float)nbd->sizex*in[1]->vec[0])/2.0f, sy = ((float)nbd->sizey*in[1]->vec[0])/2.0f; + const float sx = ((float)nbd->sizex * in[1]->vec[0]) / 2.0f, sy = ((float)nbd->sizey * in[1]->vec[0]) / 2.0f; int c; - if ((img==NULL) || (out[0]->hasoutput==0)) return; + if ((img == NULL) || (out[0]->hasoutput == 0)) return; if (img->type == CB_VEC2) new = typecheck_compbuf(img, CB_VAL); @@ -623,16 +623,16 @@ static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bN new = dupalloc_compbuf(img); if ((sx == sy) && (sx > 0.f)) { - for (c=0; ctype; ++c) + for (c = 0; c < new->type; ++c) IIR_gauss(new, sx, c, 3); } else { if (sx > 0.f) { - for (c=0; ctype; ++c) + for (c = 0; c < new->type; ++c) IIR_gauss(new, sx, c, 1); } if (sy > 0.f) { - for (c=0; ctype; ++c) + for (c = 0; c < new->type; ++c) IIR_gauss(new, sy, c, 2); } } @@ -641,8 +641,8 @@ static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bN } else { /* All non fast gauss blur methods */ - if (img->type==CB_VEC2 || img->type==CB_VEC3) { - img= typecheck_compbuf(in[0]->data, CB_RGBA); + if (img->type == CB_VEC2 || img->type == CB_VEC3) { + img = typecheck_compbuf(in[0]->data, CB_RGBA); } /* if fac input, we do it different */ @@ -650,17 +650,17 @@ static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bN CompBuf *gammabuf; /* make output size of input image */ - new= alloc_compbuf(img->x, img->y, img->type, 1); /* allocs */ + new = alloc_compbuf(img->x, img->y, img->type, 1); /* allocs */ /* accept image offsets from other nodes */ new->xof = img->xof; new->yof = img->yof; if (nbd->gamma) { - gammabuf= dupalloc_compbuf(img); + gammabuf = dupalloc_compbuf(img); gamma_correct_compbuf(gammabuf, 0); } - else gammabuf= img; + else gammabuf = img; blur_with_reference(node, new, gammabuf, in[1]->data); @@ -670,30 +670,30 @@ static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bN } if (node->exec & NODE_BREAK) { free_compbuf(new); - new= NULL; + new = NULL; } - out[0]->data= new; + out[0]->data = new; } else { - if (in[1]->vec[0]<=0.001f) { /* time node inputs can be a tiny value */ - new= pass_on_compbuf(img); + if (in[1]->vec[0] <= 0.001f) { /* time node inputs can be a tiny value */ + new = pass_on_compbuf(img); } else { CompBuf *gammabuf; /* make output size of input image */ - new= alloc_compbuf(img->x, img->y, img->type, 1); /* allocs */ + new = alloc_compbuf(img->x, img->y, img->type, 1); /* allocs */ /* accept image offsets from other nodes */ new->xof = img->xof; new->yof = img->yof; if (nbd->gamma) { - gammabuf= dupalloc_compbuf(img); + gammabuf = dupalloc_compbuf(img); gamma_correct_compbuf(gammabuf, 0); } - else gammabuf= img; + else gammabuf = img; if (nbd->bokeh) bokeh_single_image(node, new, gammabuf, in[1]->vec[0]); @@ -708,28 +708,28 @@ static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bN } if (node->exec & NODE_BREAK) { free_compbuf(new); - new= NULL; + new = NULL; } } - out[0]->data= new; + out[0]->data = new; } - if (img!=in[0]->data) + if (img != in[0]->data) free_compbuf(img); } generate_preview(data, node, out[0]->data); } -static void node_composit_init_blur(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +static void node_composit_init_blur(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) { - node->storage= MEM_callocN(sizeof(NodeBlurData), "node blur data"); + node->storage = MEM_callocN(sizeof(NodeBlurData), "node blur data"); } void register_node_type_cmp_blur(bNodeTreeType *ttype) { static bNodeType ntype; - node_type_base(ttype, &ntype, CMP_NODE_BLUR, "Blur", NODE_CLASS_OP_FILTER, NODE_PREVIEW|NODE_OPTIONS); + node_type_base(ttype, &ntype, CMP_NODE_BLUR, "Blur", NODE_CLASS_OP_FILTER, NODE_PREVIEW | NODE_OPTIONS); node_type_socket_templates(&ntype, cmp_node_blur_in, cmp_node_blur_out); node_type_size(&ntype, 120, 80, 200); node_type_init(&ntype, node_composit_init_blur); diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehblur.c b/source/blender/nodes/composite/nodes/node_composite_bokehblur.c index 6b24bdb5c52..222ac7a5cdf 100644 --- a/source/blender/nodes/composite/nodes/node_composite_bokehblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_bokehblur.c @@ -36,20 +36,20 @@ #include "../node_composite_util.h" /* **************** BLUR ******************** */ -static bNodeSocketTemplate cmp_node_bokehblur_in[]= { - { SOCK_RGBA, 1, N_("Image"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, N_("Bokeh"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("Size"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f}, - { SOCK_FLOAT, 1, N_("Bounding box"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_bokehblur_in[] = { + { SOCK_RGBA, 1, N_("Image"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, N_("Bokeh"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, N_("Size"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f}, + { SOCK_FLOAT, 1, N_("Bounding box"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; -static bNodeSocketTemplate cmp_node_bokehblur_out[]= { - { SOCK_RGBA, 0, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_bokehblur_out[] = { + { SOCK_RGBA, 0, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; -static void node_composit_init_bokehblur(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +static void node_composit_init_bokehblur(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) { node->custom3 = 4.0f; node->custom4 = 16.0f; diff --git a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c index 395fa154a89..73e28658309 100644 --- a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c @@ -32,23 +32,23 @@ #include "node_composite_util.h" -static bNodeSocketTemplate cmp_node_dblur_in[]= { - { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.f}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_dblur_in[] = { + { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.f}, + { -1, 0, "" } }; -static bNodeSocketTemplate cmp_node_dblur_out[]= { - { SOCK_RGBA, 0, N_("Image")}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_dblur_out[] = { + { SOCK_RGBA, 0, N_("Image")}, + { -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) + 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; - const float itsc= 1.f / powf(2.f, (float)iterations); + void (*getpix)(CompBuf *, float, float, float *) = wrap ? qd_getPixelLerpWrap : qd_getPixelLerp; + const float a = angle; + const float itsc = 1.f / powf(2.f, (float)iterations); float D; float center_x_pix, center_y_pix; float tx, ty; @@ -56,36 +56,36 @@ static CompBuf *dblur(bNode *node, CompBuf *img, int iterations, int wrap, CompBuf *tmp; int i, j; - tmp= dupalloc_compbuf(img); + 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; + 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 * cosf(a); - ty= -itsc * D * sinf(a); - sc= itsc * zoom; - rot= itsc * spin; + tx = itsc * D * cosf(a); + ty = -itsc *D *sinf(a); + sc = itsc * zoom; + rot = itsc * spin; /* blur the image */ - for (i= 0; i < iterations; ++i) { - const float cs= cosf(rot), ss= sinf(rot); - const float isc= 1.f / (1.f + sc); + for (i = 0; i < iterations; ++i) { + const float cs = cosf(rot), ss = sinf(rot); + const float isc = 1.f / (1.f + sc); unsigned int x, y; - float col[4]= {0, 0, 0, 0}; + float col[4] = {0, 0, 0, 0}; - for (y= 0; y < img->y; ++y) { - const float v= isc * (y - center_y_pix) + ty; + 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; + 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]= 0.5f * (img->rect[p + j] + col[j]); + for (j = 0; j < 4; ++j) { + img->rect[p + j] = 0.5f * (img->rect[p + j] + col[j]); } } } @@ -109,8 +109,8 @@ static CompBuf *dblur(bNode *node, CompBuf *img, int iterations, int wrap, static void node_composit_exec_dblur(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) { - NodeDBlurData *ndbd= node->storage; - CompBuf *new, *img= in[0]->data; + NodeDBlurData *ndbd = node->storage; + CompBuf *new, *img = in[0]->data; if ((img == NULL) || (out[0]->hasoutput == 0)) return; @@ -119,15 +119,15 @@ static void node_composit_exec_dblur(void *UNUSED(data), bNode *node, bNodeStack 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); + 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(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +static void node_composit_init_dblur(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) { - NodeDBlurData *ndbd= MEM_callocN(sizeof(NodeDBlurData), "node dblur data"); - node->storage= ndbd; - ndbd->center_x= 0.5; - ndbd->center_y= 0.5; + NodeDBlurData *ndbd = MEM_callocN(sizeof(NodeDBlurData), "node dblur data"); + node->storage = ndbd; + ndbd->center_x = 0.5; + ndbd->center_y = 0.5; } void register_node_type_cmp_dblur(bNodeTreeType *ttype) diff --git a/source/blender/nodes/composite/nodes/node_composite_vecBlur.c b/source/blender/nodes/composite/nodes/node_composite_vecBlur.c index fd2cc724b82..e1a20a65227 100644 --- a/source/blender/nodes/composite/nodes/node_composite_vecBlur.c +++ b/source/blender/nodes/composite/nodes/node_composite_vecBlur.c @@ -34,63 +34,63 @@ /* **************** VECTOR BLUR ******************** */ -static bNodeSocketTemplate cmp_node_vecblur_in[]= { - { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("Z"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, - { SOCK_VECTOR, 1, N_("Speed"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_VELOCITY}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_vecblur_in[] = { + { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_FLOAT, 1, N_("Z"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_VECTOR, 1, N_("Speed"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_VELOCITY}, + { -1, 0, "" } }; -static bNodeSocketTemplate cmp_node_vecblur_out[]= { - { SOCK_RGBA, 0, N_("Image")}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_vecblur_out[] = { + { SOCK_RGBA, 0, N_("Image")}, + { -1, 0, "" } }; static void node_composit_exec_vecblur(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) { - NodeBlurData *nbd= node->storage; - CompBuf *new, *img= in[0]->data, *vecbuf= in[2]->data, *zbuf= in[1]->data; + NodeBlurData *nbd = node->storage; + CompBuf *new, *img = in[0]->data, *vecbuf = in[2]->data, *zbuf = in[1]->data; - if (img==NULL || vecbuf==NULL || zbuf==NULL || out[0]->hasoutput==0) + if (img == NULL || vecbuf == NULL || zbuf == NULL || out[0]->hasoutput == 0) return; - if (vecbuf->x!=img->x || vecbuf->y!=img->y) { + if (vecbuf->x != img->x || vecbuf->y != img->y) { printf("ERROR: cannot do different sized vecbuf yet\n"); return; } - if (vecbuf->type!=CB_VEC4) { + if (vecbuf->type != CB_VEC4) { printf("ERROR: input should be vecbuf\n"); return; } - if (zbuf->type!=CB_VAL) { + if (zbuf->type != CB_VAL) { printf("ERROR: input should be zbuf\n"); return; } - if (zbuf->x!=img->x || zbuf->y!=img->y) { + if (zbuf->x != img->x || zbuf->y != img->y) { printf("ERROR: cannot do different sized zbuf yet\n"); return; } /* allow the input image to be of another type */ - img= typecheck_compbuf(in[0]->data, CB_RGBA); + img = typecheck_compbuf(in[0]->data, CB_RGBA); - new= dupalloc_compbuf(img); + new = dupalloc_compbuf(img); /* call special zbuffer version */ RE_zbuf_accumulate_vecblur(nbd, img->x, img->y, new->rect, img->rect, vecbuf->rect, zbuf->rect); - out[0]->data= new; + out[0]->data = new; - if (img!=in[0]->data) + if (img != in[0]->data) free_compbuf(img); } -static void node_composit_init_vecblur(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +static void node_composit_init_vecblur(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) { - NodeBlurData *nbd= MEM_callocN(sizeof(NodeBlurData), "node blur data"); - node->storage= nbd; - nbd->samples= 32; - nbd->fac= 1.0f; + NodeBlurData *nbd = MEM_callocN(sizeof(NodeBlurData), "node blur data"); + node->storage = nbd; + nbd->samples = 32; + nbd->fac = 1.0f; } /* custom1: itterations, custom2: maxspeed (0 = nolimit) */ From 6a8fceb8b8691f0084fa9fe69298aca2cebaaba4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 15 Jun 2012 10:15:10 +0000 Subject: [PATCH 337/360] Fix cycles non-progressive integrator not delivering correct AO pass. --- intern/cycles/kernel/kernel_path.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 2da6a7e4d8f..98ab9169c21 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -692,6 +692,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion) { int num_samples = kernel_data.integrator.ao_samples; + float num_samples_inv = 1.0f/num_samples; float ao_factor = kernel_data.background.ao_factor/num_samples; for(int j = 0; j < num_samples; j++) { @@ -717,7 +718,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) { float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*ao_factor; - path_radiance_accum_ao(&L, throughput, ao_bsdf, ao_shadow, state.bounce); + path_radiance_accum_ao(&L, throughput*num_samples_inv, ao_bsdf, ao_shadow, state.bounce); } } } From f0c724219df2e4b13a2501bd4001860f840a2afb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 11:03:23 +0000 Subject: [PATCH 338/360] Internal refactoring of tracking module, should be no functional changes - Re-arrange functions in headers and implementation file to make them more grouped by entity they're operating with. Also order of functions in implementation file should match order of functions in header for easier navigation. - Rename some functions to match conventions of naming public functions. - Some code de-duplication, still some room for improvements tho. - Split main 2D tracking functions into smaller steps to make it more clear. Accidentally OpenMP was disabled in some of previous commits, re-enable it. --- source/blender/blenkernel/BKE_tracking.h | 228 +- source/blender/blenkernel/intern/constraint.c | 20 +- source/blender/blenkernel/intern/mask.c | 6 +- source/blender/blenkernel/intern/movieclip.c | 16 +- source/blender/blenkernel/intern/tracking.c | 3624 +++++++++-------- source/blender/blenloader/intern/readfile.c | 2 +- .../compositor/nodes/COM_MovieClipNode.cpp | 2 +- .../operations/COM_KeyingScreenOperation.cpp | 8 +- .../COM_MovieClipAttributeOperation.cpp | 2 +- .../operations/COM_MovieDistortionOperation.h | 4 +- source/blender/editors/gpencil/gpencil_edit.c | 2 +- .../blender/editors/gpencil/gpencil_paint.c | 4 +- .../editors/interface/interface_draw.c | 2 +- .../editors/interface/interface_handlers.c | 2 +- .../blender/editors/mask/mask_relationships.c | 4 +- .../editors/object/object_constraint.c | 6 +- .../blender/editors/space_clip/clip_buttons.c | 12 +- .../editors/space_clip/clip_dopesheet_ops.c | 6 +- source/blender/editors/space_clip/clip_draw.c | 56 +- .../blender/editors/space_clip/clip_editor.c | 8 +- .../editors/space_clip/clip_graph_draw.c | 4 +- .../editors/space_clip/clip_graph_ops.c | 24 +- source/blender/editors/space_clip/clip_ops.c | 4 +- .../blender/editors/space_clip/clip_utils.c | 10 +- .../blender/editors/space_clip/space_clip.c | 2 +- .../blender/editors/space_clip/tracking_ops.c | 223 +- .../blender/editors/space_view3d/drawobject.c | 8 +- .../editors/space_view3d/view3d_select.c | 10 +- .../editors/space_view3d/view3d_snap.c | 6 +- .../editors/transform/transform_conversions.c | 14 +- .../editors/transform/transform_generics.c | 14 +- source/blender/makesrna/intern/rna_tracking.c | 26 +- .../nodes/composite/node_composite_tree.c | 2 +- .../nodes/node_composite_keyingscreen.c | 8 +- .../nodes/node_composite_movieclip.c | 2 +- .../nodes/node_composite_moviedistortion.c | 4 +- .../nodes/node_composite_stabilize2d.c | 2 +- .../windowmanager/intern/wm_init_exit.c | 2 +- 38 files changed, 2252 insertions(+), 2127 deletions(-) diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index e6c98c72b55..2b30c845754 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -47,127 +47,159 @@ struct Camera; struct Object; struct Scene; -void BKE_tracking_init_settings(struct MovieTracking *tracking); -void BKE_tracking_clamp_marker(struct MovieTrackingMarker *marker, int event); -void BKE_tracking_track_flag(struct MovieTrackingTrack *track, int area, int flag, int clear); +/* **** Common functions **** */ -struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, struct ListBase *tracksbase, - float x, float y, int framenr, int width, int height); -struct MovieTrackingMarker *BKE_tracking_insert_marker(struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker); -void BKE_tracking_delete_marker(struct MovieTrackingTrack *track, int framenr); - -void BKE_tracking_marker_pattern_minmax(const struct MovieTrackingMarker *marker, float min[2], float max[2]); -struct MovieTrackingMarker *BKE_tracking_get_marker(struct MovieTrackingTrack *track, int framenr); -struct MovieTrackingMarker *BKE_tracking_ensure_marker(struct MovieTrackingTrack *track, int framenr); -struct MovieTrackingMarker *BKE_tracking_exact_marker(struct MovieTrackingTrack *track, int framenr); -int BKE_tracking_has_marker(struct MovieTrackingTrack *track, int framenr); -int BKE_tracking_has_enabled_marker(struct MovieTrackingTrack *track, int framenr); - -void BKE_tracking_free_track(struct MovieTrackingTrack *track); - -void BKE_tracking_clear_path(struct MovieTrackingTrack *track, int ref_frame, int action); - -void BKE_tracking_join_tracks(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); void BKE_tracking_free(struct MovieTracking *tracking); -struct ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, - struct ImBuf *struct_ibuf, struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker, int use_mask, - int num_samples_x, int num_samples_y, float pos[2]); -struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker, int anchored, int disable_channels); -struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker, int anchored, int disable_channels); -float *BKE_tracking_track_mask_get(int frame_width, int frame_height, struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker); +void BKE_tracking_settings_init(struct MovieTracking *tracking); -void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track); +struct ListBase *BKE_tracking_get_active_tracks(struct MovieTracking *tracking); +struct MovieTrackingReconstruction *BKE_tracking_get_active_reconstruction(struct MovieTracking *tracking); -struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, struct MovieTrackingObject *object, const char *name); -struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr, struct ListBase **tracksbase_r); +/* matrices for constraints and drawing */ +void BKE_tracking_get_camera_object_matrix(struct Scene *scene, struct Object *ob, float mat[4][4]); +void BKE_tracking_get_projection_matrix(struct MovieTracking *tracking, struct MovieTrackingObject *object, + int framenr, int winx, int winy, float mat[4][4]); -void BKE_tracking_camera_shift(struct MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty); -void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene, struct Camera *camera, int width, int height); - -void BKE_get_tracking_mat(struct Scene *scene, struct Object *ob, float mat[4][4]); -void BKE_tracking_projection_matrix(struct MovieTracking *tracking, struct MovieTrackingObject *object, - int framenr, int winx, int winy, float mat[4][4]); - -struct ListBase *BKE_tracking_get_tracks(struct MovieTracking *tracking); -struct MovieTrackingReconstruction *BKE_tracking_get_reconstruction(struct MovieTracking *tracking); - -struct MovieTrackingTrack *BKE_tracking_active_track(struct MovieTracking *tracking); -struct MovieTrackingObject *BKE_tracking_active_object(struct MovieTracking *tracking); -struct MovieTrackingObject *BKE_tracking_get_camera_object(struct MovieTracking *tracking); -struct ListBase *BKE_tracking_object_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object); -struct MovieTrackingReconstruction *BKE_tracking_object_reconstruction(struct MovieTracking *tracking, - struct MovieTrackingObject *object); - -void BKE_tracking_disable_imbuf_channels(struct ImBuf *ibuf, int disable_red, int disable_green, int disable_blue, int grayscale); - -/* clipboard */ -void BKE_tracking_free_clipboard(void); +/* **** Clipboard **** */ +void BKE_tracking_clipboard_free(void); void BKE_tracking_clipboard_copy_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object); int BKE_tracking_clipboard_has_tracks(void); void BKE_tracking_clipboard_paste_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object); -/* 2D tracking */ +/* **** Track **** */ +struct MovieTrackingTrack *BKE_tracking_track_add(struct MovieTracking *tracking, struct ListBase *tracksbase, + float x, float y, int framenr, int width, int height); +void BKE_tracking_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track); +void BKE_tracking_track_free(struct MovieTrackingTrack *track); + +void BKE_tracking_track_flag_set(struct MovieTrackingTrack *track, int area, int flag); +void BKE_tracking_track_flag_clear(struct MovieTrackingTrack *track, int area, int flag); + +int BKE_tracking_track_has_marker_at_frame(struct MovieTrackingTrack *track, int framenr); +int BKE_tracking_track_has_enabled_marker_at_frame(struct MovieTrackingTrack *track, int framenr); + +void BKE_tracking_track_path_clear(struct MovieTrackingTrack *track, int ref_frame, int action); +void BKE_tracking_tracks_join(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); + +struct MovieTrackingTrack *BKE_tracking_track_get_named(struct MovieTracking *tracking, + struct MovieTrackingObject *object, + const char *name); +struct MovieTrackingTrack *BKE_tracking_track_get_indexed(struct MovieTracking *tracking, int tracknr, + struct ListBase **tracksbase_r); + +struct MovieTrackingTrack *BKE_tracking_track_get_active(struct MovieTracking *tracking); + +float *BKE_tracking_track_get_mask(int frame_width, int frame_height, struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker); + +/* selection */ +void BKE_tracking_track_select(struct ListBase *tracksbase, struct MovieTrackingTrack *track, int area, int extend); +void BKE_tracking_track_deselect(struct MovieTrackingTrack *track, int area); + +/* **** Marker **** */ +struct MovieTrackingMarker *BKE_tracking_marker_insert(struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker); +void BKE_tracking_marker_delete(struct MovieTrackingTrack *track, int framenr); + +void BKE_tracking_marker_clamp(struct MovieTrackingMarker *marker, int event); + +struct MovieTrackingMarker *BKE_tracking_marker_get(struct MovieTrackingTrack *track, int framenr); +struct MovieTrackingMarker *BKE_tracking_marker_get_exact(struct MovieTrackingTrack *track, int framenr); +struct MovieTrackingMarker *BKE_tracking_marker_ensure(struct MovieTrackingTrack *track, int framenr); + +void BKE_tracking_marker_pattern_minmax(const struct MovieTrackingMarker *marker, float min[2], float max[2]); + +/* **** Object **** */ +struct MovieTrackingObject *BKE_tracking_object_add(struct MovieTracking *tracking, const char *name); +void BKE_tracking_object_delete(struct MovieTracking *tracking, struct MovieTrackingObject *object); + +void BKE_tracking_object_unique_name(struct MovieTracking *tracking, struct MovieTrackingObject *object); + +struct MovieTrackingObject *BKE_tracking_object_get_named(struct MovieTracking *tracking, const char *name); + +struct MovieTrackingObject *BKE_tracking_object_get_active(struct MovieTracking *tracking); +struct MovieTrackingObject *BKE_tracking_object_get_camera(struct MovieTracking *tracking); + +struct ListBase *BKE_tracking_object_get_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object); +struct MovieTrackingReconstruction *BKE_tracking_object_get_reconstruction(struct MovieTracking *tracking, + struct MovieTrackingObject *object); + +/* **** Camera **** */ +void BKE_tracking_camera_shift_get(struct MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty); +void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene, + struct Camera *camera, int width, int height); + +struct MovieReconstructedCamera *BKE_tracking_camera_get_reconstructed(struct MovieTracking *tracking, + struct MovieTrackingObject *object, + int framenr); +void BKE_tracking_camera_get_reconstructed_interpolate(struct MovieTracking *tracking, + struct MovieTrackingObject *object, + int framenr, float mat[4][4]); + +/* **** Distortion/Undistortion **** */ +struct MovieDistortion *BKE_tracking_distortion_new(void); +void BKE_tracking_distortion_update(struct MovieDistortion *distortion, struct MovieTracking *tracking, + int calibration_width, int calibration_height); +struct MovieDistortion *BKE_tracking_distortion_copy(struct MovieDistortion *distortion); +struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, struct MovieTracking *tracking, + struct ImBuf *ibuf, int width, int height, float overscan, int undistort); +void BKE_tracking_distortion_free(struct MovieDistortion *distortion); + +void BKE_tracking_distort_v2(struct MovieTracking *tracking, float co[2], float nco[2]); +void BKE_tracking_undistort_v2(struct MovieTracking *tracking, float co[2], float nco[2]); + +struct ImBuf *BKE_tracking_undistort_frame(struct MovieTracking *tracking, struct ImBuf *ibuf, + int calibration_width, int calibration_height, float overscan); +struct ImBuf *BKE_tracking_distort_frame(struct MovieTracking *tracking, struct ImBuf *ibuf, + int calibration_width, int calibration_height, float overscan); + +/* **** Image sampling **** */ +struct ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, + struct ImBuf *struct_ibuf, struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker, int use_mask, + int num_samples_x, int num_samples_y, float pos[2]); +struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker, int anchored, int disable_channels); +struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker, int anchored, int disable_channels); + +void BKE_tracking_disable_channels(struct ImBuf *ibuf, int disable_red, int disable_green, + int disable_blue, int grayscale); + +/* **** 2D tracking **** */ struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user, short backwards, short sequence); void BKE_tracking_context_free(struct MovieTrackingContext *context); -void BKE_tracking_sync(struct MovieTrackingContext *context); -void BKE_tracking_sync_user(struct MovieClipUser *user, struct MovieTrackingContext *context); -int BKE_tracking_next(struct MovieTrackingContext *context); +void BKE_tracking_context_sync(struct MovieTrackingContext *context); +void BKE_tracking_context_sync_user(const struct MovieTrackingContext *context, struct MovieClipUser *user); +int BKE_tracking_context_step(struct MovieTrackingContext *context); -/* Camera solving */ -int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, struct MovieTrackingObject *object, - char *error_msg, int error_size); +/* **** Camera solving **** */ +int BKE_tracking_reconstruction_check(struct MovieTracking *tracking, struct MovieTrackingObject *object, + char *error_msg, int error_size); struct MovieReconstructContext *BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking, - struct MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height); + struct MovieTrackingObject *object, + int keyframe1, int keyframe2, + int width, int height); void BKE_tracking_reconstruction_context_free(struct MovieReconstructContext *context); -void BKE_tracking_solve_reconstruction(struct MovieReconstructContext *context, short *stop, short *do_update, +void BKE_tracking_reconstruction_solve(struct MovieReconstructContext *context, short *stop, short *do_update, float *progress, char *stats_message, int message_size); -int BKE_tracking_finish_reconstruction(struct MovieReconstructContext *context, struct MovieTracking *tracking); +int BKE_tracking_reconstruction_finish(struct MovieReconstructContext *context, struct MovieTracking *tracking); -struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking, - struct MovieTrackingObject *object, int framenr); -void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking, struct MovieTrackingObject *object, - int framenr, float mat[4][4]); - -/* Feature detection */ +/* **** Feature detection **** */ void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ListBase *tracksbase, struct ImBuf *imbuf, int framenr, int margin, int min_trackness, int min_distance, struct bGPDlayer *layer, int place_outside_layer); -/* 2D stabilization */ -void BKE_tracking_stabilization_data(struct MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle); -struct ImBuf *BKE_tracking_stabilize(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf, float loc[2], float *scale, float *angle); -void BKE_tracking_stabdata_to_mat4(int width, int height, float aspect, float loc[2], float scale, float angle, float mat[4][4]); - -/* Distortion/Undistortion */ -void BKE_tracking_apply_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]); -void BKE_tracking_invert_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]); - -struct MovieDistortion *BKE_tracking_distortion_create(void); -struct MovieDistortion *BKE_tracking_distortion_copy(struct MovieDistortion *distortion); -struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, struct MovieTracking *tracking, - struct ImBuf *ibuf, int width, int height, float overscan, int undistort); -void BKE_tracking_distortion_destroy(struct MovieDistortion *distortion); - -struct ImBuf *BKE_tracking_undistort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan); -struct ImBuf *BKE_tracking_distort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan); - -/* Object tracking */ -struct MovieTrackingObject *BKE_tracking_new_object(struct MovieTracking *tracking, const char *name); -void BKE_tracking_remove_object(struct MovieTracking *tracking, struct MovieTrackingObject *object); -void BKE_tracking_object_unique_name(struct MovieTracking *tracking, struct MovieTrackingObject *object); -struct MovieTrackingObject *BKE_tracking_named_object(struct MovieTracking *tracking, const char *name); - -/* Select */ -void BKE_tracking_select_track(struct ListBase *tracksbase, struct MovieTrackingTrack *track, int area, int extend); -void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area); +/* **** 2D stabilization **** */ +void BKE_tracking_stabilization_data_get(struct MovieTracking *tracking, int framenr, int width, int height, + float loc[2], float *scale, float *angle); +struct ImBuf *BKE_tracking_stabilize_frame(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf, + float loc[2], float *scale, float *angle); +void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float loc[2], + float scale, float angle, float mat[4][4]); /* Dopesheet */ void BKE_tracking_dopesheet_tag_update(struct MovieTracking *tracking); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 9bb0980ad5c..c12e740958c 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3917,14 +3917,14 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase tracking = &clip->tracking; if (data->object[0]) - tracking_object = BKE_tracking_named_object(tracking, data->object); + tracking_object = BKE_tracking_object_get_named(tracking, data->object); else - tracking_object = BKE_tracking_get_camera_object(tracking); + tracking_object = BKE_tracking_object_get_camera(tracking); if (!tracking_object) return; - track = BKE_tracking_named_track(tracking, tracking_object, data->track); + track = BKE_tracking_track_get_named(tracking, tracking_object, data->track); if (!track) return; @@ -3942,14 +3942,14 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase copy_m4_m4(mat, camob->obmat); - BKE_tracking_get_interpolated_camera(tracking, tracking_object, framenr, imat); + BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, imat); invert_m4(imat); mul_serie_m4(cob->matrix, obmat, mat, imat, NULL, NULL, NULL, NULL, NULL); translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); } else { - BKE_get_tracking_mat(cob->scene, camob, mat); + BKE_tracking_get_camera_object_matrix(cob->scene, camob, mat); mult_m4_m4m4(cob->matrix, obmat, mat); translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); @@ -3981,7 +3981,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase CameraParams params; float pos[2], rmat[4][4]; - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); add_v2_v2v2(pos, marker->pos, track->offset); @@ -4103,10 +4103,10 @@ static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase if (clip) { float mat[4][4], obmat[4][4]; MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *object = BKE_tracking_get_camera_object(tracking); + MovieTrackingObject *object = BKE_tracking_object_get_camera(tracking); int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra); - BKE_tracking_get_interpolated_camera(tracking, object, framenr, mat); + BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat); copy_m4_m4(obmat, cob->matrix); @@ -4165,7 +4165,7 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase MovieTracking *tracking = &clip->tracking; MovieTrackingObject *object; - object = BKE_tracking_named_object(tracking, data->object); + object = BKE_tracking_object_get_named(tracking, data->object); if (object) { float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4]; @@ -4173,7 +4173,7 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase BKE_object_where_is_calc_mat4(scene, camob, cammat); - BKE_tracking_get_interpolated_camera(tracking, object, framenr, mat); + BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat); invert_m4_m4(camimat, cammat); mult_m4_m4m4(parmat, cammat, data->invmat); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 7e9f189ae01..48db916b4ba 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1156,16 +1156,16 @@ static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[ if (parent->id) { MovieClip *clip = (MovieClip *) parent->id; MovieTracking *tracking = (MovieTracking *) &clip->tracking; - MovieTrackingObject *ob = BKE_tracking_named_object(tracking, parent->parent); + MovieTrackingObject *ob = BKE_tracking_object_get_named(tracking, parent->parent); if (ob) { - MovieTrackingTrack *track = BKE_tracking_named_track(tracking, ob, parent->sub_parent); + MovieTrackingTrack *track = BKE_tracking_track_get_named(tracking, ob, parent->sub_parent); MovieClipUser user = {0}; user.framenr = ctime; if (track) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, ctime); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, ctime); float marker_pos_ofs[2]; add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset); BKE_mask_coord_from_movieclip(clip, &user, r_co, marker_pos_ofs); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index adf1a2fd9a8..52c9ec4cb59 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -436,7 +436,7 @@ static MovieClip *movieclip_alloc(const char *name) clip->aspx = clip->aspy = 1.0f; - BKE_tracking_init_settings(&clip->tracking); + BKE_tracking_settings_init(&clip->tracking); clip->proxy.build_size_flag = IMB_PROXY_25; clip->proxy.build_tc_flag = IMB_TC_RECORD_RUN | @@ -548,7 +548,7 @@ static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *dist if (distortion) undistibuf = BKE_tracking_distortion_exec(distortion, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1); else - undistibuf = BKE_tracking_undistort(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); + undistibuf = BKE_tracking_undistort_frame(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); if (undistibuf->userflags & IB_RECT_INVALID) { ibuf->userflags &= ~IB_RECT_INVALID; @@ -678,7 +678,7 @@ static ImBuf *put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *u postproc_ibuf = IMB_dupImBuf(ibuf); if (disable_red || disable_green || disable_blue || grayscale) - BKE_tracking_disable_imbuf_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1); + BKE_tracking_disable_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1); } IMB_refImBuf(postproc_ibuf); @@ -799,7 +799,7 @@ static ImBuf *get_stable_cached_frame(MovieClip *clip, MovieClipUser *user, int stableibuf = cache->stabilized.ibuf; - BKE_tracking_stabilization_data(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle); + BKE_tracking_stabilization_data_get(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle); /* check for stabilization parameters */ if (tscale != cache->stabilized.scale || @@ -825,7 +825,7 @@ static ImBuf *put_stabilized_frame_to_cache(MovieClip *clip, MovieClipUser *user if (cache->stabilized.ibuf) IMB_freeImBuf(cache->stabilized.ibuf); - stableibuf = BKE_tracking_stabilize(&clip->tracking, framenr, ibuf, tloc, &tscale, &tangle); + stableibuf = BKE_tracking_stabilize_frame(&clip->tracking, framenr, ibuf, tloc, &tscale, &tangle); cache->stabilized.ibuf = stableibuf; @@ -1043,12 +1043,12 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip scopes->track_locked = TRUE; if (clip) { - MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking); if (act_track) { MovieTrackingTrack *track = act_track; int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (marker->flag & MARKER_DISABLED) { scopes->track_disabled = TRUE; @@ -1073,7 +1073,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip undist_marker.pos[0] *= width; undist_marker.pos[1] *= height * aspy; - BKE_tracking_invert_intrinsics(&clip->tracking, undist_marker.pos, undist_marker.pos); + BKE_tracking_undistort_v2(&clip->tracking, undist_marker.pos, undist_marker.pos); undist_marker.pos[0] /= width; undist_marker.pos[1] /= height * aspy; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 0aa0d36c537..43fe94d625b 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -76,7 +76,191 @@ static struct { ListBase tracks; } tracking_clipboard; -/*********************** space transformation functions *************************/ +/*********************** Common functions *************************/ + +static MovieTrackingTrack *tracking_track_duplicate(MovieTrackingTrack *track) +{ + MovieTrackingTrack *new_track; + + new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track"); + + *new_track = *track; + new_track->next = new_track->prev = NULL; + + new_track->markers = MEM_dupallocN(new_track->markers); + + return new_track; +} + +static void tracking_tracks_free(ListBase *tracks) +{ + MovieTrackingTrack *track; + + for (track = tracks->first; track; track = track->next) { + BKE_tracking_track_free(track); + } + + BLI_freelistN(tracks); +} + +static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction) +{ + if (reconstruction->cameras) + MEM_freeN(reconstruction->cameras); +} + +static void tracking_object_free(MovieTrackingObject *object) +{ + tracking_tracks_free(&object->tracks); + tracking_reconstruction_free(&object->reconstruction); +} + +static void tracking_objects_free(ListBase *objects) +{ + MovieTrackingObject *object; + + for (object = objects->first; object; object = object->next) + tracking_object_free(object); + + BLI_freelistN(objects); +} + +static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet) +{ + MovieTrackingDopesheetChannel *channel; + + channel = dopesheet->channels.first; + while (channel) { + if (channel->segments) { + MEM_freeN(channel->segments); + } + + channel = channel->next; + } + + BLI_freelistN(&dopesheet->channels); + + dopesheet->channels.first = dopesheet->channels.last = NULL; + dopesheet->tot_channel = 0; +} + +void BKE_tracking_free(MovieTracking *tracking) +{ + tracking_tracks_free(&tracking->tracks); + tracking_reconstruction_free(&tracking->reconstruction); + tracking_objects_free(&tracking->objects); + + if (tracking->stabilization.scaleibuf) + IMB_freeImBuf(tracking->stabilization.scaleibuf); + + if (tracking->camera.intrinsics) + BKE_tracking_distortion_free(tracking->camera.intrinsics); + + tracking_dopesheet_free(&tracking->dopesheet); +} + +void BKE_tracking_settings_init(MovieTracking *tracking) +{ + tracking->camera.sensor_width = 35.0f; + tracking->camera.pixel_aspect = 1.0f; + tracking->camera.units = CAMERA_UNITS_MM; + + tracking->settings.default_motion_model = TRACK_MOTION_MODEL_TRANSLATION; + tracking->settings.default_minimum_correlation = 0.75; + tracking->settings.default_pattern_size = 11; + tracking->settings.default_search_size = 61; + tracking->settings.keyframe1 = 1; + tracking->settings.keyframe2 = 30; + tracking->settings.dist = 1; + tracking->settings.object_distance = 1; + + tracking->stabilization.scaleinf = 1.0f; + tracking->stabilization.locinf = 1.0f; + tracking->stabilization.rotinf = 1.0f; + tracking->stabilization.maxscale = 2.0f; + + BKE_tracking_object_add(tracking, "Camera"); +} + +ListBase *BKE_tracking_get_active_tracks(MovieTracking *tracking) +{ + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); + + if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) { + return &object->tracks; + } + + return &tracking->tracks; +} + +MovieTrackingReconstruction *BKE_tracking_get_active_reconstruction(MovieTracking *tracking) +{ + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); + + return BKE_tracking_object_get_reconstruction(tracking, object); +} + +void BKE_tracking_get_camera_object_matrix(Scene *scene, Object *ob, float mat[4][4]) +{ + if (!ob) { + if (scene->camera) + ob = scene->camera; + else + ob = BKE_scene_camera_find(scene); + } + + if (ob) + BKE_object_where_is_calc_mat4(scene, ob, mat); + else + unit_m4(mat); +} + +void BKE_tracking_get_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object, + int framenr, int winx, int winy, float mat[4][4]) +{ + MovieReconstructedCamera *camera; + float lens = tracking->camera.focal * tracking->camera.sensor_width / (float)winx; + float viewfac, pixsize, left, right, bottom, top, clipsta, clipend; + float winmat[4][4]; + float ycor = 1.0f / tracking->camera.pixel_aspect; + float shiftx, shifty, winside = MAX2(winx, winy); + + BKE_tracking_camera_shift_get(tracking, winx, winy, &shiftx, &shifty); + + clipsta = 0.1f; + clipend = 1000.0f; + + if (winx >= winy) + viewfac = (lens * winx) / tracking->camera.sensor_width; + else + viewfac = (ycor * lens * winy) / tracking->camera.sensor_width; + + pixsize = clipsta / viewfac; + + left = -0.5f * (float)winx + shiftx * winside; + bottom = -0.5f * (ycor) * (float)winy + shifty * winside; + right = 0.5f * (float)winx + shiftx * winside; + top = 0.5f * (ycor) * (float)winy + shifty * winside; + + left *= pixsize; + right *= pixsize; + bottom *= pixsize; + top *= pixsize; + + perspective_m4(winmat, left, right, bottom, top, clipsta, clipend); + + camera = BKE_tracking_camera_get_reconstructed(tracking, object, framenr); + + if (camera) { + float imat[4][4]; + + invert_m4_m4(imat, camera->mat); + mult_m4_m4m4(mat, winmat, imat); + } + else copy_m4_m4(mat, winmat); +} + +/* **** space transformation functions **** */ /* Three coordinate frames: Frame, Search, and Marker * Two units: Pixels, Unified @@ -100,7 +284,8 @@ static void marker_to_frame_unified(const MovieTrackingMarker *marker, const flo static void marker_unified_to_frame_pixel_coordinates(int frame_width, int frame_height, const MovieTrackingMarker *marker, - const float marker_unified_coords[2], float frame_pixel_coords[2]) + const float marker_unified_coords[2], + float frame_pixel_coords[2]) { marker_to_frame_unified(marker, marker_unified_coords, frame_pixel_coords); unified_to_pixel(frame_width, frame_height, frame_pixel_coords, frame_pixel_coords); @@ -168,6 +353,7 @@ static void get_marker_coords_for_tracking(int frame_width, int frame_height, search_pixel_x[i] = pixel_coords[0]; search_pixel_y[i] = pixel_coords[1]; } + /* Convert the center position (aka "pos"); this is the origin */ unified_coords[0] = 0.0; unified_coords[1] = 0.0; @@ -211,121 +397,81 @@ static void set_marker_coords_from_tracking(int frame_width, int frame_height, M } #endif -/*********************** common functions *************************/ +/*********************** clipboard *************************/ -void BKE_tracking_init_settings(MovieTracking *tracking) +void BKE_tracking_clipboard_free(void) { - tracking->camera.sensor_width = 35.0f; - tracking->camera.pixel_aspect = 1.0f; - tracking->camera.units = CAMERA_UNITS_MM; + MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track; - tracking->settings.default_motion_model = TRACK_MOTION_MODEL_TRANSLATION; - tracking->settings.default_minimum_correlation = 0.75; - tracking->settings.default_pattern_size = 11; - tracking->settings.default_search_size = 61; - tracking->settings.keyframe1 = 1; - tracking->settings.keyframe2 = 30; - tracking->settings.dist = 1; - tracking->settings.object_distance = 1; + while (track) { + next_track = track->next; - tracking->stabilization.scaleinf = 1.0f; - tracking->stabilization.locinf = 1.0f; - tracking->stabilization.rotinf = 1.0f; - tracking->stabilization.maxscale = 2.0f; + BKE_tracking_track_free(track); + MEM_freeN(track); - BKE_tracking_new_object(tracking, "Camera"); -} - -void BKE_tracking_clamp_marker(MovieTrackingMarker *marker, int event) -{ - int a; - float pat_min[2], pat_max[2]; - - BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - - if (event == CLAMP_PAT_DIM) { - for (a = 0; a < 2; a++) { - /* search shouldn't be resized smaller than pattern */ - marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]); - marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]); - } - } - else if (event == CLAMP_PAT_POS) { - float dim[2]; - - sub_v2_v2v2(dim, pat_max, pat_min); - - for (a = 0; a < 2; a++) { - int b; - /* pattern shouldn't be moved outside of search */ - if (pat_min[a] < marker->search_min[a]) { - for (b = 0; b < 4; b++) - marker->pattern_corners[b][a] += marker->search_min[a] - pat_min[a]; - } - if (pat_max[a] > marker->search_max[a]) { - for (b = 0; b < 4; b++) - marker->pattern_corners[b][a] -= pat_max[a] - marker->search_max[a]; - } - } - } - else if (event == CLAMP_SEARCH_DIM) { - for (a = 0; a < 2; a++) { - /* search shouldn't be resized smaller than pattern */ - marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]); - marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]); - } - } - else if (event == CLAMP_SEARCH_POS) { - float dim[2]; - - sub_v2_v2v2(dim, marker->search_max, marker->search_min); - - for (a = 0; a < 2; a++) { - /* search shouldn't be moved inside pattern */ - if (marker->search_min[a] > pat_min[a]) { - marker->search_min[a] = pat_min[a]; - marker->search_max[a] = marker->search_min[a] + dim[a]; - } - if (marker->search_max[a] < pat_max[a]) { - marker->search_max[a] = pat_max[a]; - marker->search_min[a] = marker->search_max[a] - dim[a]; - } - } - } - else if (event == CLAMP_SEARCH_DIM) { - float dim[2]; - sub_v2_v2v2(dim, pat_max, pat_min); - for (a = 0; a < 2; a++) { - marker->search_min[a] = pat_min[a]; - marker->search_max[a] = pat_max[a]; - } + track = next_track; } } -void BKE_tracking_track_flag(MovieTrackingTrack *track, int area, int flag, int clear) +void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object) { - if (area == TRACK_AREA_NONE) - return; + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); + MovieTrackingTrack *track = tracksbase->first; - if (clear) { - if (area & TRACK_AREA_POINT) - track->flag &= ~flag; - if (area & TRACK_AREA_PAT) - track->pat_flag &= ~flag; - if (area & TRACK_AREA_SEARCH) - track->search_flag &= ~flag; - } - else { - if (area & TRACK_AREA_POINT) - track->flag |= flag; - if (area & TRACK_AREA_PAT) - track->pat_flag |= flag; - if (area & TRACK_AREA_SEARCH) - track->search_flag |= flag; + BKE_tracking_clipboard_free(); + + while (track) { + if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) { + MovieTrackingTrack *new_track = tracking_track_duplicate(track); + + BLI_addtail(&tracking_clipboard.tracks, new_track); + } + + track = track->next; } } -MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tracksbase, float x, float y, +int BKE_tracking_clipboard_has_tracks(void) +{ + return tracking_clipboard.tracks.first != NULL; +} + +void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object) +{ + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); + MovieTrackingTrack *track = tracking_clipboard.tracks.first; + + while (track) { + MovieTrackingTrack *new_track = tracking_track_duplicate(track); + + BLI_addtail(tracksbase, new_track); + BKE_tracking_track_unique_name(tracksbase, new_track); + + track = track->next; + } +} + +/*********************** Tracks *************************/ + +static void tracking_marker_insert_disabled(MovieTrackingTrack *track, MovieTrackingMarker *ref_marker, + int before, int overwrite) +{ + MovieTrackingMarker marker_new; + + marker_new = *ref_marker; + marker_new.flag &= ~MARKER_TRACKED; + marker_new.flag |= MARKER_DISABLED; + + if (before) + marker_new.framenr--; + else + marker_new.framenr++; + + if (overwrite || !BKE_tracking_track_has_marker_at_frame(track, marker_new.framenr)) + BKE_tracking_marker_insert(track, &marker_new); +} + +MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking, ListBase *tracksbase, float x, float y, int framenr, int width, int height) { MovieTrackingTrack *track; @@ -345,6 +491,7 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tr track = MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track"); strcpy(track->name, "Track"); + /* fill track's settings from default settings */ track->motion_model = settings->default_motion_model; track->minimum_correlation = settings->default_minimum_correlation; track->margin = settings->default_margin; @@ -370,194 +517,64 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tr copy_v2_v2(marker.search_max, search); negate_v2_v2(marker.search_min, search); - BKE_tracking_insert_marker(track, &marker); + BKE_tracking_marker_insert(track, &marker); BLI_addtail(tracksbase, track); - BKE_track_unique_name(tracksbase, track); + BKE_tracking_track_unique_name(tracksbase, track); return track; } -MovieTrackingMarker *BKE_tracking_insert_marker(MovieTrackingTrack *track, MovieTrackingMarker *marker) +void BKE_tracking_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track) { - MovieTrackingMarker *old_marker = NULL; - - if (track->markersnr) - old_marker = BKE_tracking_exact_marker(track, marker->framenr); - - if (old_marker) { - *old_marker = *marker; - - return old_marker; - } - else { - int a = track->markersnr; - - while (a--) { - if (track->markers[a].framenr < marker->framenr) - break; - } - - track->markersnr++; - - if (track->markers) - track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr); - else - track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers"); - - memmove(track->markers + a + 2, track->markers + a + 1, - (track->markersnr - a - 2) * sizeof(MovieTrackingMarker)); - track->markers[a + 1] = *marker; - - track->last_marker = a + 1; - - return &track->markers[a + 1]; - } + BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name)); } -void BKE_tracking_delete_marker(MovieTrackingTrack *track, int framenr) -{ - int a = 0; - - while (a < track->markersnr) { - if (track->markers[a].framenr == framenr) { - if (track->markersnr > 1) { - memmove(track->markers + a, track->markers + a + 1, - (track->markersnr - a - 1) * sizeof(MovieTrackingMarker)); - track->markersnr--; - track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr); - } - else { - MEM_freeN(track->markers); - track->markers = NULL; - track->markersnr = 0; - } - - break; - } - - a++; - } -} - -void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float min[2], float max[2]) -{ - INIT_MINMAX2(min, max); - - DO_MINMAX2(marker->pattern_corners[0], min, max); - DO_MINMAX2(marker->pattern_corners[1], min, max); - DO_MINMAX2(marker->pattern_corners[2], min, max); - DO_MINMAX2(marker->pattern_corners[3], min, max); -} - -MovieTrackingMarker *BKE_tracking_get_marker(MovieTrackingTrack *track, int framenr) -{ - int a = track->markersnr - 1; - - if (!track->markersnr) - return NULL; - - /* approximate pre-first framenr marker with first marker */ - if (framenr < track->markers[0].framenr) - return &track->markers[0]; - - if (track->last_marker < track->markersnr) - a = track->last_marker; - - if (track->markers[a].framenr <= framenr) { - while (a < track->markersnr && track->markers[a].framenr <= framenr) { - if (track->markers[a].framenr == framenr) { - track->last_marker = a; - - return &track->markers[a]; - } - a++; - } - - /* if there's no marker for exact position, use nearest marker from left side */ - return &track->markers[a - 1]; - } - else { - while (a >= 0 && track->markers[a].framenr >= framenr) { - if (track->markers[a].framenr == framenr) { - track->last_marker = a; - - return &track->markers[a]; - } - - a--; - } - - /* if there's no marker for exact position, use nearest marker from left side */ - return &track->markers[a]; - } - - return NULL; -} - -MovieTrackingMarker *BKE_tracking_ensure_marker(MovieTrackingTrack *track, int framenr) -{ - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); - - if (marker->framenr != framenr) { - MovieTrackingMarker marker_new; - - marker_new = *marker; - marker_new.framenr = framenr; - - BKE_tracking_insert_marker(track, &marker_new); - marker = BKE_tracking_get_marker(track, framenr); - } - - return marker; -} - -MovieTrackingMarker *BKE_tracking_exact_marker(MovieTrackingTrack *track, int framenr) -{ - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); - - if (marker->framenr != framenr) - return NULL; - - return marker; -} - -int BKE_tracking_has_marker(MovieTrackingTrack *track, int framenr) -{ - return BKE_tracking_exact_marker(track, framenr) != 0; -} - -int BKE_tracking_has_enabled_marker(MovieTrackingTrack *track, int framenr) -{ - MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); - - return marker && (marker->flag & MARKER_DISABLED) == 0; -} - -void BKE_tracking_free_track(MovieTrackingTrack *track) +void BKE_tracking_track_free(MovieTrackingTrack *track) { if (track->markers) MEM_freeN(track->markers); } -static void put_disabled_marker(MovieTrackingTrack *track, MovieTrackingMarker *ref_marker, int before, int overwrite) +void BKE_tracking_track_flag_set(MovieTrackingTrack *track, int area, int flag) { - MovieTrackingMarker marker_new; + if (area == TRACK_AREA_NONE) + return; - marker_new = *ref_marker; - marker_new.flag &= ~MARKER_TRACKED; - marker_new.flag |= MARKER_DISABLED; - - if (before) - marker_new.framenr--; - else - marker_new.framenr++; - - if (!BKE_tracking_has_marker(track, marker_new.framenr) || overwrite) - BKE_tracking_insert_marker(track, &marker_new); + if (area & TRACK_AREA_POINT) + track->flag |= flag; + if (area & TRACK_AREA_PAT) + track->pat_flag |= flag; + if (area & TRACK_AREA_SEARCH) + track->search_flag |= flag; } -void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int action) +void BKE_tracking_track_flag_clear(MovieTrackingTrack *track, int area, int flag) +{ + if (area == TRACK_AREA_NONE) + return; + + if (area & TRACK_AREA_POINT) + track->flag &= ~flag; + if (area & TRACK_AREA_PAT) + track->pat_flag &= ~flag; + if (area & TRACK_AREA_SEARCH) + track->search_flag &= ~flag; +} + +int BKE_tracking_track_has_marker_at_frame(MovieTrackingTrack *track, int framenr) +{ + return BKE_tracking_marker_get_exact(track, framenr) != 0; +} + +int BKE_tracking_track_has_enabled_marker_at_frame(MovieTrackingTrack *track, int framenr) +{ + MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr); + + return marker && (marker->flag & MARKER_DISABLED) == 0; +} + +void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int action) { int a; @@ -576,7 +593,7 @@ void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int actio } if (track->markersnr) - put_disabled_marker(track, &track->markers[track->markersnr - 1], 0, 1); + tracking_marker_insert_disabled(track, &track->markers[track->markersnr - 1], FALSE, TRUE); } else if (action == TRACK_CLEAR_UPTO) { a = track->markersnr - 1; @@ -595,26 +612,26 @@ void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int actio } if (track->markersnr) - put_disabled_marker(track, &track->markers[0], 1, 1); + tracking_marker_insert_disabled(track, &track->markers[0], TRUE, TRUE); } else if (action == TRACK_CLEAR_ALL) { MovieTrackingMarker *marker, marker_new; - marker = BKE_tracking_get_marker(track, ref_frame); + marker = BKE_tracking_marker_get(track, ref_frame); marker_new = *marker; MEM_freeN(track->markers); track->markers = NULL; track->markersnr = 0; - BKE_tracking_insert_marker(track, &marker_new); + BKE_tracking_marker_insert(track, &marker_new); - put_disabled_marker(track, &marker_new, 1, 1); - put_disabled_marker(track, &marker_new, 0, 1); + tracking_marker_insert_disabled(track, &marker_new, TRUE, TRUE); + tracking_marker_insert_disabled(track, &marker_new, FALSE, TRUE); } } -void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) +void BKE_tracking_tracks_join(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) { int i = 0, a = 0, b = 0, tot; MovieTrackingMarker *markers; @@ -694,9 +711,13 @@ void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack /* this values will be incremented at the end of the loop cycle */ a--; b--; i--; } - else markers[i] = src_track->markers[a]; + else { + markers[i] = src_track->markers[a]; + } + } + else { + markers[i] = dst_track->markers[b]; } - else markers[i] = dst_track->markers[b]; a++; b++; @@ -715,662 +736,66 @@ void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack MEM_freeN(markers); } -static void tracking_tracks_free(ListBase *tracks) +MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking, MovieTrackingObject *object, const char *name) { - MovieTrackingTrack *track; - - for (track = tracks->first; track; track = track->next) { - BKE_tracking_free_track(track); - } - - BLI_freelistN(tracks); -} - -static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction) -{ - if (reconstruction->cameras) - MEM_freeN(reconstruction->cameras); -} - -static void tracking_object_free(MovieTrackingObject *object) -{ - tracking_tracks_free(&object->tracks); - tracking_reconstruction_free(&object->reconstruction); -} - -static void tracking_objects_free(ListBase *objects) -{ - MovieTrackingObject *object; - - for (object = objects->first; object; object = object->next) - tracking_object_free(object); - - BLI_freelistN(objects); -} - -static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet) -{ - MovieTrackingDopesheetChannel *channel; - - channel = dopesheet->channels.first; - while (channel) { - if (channel->segments) { - MEM_freeN(channel->segments); - } - - channel = channel->next; - } - - BLI_freelistN(&dopesheet->channels); - - dopesheet->channels.first = dopesheet->channels.last = NULL; - dopesheet->tot_channel = 0; -} - -void BKE_tracking_free(MovieTracking *tracking) -{ - tracking_tracks_free(&tracking->tracks); - tracking_reconstruction_free(&tracking->reconstruction); - tracking_objects_free(&tracking->objects); - - if (tracking->stabilization.scaleibuf) - IMB_freeImBuf(tracking->stabilization.scaleibuf); - - if (tracking->camera.intrinsics) - BKE_tracking_distortion_destroy(tracking->camera.intrinsics); - - tracking_dopesheet_free(&tracking->dopesheet); -} - -static MovieTrackingTrack *duplicate_track(MovieTrackingTrack *track) -{ - MovieTrackingTrack *new_track; - - new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track"); - - *new_track = *track; - new_track->next = new_track->prev = NULL; - - new_track->markers = MEM_dupallocN(new_track->markers); - - return new_track; -} - -/*********************** clipboard *************************/ - -void BKE_tracking_free_clipboard(void) -{ - MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track; - - while (track) { - next_track = track->next; - - BKE_tracking_free_track(track); - MEM_freeN(track); - - track = next_track; - } -} - -void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object) -{ - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); MovieTrackingTrack *track = tracksbase->first; - BKE_tracking_free_clipboard(); - while (track) { - if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingTrack *new_track = duplicate_track(track); - - BLI_addtail(&tracking_clipboard.tracks, new_track); - } - - track = track->next; - } -} - -int BKE_tracking_clipboard_has_tracks(void) -{ - return tracking_clipboard.tracks.first != NULL; -} - -void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object) -{ - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); - MovieTrackingTrack *track = tracking_clipboard.tracks.first; - - while (track) { - MovieTrackingTrack *new_track = duplicate_track(track); - - BLI_addtail(tracksbase, new_track); - BKE_track_unique_name(tracksbase, new_track); - - track = track->next; - } -} - -/*********************** tracks map *************************/ - -typedef struct TracksMap { - char object_name[MAX_NAME]; - int is_camera; - - int num_tracks; - int customdata_size; - - char *customdata; - MovieTrackingTrack *tracks; - - GHash *hash; - - int ptr; -} TracksMap; - -static TracksMap *tracks_map_new(const char *object_name, int is_camera, int num_tracks, int customdata_size) -{ - TracksMap *map = MEM_callocN(sizeof(TracksMap), "TrackingsMap"); - - BLI_strncpy(map->object_name, object_name, sizeof(map->object_name)); - map->is_camera = is_camera; - - map->num_tracks = num_tracks; - map->customdata_size = customdata_size; - - map->tracks = MEM_callocN(sizeof(MovieTrackingTrack) * num_tracks, "TrackingsMap tracks"); - - if (customdata_size) - map->customdata = MEM_callocN(customdata_size * num_tracks, "TracksMap customdata"); - - map->hash = BLI_ghash_ptr_new("TracksMap hash"); - - return map; -} - -static int tracks_map_size(TracksMap *map) -{ - return map->num_tracks; -} - -static void tracks_map_get(TracksMap *map, int index, MovieTrackingTrack **track, void **customdata) -{ - *track = &map->tracks[index]; - - if (map->customdata) - *customdata = &map->customdata[index * map->customdata_size]; -} - -static void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *customdata) -{ - MovieTrackingTrack new_track = *track; - - new_track.markers = MEM_dupallocN(new_track.markers); - - map->tracks[map->ptr] = new_track; - - if (customdata) - memcpy(&map->customdata[map->ptr * map->customdata_size], customdata, map->customdata_size); - - BLI_ghash_insert(map->hash, &map->tracks[map->ptr], track); - - map->ptr++; -} - -static void tracks_map_merge(TracksMap *map, MovieTracking *tracking) -{ - MovieTrackingTrack *track; - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); - MovieTrackingTrack *rot_track = tracking->stabilization.rot_track; - ListBase tracks = {NULL, NULL}, new_tracks = {NULL, NULL}; - ListBase *old_tracks; - int a; - - if (map->is_camera) { - old_tracks = &tracking->tracks; - } - else { - MovieTrackingObject *object = BKE_tracking_named_object(tracking, map->object_name); - - if (!object) { - /* object was deleted by user, create new one */ - object = BKE_tracking_new_object(tracking, map->object_name); - } - - old_tracks = &object->tracks; - } - - /* duplicate currently operating tracks to temporary list. - * this is needed to keep names in unique state and it's faster to change names - * of currently operating tracks (if needed) - */ - for (a = 0; a < map->num_tracks; a++) { - int replace_sel = 0, replace_rot = 0; - MovieTrackingTrack *new_track, *old; - - track = &map->tracks[a]; - - /* find original of operating track in list of previously displayed tracks */ - old = BLI_ghash_lookup(map->hash, track); - if (old) { - MovieTrackingTrack *cur = old_tracks->first; - - while (cur) { - if (cur == old) - break; - - cur = cur->next; - } - - /* original track was found, re-use flags and remove this track */ - if (cur) { - if (cur == act_track) - replace_sel = 1; - if (cur == rot_track) - replace_rot = 1; - - track->flag = cur->flag; - track->pat_flag = cur->pat_flag; - track->search_flag = cur->search_flag; - - BKE_tracking_free_track(cur); - BLI_freelinkN(old_tracks, cur); - } - } - - new_track = duplicate_track(track); - - BLI_ghash_remove(map->hash, track, NULL, NULL); /* XXX: are we actually need this */ - BLI_ghash_insert(map->hash, track, new_track); - - if (replace_sel) /* update current selection in clip */ - tracking->act_track = new_track; - - if (replace_rot) /* update track used for rotation stabilization */ - tracking->stabilization.rot_track = new_track; - - BLI_addtail(&tracks, new_track); - } - - /* move all tracks, which aren't operating */ - track = old_tracks->first; - while (track) { - MovieTrackingTrack *next = track->next; - - track->next = track->prev = NULL; - BLI_addtail(&new_tracks, track); - - track = next; - } - - /* now move all tracks which are currently operating and keep their names unique */ - track = tracks.first; - while (track) { - MovieTrackingTrack *next = track->next; - - BLI_remlink(&tracks, track); - - track->next = track->prev = NULL; - BLI_addtail(&new_tracks, track); - - BLI_uniquename(&new_tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name)); - - track = next; - } - - *old_tracks = new_tracks; -} - -static void tracks_map_free(TracksMap *map, void (*customdata_free)(void *customdata)) -{ - int i = 0; - - BLI_ghash_free(map->hash, NULL, NULL); - - for (i = 0; i < map->num_tracks; i++) { - if (map->customdata && customdata_free) - customdata_free(&map->customdata[i * map->customdata_size]); - - BKE_tracking_free_track(&map->tracks[i]); - } - - if (map->customdata) - MEM_freeN(map->customdata); - - MEM_freeN(map->tracks); - MEM_freeN(map); -} - -/*********************** tracking *************************/ - -typedef struct TrackContext { -#ifdef WITH_LIBMV - /* the reference marker and cutout search area */ - MovieTrackingMarker marker; - - /* keyframed patch. This is the search area */ - float *search_area; - int search_area_height; - int search_area_width; - int framenr; - - float *mask; -#else - int pad; -#endif -} TrackContext; - -typedef struct MovieTrackingContext { - MovieClipUser user; - MovieClip *clip; - int clip_flag; - - int first_time, frames; - - MovieTrackingSettings settings; - TracksMap *tracks_map; - - short backwards, sequence; - int sync_frame; -} MovieTrackingContext; - -MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short sequence) -{ - MovieTrackingContext *context = MEM_callocN(sizeof(MovieTrackingContext), "trackingContext"); - MovieTracking *tracking = &clip->tracking; - MovieTrackingSettings *settings = &tracking->settings; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); - MovieTrackingTrack *track; - MovieTrackingObject *object = BKE_tracking_active_object(tracking); - int num_tracks = 0; - - context->settings = *settings; - context->backwards = backwards; - context->sync_frame = user->framenr; - context->first_time = TRUE; - context->sequence = sequence; - - /* count */ - track = tracksbase->first; - while (track) { - if (TRACK_SELECTED(track) && (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0) { - int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); - - if ((marker->flag & MARKER_DISABLED) == 0) - num_tracks++; - } + if (!strcmp(track->name, name)) + return track; track = track->next; } - if (num_tracks) { - int width, height; + return NULL; +} - context->tracks_map = tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA, - num_tracks, sizeof(TrackContext)); +MovieTrackingTrack *BKE_tracking_track_get_indexed(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r) +{ + MovieTrackingObject *object; + int cur = 1; - BKE_movieclip_get_size(clip, user, &width, &height); + object = tracking->objects.first; + while (object) { + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); + MovieTrackingTrack *track = tracksbase->first; - /* create tracking data */ - track = tracksbase->first; while (track) { - if (TRACK_SELECTED(track) && (track->flag & (TRACK_HIDDEN | TRACK_LOCKED)) == 0) { - int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); - - if ((marker->flag & MARKER_DISABLED) == 0) { - TrackContext track_context; - memset(&track_context, 0, sizeof(TrackContext)); - tracks_map_insert(context->tracks_map, track, &track_context); + if (track->flag & TRACK_HAS_BUNDLE) { + if (cur == tracknr) { + *tracksbase_r = tracksbase; + return track; } + + cur++; } track = track->next; } + + object = object->next; } - context->clip = clip; + *tracksbase_r = NULL; - /* store needed clip flags passing to get_buffer functions - * - MCLIP_USE_PROXY is needed to because timecode affects on movie clip - * only in case Proxy/Timecode flag is set, so store this flag to use - * timecodes properly but reset render size to SIZE_FULL so correct resolution - * would be used for images - * - MCLIP_USE_PROXY_CUSTOM_DIR is needed because proxy/timecode files might - * be stored in a different location - * ignore all the rest possible flags for now - */ - context->clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS; - - context->user = *user; - context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; - context->user.render_flag = 0; - - if (!sequence) - BLI_begin_threaded_malloc(); - - return context; + return NULL; } -static void track_context_free(void *customdata) +MovieTrackingTrack *BKE_tracking_track_get_active(MovieTracking *tracking) { - TrackContext *track_context = (TrackContext *)customdata; + ListBase *tracksbase; -#if WITH_LIBMV - if (track_context->search_area) - MEM_freeN(track_context->search_area); + if (!tracking->act_track) + return NULL; - if (track_context->mask) - MEM_freeN(track_context->mask); + tracksbase = BKE_tracking_get_active_tracks(tracking); -#else - (void)track_context; -#endif -} + /* check that active track is in current tracks list */ + if (BLI_findindex(tracksbase, tracking->act_track) >= 0) + return tracking->act_track; -void BKE_tracking_context_free(MovieTrackingContext *context) -{ - if (!context->sequence) - BLI_end_threaded_malloc(); - - tracks_map_free(context->tracks_map, track_context_free); - - MEM_freeN(context); -} - -/* zap channels from the imbuf that are disabled by the user. this can lead to - * better tracks sometimes. however, instead of simply zeroing the channels - * out, do a partial grayscale conversion so the display is better. - */ -void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disable_green, int disable_blue, - int grayscale) -{ - int x, y; - float scale; - - if (!disable_red && !disable_green && !disable_blue && !grayscale) - return; - - /* If only some components are selected, it's important to rescale the result - * appropriately so that e.g. if only blue is selected, it's not zeroed out. - */ - scale = (disable_red ? 0.0f : 0.2126f) + - (disable_green ? 0.0f : 0.7152f) + - (disable_blue ? 0.0f : 0.0722f); - - for (y = 0; y < ibuf->y; y++) { - for (x = 0; x < ibuf->x; x++) { - int pixel = ibuf->x * y + x; - - if (ibuf->rect_float) { - float *rrgbf = ibuf->rect_float + pixel * 4; - float r = disable_red ? 0.0f : rrgbf[0]; - float g = disable_green ? 0.0f : rrgbf[1]; - float b = disable_blue ? 0.0f : rrgbf[2]; - - if (grayscale) { - float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale; - - rrgbf[0] = rrgbf[1] = rrgbf[2] = gray; - } - else { - rrgbf[0] = r; - rrgbf[1] = g; - rrgbf[2] = b; - } - } - else { - char *rrgb = (char *)ibuf->rect + pixel * 4; - char r = disable_red ? 0 : rrgb[0]; - char g = disable_green ? 0 : rrgb[1]; - char b = disable_blue ? 0 : rrgb[2]; - - if (grayscale) { - float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale; - - rrgb[0] = rrgb[1] = rrgb[2] = gray; - } - else { - rrgb[0] = r; - rrgb[1] = g; - rrgb[2] = b; - } - } - } - } - - if (ibuf->rect_float) - ibuf->userflags |= IB_RECT_INVALID; -} - -static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale) -{ - BKE_tracking_disable_imbuf_channels(ibuf, track->flag & TRACK_DISABLE_RED, - track->flag & TRACK_DISABLE_GREEN, track->flag & TRACK_DISABLE_BLUE, grayscale); -} - -ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, ImBuf *search_ibuf, - MovieTrackingTrack *track, MovieTrackingMarker *marker, - int use_mask, int num_samples_x, int num_samples_y, - float pos[2]) -{ -#ifdef WITH_LIBMV - ImBuf *pattern_ibuf; - double src_pixel_x[5], src_pixel_y[5]; - double warped_position_x, warped_position_y; - float *mask = NULL; - - pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); - pattern_ibuf->profile = IB_PROFILE_LINEAR_RGB; - - if (!search_ibuf->rect_float) { - IMB_float_from_rect(search_ibuf); - } - - get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y); - - if (use_mask) { - mask = BKE_tracking_track_mask_get(frame_width, frame_height, track, marker); - } - - libmv_samplePlanarPatch(search_ibuf->rect_float, search_ibuf->x, search_ibuf->y, 4, - src_pixel_x, src_pixel_y, num_samples_x, - num_samples_y, mask, pattern_ibuf->rect_float, - &warped_position_x, &warped_position_y); - - if (pos) { - pos[0] = warped_position_x; - pos[1] = warped_position_y; - } - - if (mask) { - MEM_freeN(mask); - } - - return pattern_ibuf; -#else - ImBuf *pattern_ibuf; - - /* real sampling requires libmv, but areas are supposing pattern would be - * sampled if search area does exists, so we'll need to create empty - * pattern area here to prevent adding NULL-checks all over just to deal - * with situation when lubmv is disabled - */ - - (void) frame_width; - (void) frame_height; - (void) search_ibuf; - (void) marker; - (void) track; - (void) use_mask; - - pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); - - pos[0] = num_samples_x / 2.0f; - pos[1] = num_samples_y / 2.0f; - - return pattern_ibuf; -#endif -} - -ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int anchored, int disable_channels) -{ - ImBuf *pattern_ibuf, *search_ibuf; - float pat_min[2], pat_max[2]; - int num_samples_x, num_samples_y; - - BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - - num_samples_x = (pat_max[0] - pat_min[0]) * ibuf->x; - num_samples_y = (pat_max[1] - pat_min[1]) * ibuf->y; - - search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels); - - pattern_ibuf = BKE_tracking_sample_pattern_imbuf(ibuf->x, ibuf->y, search_ibuf, track, marker, - FALSE, num_samples_x, num_samples_y, NULL); - - IMB_freeImBuf(search_ibuf); - - return pattern_ibuf; -} - -ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int anchored, int disable_channels) -{ - ImBuf *searchibuf; - int x, y, w, h; - float search_origin[2]; - - get_search_origin_frame_pixel(ibuf->x, ibuf->y, marker, search_origin); - - x = search_origin[0]; - y = search_origin[1]; - - if (anchored) { - x += track->offset[0] * ibuf->x; - y += track->offset[1] * ibuf->y; - } - - w = (marker->search_max[0] - marker->search_min[0]) * ibuf->x; - h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y; - - searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); - searchibuf->profile = ibuf->profile; - - IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h); - - if (disable_channels) { - if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || - (track->flag & TRACK_DISABLE_RED) || - (track->flag & TRACK_DISABLE_GREEN) || - (track->flag & TRACK_DISABLE_BLUE)) - { - disable_imbuf_channels(searchibuf, track, TRUE); - } - } - - return searchibuf; + return NULL; } static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track) @@ -1440,7 +865,7 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height } } -float *BKE_tracking_track_mask_get(int frame_width, int frame_height, +float *BKE_tracking_track_get_mask(int frame_width, int frame_height, MovieTrackingTrack *track, MovieTrackingMarker *marker) { float *mask = NULL; @@ -1460,9 +885,1246 @@ float *BKE_tracking_track_mask_get(int frame_width, int frame_height, return mask; } -#ifdef WITH_LIBMV +/* area - which part of marker should be selected. see TRACK_AREA_* constants */ +void BKE_tracking_track_select(ListBase *tracksbase, MovieTrackingTrack *track, int area, int extend) +{ + if (extend) { + BKE_tracking_track_flag_set(track, area, SELECT); + } + else { + MovieTrackingTrack *cur = tracksbase->first; -/* Convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */ + while (cur) { + if ((cur->flag & TRACK_HIDDEN) == 0) { + if (cur == track) { + BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT); + BKE_tracking_track_flag_set(cur, area, SELECT); + } + else { + BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT); + } + } + + cur = cur->next; + } + } +} + +void BKE_tracking_track_deselect(MovieTrackingTrack *track, int area) +{ + BKE_tracking_track_flag_clear(track, area, SELECT); +} + +/*********************** Marker *************************/ + +MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track, MovieTrackingMarker *marker) +{ + MovieTrackingMarker *old_marker = NULL; + + if (track->markersnr) + old_marker = BKE_tracking_marker_get_exact(track, marker->framenr); + + if (old_marker) { + /* simply replace settings for already allocated marker */ + *old_marker = *marker; + + return old_marker; + } + else { + int a = track->markersnr; + + /* find position in array where to add new marker */ + while (a--) { + if (track->markers[a].framenr < marker->framenr) + break; + } + + track->markersnr++; + + if (track->markers) + track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr); + else + track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers"); + + /* shift array to "free" space for new marker */ + memmove(track->markers + a + 2, track->markers + a + 1, + (track->markersnr - a - 2) * sizeof(MovieTrackingMarker)); + + /* put new marker */ + track->markers[a + 1] = *marker; + + track->last_marker = a + 1; + + return &track->markers[a + 1]; + } +} + +void BKE_tracking_marker_delete(MovieTrackingTrack *track, int framenr) +{ + int a = 0; + + while (a < track->markersnr) { + if (track->markers[a].framenr == framenr) { + if (track->markersnr > 1) { + memmove(track->markers + a, track->markers + a + 1, + (track->markersnr - a - 1) * sizeof(MovieTrackingMarker)); + track->markersnr--; + track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr); + } + else { + MEM_freeN(track->markers); + track->markers = NULL; + track->markersnr = 0; + } + + break; + } + + a++; + } +} + +void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event) +{ + int a; + float pat_min[2], pat_max[2]; + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + if (event == CLAMP_PAT_DIM) { + for (a = 0; a < 2; a++) { + /* search shouldn't be resized smaller than pattern */ + marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]); + marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]); + } + } + else if (event == CLAMP_PAT_POS) { + float dim[2]; + + sub_v2_v2v2(dim, pat_max, pat_min); + + for (a = 0; a < 2; a++) { + int b; + /* pattern shouldn't be moved outside of search */ + if (pat_min[a] < marker->search_min[a]) { + for (b = 0; b < 4; b++) + marker->pattern_corners[b][a] += marker->search_min[a] - pat_min[a]; + } + if (pat_max[a] > marker->search_max[a]) { + for (b = 0; b < 4; b++) + marker->pattern_corners[b][a] -= pat_max[a] - marker->search_max[a]; + } + } + } + else if (event == CLAMP_SEARCH_DIM) { + for (a = 0; a < 2; a++) { + /* search shouldn't be resized smaller than pattern */ + marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]); + marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]); + } + } + else if (event == CLAMP_SEARCH_POS) { + float dim[2]; + + sub_v2_v2v2(dim, marker->search_max, marker->search_min); + + for (a = 0; a < 2; a++) { + /* search shouldn't be moved inside pattern */ + if (marker->search_min[a] > pat_min[a]) { + marker->search_min[a] = pat_min[a]; + marker->search_max[a] = marker->search_min[a] + dim[a]; + } + if (marker->search_max[a] < pat_max[a]) { + marker->search_max[a] = pat_max[a]; + marker->search_min[a] = marker->search_max[a] - dim[a]; + } + } + } + else if (event == CLAMP_SEARCH_DIM) { + float dim[2]; + sub_v2_v2v2(dim, pat_max, pat_min); + for (a = 0; a < 2; a++) { + marker->search_min[a] = pat_min[a]; + marker->search_max[a] = pat_max[a]; + } + } +} + +MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr) +{ + int a = track->markersnr - 1; + + if (!track->markersnr) + return NULL; + + /* approximate pre-first framenr marker with first marker */ + if (framenr < track->markers[0].framenr) + return &track->markers[0]; + + if (track->last_marker < track->markersnr) + a = track->last_marker; + + if (track->markers[a].framenr <= framenr) { + while (a < track->markersnr && track->markers[a].framenr <= framenr) { + if (track->markers[a].framenr == framenr) { + track->last_marker = a; + + return &track->markers[a]; + } + a++; + } + + /* if there's no marker for exact position, use nearest marker from left side */ + return &track->markers[a - 1]; + } + else { + while (a >= 0 && track->markers[a].framenr >= framenr) { + if (track->markers[a].framenr == framenr) { + track->last_marker = a; + + return &track->markers[a]; + } + + a--; + } + + /* if there's no marker for exact position, use nearest marker from left side */ + return &track->markers[a]; + } + + return NULL; +} + +MovieTrackingMarker *BKE_tracking_marker_get_exact(MovieTrackingTrack *track, int framenr) +{ + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); + + if (marker->framenr != framenr) + return NULL; + + return marker; +} + +MovieTrackingMarker *BKE_tracking_marker_ensure(MovieTrackingTrack *track, int framenr) +{ + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); + + if (marker->framenr != framenr) { + MovieTrackingMarker marker_new; + + marker_new = *marker; + marker_new.framenr = framenr; + + BKE_tracking_marker_insert(track, &marker_new); + marker = BKE_tracking_marker_get(track, framenr); + } + + return marker; +} + +void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float min[2], float max[2]) +{ + INIT_MINMAX2(min, max); + + DO_MINMAX2(marker->pattern_corners[0], min, max); + DO_MINMAX2(marker->pattern_corners[1], min, max); + DO_MINMAX2(marker->pattern_corners[2], min, max); + DO_MINMAX2(marker->pattern_corners[3], min, max); +} + +/*********************** Object *************************/ + +MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char *name) +{ + MovieTrackingObject *object = MEM_callocN(sizeof(MovieTrackingObject), "tracking object"); + + if (tracking->tot_object == 0) { + /* first object is always camera */ + BLI_strncpy(object->name, "Camera", sizeof(object->name)); + + object->flag |= TRACKING_OBJECT_CAMERA; + } + else { + BLI_strncpy(object->name, name, sizeof(object->name)); + } + + BLI_addtail(&tracking->objects, object); + + tracking->tot_object++; + tracking->objectnr = BLI_countlist(&tracking->objects) - 1; + + object->scale = 1.0f; + + BKE_tracking_object_unique_name(tracking, object); + + return object; +} + +void BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *object) +{ + MovieTrackingTrack *track; + int index = BLI_findindex(&tracking->objects, object); + + if (index < 0) + return; + + if (object->flag & TRACKING_OBJECT_CAMERA) { + /* object used for camera solving can't be deleted */ + return; + } + + track = object->tracks.first; + while (track) { + if (track == tracking->act_track) + tracking->act_track = NULL; + + track = track->next; + } + + tracking_object_free(object); + BLI_freelinkN(&tracking->objects, object); + + tracking->tot_object--; + + if (index > 0) + tracking->objectnr = index - 1; + else + tracking->objectnr = 0; +} + +void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object) +{ + BLI_uniquename(&tracking->objects, object, "Object", '.', + offsetof(MovieTrackingObject, name), sizeof(object->name)); +} + +MovieTrackingObject *BKE_tracking_object_get_named(MovieTracking *tracking, const char *name) +{ + MovieTrackingObject *object = tracking->objects.first; + + while (object) { + if (!strcmp(object->name, name)) + return object; + + object = object->next; + } + + return NULL; +} + +MovieTrackingObject *BKE_tracking_object_get_active(MovieTracking *tracking) +{ + return BLI_findlink(&tracking->objects, tracking->objectnr); +} + +MovieTrackingObject *BKE_tracking_object_get_camera(MovieTracking *tracking) +{ + MovieTrackingObject *object = tracking->objects.first; + + while (object) { + if (object->flag & TRACKING_OBJECT_CAMERA) + return object; + + object = object->next; + } + + return NULL; +} + +ListBase *BKE_tracking_object_get_tracks(MovieTracking *tracking, MovieTrackingObject *object) +{ + if (object->flag & TRACKING_OBJECT_CAMERA) { + return &tracking->tracks; + } + + return &object->tracks; +} + +MovieTrackingReconstruction *BKE_tracking_object_get_reconstruction(MovieTracking *tracking, + MovieTrackingObject *object) +{ + if (object->flag & TRACKING_OBJECT_CAMERA) { + return &tracking->reconstruction; + } + + return &object->reconstruction; +} + +/*********************** Camera *************************/ + +static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstruction, int framenr, int nearest) +{ + MovieReconstructedCamera *cameras = reconstruction->cameras; + int a = 0, d = 1; + + if (!reconstruction->camnr) + return -1; + + if (framenr < cameras[0].framenr) { + if (nearest) + return 0; + else + return -1; + } + + if (framenr > cameras[reconstruction->camnr - 1].framenr) { + if (nearest) + return reconstruction->camnr - 1; + else + return -1; + } + + if (reconstruction->last_camera < reconstruction->camnr) + a = reconstruction->last_camera; + + if (cameras[a].framenr >= framenr) + d = -1; + + while (a >= 0 && a < reconstruction->camnr) { + int cfra = cameras[a].framenr; + + /* check if needed framenr was "skipped" -- no data for requested frame */ + + if (d > 0 && cfra > framenr) { + /* interpolate with previous position */ + if (nearest) + return a - 1; + else + break; + } + + if (d < 0 && cfra < framenr) { + /* interpolate with next position */ + if (nearest) + return a; + else + break; + } + + if (cfra == framenr) { + reconstruction->last_camera = a; + + return a; + } + + a += d; + } + + return -1; +} + +static void reconstructed_camera_scale_set(MovieTrackingObject *object, float mat[4][4]) +{ + if ((object->flag & TRACKING_OBJECT_CAMERA) == 0) { + float smat[4][4]; + + scale_m4_fl(smat, 1.0f / object->scale); + mult_m4_m4m4(mat, mat, smat); + } +} + + +/* converts principal offset from center to offset of blender's camera */ +void BKE_tracking_camera_shift_get(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty) +{ + /* indeed in both of cases it should be winx -- it's just how camera shift works for blender's camera */ + *shiftx = (0.5f * winx - tracking->camera.principal[0]) / winx; + *shifty = (0.5f * winy - tracking->camera.principal[1]) / winx; +} + +void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height) +{ + float focal = tracking->camera.focal; + + camera->sensor_x = tracking->camera.sensor_width; + camera->sensor_fit = CAMERA_SENSOR_FIT_AUTO; + camera->lens = focal * camera->sensor_x / width; + + scene->r.xsch = width * tracking->camera.pixel_aspect; + scene->r.ysch = height; + + scene->r.xasp = 1.0f; + scene->r.yasp = 1.0f; + + BKE_tracking_camera_shift_get(tracking, width, height, &camera->shiftx, &camera->shifty); +} + +MovieReconstructedCamera *BKE_tracking_camera_get_reconstructed(MovieTracking *tracking, + MovieTrackingObject *object, int framenr) +{ + MovieTrackingReconstruction *reconstruction; + int a; + + reconstruction = BKE_tracking_object_get_reconstruction(tracking, object); + a = reconstructed_camera_index_get(reconstruction, framenr, FALSE); + + if (a == -1) + return NULL; + + return &reconstruction->cameras[a]; +} + +void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking, MovieTrackingObject *object, + int framenr, float mat[4][4]) +{ + MovieTrackingReconstruction *reconstruction; + MovieReconstructedCamera *cameras; + int a; + + reconstruction = BKE_tracking_object_get_reconstruction(tracking, object); + cameras = reconstruction->cameras; + a = reconstructed_camera_index_get(reconstruction, framenr, 1); + + if (a == -1) { + unit_m4(mat); + + return; + } + + if (cameras[a].framenr != framenr && a > 0 && a < reconstruction->camnr - 1) { + float t = ((float)framenr - cameras[a].framenr) / (cameras[a + 1].framenr - cameras[a].framenr); + + blend_m4_m4m4(mat, cameras[a].mat, cameras[a + 1].mat, t); + } + else { + copy_m4_m4(mat, cameras[a].mat); + } + + reconstructed_camera_scale_set(object, mat); +} + +/*********************** Distortion/Undistortion *************************/ + +MovieDistortion *BKE_tracking_distortion_new(void) +{ + MovieDistortion *distortion; + + distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create"); + + return distortion; +} + +void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, + int calibration_width, int calibration_height) +{ + MovieTrackingCamera *camera = &tracking->camera; + float aspy = 1.0f / tracking->camera.pixel_aspect; + +#ifdef WITH_LIBMV + if (!distortion->intrinsics) { + distortion->intrinsics = libmv_CameraIntrinsicsNew(camera->focal, + camera->principal[0], camera->principal[1] * aspy, + camera->k1, camera->k2, camera->k3, + calibration_width, calibration_height * aspy); + } + else { + libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal, + camera->principal[0], camera->principal[1] * aspy, + camera->k1, camera->k2, camera->k3, + calibration_width, calibration_height * aspy); + } +#else + (void) distortion; + (void) width; + (void) height; + (void) camera; + (void) aspy; +#endif +} + +MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion) +{ + MovieDistortion *new_distortion; + + new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create"); + +#ifdef WITH_LIBMV + new_distortion->intrinsics = libmv_CameraIntrinsicsCopy(distortion->intrinsics); +#else + (void) distortion; +#endif + + return new_distortion; +} + +ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking, ImBuf *ibuf, + int calibration_width, int calibration_height, float overscan, int undistort) +{ + ImBuf *resibuf; + + BKE_tracking_distortion_update(distortion, tracking, calibration_width, calibration_height); + + resibuf = IMB_dupImBuf(ibuf); + +#ifdef WITH_LIBMV + if (ibuf->rect_float) { + if (undistort) { + libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics, + ibuf->rect_float, resibuf->rect_float, + ibuf->x, ibuf->y, overscan, ibuf->channels); + } + else { + libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics, + ibuf->rect_float, resibuf->rect_float, + ibuf->x, ibuf->y, overscan, ibuf->channels); + } + + resibuf->userflags |= IB_RECT_INVALID; + } + else { + if (undistort) { + libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics, + (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect, + ibuf->x, ibuf->y, overscan, ibuf->channels); + } + else { + libmv_CameraIntrinsicsDistortByte(distortion->intrinsics, + (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect, + ibuf->x, ibuf->y, overscan, ibuf->channels); + } + } +#else + (void) overscan; + (void) undistort; + + if (ibuf->rect_float) { + resibuf->userflags |= IB_RECT_INVALID; + } +#endif + + return resibuf; +} + +void BKE_tracking_distortion_free(MovieDistortion *distortion) +{ +#ifdef WITH_LIBMV + libmv_CameraIntrinsicsDestroy(distortion->intrinsics); +#endif + + MEM_freeN(distortion); +} + +void BKE_tracking_distort_v2(MovieTracking *tracking, float co[2], float nco[2]) +{ + MovieTrackingCamera *camera = &tracking->camera; + +#ifdef WITH_LIBMV + double x, y; + float aspy = 1.0f / tracking->camera.pixel_aspect; + + /* normalize coords */ + x = (co[0] - camera->principal[0]) / camera->focal; + y = (co[1] - camera->principal[1] * aspy) / camera->focal; + + libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy, + camera->k1, camera->k2, camera->k3, x, y, &x, &y); + + /* result is in image coords already */ + nco[0] = x; + nco[1] = y; +#else + (void) camera; + (void) co; + (void) nco; +#endif +} + +void BKE_tracking_undistort_v2(MovieTracking *tracking, float co[2], float nco[2]) +{ + MovieTrackingCamera *camera = &tracking->camera; + +#ifdef WITH_LIBMV + double x = co[0], y = co[1]; + float aspy = 1.0f / tracking->camera.pixel_aspect; + + libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy, + camera->k1, camera->k2, camera->k3, x, y, &x, &y); + + nco[0] = x * camera->focal + camera->principal[0]; + nco[1] = y * camera->focal + camera->principal[1] * aspy; +#else + (void) camera; + (void) co; + (void) nco; +#endif +} + +ImBuf *BKE_tracking_undistort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width, + int calibration_height, float overscan) +{ + MovieTrackingCamera *camera = &tracking->camera; + + if (camera->intrinsics == NULL) + camera->intrinsics = BKE_tracking_distortion_new(); + + return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width, + calibration_height, overscan, TRUE); +} + +ImBuf *BKE_tracking_distort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width, + int calibration_height, float overscan) +{ + MovieTrackingCamera *camera = &tracking->camera; + + if (camera->intrinsics == NULL) + camera->intrinsics = BKE_tracking_distortion_new(); + + return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width, + calibration_height, overscan, FALSE); +} + +/*********************** Image sampling *************************/ + +static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale) +{ + BKE_tracking_disable_channels(ibuf, track->flag & TRACK_DISABLE_RED, + track->flag & TRACK_DISABLE_GREEN, + track->flag & TRACK_DISABLE_BLUE, grayscale); +} + +ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *search_ibuf, + MovieTrackingTrack *track, MovieTrackingMarker *marker, + int use_mask, int num_samples_x, int num_samples_y, + float pos[2]) +{ +#ifdef WITH_LIBMV + ImBuf *pattern_ibuf; + double src_pixel_x[5], src_pixel_y[5]; + double warped_position_x, warped_position_y; + float *mask = NULL; + + pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); + pattern_ibuf->profile = IB_PROFILE_LINEAR_RGB; + + if (!search_ibuf->rect_float) { + IMB_float_from_rect(search_ibuf); + } + + get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y); + + if (use_mask) { + mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker); + } + + libmv_samplePlanarPatch(search_ibuf->rect_float, search_ibuf->x, search_ibuf->y, 4, + src_pixel_x, src_pixel_y, num_samples_x, + num_samples_y, mask, pattern_ibuf->rect_float, + &warped_position_x, &warped_position_y); + + if (pos) { + pos[0] = warped_position_x; + pos[1] = warped_position_y; + } + + if (mask) { + MEM_freeN(mask); + } + + return pattern_ibuf; +#else + ImBuf *pattern_ibuf; + + /* real sampling requires libmv, but areas are supposing pattern would be + * sampled if search area does exists, so we'll need to create empty + * pattern area here to prevent adding NULL-checks all over just to deal + * with situation when lubmv is disabled + */ + + (void) frame_width; + (void) frame_height; + (void) search_ibuf; + (void) marker; + (void) track; + (void) use_mask; + + pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); + + pos[0] = num_samples_x / 2.0f; + pos[1] = num_samples_y / 2.0f; + + return pattern_ibuf; +#endif +} + +ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int anchored, int disable_channels) +{ + ImBuf *pattern_ibuf, *search_ibuf; + float pat_min[2], pat_max[2]; + int num_samples_x, num_samples_y; + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + num_samples_x = (pat_max[0] - pat_min[0]) * ibuf->x; + num_samples_y = (pat_max[1] - pat_min[1]) * ibuf->y; + + search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels); + + pattern_ibuf = BKE_tracking_sample_pattern(ibuf->x, ibuf->y, search_ibuf, track, marker, + FALSE, num_samples_x, num_samples_y, NULL); + + IMB_freeImBuf(search_ibuf); + + return pattern_ibuf; +} + +ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int anchored, int disable_channels) +{ + ImBuf *searchibuf; + int x, y, w, h; + float search_origin[2]; + + get_search_origin_frame_pixel(ibuf->x, ibuf->y, marker, search_origin); + + x = search_origin[0]; + y = search_origin[1]; + + if (anchored) { + x += track->offset[0] * ibuf->x; + y += track->offset[1] * ibuf->y; + } + + w = (marker->search_max[0] - marker->search_min[0]) * ibuf->x; + h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y; + + searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); + searchibuf->profile = ibuf->profile; + + IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h); + + if (disable_channels) { + if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || + (track->flag & TRACK_DISABLE_RED) || + (track->flag & TRACK_DISABLE_GREEN) || + (track->flag & TRACK_DISABLE_BLUE)) + { + disable_imbuf_channels(searchibuf, track, TRUE); + } + } + + return searchibuf; +} + +/* zap channels from the imbuf that are disabled by the user. this can lead to + * better tracks sometimes. however, instead of simply zeroing the channels + * out, do a partial grayscale conversion so the display is better. + */ +void BKE_tracking_disable_channels(ImBuf *ibuf, int disable_red, int disable_green, int disable_blue, + int grayscale) +{ + int x, y; + float scale; + + if (!disable_red && !disable_green && !disable_blue && !grayscale) + return; + + /* if only some components are selected, it's important to rescale the result + * appropriately so that e.g. if only blue is selected, it's not zeroed out. + */ + scale = (disable_red ? 0.0f : 0.2126f) + + (disable_green ? 0.0f : 0.7152f) + + (disable_blue ? 0.0f : 0.0722f); + + for (y = 0; y < ibuf->y; y++) { + for (x = 0; x < ibuf->x; x++) { + int pixel = ibuf->x * y + x; + + if (ibuf->rect_float) { + float *rrgbf = ibuf->rect_float + pixel * 4; + float r = disable_red ? 0.0f : rrgbf[0]; + float g = disable_green ? 0.0f : rrgbf[1]; + float b = disable_blue ? 0.0f : rrgbf[2]; + + if (grayscale) { + float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale; + + rrgbf[0] = rrgbf[1] = rrgbf[2] = gray; + } + else { + rrgbf[0] = r; + rrgbf[1] = g; + rrgbf[2] = b; + } + } + else { + char *rrgb = (char *)ibuf->rect + pixel * 4; + char r = disable_red ? 0 : rrgb[0]; + char g = disable_green ? 0 : rrgb[1]; + char b = disable_blue ? 0 : rrgb[2]; + + if (grayscale) { + float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale; + + rrgb[0] = rrgb[1] = rrgb[2] = gray; + } + else { + rrgb[0] = r; + rrgb[1] = g; + rrgb[2] = b; + } + } + } + } + + if (ibuf->rect_float) + ibuf->userflags |= IB_RECT_INVALID; +} + +/*********************** Tracks map *************************/ + +typedef struct TracksMap { + char object_name[MAX_NAME]; + int is_camera; + + int num_tracks; + int customdata_size; + + char *customdata; + MovieTrackingTrack *tracks; + + GHash *hash; + + int ptr; +} TracksMap; + +static TracksMap *tracks_map_new(const char *object_name, int is_camera, int num_tracks, int customdata_size) +{ + TracksMap *map = MEM_callocN(sizeof(TracksMap), "TrackingsMap"); + + BLI_strncpy(map->object_name, object_name, sizeof(map->object_name)); + map->is_camera = is_camera; + + map->num_tracks = num_tracks; + map->customdata_size = customdata_size; + + map->tracks = MEM_callocN(sizeof(MovieTrackingTrack) * num_tracks, "TrackingsMap tracks"); + + if (customdata_size) + map->customdata = MEM_callocN(customdata_size * num_tracks, "TracksMap customdata"); + + map->hash = BLI_ghash_ptr_new("TracksMap hash"); + + return map; +} + +static int tracks_map_get_size(TracksMap *map) +{ + return map->num_tracks; +} + +static void tracks_map_get_indexed_element(TracksMap *map, int index, MovieTrackingTrack **track, void **customdata) +{ + *track = &map->tracks[index]; + + if (map->customdata) + *customdata = &map->customdata[index * map->customdata_size]; +} + +static void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *customdata) +{ + MovieTrackingTrack new_track = *track; + + new_track.markers = MEM_dupallocN(new_track.markers); + + map->tracks[map->ptr] = new_track; + + if (customdata) + memcpy(&map->customdata[map->ptr * map->customdata_size], customdata, map->customdata_size); + + BLI_ghash_insert(map->hash, &map->tracks[map->ptr], track); + + map->ptr++; +} + +static void tracks_map_merge(TracksMap *map, MovieTracking *tracking) +{ + MovieTrackingTrack *track; + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); + MovieTrackingTrack *rot_track = tracking->stabilization.rot_track; + ListBase tracks = {NULL, NULL}, new_tracks = {NULL, NULL}; + ListBase *old_tracks; + int a; + + if (map->is_camera) { + old_tracks = &tracking->tracks; + } + else { + MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, map->object_name); + + if (!object) { + /* object was deleted by user, create new one */ + object = BKE_tracking_object_add(tracking, map->object_name); + } + + old_tracks = &object->tracks; + } + + /* duplicate currently operating tracks to temporary list. + * this is needed to keep names in unique state and it's faster to change names + * of currently operating tracks (if needed) + */ + for (a = 0; a < map->num_tracks; a++) { + int replace_sel = 0, replace_rot = 0; + MovieTrackingTrack *new_track, *old; + + track = &map->tracks[a]; + + /* find original of operating track in list of previously displayed tracks */ + old = BLI_ghash_lookup(map->hash, track); + if (old) { + MovieTrackingTrack *cur = old_tracks->first; + + while (cur) { + if (cur == old) + break; + + cur = cur->next; + } + + /* original track was found, re-use flags and remove this track */ + if (cur) { + if (cur == act_track) + replace_sel = 1; + if (cur == rot_track) + replace_rot = 1; + + track->flag = cur->flag; + track->pat_flag = cur->pat_flag; + track->search_flag = cur->search_flag; + + BKE_tracking_track_free(cur); + BLI_freelinkN(old_tracks, cur); + } + } + + new_track = tracking_track_duplicate(track); + + BLI_ghash_remove(map->hash, track, NULL, NULL); /* XXX: are we actually need this */ + BLI_ghash_insert(map->hash, track, new_track); + + if (replace_sel) /* update current selection in clip */ + tracking->act_track = new_track; + + if (replace_rot) /* update track used for rotation stabilization */ + tracking->stabilization.rot_track = new_track; + + BLI_addtail(&tracks, new_track); + } + + /* move all tracks, which aren't operating */ + track = old_tracks->first; + while (track) { + MovieTrackingTrack *next = track->next; + + track->next = track->prev = NULL; + BLI_addtail(&new_tracks, track); + + track = next; + } + + /* now move all tracks which are currently operating and keep their names unique */ + track = tracks.first; + while (track) { + MovieTrackingTrack *next = track->next; + + BLI_remlink(&tracks, track); + + track->next = track->prev = NULL; + BLI_addtail(&new_tracks, track); + + BLI_uniquename(&new_tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name)); + + track = next; + } + + *old_tracks = new_tracks; +} + +static void tracks_map_free(TracksMap *map, void (*customdata_free)(void *customdata)) +{ + int i = 0; + + BLI_ghash_free(map->hash, NULL, NULL); + + for (i = 0; i < map->num_tracks; i++) { + if (map->customdata && customdata_free) + customdata_free(&map->customdata[i * map->customdata_size]); + + BKE_tracking_track_free(&map->tracks[i]); + } + + if (map->customdata) + MEM_freeN(map->customdata); + + MEM_freeN(map->tracks); + MEM_freeN(map); +} + +/*********************** 2D tracking *************************/ + +typedef struct TrackContext { +#ifdef WITH_LIBMV + /* the reference marker and cutout search area */ + MovieTrackingMarker marker; + + /* keyframed patch. This is the search area */ + float *search_area; + int search_area_height; + int search_area_width; + int framenr; + + float *mask; +#else + int pad; +#endif +} TrackContext; + +typedef struct MovieTrackingContext { + MovieClipUser user; + MovieClip *clip; + int clip_flag; + + int first_time, frames; + + MovieTrackingSettings settings; + TracksMap *tracks_map; + + short backwards, sequence; + int sync_frame; +} MovieTrackingContext; + +static void track_context_free(void *customdata) +{ + TrackContext *track_context = (TrackContext *)customdata; + +#if WITH_LIBMV + if (track_context->search_area) + MEM_freeN(track_context->search_area); + + if (track_context->mask) + MEM_freeN(track_context->mask); + +#else + (void)track_context; +#endif +} + +MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short sequence) +{ + MovieTrackingContext *context = MEM_callocN(sizeof(MovieTrackingContext), "trackingContext"); + MovieTracking *tracking = &clip->tracking; + MovieTrackingSettings *settings = &tracking->settings; + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + MovieTrackingTrack *track; + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); + int num_tracks = 0; + + context->clip = clip; + context->settings = *settings; + context->backwards = backwards; + context->sync_frame = user->framenr; + context->first_time = TRUE; + context->sequence = sequence; + + /* count */ + track = tracksbase->first; + while (track) { + if (TRACK_SELECTED(track) && (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0) { + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); + + if ((marker->flag & MARKER_DISABLED) == 0) + num_tracks++; + } + + track = track->next; + } + + /* create tracking contextx for all tracks which would be tracked */ + if (num_tracks) { + int width, height; + + context->tracks_map = tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA, + num_tracks, sizeof(TrackContext)); + + BKE_movieclip_get_size(clip, user, &width, &height); + + /* create tracking data */ + track = tracksbase->first; + while (track) { + if (TRACK_SELECTED(track) && (track->flag & (TRACK_HIDDEN | TRACK_LOCKED)) == 0) { + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); + + if ((marker->flag & MARKER_DISABLED) == 0) { + TrackContext track_context; + memset(&track_context, 0, sizeof(TrackContext)); + tracks_map_insert(context->tracks_map, track, &track_context); + } + } + + track = track->next; + } + } + + /* store needed clip flags passing to get_buffer functions + * - MCLIP_USE_PROXY is needed to because timecode affects on movie clip + * only in case Proxy/Timecode flag is set, so store this flag to use + * timecodes properly but reset render size to SIZE_FULL so correct resolution + * would be used for images + * - MCLIP_USE_PROXY_CUSTOM_DIR is needed because proxy/timecode files might + * be stored in a different location + * ignore all the rest possible flags for now + */ + context->clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS; + + context->user = *user; + context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; + context->user.render_flag = 0; + + if (!sequence) + BLI_begin_threaded_malloc(); + + return context; +} + +void BKE_tracking_context_free(MovieTrackingContext *context) +{ + if (!context->sequence) + BLI_end_threaded_malloc(); + + tracks_map_free(context->tracks_map, track_context_free); + + MEM_freeN(context); +} + +void BKE_tracking_context_sync(MovieTrackingContext *context) +{ + MovieTracking *tracking = &context->clip->tracking; + int newframe; + + tracks_map_merge(context->tracks_map, tracking); + + if (context->backwards) + newframe = context->user.framenr + 1; + else + newframe = context->user.framenr - 1; + + context->sync_frame = newframe; + + tracking->dopesheet.ok = FALSE; +} + +void BKE_tracking_context_sync_user(const MovieTrackingContext *context, MovieClipUser *user) +{ + user->framenr = context->sync_frame; +} + +#ifdef WITH_LIBMV +/* **** utility functions for tracking **** */ + +/* convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */ static void float_rgba_to_gray(const float *rgba, float *gray, int num_pixels, float weight_red, float weight_green, float weight_blue) { @@ -1483,12 +2145,12 @@ static void uint8_rgba_to_float_gray(const unsigned char *rgba, float *gray, int for (i = 0; i < num_pixels; i++) { const unsigned char *pixel = rgba + i * 4; - *gray++ = (weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]) / 255.0f; + gray[i] = (weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]) / 255.0f; } } -static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int *width_r, int *height_r) +static float *track_get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int *width_r, int *height_r) { ImBuf *searchibuf; float *gray_pixels; @@ -1499,9 +2161,6 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT width = searchibuf->x; height = searchibuf->y; - *width_r = searchibuf->x; - *height_r = searchibuf->y; - gray_pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf"); if (searchibuf->rect_float) { @@ -1515,39 +2174,13 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT IMB_freeImBuf(searchibuf); + *width_r = width; + *height_r = height; + return gray_pixels; } -static unsigned char *get_ucharbuf(ImBuf *ibuf) -{ - int x, y; - unsigned char *pixels, *cp; - - cp = pixels = MEM_callocN(ibuf->x * ibuf->y * sizeof(unsigned char), "tracking ucharBuf"); - for (y = 0; y < ibuf->y; y++) { - for (x = 0; x < ibuf->x; x++) { - int pixel = ibuf->x * y + x; - - if (ibuf->rect_float) { - const float *rrgbf = ibuf->rect_float + pixel * 4; - const float grey_f = 0.2126f * rrgbf[0] + 0.7152f * rrgbf[1] + 0.0722f * rrgbf[2]; - - *cp = FTOCHAR(grey_f); - } - else { - const unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4; - - *cp = 0.2126f * rrgb[0] + 0.7152f * rrgb[1] + 0.0722f * rrgb[2]; - } - - cp++; - } - } - - return pixels; -} - -static ImBuf *get_frame_ibuf(MovieTrackingContext *context, int framenr) +static ImBuf *tracking_context_get_frame_ibuf(MovieTrackingContext *context, int framenr) { ImBuf *ibuf; MovieClipUser user = context->user; @@ -1559,13 +2192,11 @@ static ImBuf *get_frame_ibuf(MovieTrackingContext *context, int framenr) return ibuf; } -static ImBuf *get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track, - MovieTrackingMarker *marker, MovieTrackingMarker **marker_keyed) +MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingContext *context, MovieTrackingTrack *track, + MovieTrackingMarker *marker) { - int framenr = marker->framenr; int a = marker - track->markers; - - *marker_keyed = marker; + MovieTrackingMarker *marker_keyed = marker; while (a >= 0 && a < track->markersnr) { int next = (context->backwards) ? a + 1 : a - 1; @@ -1583,8 +2214,7 @@ static ImBuf *get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTra is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0; if (is_keyframed) { - framenr = cur_marker->framenr; - *marker_keyed = cur_marker; + marker_keyed = cur_marker; break; } @@ -1592,19 +2222,34 @@ static ImBuf *get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTra a = next; } - return get_frame_ibuf(context, framenr); + return marker_keyed; } -static ImBuf *get_adjust_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int curfra, MovieTrackingMarker **marker_keyed) +static ImBuf *tracking_context_get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track, + MovieTrackingMarker *marker, MovieTrackingMarker **marker_keyed_r) +{ + MovieTrackingMarker *marker_keyed; + int keyed_framenr; + + marker_keyed = tracking_context_get_keyframed_marker(context, track, marker); + keyed_framenr = marker_keyed->framenr; + + *marker_keyed_r = marker_keyed; + + return tracking_context_get_frame_ibuf(context, keyed_framenr); +} + +static ImBuf *tracking_context_get_reference_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track, + MovieTrackingMarker *marker, int curfra, + MovieTrackingMarker **marker_keyed) { ImBuf *ibuf = NULL; if (track->pattern_match == TRACK_MATCH_KEYFRAME) { - ibuf = get_keyframed_ibuf(context, track, marker, marker_keyed); + ibuf = tracking_context_get_keyframed_ibuf(context, track, marker, marker_keyed); } else { - ibuf = get_frame_ibuf(context, curfra); + ibuf = tracking_context_get_frame_ibuf(context, curfra); /* use current marker as keyframed position */ *marker_keyed = marker; @@ -1613,7 +2258,78 @@ static ImBuf *get_adjust_ibuf(MovieTrackingContext *context, MovieTrackingTrack return ibuf; } -static void marker_search_scale_after_tracking(const MovieTrackingMarker *old_marker, MovieTrackingMarker *new_marker) +static void track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context, + MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra, + int frame_width, int frame_height) +{ + MovieTrackingMarker *marker_keyed = NULL; + ImBuf *reference_ibuf = NULL; + int width, height; + + /* calculate patch for keyframed position */ + reference_ibuf = tracking_context_get_reference_ibuf(context, track, marker, curfra, &marker_keyed); + track_context->marker = *marker_keyed; + + if (track_context->search_area) { + MEM_freeN(track_context->search_area); + } + + track_context->search_area = track_get_search_floatbuf(reference_ibuf, track, marker_keyed, &width, &height); + track_context->search_area_height = height; + track_context->search_area_width = width; + + if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) { + if (track_context->mask) + MEM_freeN(track_context->mask); + + track_context->mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker); + } + + IMB_freeImBuf(reference_ibuf); +} + +static void tracking_configure_tracker(TrackContext *track_context, MovieTrackingTrack *track, + struct libmv_trackRegionOptions *options) +{ + options->motion_model = track->motion_model; + + options->use_brute = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) != 0); + + options->use_normalization = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) != 0); + + options->num_iterations = 50; + options->minimum_correlation = track->minimum_correlation; + options->sigma = 0.9; + + if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) + options->image1_mask = track_context->mask; +} + +/* returns FALSE if marker crossed margin area from frame bounds */ +static int tracking_check_marker_margin(MovieTrackingTrack *track, MovieTrackingMarker *marker, + int frame_width, int frame_height) +{ + float pat_min[2], pat_max[2], dim[2], margin[2]; + + /* margin from frame boundaries */ + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + sub_v2_v2v2(dim, pat_max, pat_min); + margin[0] = margin[1] = MAX2(dim[0], dim[1]) / 2.0f; + + margin[0] = MAX2(margin[0], (float)track->margin / frame_width); + margin[1] = MAX2(margin[1], (float)track->margin / frame_height); + + /* do not track markers which are too close to boundary */ + if (marker->pos[0] < margin[0] || marker->pos[0] > 1.0f - margin[0] || + marker->pos[1] < margin[1] || marker->pos[1] > 1.0f - margin[1]) + { + return FALSE; + } + + return TRUE; +} + +static void tracking_scale_marker_search(const MovieTrackingMarker *old_marker, MovieTrackingMarker *new_marker) { float old_pat_min[2], old_pat_max[2]; float new_pat_min[2], new_pat_max[2]; @@ -1632,73 +2348,89 @@ static void marker_search_scale_after_tracking(const MovieTrackingMarker *old_ma new_marker->search_max[1] *= scale_y; } +static void tracking_insert_new_marker(MovieTrackingContext *context, MovieTrackingTrack *track, + const MovieTrackingMarker *old_marker, int curfra, int tracked, + int frame_width, int frame_height, + double dst_pixel_x[5], double dst_pixel_y[5]) +{ + MovieTrackingMarker new_marker; + int frame_delta = context->backwards ? -1 : 1; + int nextfra = curfra + frame_delta; + + new_marker = *old_marker; + + if (tracked) { + set_marker_coords_from_tracking(frame_width, frame_height, &new_marker, dst_pixel_x, dst_pixel_y); + new_marker.flag |= MARKER_TRACKED; + new_marker.framenr = nextfra; + + tracking_scale_marker_search(old_marker, &new_marker); + + if (context->first_time) { + /* check if there's no keyframe/tracked markers before tracking marker. + * if so -- create disabled marker before currently tracking "segment" + */ + + tracking_marker_insert_disabled(track, &new_marker, !context->backwards, FALSE); + } + + /* insert currently tracked marker */ + BKE_tracking_marker_insert(track, &new_marker); + + /* make currently tracked segment be finished with disabled marker */ + tracking_marker_insert_disabled(track, &new_marker, context->backwards, FALSE); + } + else { + new_marker.framenr = nextfra; + new_marker.flag |= MARKER_DISABLED; + + BKE_tracking_marker_insert(track, &new_marker); + } +} + #endif -void BKE_tracking_sync(MovieTrackingContext *context) -{ - MovieTracking *tracking = &context->clip->tracking; - int newframe; - - tracks_map_merge(context->tracks_map, tracking); - - if (context->backwards) - newframe = context->user.framenr + 1; - else - newframe = context->user.framenr - 1; - - context->sync_frame = newframe; - - tracking->dopesheet.ok = FALSE; -} - -void BKE_tracking_sync_user(MovieClipUser *user, MovieTrackingContext *context) -{ - user->framenr = context->sync_frame; -} - -int BKE_tracking_next(MovieTrackingContext *context) +int BKE_tracking_context_step(MovieTrackingContext *context) { ImBuf *destination_ibuf; + int frame_delta = context->backwards ? -1 : 1; int curfra = BKE_movieclip_remap_scene_to_clip_frame(context->clip, context->user.framenr); + int nextfra; int a, ok = FALSE, map_size; int frame_width, frame_height; - map_size = tracks_map_size(context->tracks_map); + map_size = tracks_map_get_size(context->tracks_map); /* nothing to track, avoid unneeded frames reading to save time and memory */ if (!map_size) return FALSE; - if (context->backwards) - context->user.framenr--; - else - context->user.framenr++; + context->user.framenr += frame_delta; destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user, context->clip_flag, MOVIECLIP_CACHE_SKIP); if (!destination_ibuf) return FALSE; + nextfra = curfra + frame_delta; + frame_width = destination_ibuf->x; frame_height = destination_ibuf->y; - //#pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1) + #pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1) for (a = 0; a < map_size; a++) { TrackContext *track_context = NULL; MovieTrackingTrack *track; MovieTrackingMarker *marker; - tracks_map_get(context->tracks_map, a, &track, (void **)&track_context); + tracks_map_get_indexed_element(context->tracks_map, a, &track, (void **)&track_context); - marker = BKE_tracking_exact_marker(track, curfra); + marker = BKE_tracking_marker_get_exact(track, curfra); if (marker && (marker->flag & MARKER_DISABLED) == 0) { #ifdef WITH_LIBMV - int width, height, tracked = 0, need_readjust = 0; - float margin[2], dim[2], pat_min[2], pat_max[2]; - MovieTrackingMarker marker_new, *marker_keyed; - int onbound = FALSE, nextfra; + int width, height, tracked = FALSE, need_readjust; double dst_pixel_x[5], dst_pixel_y[5]; if (track->pattern_match == TRACK_MATCH_KEYFRAME) @@ -1706,29 +2438,10 @@ int BKE_tracking_next(MovieTrackingContext *context) else need_readjust = TRUE; - if (context->backwards) - nextfra = curfra - 1; - else - nextfra = curfra + 1; - - /* margin from frame boundaries */ - BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - sub_v2_v2v2(dim, pat_max, pat_min); - margin[0] = margin[1] = MAX2(dim[0], dim[1]) / 2.0f; - - margin[0] = MAX2(margin[0], (float)track->margin / destination_ibuf->x); - margin[1] = MAX2(margin[1], (float)track->margin / destination_ibuf->y); - /* do not track markers which are too close to boundary */ - if (marker->pos[0] < margin[0] || marker->pos[0] > 1.0f - margin[0] || - marker->pos[1] < margin[1] || marker->pos[1] > 1.0f - margin[1]) - { - onbound = TRUE; - } - else { + if (tracking_check_marker_margin(track, marker, frame_width, frame_height)) { /* to convert to the x/y split array format for libmv. */ - double src_pixel_x[5]; - double src_pixel_y[5]; + double src_pixel_x[5], src_pixel_y[5]; /* settings for the tracker */ struct libmv_trackRegionOptions options = {0}; @@ -1737,57 +2450,24 @@ int BKE_tracking_next(MovieTrackingContext *context) float *patch_new; if (need_readjust) { - ImBuf *reference_ibuf = NULL; - /* calculate patch for keyframed position */ - reference_ibuf = get_adjust_ibuf(context, track, marker, curfra, &marker_keyed); - track_context->marker = *marker_keyed; - - if (track_context->search_area) - MEM_freeN(track_context->search_area); - - track_context->search_area = get_search_floatbuf(reference_ibuf, track, - marker_keyed, &width, &height); - track_context->search_area_height = height; - track_context->search_area_width = width; - - IMB_freeImBuf(reference_ibuf); - - if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) { - if (track_context->mask) - MEM_freeN(track_context->mask); - - track_context->mask = BKE_tracking_track_mask_get(frame_width, frame_height, - track, marker); - } + track_context_update_reference(context, track_context, track, marker, + curfra, frame_width, frame_height); } /* for now track to the same search area dimension as marker has got for current frame * will make all tracked markers in currently tracked segment have the same search area * size, but it's quite close to what is actually needed */ - patch_new = get_search_floatbuf(destination_ibuf, track, marker, &width, &height); + patch_new = track_get_search_floatbuf(destination_ibuf, track, marker, &width, &height); - /* Configure the tracker */ - options.motion_model = track->motion_model; + /* configure the tracker */ + tracking_configure_tracker(track_context, track, &options); - options.use_brute = - ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) != 0); - - options.use_normalization = - ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) != 0); - - options.num_iterations = 50; - options.minimum_correlation = track->minimum_correlation; - options.sigma = 0.9; - - if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) - options.image1_mask = track_context->mask; - - /* Convert the marker corners and center into pixel coordinates in the search/destination images. */ + /* convert the marker corners and center into pixel coordinates in the search/destination images. */ get_marker_coords_for_tracking(frame_width, frame_height, &track_context->marker, src_pixel_x, src_pixel_y); get_marker_coords_for_tracking(frame_width, frame_height, marker, dst_pixel_x, dst_pixel_y); - /* Run the tracker! */ + /* run the tracker! */ tracked = libmv_trackRegion(&options, track_context->search_area, track_context->search_area_width, @@ -1799,42 +2479,10 @@ int BKE_tracking_next(MovieTrackingContext *context) MEM_freeN(patch_new); } - if (tracked && !onbound) { - memset(&marker_new, 0, sizeof(marker_new)); - marker_new = *marker; - set_marker_coords_from_tracking(frame_width, frame_height, &marker_new, dst_pixel_x, dst_pixel_y); - marker_new.flag |= MARKER_TRACKED; - marker_new.framenr = nextfra; - - marker_search_scale_after_tracking(marker, &marker_new); - - //#pragma omp critical - { - if (context->first_time) { - /* check if there's no keyframe/tracked markers before tracking marker. - * if so -- create disabled marker before currently tracking "segment" - */ - - put_disabled_marker(track, &marker_new, !context->backwards, 0); - } - - /* insert currently tracked marker */ - BKE_tracking_insert_marker(track, &marker_new); - - /* make currently tracked segment be finished with disabled marker */ - put_disabled_marker(track, &marker_new, context->backwards, 0); - } - } - else { - marker_new = *marker; - - marker_new.framenr = nextfra; - marker_new.flag |= MARKER_DISABLED; - - //#pragma omp critical - { - BKE_tracking_insert_marker(track, &marker_new); - } + #pragma omp critical + { + tracking_insert_new_marker(context, track, marker, curfra, tracked, + frame_width, frame_height, dst_pixel_x, dst_pixel_y); } ok = TRUE; @@ -1853,7 +2501,7 @@ int BKE_tracking_next(MovieTrackingContext *context) return ok; } -/*********************** camera solving *************************/ +/*********************** Camera solving *************************/ typedef struct MovieReconstructContext { #ifdef WITH_LIBMV @@ -1886,8 +2534,8 @@ typedef struct ReconstructProgressData { int message_size; } ReconstructProgressData; -#if WITH_LIBMV -static struct libmv_Tracks *create_libmv_tracks(ListBase *tracksbase, int width, int height) +#ifdef WITH_LIBMV +static struct libmv_Tracks *libmv_tracks_new(ListBase *tracksbase, int width, int height) { int tracknr = 0; MovieTrackingTrack *track; @@ -1913,7 +2561,7 @@ static struct libmv_Tracks *create_libmv_tracks(ListBase *tracksbase, int width, return tracks; } -static void retrieve_libmv_reconstruct_intrinscis(MovieReconstructContext *context, MovieTracking *tracking) +static void reconstruct_retrieve_libmv_intrinscis(MovieReconstructContext *context, MovieTracking *tracking) { struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction; struct libmv_CameraIntrinsics *libmv_intrinsics = libmv_ReconstructionExtractIntrinsics(libmv_reconstruction); @@ -1934,7 +2582,7 @@ static void retrieve_libmv_reconstruct_intrinscis(MovieReconstructContext *conte tracking->camera.k2 = k2; } -static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, MovieTracking *tracking) +static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, MovieTracking *tracking) { struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction; MovieTrackingReconstruction *reconstruction = NULL; @@ -1950,7 +2598,7 @@ static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, M reconstruction = &tracking->reconstruction; } else { - MovieTrackingObject *object = BKE_tracking_named_object(tracking, context->object_name); + MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, context->object_name); tracksbase = &object->tracks; reconstruction = &object->reconstruction; @@ -2042,15 +2690,15 @@ static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, M return ok; } -static int retrieve_libmv_reconstruct(MovieReconstructContext *context, MovieTracking *tracking) +static int reconstruct_retrieve_libmv(MovieReconstructContext *context, MovieTracking *tracking) { /* take the intrinscis back from libmv */ - retrieve_libmv_reconstruct_intrinscis(context, tracking); + reconstruct_retrieve_libmv_intrinscis(context, tracking); - return retrieve_libmv_reconstruct_tracks(context, tracking); + return reconstruct_retrieve_libmv_tracks(context, tracking); } -static int get_refine_intrinsics_flags(MovieTracking *tracking, MovieTrackingObject *object) +static int reconstruct_refine_intrinsics_get_flags(MovieTracking *tracking, MovieTrackingObject *object) { int refine = tracking->settings.refine_camera_intrinsics; int flags = 0; @@ -2073,7 +2721,7 @@ static int get_refine_intrinsics_flags(MovieTracking *tracking, MovieTrackingObj return flags; } -static int count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase) +static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase) { int tot = 0; int frame1 = tracking->settings.keyframe1, frame2 = tracking->settings.keyframe2; @@ -2081,9 +2729,11 @@ static int count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tra track = tracksbase->first; while (track) { - if (BKE_tracking_has_enabled_marker(track, frame1)) - if (BKE_tracking_has_enabled_marker(track, frame2)) + if (BKE_tracking_track_has_enabled_marker_at_frame(track, frame1)) { + if (BKE_tracking_track_has_enabled_marker_at_frame(track, frame2)) { tot++; + } + } track = track->next; } @@ -2092,16 +2742,16 @@ static int count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tra } #endif -int BKE_tracking_can_reconstruct(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size) +int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size) { #if WITH_LIBMV - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); if (tracking->settings.motion_flag & TRACKING_MOTION_MODAL) { /* TODO: check for number of tracks? */ return TRUE; } - else if (count_tracks_on_both_keyframes(tracking, tracksbase) < 8) { + else if (reconstruct_count_tracks_on_both_keyframes(tracking, tracksbase) < 8) { BLI_strncpy(error_msg, "At least 8 common tracks on both of keyframes are needed for reconstruction", error_size); @@ -2124,7 +2774,7 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking * { MovieReconstructContext *context = MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data"); MovieTrackingCamera *camera = &tracking->camera; - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); float aspy = 1.0f / tracking->camera.pixel_aspect; int num_tracks = BLI_countlist(tracksbase); int sfra = INT_MAX, efra = INT_MIN; @@ -2134,6 +2784,14 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking * context->is_camera = object->flag & TRACKING_OBJECT_CAMERA; context->motion_flag = tracking->settings.motion_flag; + context->focal_length = camera->focal; + context->principal_point[0] = camera->principal[0]; + context->principal_point[1] = camera->principal[1] * aspy; + + context->k1 = camera->k1; + context->k2 = camera->k2; + context->k3 = camera->k3; + context->tracks_map = tracks_map_new(context->object_name, context->is_camera, num_tracks, 0); track = tracksbase->first; @@ -2169,10 +2827,10 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking * context->efra = efra; #ifdef WITH_LIBMV - context->tracks = create_libmv_tracks(tracksbase, width, height * aspy); + context->tracks = libmv_tracks_new(tracksbase, width, height * aspy); context->keyframe1 = keyframe1; context->keyframe2 = keyframe2; - context->refine_flags = get_refine_intrinsics_flags(tracking, object); + context->refine_flags = reconstruct_refine_intrinsics_get_flags(tracking, object); #else (void) width; (void) height; @@ -2180,14 +2838,6 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking * (void) keyframe2; #endif - context->focal_length = camera->focal; - context->principal_point[0] = camera->principal[0]; - context->principal_point[1] = camera->principal[1] * aspy; - - context->k1 = camera->k1; - context->k2 = camera->k2; - context->k3 = camera->k3; - return context; } @@ -2206,7 +2856,7 @@ void BKE_tracking_reconstruction_context_free(MovieReconstructContext *context) } #ifdef WITH_LIBMV -static void solve_reconstruction_update_cb(void *customdata, double progress, const char *message) +static void reconstruct_update_solve_cb(void *customdata, double progress, const char *message) { ReconstructProgressData *progressdata = customdata; @@ -2231,7 +2881,7 @@ static int solve_reconstruction_testbreak_cb(void *customdata) } #endif -void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short *stop, short *do_update, +void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *stop, short *do_update, float *progress, char *stats_message, int message_size) { #ifdef WITH_LIBMV @@ -2250,7 +2900,7 @@ void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short * context->focal_length, context->principal_point[0], context->principal_point[1], context->k1, context->k2, context->k3, - solve_reconstruction_update_cb, &progressdata); + reconstruct_update_solve_cb, &progressdata); } else { context->reconstruction = libmv_solveReconstruction(context->tracks, @@ -2259,7 +2909,7 @@ void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short * context->focal_length, context->principal_point[0], context->principal_point[1], context->k1, context->k2, context->k3, - solve_reconstruction_update_cb, &progressdata); + reconstruct_update_solve_cb, &progressdata); } error = libmv_reprojectionError(context->reconstruction); @@ -2275,7 +2925,7 @@ void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short * #endif } -int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTracking *tracking) +int BKE_tracking_reconstruction_finish(MovieReconstructContext *context, MovieTracking *tracking) { MovieTrackingReconstruction *reconstruction; @@ -2287,7 +2937,7 @@ int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTr else { MovieTrackingObject *object; - object = BKE_tracking_named_object(tracking, context->object_name); + object = BKE_tracking_object_get_named(tracking, context->object_name); reconstruction = &object->reconstruction; } @@ -2295,350 +2945,17 @@ int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTr reconstruction->flag |= TRACKING_RECONSTRUCTED; #ifdef WITH_LIBMV - if (!retrieve_libmv_reconstruct(context, tracking)) + if (!reconstruct_retrieve_libmv(context, tracking)) return FALSE; #endif return TRUE; } -void BKE_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track) -{ - BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name)); -} - -MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, MovieTrackingObject *object, const char *name) -{ - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); - MovieTrackingTrack *track = tracksbase->first; - - while (track) { - if (!strcmp(track->name, name)) - return track; - - track = track->next; - } - - return NULL; -} - -static int reconstruction_camera_index(MovieTrackingReconstruction *reconstruction, int framenr, int nearest) -{ - MovieReconstructedCamera *cameras = reconstruction->cameras; - int a = 0, d = 1; - - if (!reconstruction->camnr) - return -1; - - if (framenr < cameras[0].framenr) { - if (nearest) - return 0; - else - return -1; - } - - if (framenr > cameras[reconstruction->camnr - 1].framenr) { - if (nearest) - return reconstruction->camnr - 1; - else - return -1; - } - - if (reconstruction->last_camera < reconstruction->camnr) - a = reconstruction->last_camera; - - if (cameras[a].framenr >= framenr) - d = -1; - - while (a >= 0 && a < reconstruction->camnr) { - int cfra = cameras[a].framenr; - - /* check if needed framenr was "skipped" -- no data for requested frame */ - - if (d > 0 && cfra > framenr) { - /* interpolate with previous position */ - if (nearest) - return a - 1; - else - break; - } - - if (d < 0 && cfra < framenr) { - /* interpolate with next position */ - if (nearest) - return a; - else - break; - } - - if (cfra == framenr) { - reconstruction->last_camera = a; - - return a; - } - - a += d; - } - - return -1; -} - -static void scale_reconstructed_camera(MovieTrackingObject *object, float mat[4][4]) -{ - if ((object->flag & TRACKING_OBJECT_CAMERA) == 0) { - float smat[4][4]; - - scale_m4_fl(smat, 1.0f / object->scale); - mult_m4_m4m4(mat, mat, smat); - } -} - -MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, - MovieTrackingObject *object, int framenr) -{ - MovieTrackingReconstruction *reconstruction; - int a; - - reconstruction = BKE_tracking_object_reconstruction(tracking, object); - a = reconstruction_camera_index(reconstruction, framenr, FALSE); - - if (a == -1) - return NULL; - - return &reconstruction->cameras[a]; -} - -void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, MovieTrackingObject *object, - int framenr, float mat[4][4]) -{ - MovieTrackingReconstruction *reconstruction; - MovieReconstructedCamera *cameras; - int a; - - reconstruction = BKE_tracking_object_reconstruction(tracking, object); - cameras = reconstruction->cameras; - a = reconstruction_camera_index(reconstruction, framenr, 1); - - if (a == -1) { - unit_m4(mat); - - return; - } - - if (cameras[a].framenr != framenr && a > 0 && a < reconstruction->camnr - 1) { - float t = ((float)framenr - cameras[a].framenr) / (cameras[a + 1].framenr - cameras[a].framenr); - - blend_m4_m4m4(mat, cameras[a].mat, cameras[a + 1].mat, t); - } - else { - copy_m4_m4(mat, cameras[a].mat); - } - - scale_reconstructed_camera(object, mat); -} - -void BKE_get_tracking_mat(Scene *scene, Object *ob, float mat[4][4]) -{ - if (!ob) { - if (scene->camera) - ob = scene->camera; - else - ob = BKE_scene_camera_find(scene); - } - - if (ob) - BKE_object_where_is_calc_mat4(scene, ob, mat); - else - unit_m4(mat); -} - -void BKE_tracking_camera_shift(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty) -{ - /* indeed in both of cases it should be winx -- it's just how camera shift works for blender's camera */ - *shiftx = (0.5f * winx - tracking->camera.principal[0]) / winx; - *shifty = (0.5f * winy - tracking->camera.principal[1]) / winx; -} - -void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height) -{ - float focal = tracking->camera.focal; - - camera->sensor_x = tracking->camera.sensor_width; - camera->sensor_fit = CAMERA_SENSOR_FIT_AUTO; - camera->lens = focal * camera->sensor_x / width; - - scene->r.xsch = width * tracking->camera.pixel_aspect; - scene->r.ysch = height; - - scene->r.xasp = 1.0f; - scene->r.yasp = 1.0f; - - BKE_tracking_camera_shift(tracking, width, height, &camera->shiftx, &camera->shifty); -} - -void BKE_tracking_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object, - int framenr, int winx, int winy, float mat[4][4]) -{ - MovieReconstructedCamera *camera; - float lens = tracking->camera.focal * tracking->camera.sensor_width / (float)winx; - float viewfac, pixsize, left, right, bottom, top, clipsta, clipend; - float winmat[4][4]; - float ycor = 1.0f / tracking->camera.pixel_aspect; - float shiftx, shifty, winside = MAX2(winx, winy); - - BKE_tracking_camera_shift(tracking, winx, winy, &shiftx, &shifty); - - clipsta = 0.1f; - clipend = 1000.0f; - - if (winx >= winy) - viewfac = (lens * winx) / tracking->camera.sensor_width; - else - viewfac = (ycor * lens * winy) / tracking->camera.sensor_width; - - pixsize = clipsta / viewfac; - - left = -0.5f * (float)winx + shiftx * winside; - bottom = -0.5f * (ycor) * (float)winy + shifty * winside; - right = 0.5f * (float)winx + shiftx * winside; - top = 0.5f * (ycor) * (float)winy + shifty * winside; - - left *= pixsize; - right *= pixsize; - bottom *= pixsize; - top *= pixsize; - - perspective_m4(winmat, left, right, bottom, top, clipsta, clipend); - - camera = BKE_tracking_get_reconstructed_camera(tracking, object, framenr); - - if (camera) { - float imat[4][4]; - - invert_m4_m4(imat, camera->mat); - mult_m4_m4m4(mat, winmat, imat); - } - else copy_m4_m4(mat, winmat); -} - -ListBase *BKE_tracking_get_tracks(MovieTracking *tracking) -{ - MovieTrackingObject *object = BKE_tracking_active_object(tracking); - - if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) { - return &object->tracks; - } - - return &tracking->tracks; -} - -MovieTrackingTrack *BKE_tracking_active_track(MovieTracking *tracking) -{ - ListBase *tracksbase; - - if (!tracking->act_track) - return NULL; - - tracksbase = BKE_tracking_get_tracks(tracking); - - /* check that active track is in current tracks list */ - if (BLI_findindex(tracksbase, tracking->act_track) >= 0) - return tracking->act_track; - - return NULL; -} - -MovieTrackingObject *BKE_tracking_active_object(MovieTracking *tracking) -{ - return BLI_findlink(&tracking->objects, tracking->objectnr); -} - -MovieTrackingObject *BKE_tracking_get_camera_object(MovieTracking *tracking) -{ - MovieTrackingObject *object = tracking->objects.first; - - while (object) { - if (object->flag & TRACKING_OBJECT_CAMERA) - return object; - - object = object->next; - } - - return NULL; -} - -ListBase *BKE_tracking_object_tracks(MovieTracking *tracking, MovieTrackingObject *object) -{ - if (object->flag & TRACKING_OBJECT_CAMERA) { - return &tracking->tracks; - } - - return &object->tracks; -} - -MovieTrackingReconstruction *BKE_tracking_object_reconstruction(MovieTracking *tracking, MovieTrackingObject *object) -{ - if (object->flag & TRACKING_OBJECT_CAMERA) { - return &tracking->reconstruction; - } - - return &object->reconstruction; -} - -MovieTrackingReconstruction *BKE_tracking_get_reconstruction(MovieTracking *tracking) -{ - MovieTrackingObject *object = BKE_tracking_active_object(tracking); - - return BKE_tracking_object_reconstruction(tracking, object); -} - -void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float nco[2]) -{ - MovieTrackingCamera *camera = &tracking->camera; +/*********************** Feature detection *************************/ #ifdef WITH_LIBMV - double x, y; - float aspy = 1.0f / tracking->camera.pixel_aspect; - - /* normalize coords */ - x = (co[0] - camera->principal[0]) / camera->focal; - y = (co[1] - camera->principal[1] * aspy) / camera->focal; - - libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, x, y, &x, &y); - - /* result is in image coords already */ - nco[0] = x; - nco[1] = y; -#else - (void) camera; - (void) co; - (void) nco; -#endif -} - -void BKE_tracking_invert_intrinsics(MovieTracking *tracking, float co[2], float nco[2]) -{ - MovieTrackingCamera *camera = &tracking->camera; - -#ifdef WITH_LIBMV - double x = co[0], y = co[1]; - float aspy = 1.0f / tracking->camera.pixel_aspect; - - libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, x, y, &x, &y); - - nco[0] = x * camera->focal + camera->principal[0]; - nco[1] = y * camera->focal + camera->principal[1] * aspy; -#else - (void) camera; - (void) co; - (void) nco; -#endif -} - -#ifdef WITH_LIBMV -static int point_in_stroke(bGPDstroke *stroke, float x, float y) +static int check_point_in_stroke(bGPDstroke *stroke, float x, float y) { int i, prev; int count = 0; @@ -2660,7 +2977,7 @@ static int point_in_stroke(bGPDstroke *stroke, float x, float y) return count % 2; } -static int point_in_layer(bGPDlayer *layer, float x, float y) +static int check_point_in_layer(bGPDlayer *layer, float x, float y) { bGPDframe *frame = layer->frames.first; @@ -2668,7 +2985,7 @@ static int point_in_layer(bGPDlayer *layer, float x, float y) bGPDstroke *stroke = frame->strokes.first; while (stroke) { - if (point_in_stroke(stroke, x, y)) + if (check_point_in_stroke(stroke, x, y)) return TRUE; stroke = stroke->next; @@ -2679,9 +2996,9 @@ static int point_in_layer(bGPDlayer *layer, float x, float y) return FALSE; } -static void retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase, - struct libmv_Features *features, int framenr, int width, int height, - bGPDlayer *layer, int place_outside_layer) +static void detect_retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase, + struct libmv_Features *features, int framenr, int width, int height, + bGPDlayer *layer, int place_outside_layer) { int a; @@ -2698,16 +3015,45 @@ static void retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbas yu = y / height; if (layer) - ok = point_in_layer(layer, xu, yu) != place_outside_layer; + ok = check_point_in_layer(layer, xu, yu) != place_outside_layer; if (ok) { - track = BKE_tracking_add_track(tracking, tracksbase, xu, yu, framenr, width, height); + track = BKE_tracking_track_add(tracking, tracksbase, xu, yu, framenr, width, height); track->flag |= SELECT; track->pat_flag |= SELECT; track->search_flag |= SELECT; } } } + +static unsigned char *detect_get_frame_ucharbuf(ImBuf *ibuf) +{ + int x, y; + unsigned char *pixels, *cp; + + cp = pixels = MEM_callocN(ibuf->x * ibuf->y * sizeof(unsigned char), "tracking ucharBuf"); + for (y = 0; y < ibuf->y; y++) { + for (x = 0; x < ibuf->x; x++) { + int pixel = ibuf->x * y + x; + + if (ibuf->rect_float) { + const float *rrgbf = ibuf->rect_float + pixel * 4; + const float grey_f = 0.2126f * rrgbf[0] + 0.7152f * rrgbf[1] + 0.0722f * rrgbf[2]; + + *cp = FTOCHAR(grey_f); + } + else { + const unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4; + + *cp = 0.2126f * rrgb[0] + 0.7152f * rrgb[1] + 0.0722f * rrgb[2]; + } + + cp++; + } + } + + return pixels; +} #endif void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImBuf *ibuf, @@ -2716,14 +3062,14 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImB { #ifdef WITH_LIBMV struct libmv_Features *features; - unsigned char *pixels = get_ucharbuf(ibuf); + unsigned char *pixels = detect_get_frame_ucharbuf(ibuf); features = libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x, margin, min_trackness, min_distance); MEM_freeN(pixels); - retrieve_libmv_features(tracking, tracksbase, features, framenr, + detect_retrieve_libmv_features(tracking, tracksbase, features, framenr, ibuf->x, ibuf->y, layer, place_outside_layer); libmv_destroyFeatures(features); @@ -2740,38 +3086,9 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImB #endif } -MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r) -{ - MovieTrackingObject *object; - int cur = 1; +/*********************** 2D stabilization *************************/ - object = tracking->objects.first; - while (object) { - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); - MovieTrackingTrack *track = tracksbase->first; - - while (track) { - if (track->flag & TRACK_HAS_BUNDLE) { - if (cur == tracknr) { - *tracksbase_r = tracksbase; - return track; - } - - cur++; - } - - track = track->next; - } - - object = object->next; - } - - *tracksbase_r = NULL; - - return NULL; -} - -static int stabilization_median_point(MovieTracking *tracking, int framenr, float median[2]) +static int stabilization_median_point_get(MovieTracking *tracking, int framenr, float median[2]) { int ok = FALSE; float min[2], max[2]; @@ -2782,7 +3099,7 @@ static int stabilization_median_point(MovieTracking *tracking, int framenr, floa track = tracking->tracks.first; while (track) { if (track->flag & TRACK_USE_2D_STAB) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); DO_MINMAX2(marker->pos, min, max); @@ -2798,8 +3115,9 @@ static int stabilization_median_point(MovieTracking *tracking, int framenr, floa return ok; } -static void calculate_stabdata(MovieTracking *tracking, int framenr, float width, float height, - float firstmedian[2], float median[2], float loc[2], float *scale, float *angle) +static void stabilization_calculate_data(MovieTracking *tracking, int framenr, float width, float height, + float firstmedian[2], float median[2], float loc[2], + float *scale, float *angle) { MovieTrackingStabilization *stab = &tracking->stabilization; @@ -2817,12 +3135,12 @@ static void calculate_stabdata(MovieTracking *tracking, int framenr, float width float x0 = (float)width / 2.0f, y0 = (float)height / 2.0f; float x = median[0] * width, y = median[1] * height; - marker = BKE_tracking_get_marker(stab->rot_track, 1); + marker = BKE_tracking_marker_get(stab->rot_track, 1); sub_v2_v2v2(a, marker->pos, firstmedian); a[0] *= width; a[1] *= height; - marker = BKE_tracking_get_marker(stab->rot_track, framenr); + marker = BKE_tracking_marker_get(stab->rot_track, framenr); sub_v2_v2v2(b, marker->pos, median); b[0] *= width; b[1] *= height; @@ -2836,7 +3154,7 @@ static void calculate_stabdata(MovieTracking *tracking, int framenr, float width } } -static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, int height) +static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, int width, int height) { float firstmedian[2]; MovieTrackingStabilization *stab = &tracking->stabilization; @@ -2845,7 +3163,7 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, if (stab->ok) return stab->scale; - if (stabilization_median_point(tracking, 1, firstmedian)) { + if (stabilization_median_point_get(tracking, 1, firstmedian)) { int sfra = INT_MAX, efra = INT_MIN, cfra; float scale = 1.0f; MovieTrackingTrack *track; @@ -2872,11 +3190,11 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, float points[4][2] = {{0.0f, 0.0f}, {0.0f, height}, {width, height}, {width, 0.0f}}; float si, co; - stabilization_median_point(tracking, cfra, median); + stabilization_median_point_get(tracking, cfra, median); - calculate_stabdata(tracking, cfra, width, height, firstmedian, median, loc, &tmp_scale, &angle); + stabilization_calculate_data(tracking, cfra, width, height, firstmedian, median, loc, &tmp_scale, &angle); - BKE_tracking_stabdata_to_mat4(width, height, aspect, loc, 1.0f, angle, mat); + BKE_tracking_stabilization_data_to_mat4(width, height, aspect, loc, 1.0f, angle, mat); si = sin(angle); co = cos(angle); @@ -2954,7 +3272,7 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, return stab->scale; } -static ImBuf *stabilize_alloc_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill) +static ImBuf *stabilization_allocate_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill) { int flags; @@ -2983,8 +3301,8 @@ static ImBuf *stabilize_alloc_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill) return cacheibuf; } -void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int width, int height, - float loc[2], float *scale, float *angle) +void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, int width, int height, + float loc[2], float *scale, float *angle) { float firstmedian[2], median[2]; MovieTrackingStabilization *stab = &tracking->stabilization; @@ -2997,22 +3315,22 @@ void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int w return; } - if (stabilization_median_point(tracking, 1, firstmedian)) { - stabilization_median_point(tracking, framenr, median); + if (stabilization_median_point_get(tracking, 1, firstmedian)) { + stabilization_median_point_get(tracking, framenr, median); if ((stab->flag & TRACKING_AUTOSCALE) == 0) stab->scale = 1.0f; if (!stab->ok) { if (stab->flag & TRACKING_AUTOSCALE) - stabilization_auto_scale_factor(tracking, width, height); + stabilization_calculate_autoscale_factor(tracking, width, height); - calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle); + stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, loc, scale, angle); stab->ok = TRUE; } else { - calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle); + stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, loc, scale, angle); } } else { @@ -3022,8 +3340,8 @@ void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int w } } -ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, - float loc[2], float *scale, float *angle) +ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf *ibuf, + float loc[2], float *scale, float *angle) { float tloc[2], tscale, tangle; MovieTrackingStabilization *stab = &tracking->stabilization; @@ -3047,17 +3365,17 @@ ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, return ibuf; } - BKE_tracking_stabilization_data(tracking, framenr, width, height, tloc, &tscale, &tangle); + BKE_tracking_stabilization_data_get(tracking, framenr, width, height, tloc, &tscale, &tangle); - tmpibuf = stabilize_alloc_ibuf(NULL, ibuf, TRUE); + tmpibuf = stabilization_allocate_ibuf(NULL, ibuf, TRUE); /* scale would be handled by matrix transformation when angle is non-zero */ if (tscale != 1.0f && tangle == 0.0f) { ImBuf *scaleibuf; - stabilization_auto_scale_factor(tracking, width, height); + stabilization_calculate_autoscale_factor(tracking, width, height); - scaleibuf = stabilize_alloc_ibuf(stab->scaleibuf, ibuf, 0); + scaleibuf = stabilization_allocate_ibuf(stab->scaleibuf, ibuf, 0); stab->scaleibuf = scaleibuf; IMB_rectcpy(scaleibuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); @@ -3080,7 +3398,7 @@ ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, int i, j, filter = tracking->stabilization.filter; void (*interpolation)(struct ImBuf *, struct ImBuf *, float, float, int, int) = NULL; - BKE_tracking_stabdata_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat); + BKE_tracking_stabilization_data_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat); invert_m4(mat); if (filter == TRACKING_FILTER_NEAREAST) @@ -3121,8 +3439,8 @@ ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, return tmpibuf; } -void BKE_tracking_stabdata_to_mat4(int width, int height, float aspect, - float loc[2], float scale, float angle, float mat[4][4]) +void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float loc[2], + float scale, float angle, float mat[4][4]) { float lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4], amat[4][4], iamat[4][4]; float svec[3] = {scale, scale, scale}; @@ -3150,241 +3468,7 @@ void BKE_tracking_stabdata_to_mat4(int width, int height, float aspect, mul_serie_m4(mat, lmat, cmat, amat, rmat, iamat, smat, icmat, NULL); } -MovieDistortion *BKE_tracking_distortion_create(void) -{ - MovieDistortion *distortion; - - distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create"); - - return distortion; -} - -MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion) -{ - MovieDistortion *new_distortion; - - new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create"); - -#ifdef WITH_LIBMV - new_distortion->intrinsics = libmv_CameraIntrinsicsCopy(distortion->intrinsics); -#else - (void) distortion; -#endif - - return new_distortion; -} - -void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, int width, int height) -{ - MovieTrackingCamera *camera = &tracking->camera; - float aspy = 1.0f / tracking->camera.pixel_aspect; - -#ifdef WITH_LIBMV - if (!distortion->intrinsics) { - distortion->intrinsics = libmv_CameraIntrinsicsNew(camera->focal, - camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, width, height * aspy); - } - else { - libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal, - camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, width, height * aspy); - } -#else - (void) distortion; - (void) width; - (void) height; - (void) camera; - (void) aspy; -#endif -} - -ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking, - ImBuf *ibuf, int width, int height, float overscan, int undistort) -{ - ImBuf *resibuf; - - BKE_tracking_distortion_update(distortion, tracking, width, height); - - resibuf = IMB_dupImBuf(ibuf); - - if (ibuf->rect_float) { -#ifdef WITH_LIBMV - if (undistort) { - libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics, - ibuf->rect_float, resibuf->rect_float, - ibuf->x, ibuf->y, overscan, ibuf->channels); - } - else { - libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics, - ibuf->rect_float, resibuf->rect_float, - ibuf->x, ibuf->y, overscan, ibuf->channels); - } -#endif - - resibuf->userflags |= IB_RECT_INVALID; - } - else { -#ifdef WITH_LIBMV - if (undistort) { - libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics, - (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect, - ibuf->x, ibuf->y, overscan, ibuf->channels); - } - else { - libmv_CameraIntrinsicsDistortByte(distortion->intrinsics, - (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect, - ibuf->x, ibuf->y, overscan, ibuf->channels); - } -#endif - } - -#ifndef WITH_LIBMV - (void) overscan; - (void) undistort; -#endif - - return resibuf; -} - -void BKE_tracking_distortion_destroy(MovieDistortion *distortion) -{ -#ifdef WITH_LIBMV - libmv_CameraIntrinsicsDestroy(distortion->intrinsics); -#endif - - MEM_freeN(distortion); -} - -ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan) -{ - MovieTrackingCamera *camera = &tracking->camera; - - if (camera->intrinsics == NULL) - camera->intrinsics = BKE_tracking_distortion_create(); - - return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 1); -} - -ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan) -{ - MovieTrackingCamera *camera = &tracking->camera; - - if (camera->intrinsics == NULL) - camera->intrinsics = BKE_tracking_distortion_create(); - - return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 0); -} - -/* area - which part of marker should be selected. see TRACK_AREA_* constants */ -void BKE_tracking_select_track(ListBase *tracksbase, MovieTrackingTrack *track, int area, int extend) -{ - if (extend) { - BKE_tracking_track_flag(track, area, SELECT, 0); - } - else { - MovieTrackingTrack *cur = tracksbase->first; - - while (cur) { - if ((cur->flag & TRACK_HIDDEN) == 0) { - if (cur == track) { - BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1); - BKE_tracking_track_flag(cur, area, SELECT, 0); - } - else { - BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1); - } - } - - cur = cur->next; - } - } -} - -void BKE_tracking_deselect_track(MovieTrackingTrack *track, int area) -{ - BKE_tracking_track_flag(track, area, SELECT, 1); -} - -MovieTrackingObject *BKE_tracking_new_object(MovieTracking *tracking, const char *name) -{ - MovieTrackingObject *object = MEM_callocN(sizeof(MovieTrackingObject), "tracking object"); - - if (tracking->tot_object == 0) { - /* first object is always camera */ - BLI_strncpy(object->name, "Camera", sizeof(object->name)); - - object->flag |= TRACKING_OBJECT_CAMERA; - } - else { - BLI_strncpy(object->name, name, sizeof(object->name)); - } - - BLI_addtail(&tracking->objects, object); - - tracking->tot_object++; - tracking->objectnr = BLI_countlist(&tracking->objects) - 1; - - object->scale = 1.0f; - - BKE_tracking_object_unique_name(tracking, object); - - return object; -} - -void BKE_tracking_remove_object(MovieTracking *tracking, MovieTrackingObject *object) -{ - MovieTrackingTrack *track; - int index = BLI_findindex(&tracking->objects, object); - - if (index < 0) - return; - - if (object->flag & TRACKING_OBJECT_CAMERA) { - /* object used for camera solving can't be deleted */ - return; - } - - track = object->tracks.first; - while (track) { - if (track == tracking->act_track) - tracking->act_track = NULL; - - track = track->next; - } - - tracking_object_free(object); - BLI_freelinkN(&tracking->objects, object); - - tracking->tot_object--; - - if (index > 0) - tracking->objectnr = index - 1; - else - tracking->objectnr = 0; -} - -void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object) -{ - BLI_uniquename(&tracking->objects, object, "Object", '.', - offsetof(MovieTrackingObject, name), sizeof(object->name)); -} - -MovieTrackingObject *BKE_tracking_named_object(MovieTracking *tracking, const char *name) -{ - MovieTrackingObject *object = tracking->objects.first; - - while (object) { - if (!strcmp(object->name, name)) - return object; - - object = object->next; - } - - return NULL; -} - -/*********************** dopesheet functions *************************/ +/*********************** Dopesheet functions *************************/ static int channels_alpha_sort(void *a, void *b) { @@ -3586,11 +3670,11 @@ void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking) void BKE_tracking_dopesheet_update(MovieTracking *tracking) { - MovieTrackingObject *object = BKE_tracking_active_object(tracking); + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; MovieTrackingTrack *track; MovieTrackingReconstruction *reconstruction; - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); short sort_method = dopesheet->sort_method; short inverse = dopesheet->flag & TRACKING_DOPE_SORT_INVERSE; @@ -3602,7 +3686,7 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking) tracking_dopesheet_free(dopesheet); - reconstruction = BKE_tracking_object_reconstruction(tracking, object); + reconstruction = BKE_tracking_object_get_reconstruction(tracking, object); for (track = tracksbase->first; track; track = track->next) { MovieTrackingDopesheetChannel *channel; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index db4d40dd4c4..48f9d1df687 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7260,7 +7260,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) tracking->settings.object_distance = 1.0f; if (tracking->objects.first == NULL) - BKE_tracking_new_object(tracking, "Camera"); + BKE_tracking_object_add(tracking, "Camera"); while (tracking_object) { if (!tracking_object->scale) diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.cpp b/source/blender/compositor/nodes/COM_MovieClipNode.cpp index eac581dc903..6a325d7d885 100644 --- a/source/blender/compositor/nodes/COM_MovieClipNode.cpp +++ b/source/blender/compositor/nodes/COM_MovieClipNode.cpp @@ -91,7 +91,7 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex if (ibuf) { if (stab->flag&TRACKING_2D_STABILIZATION) { - BKE_tracking_stabilization_data(&movieClip->tracking, context->getFramenumber(), ibuf->x, ibuf->y, loc, &scale, &angle); + BKE_tracking_stabilization_data_get(&movieClip->tracking, context->getFramenumber(), ibuf->x, ibuf->y, loc, &scale, &angle); } } diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp index 757afe7b394..f6301557aaf 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -87,15 +87,15 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri int height = this->getHeight(); if (this->trackingObject[0]) { - MovieTrackingObject *object = BKE_tracking_named_object(tracking, this->trackingObject); + MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, this->trackingObject); if (!object) return NULL; - tracksbase = BKE_tracking_object_tracks(tracking, object); + tracksbase = BKE_tracking_object_get_tracks(tracking, object); } else - tracksbase = BKE_tracking_get_tracks(tracking); + tracksbase = BKE_tracking_get_active_tracks(tracking); sites_total = BLI_countlist(tracksbase); @@ -115,7 +115,7 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri i = 0; while (track) { VoronoiSite *site = &sites[i]; - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenumber); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenumber); ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE); int j; diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp index a81288be3f7..5a2e58d6b21 100644 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp @@ -41,7 +41,7 @@ void MovieClipAttributeOperation::executePixel(float *outputValue, float x, floa scale = 1.0f; angle = 0.0f; if (clip) { - BKE_tracking_stabilization_data(&clip->tracking, framenumber, getWidth(), getHeight(), loc, &scale, &angle); + BKE_tracking_stabilization_data_get(&clip->tracking, framenumber, getWidth(), getHeight(), loc, &scale, &angle); } switch (this->attribute) { case MCA_SCALE: diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index 9c7050e1da0..c2ce04a78e1 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -99,10 +99,10 @@ public: in[1] = (y /* - 0.5 * overscan * h */) / aspy / this->pixel_aspect; if (inverted) { - BKE_tracking_invert_intrinsics(trackingData, in, out); + BKE_tracking_undistort_v2(trackingData, in, out); } else { - BKE_tracking_apply_intrinsics(trackingData, in, out); + BKE_tracking_distort_v2(trackingData, in, out); } buffer[offset2] = out[0] * aspx /* + 0.5 * overscan * w */; diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 7708d99e990..ed530bea4bd 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -150,7 +150,7 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) if (clip) { if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { - MovieTrackingTrack *track = BKE_tracking_active_track(&clip->tracking); + MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking); if (!track) return NULL; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 4004efacadc..6d90824668e 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1033,8 +1033,8 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { int framenr = sc->user.framenr; - MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); - MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking); + MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr); p->imat[3][0] -= marker->pos[0]; p->imat[3][1] -= marker->pos[1]; diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 22aa1031f48..3c802020747 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1549,7 +1549,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc if (scopes->track_preview) IMB_freeImBuf(scopes->track_preview); - tmpibuf = BKE_tracking_sample_pattern_imbuf(scopes->frame_width, scopes->frame_height, + tmpibuf = BKE_tracking_sample_pattern(scopes->frame_width, scopes->frame_height, scopes->track_search, scopes->track, &scopes->undist_marker, scopes->use_track_mask, width, height, scopes->track_pos); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 4615906b0da..a8a7a55c653 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4203,7 +4203,7 @@ static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDa else { if (!scopes->track_locked) { if (scopes->marker->framenr != scopes->framenr) - scopes->marker = BKE_tracking_ensure_marker(scopes->track, scopes->framenr); + scopes->marker = BKE_tracking_marker_ensure(scopes->track, scopes->framenr); scopes->marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED); scopes->marker->pos[0] += -dx * scopes->slide_scale[0] / (but->block->maxx - but->block->minx); diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index 77fe2a71225..7ba3c27e18d 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -113,8 +113,8 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) if ((NULL == (sc = CTX_wm_space_clip(C))) || (NULL == (clip = sc->clip)) || (NULL == (track = clip->tracking.act_track)) || - (NULL == (marker = BKE_tracking_get_marker(track, sc->user.framenr))) || - (NULL == (tracking = BKE_tracking_active_object(&clip->tracking)))) + (NULL == (marker = BKE_tracking_marker_get(track, sc->user.framenr))) || + (NULL == (tracking = BKE_tracking_object_get_active(&clip->tracking)))) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 7cc11fa0209..a38c69fba8a 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -418,15 +418,15 @@ static void test_constraints(Object *owner, bPoseChannel *pchan) MovieTrackingObject *tracking_object; if (data->object[0]) - tracking_object = BKE_tracking_named_object(tracking, data->object); + tracking_object = BKE_tracking_object_get_named(tracking, data->object); else - tracking_object = BKE_tracking_get_camera_object(tracking); + tracking_object = BKE_tracking_object_get_camera(tracking); if (!tracking_object) { curcon->flag |= CONSTRAINT_DISABLE; } else { - if (!BKE_tracking_named_track(tracking, tracking_object, data->track)) + if (!BKE_tracking_track_get_named(tracking, tracking_object, data->track)) curcon->flag |= CONSTRAINT_DISABLE; } } diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 66fa2aed862..3a12156b803 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -211,7 +211,7 @@ static void marker_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg)) if (!cb->compact) return; - marker = BKE_tracking_ensure_marker(cb->track, cb->framenr); + marker = BKE_tracking_marker_ensure(cb->track, cb->framenr); marker->flag = cb->marker_flag; @@ -226,7 +226,7 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event) BKE_movieclip_get_size(cb->clip, cb->user, &width, &height); - marker = BKE_tracking_ensure_marker(cb->track, cb->framenr); + marker = BKE_tracking_marker_ensure(cb->track, cb->framenr); if (event == B_MARKER_POS) { marker->pos[0] = cb->marker_pos[0] / width; @@ -258,7 +258,7 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event) cb->marker->pattern_corners[a][1] *= scale_y; } - BKE_tracking_clamp_marker(cb->marker, CLAMP_PAT_DIM); + BKE_tracking_marker_clamp(cb->marker, CLAMP_PAT_DIM); ok = TRUE; } @@ -274,7 +274,7 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event) sub_v2_v2v2(cb->marker->search_min, delta, side); add_v2_v2v2(cb->marker->search_max, delta, side); - BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_POS); + BKE_tracking_marker_clamp(cb->marker, CLAMP_SEARCH_POS); ok = TRUE; } @@ -295,7 +295,7 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event) cb->marker->search_max[0] += dim[0]; cb->marker->search_max[1] += dim[1]; - BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_DIM); + BKE_tracking_marker_clamp(cb->marker, CLAMP_SEARCH_DIM); ok = TRUE; } @@ -364,7 +364,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P user = userptr->data; track = trackptr->data; - marker = BKE_tracking_get_marker(track, user->framenr); + marker = BKE_tracking_marker_get(track, user->framenr); cb = MEM_callocN(sizeof(MarkerUpdateCb), "uiTemplateMarker update_cb"); cb->compact = compact; diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c index 6576d2aeb01..716994f7487 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_ops.c +++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c @@ -93,10 +93,10 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *object = BKE_tracking_active_object(tracking); + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; MovieTrackingDopesheetChannel *channel; - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); float location[2]; int extend = RNA_boolean_get(op->ptr, "extend"); int current_channel_index = 0, channel_index; @@ -115,7 +115,7 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op) if (track->flag & TRACK_DOPE_SEL) { tracking->act_track = track; - BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, TRUE); + BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, TRUE); } } else if (!extend) diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 655a09ec90c..ec709443cfb 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -98,8 +98,8 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc float x; int *points, totseg, i, a; float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1); - MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking); - MovieTrackingReconstruction *reconstruction = BKE_tracking_get_reconstruction(&clip->tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking); + MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(&clip->tracking); glEnable(GL_BLEND); @@ -346,14 +346,14 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin start_frame = framenr = ED_space_clip_clip_framenr(sc); - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); if (marker->framenr != framenr || marker->flag & MARKER_DISABLED) return; a = count; i = framenr - 1; while (i >= framenr - count) { - marker = BKE_tracking_get_marker(track, i); + marker = BKE_tracking_marker_get(track, i); if (!marker || marker->flag & MARKER_DISABLED) break; @@ -375,7 +375,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin b = count; i = framenr; while (i <= framenr + count) { - marker = BKE_tracking_get_marker(track, i); + marker = BKE_tracking_marker_get(track, i); if (!marker || marker->flag & MARKER_DISABLED) break; @@ -943,7 +943,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, { float x, y; MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track, *act_track; MovieTrackingMarker *marker; int framenr = ED_space_clip_clip_framenr(sc); @@ -967,7 +967,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, glMultMatrixf(sc->stabmat); glScalef(width, height, 0); - act_track = BKE_tracking_active_track(tracking); + act_track = BKE_tracking_track_get_active(tracking); if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { int count = 0; @@ -976,7 +976,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) count++; @@ -993,7 +993,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { ED_clip_point_undistorted_pos(sc, marker->pos, fp); @@ -1025,7 +1025,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { copy_v2_v2(cur_pos, fp ? fp : marker->pos); @@ -1050,7 +1050,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { int act = track == act_track; - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (!act) { @@ -1071,7 +1071,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, /* active marker would be displayed on top of everything else */ if (act_track) { if ((act_track->flag & TRACK_HIDDEN) == 0) { - marker = BKE_tracking_get_marker(act_track, framenr); + marker = BKE_tracking_marker_get(act_track, framenr); if (MARKER_VISIBLE(sc, act_track, marker)) { copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos); @@ -1083,19 +1083,19 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, } if (sc->flag & SC_SHOW_BUNDLES) { - MovieTrackingObject *object = BKE_tracking_active_object(tracking); + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); float pos[4], vec[4], mat[4][4], aspy; glEnable(GL_POINT_SMOOTH); glPointSize(3.0f); aspy = 1.0f / clip->tracking.camera.pixel_aspect; - BKE_tracking_projection_matrix(tracking, object, framenr, width, height, mat); + BKE_tracking_get_projection_matrix(tracking, object, framenr, width, height, mat); track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) { - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float npos[2]; @@ -1107,7 +1107,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width; pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy; - BKE_tracking_apply_intrinsics(tracking, pos, npos); + BKE_tracking_distort_v2(tracking, pos, npos); if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) { vec[0] = (marker->pos[0] + track->offset[0]) * width; @@ -1145,7 +1145,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { int act = track == act_track; @@ -1215,7 +1215,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, for (i = 0; i <= n; i++) { for (j = 0; j <= n; j++) { if (i == 0 || j == 0 || i == n || j == n) { - BKE_tracking_apply_intrinsics(tracking, pos, tpos); + BKE_tracking_distort_v2(tracking, pos, tpos); for (a = 0; a < 4; a++) { int ok; @@ -1246,7 +1246,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, pos[0] = idx[a][0] * dx; pos[1] = idx[a][1] * dy; - BKE_tracking_invert_intrinsics(tracking, pos, tpos); + BKE_tracking_undistort_v2(tracking, pos, tpos); DO_MINMAX2(tpos, min, max); } @@ -1257,7 +1257,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, for (i = 0; i <= n; i++) { for (j = 0; j <= n; j++) { - BKE_tracking_apply_intrinsics(tracking, pos, grid[i][j]); + BKE_tracking_distort_v2(tracking, pos, grid[i][j]); grid[i][j][0] /= width; grid[i][j][1] /= height * aspy; @@ -1289,11 +1289,11 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, } if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { - MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); + MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking); if (track) { int framenr = sc->user.framenr; - MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr); offsx = marker->pos[0]; offsy = marker->pos[1]; @@ -1343,15 +1343,15 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, /* we want to distort only long straight lines */ if (stroke->totpoints == 2) { - BKE_tracking_invert_intrinsics(tracking, pos, pos); - BKE_tracking_invert_intrinsics(tracking, npos, npos); + BKE_tracking_undistort_v2(tracking, pos, pos); + BKE_tracking_undistort_v2(tracking, npos, npos); } sub_v2_v2v2(dpos, npos, pos); mul_v2_fl(dpos, 1.0f / steps); for (j = 0; j <= steps; j++) { - BKE_tracking_apply_intrinsics(tracking, pos, tpos); + BKE_tracking_distort_v2(tracking, pos, tpos); glVertex2f(tpos[0] / width, tpos[1] / (height * aspy)); add_v2_v2(pos, dpos); @@ -1410,7 +1410,7 @@ void clip_draw_main(SpaceClip *sc, ARegion *ar, Scene *scene) else copy_v2_v2(loc, sc->loc); - BKE_tracking_stabdata_to_mat4(width, height, aspect, loc, sc->scale, sc->angle, sc->stabmat); + BKE_tracking_stabilization_data_to_mat4(width, height, aspect, loc, sc->scale, sc->angle, sc->stabmat); unit_m4(smat); smat[0][0] = 1.0f / width; @@ -1463,12 +1463,12 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d) glMultMatrixf(sc->unistabmat); if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { - MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); + MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking); if (track) { int framenr = sc->user.framenr; /* don't get the exact marker since it may not exist for the frame */ - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (marker) { glTranslatef(marker->pos[0], marker->pos[1], 0.0f); } diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 30965362d37..275cb782bbd 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -342,7 +342,7 @@ static int selected_boundbox(SpaceClip *sc, float min[2], float max[2]) MovieClip *clip = ED_space_clip(sc); MovieTrackingTrack *track; int width, height, ok = FALSE; - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); INIT_MINMAX2(min, max); @@ -351,7 +351,7 @@ static int selected_boundbox(SpaceClip *sc, float min[2], float max[2]) track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track)) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, sc->user.framenr); if (marker) { float pos[3]; @@ -439,7 +439,7 @@ void ED_clip_point_undistorted_pos(SpaceClip *sc, const float co[2], float r_co[ r_co[0] *= width; r_co[1] *= height * aspy; - BKE_tracking_invert_intrinsics(&clip->tracking, r_co, r_co); + BKE_tracking_undistort_v2(&clip->tracking, r_co, r_co); r_co[0] /= width; r_co[1] /= height * aspy; @@ -474,7 +474,7 @@ void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *y float aspy = 1.0f / tracking->camera.pixel_aspect; float tmp[2] = {*xr * width, *yr * height * aspy}; - BKE_tracking_apply_intrinsics(tracking, tmp, tmp); + BKE_tracking_distort_v2(tracking, tmp, tmp); *xr = tmp[0] / width; *yr = tmp[1] / (height * aspy); diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index d3d01f9f87e..6290adf6620 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -148,7 +148,7 @@ static void draw_tracks_curves(View2D *v2d, SpaceClip *sc) { MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); int width, height; struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata; @@ -182,7 +182,7 @@ static void draw_frame_curves(SpaceClip *sc) { MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingReconstruction *reconstruction = BKE_tracking_get_reconstruction(tracking); + MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); int i, lines = 0, prevfra = 0; glColor3f(0.0f, 0.0f, 1.0f); diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index 64547d32889..b7687eba717 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -170,7 +170,7 @@ static int mouse_select_knot(bContext *C, float co[2], int extend) ARegion *ar = CTX_wm_region(C); View2D *v2d = &ar->v2d; MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); static const int delta = 6; if (act_track) { @@ -213,7 +213,7 @@ static int mouse_select_curve(bContext *C, float co[2], int extend) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); MouseSelectUserData userdata; mouse_select_init_data(&userdata, co); @@ -230,11 +230,11 @@ static int mouse_select_curve(bContext *C, float co[2], int extend) } else if (act_track != userdata.track) { SelectUserData selectdata = {SEL_DESELECT}; - MovieTrackingObject *object = BKE_tracking_active_object(tracking); - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); tracking->act_track = userdata.track; - BKE_tracking_select_track(tracksbase, userdata.track, TRACK_AREA_ALL, TRUE); + BKE_tracking_track_select(tracksbase, userdata.track, TRACK_AREA_ALL, TRUE); /* deselect all knots on newly selected curve */ clip_graph_tracking_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, @@ -347,7 +347,7 @@ static int border_select_graph_exec(bContext *C, wmOperator *op) ARegion *ar = CTX_wm_region(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); BorderSelectuserData userdata; rcti rect; @@ -402,7 +402,7 @@ static int graph_select_all_markers_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); MovieTrackingMarker *marker; int action = RNA_enum_get(op->ptr, "action"); int a; @@ -468,8 +468,8 @@ static int delete_curve_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); if (act_track) clip_delete_track(C, clip, tracksbase, act_track); @@ -500,8 +500,8 @@ static int delete_knot_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); if (act_track) { int a = 0; @@ -650,7 +650,7 @@ static int graph_disable_markers_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); MovieTrackingMarker *marker; int action = RNA_enum_get(op->ptr, "action"); int a; diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 73eb8ee77ff..d5ec65e68c7 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -986,7 +986,7 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog } if (build_undistort_count) - distortion = BKE_tracking_distortion_create(); + distortion = BKE_tracking_distortion_new(); for (cfra = sfra; cfra <= efra; cfra++) { if (clip->source != MCLIP_SRC_MOVIE) @@ -1003,7 +1003,7 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog } if (distortion) - BKE_tracking_distortion_destroy(distortion); + BKE_tracking_distortion_free(distortion); if (*stop) pj->stop = 1; diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 51870c6e43d..8dda1255e56 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -128,7 +128,7 @@ void clip_graph_tracking_values_iterate(SpaceClip *sc, int selected_only, int in { MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track; for (track = tracksbase->first; track; track = track->next) { @@ -147,7 +147,7 @@ void clip_graph_tracking_iterate(SpaceClip *sc, int selected_only, int include_h { MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track; for (track = tracksbase->first; track; track = track->next) { @@ -175,7 +175,7 @@ void clip_delete_track(bContext *C, MovieClip *clip, ListBase *tracksbase, Movie { MovieTracking *tracking = &clip->tracking; MovieTrackingStabilization *stab = &tracking->stabilization; - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); int has_bundle = FALSE, update_stab = FALSE; @@ -192,7 +192,7 @@ void clip_delete_track(bContext *C, MovieClip *clip, ListBase *tracksbase, Movie if (track->flag & TRACK_HAS_BUNDLE) has_bundle = TRUE; - BKE_tracking_free_track(track); + BKE_tracking_track_free(track); BLI_freelinkN(tracksbase, track); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); @@ -215,7 +215,7 @@ void clip_delete_marker(bContext *C, MovieClip *clip, ListBase *tracksbase, clip_delete_track(C, clip, tracksbase, track); } else { - BKE_tracking_delete_marker(track, marker->framenr); + BKE_tracking_marker_delete(track, marker->framenr); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); } diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 2f684f9e330..174b7fcb373 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -1084,7 +1084,7 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) /* if tracking is in progress, we should synchronize framenr from clipuser * so latest tracked frame would be shown */ if (clip && clip->tracking_context) - BKE_tracking_sync_user(&sc->user, clip->tracking_context); + BKE_tracking_context_sync_user(clip->tracking_context, &sc->user); if (sc->flag & SC_LOCK_SELECTION) { ImBuf *tmpibuf = NULL; diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 3a195805c53..f3a7d4ef57b 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -87,16 +87,16 @@ static void add_marker(SpaceClip *sc, float x, float y) { MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track; int width, height; int framenr = ED_space_clip_clip_framenr(sc); ED_space_clip_size(sc, &width, &height); - track = BKE_tracking_add_track(tracking, tracksbase, x, y, framenr, width, height); + track = BKE_tracking_track_add(tracking, tracksbase, x, y, framenr, width, height); - BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, 0); + BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, 0); clip->tracking.act_track = track; } @@ -164,7 +164,7 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track = tracksbase->first, *next; while (track) { @@ -204,7 +204,7 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); MovieTrackingTrack *track = tracksbase->first, *next; int framenr = ED_space_clip_clip_framenr(sc); int has_selection = 0; @@ -213,7 +213,7 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) next = track->next; if (TRACK_VIEW_SELECTED(sc, track)) { - MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr); if (marker) { has_selection |= track->markersnr > 1; @@ -276,7 +276,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra SlideMarkerData *data = MEM_callocN(sizeof(SlideMarkerData), "slide marker data"); int framenr = ED_space_clip_clip_framenr(sc); - marker = BKE_tracking_ensure_marker(track, framenr); + marker = BKE_tracking_marker_ensure(track, framenr); data->area = area; data->action = action; @@ -493,7 +493,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) int width, height; float co[2]; void *customdata = NULL; - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); int framenr = ED_space_clip_clip_framenr(sc); ED_space_clip_size(sc, &width, &height); @@ -506,7 +506,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if ((marker->flag & MARKER_DISABLED) == 0) { if (!customdata) { @@ -702,9 +702,9 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_DIM); + BKE_tracking_marker_clamp(data->marker, CLAMP_SEARCH_DIM); else - BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM); + BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM); } else if (data->action == SLIDE_ACTION_OFFSET) { float d[2] = {dx, dy}; @@ -723,7 +723,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_POS); + BKE_tracking_marker_clamp(data->marker, CLAMP_SEARCH_POS); } else if (data->action == SLIDE_ACTION_POS) { if (data->scale) { @@ -754,7 +754,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } /* currently only patterns are allowed to have such combination of event and data */ - BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM); + BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM); } } @@ -842,7 +842,7 @@ static int mouse_on_crns(float co[2], float pos[2], float crns[4][2], float epsx static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *track) { int framenr = ED_space_clip_clip_framenr(sc); - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); float pat_min[2], pat_max[2]; float epsx, epsy; int width, height; @@ -920,7 +920,7 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbas cur = tracksbase->first; while (cur) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(cur, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(cur, framenr); if (((cur->flag & TRACK_HIDDEN) == 0) && MARKER_VISIBLE(sc, cur, marker)) { float dist, d1, d2 = FLT_MAX, d3 = FLT_MAX; @@ -957,8 +957,8 @@ static int mouse_select(bContext *C, float co[2], int extend) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); MovieTrackingTrack *track = NULL; /* selected marker */ track = find_nearest_track(sc, tracksbase, co); @@ -971,7 +971,7 @@ static int mouse_select(bContext *C, float co[2], int extend) if (extend && TRACK_AREA_SELECTED(track, area)) { if (track == act_track) - BKE_tracking_deselect_track(track, area); + BKE_tracking_track_deselect(track, area); else clip->tracking.act_track = track; } @@ -979,7 +979,7 @@ static int mouse_select(bContext *C, float co[2], int extend) if (area == TRACK_AREA_POINT) area = TRACK_AREA_ALL; - BKE_tracking_select_track(tracksbase, track, area, extend); + BKE_tracking_track_select(tracksbase, track, area, extend); clip->tracking.act_track = track; } } @@ -1066,7 +1066,7 @@ static int border_select_exec(bContext *C, wmOperator *op) MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); rcti rect; rctf rectf; int change = FALSE, mode, extend; @@ -1088,14 +1088,17 @@ static int border_select_exec(bContext *C, wmOperator *op) track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (BLI_in_rctf(&rectf, marker->pos[0], marker->pos[1])) { - BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode != GESTURE_MODAL_SELECT); + if (mode == GESTURE_MODAL_SELECT) + BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); + else + BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } else if (!extend) { - BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, 1); + BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } change = TRUE; @@ -1144,7 +1147,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); rcti rect; int change = FALSE; int framenr = ED_space_clip_clip_framenr(sc); @@ -1156,7 +1159,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float screen_co[2]; @@ -1167,7 +1170,10 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho if (BLI_in_rcti(&rect, screen_co[0], screen_co[1]) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED)) { - BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, !select); + if (select) + BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); + else + BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } change = TRUE; @@ -1247,7 +1253,7 @@ static int circle_select_exec(bContext *C, wmOperator *op) ARegion *ar = CTX_wm_region(C); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); int x, y, radius, width, height, mode, change = FALSE; float zoomx, zoomy, offset[2], ellipse[2]; int framenr = ED_space_clip_clip_framenr(sc); @@ -1272,10 +1278,13 @@ static int circle_select_exec(bContext *C, wmOperator *op) track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) { - BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode != GESTURE_MODAL_SELECT); + if (mode == GESTURE_MODAL_SELECT) + BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); + else + BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); change = TRUE; } @@ -1327,7 +1336,7 @@ static int select_all_exec(bContext *C, wmOperator *op) MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track = NULL; /* selected track */ MovieTrackingMarker *marker; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); int action = RNA_enum_get(op->ptr, "action"); int framenr = ED_space_clip_clip_framenr(sc); int has_selection = FALSE; @@ -1337,7 +1346,7 @@ static int select_all_exec(bContext *C, wmOperator *op) track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track)) { - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { action = SEL_DESELECT; @@ -1352,7 +1361,7 @@ static int select_all_exec(bContext *C, wmOperator *op) track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { switch (action) { @@ -1417,7 +1426,7 @@ static int select_groped_exec(bContext *C, wmOperator *op) MovieTrackingTrack *track; MovieTrackingMarker *marker; MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); int group = RNA_enum_get(op->ptr, "group"); int framenr = ED_space_clip_clip_framenr(sc); @@ -1425,7 +1434,7 @@ static int select_groped_exec(bContext *C, wmOperator *op) while (track) { int ok = FALSE; - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); if (group == 0) { /* Keyframed */ ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED) == 0; @@ -1443,7 +1452,7 @@ static int select_groped_exec(bContext *C, wmOperator *op) ok = marker->flag & MARKER_DISABLED; } else if (group == 5) { /* color */ - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); if (act_track) { ok = (track->flag & TRACK_CUSTOMCOLOR) == (act_track->flag & TRACK_CUSTOMCOLOR); @@ -1525,14 +1534,14 @@ static int track_markers_testbreak(void) static int track_count_markers(SpaceClip *sc, MovieClip *clip) { int tot = 0; - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); MovieTrackingTrack *track; int framenr = ED_space_clip_clip_framenr(sc); track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (!marker || (marker->flag & MARKER_DISABLED) == 0) tot++; @@ -1546,7 +1555,7 @@ static int track_count_markers(SpaceClip *sc, MovieClip *clip) static void clear_invisible_track_selection(SpaceClip *sc, MovieClip *clip) { - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); int hidden = 0; if ((sc->flag & SC_SHOW_MARKER_PATTERN) == 0) @@ -1560,7 +1569,7 @@ static void clear_invisible_track_selection(SpaceClip *sc, MovieClip *clip) while (track) { if ((track->flag & TRACK_HIDDEN) == 0) - BKE_tracking_track_flag(track, hidden, SELECT, 1); + BKE_tracking_track_flag_clear(track, hidden, SELECT); track = track->next; } @@ -1569,7 +1578,7 @@ static void clear_invisible_track_selection(SpaceClip *sc, MovieClip *clip) static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit_r) { - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); MovieTrackingTrack *track; int framenr = ED_space_clip_clip_framenr(sc); int frames_limit = 0; @@ -1580,7 +1589,7 @@ static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit while (track) { if (TRACK_VIEW_SELECTED(sc, track)) { if ((track->flag & TRACK_HIDDEN) == 0 && (track->flag & TRACK_LOCKED) == 0) { - BKE_tracking_ensure_marker(track, framenr); + BKE_tracking_marker_ensure(track, framenr); if (track->frames_limit) { if (frames_limit == 0) @@ -1685,14 +1694,14 @@ static void track_markers_startjob(void *tmv, short *stop, short *do_update, flo double start_time = PIL_check_seconds_timer(), exec_time; - if (!BKE_tracking_next(tmj->context)) + if (!BKE_tracking_context_step(tmj->context)) break; exec_time = PIL_check_seconds_timer() - start_time; if (tmj->delay > (float)exec_time) PIL_sleep_ms(tmj->delay - (float)exec_time); } - else if (!BKE_tracking_next(tmj->context)) + else if (!BKE_tracking_context_step(tmj->context)) break; *do_update = TRUE; @@ -1716,7 +1725,7 @@ static void track_markers_updatejob(void *tmv) { TrackMarkersJob *tmj = (TrackMarkersJob *)tmv; - BKE_tracking_sync(tmj->context); + BKE_tracking_context_sync(tmj->context); } static void track_markers_freejob(void *tmv) @@ -1727,7 +1736,7 @@ static void track_markers_freejob(void *tmv) tmj->scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(tmj->clip, tmj->lastfra); ED_update_for_newframe(tmj->main, tmj->scene, 0); - BKE_tracking_sync(tmj->context); + BKE_tracking_context_sync(tmj->context); BKE_tracking_context_free(tmj->context); MEM_freeN(tmj); @@ -1774,7 +1783,7 @@ static int track_markers_exec(bContext *C, wmOperator *op) context = BKE_tracking_context_new(clip, &sc->user, backwards, sequence); while (framenr != efra) { - if (!BKE_tracking_next(context)) + if (!BKE_tracking_context_step(context)) break; if (backwards) framenr--; @@ -1784,7 +1793,7 @@ static int track_markers_exec(bContext *C, wmOperator *op) break; } - BKE_tracking_sync(context); + BKE_tracking_context_sync(context); BKE_tracking_context_free(context); /* update scene current frame to the lastes tracked frame */ @@ -1911,10 +1920,10 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op Scene *scene = CTX_data_scene(C); MovieTracking *tracking = &clip->tracking; MovieTrackingSettings *settings = &clip->tracking.settings; - MovieTrackingObject *object = BKE_tracking_active_object(tracking); + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); int width, height; - if (!BKE_tracking_can_reconstruct(tracking, object, error_msg, max_error)) + if (!BKE_tracking_reconstruction_check(tracking, object, error_msg, max_error)) return 0; /* could fail if footage uses images with different sizes */ @@ -1945,7 +1954,7 @@ static void solve_camera_startjob(void *scv, short *stop, short *do_update, floa { SolveCameraJob *scj = (SolveCameraJob *)scv; - BKE_tracking_solve_reconstruction(scj->context, stop, do_update, progress, + BKE_tracking_reconstruction_solve(scj->context, stop, do_update, progress, scj->stats_message, sizeof(scj->stats_message)); } @@ -1963,7 +1972,7 @@ static void solve_camera_freejob(void *scv) return; } - solved = BKE_tracking_finish_reconstruction(scj->context, tracking); + solved = BKE_tracking_reconstruction_finish(scj->context, tracking); if (!solved) BKE_report(scj->reports, RPT_WARNING, "Some data failed to reconstruct, see console for details"); @@ -2033,7 +2042,7 @@ static int solve_camera_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingReconstruction *reconstruction = BKE_tracking_get_reconstruction(tracking); + MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); wmJob *steve; char error_msg[256] = "\0"; @@ -2115,8 +2124,8 @@ static int clear_solution_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); - MovieTrackingReconstruction *reconstruction = BKE_tracking_get_reconstruction(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); + MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); MovieTrackingTrack *track = tracksbase->first; while (track) { @@ -2163,20 +2172,20 @@ static int clear_track_path_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTrackingTrack *track; - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); int action = RNA_enum_get(op->ptr, "action"); int clear_active = RNA_boolean_get(op->ptr, "clear_active"); int framenr = ED_space_clip_clip_framenr(sc); if (clear_active) { - track = BKE_tracking_active_track(&clip->tracking); - BKE_tracking_clear_path(track, framenr, action); + track = BKE_tracking_track_get_active(&clip->tracking); + BKE_tracking_track_path_clear(track, framenr, action); } else { track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track)) - BKE_tracking_clear_path(track, framenr, action); + BKE_tracking_track_path_clear(track, framenr, action); track = track->next; } @@ -2220,14 +2229,14 @@ static int disable_markers_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track = tracksbase->first; int action = RNA_enum_get(op->ptr, "action"); int framenr = ED_space_clip_clip_framenr(sc); while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_ensure(track, framenr); if (action == 0) marker->flag |= MARKER_DISABLED; @@ -2302,7 +2311,7 @@ static Object *get_orientation_object(bContext *C) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); + MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); Object *object = NULL; if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { @@ -2328,7 +2337,7 @@ static int set_orientation_poll(bContext *C) if (clip) { MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); + MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { return TRUE; @@ -2346,7 +2355,7 @@ static int count_selected_bundles(bContext *C) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); MovieTrackingTrack *track; int tot = 0; @@ -2440,9 +2449,9 @@ static int set_origin_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - tracking_object = BKE_tracking_active_object(tracking); + tracking_object = BKE_tracking_object_get_active(tracking); - tracksbase = BKE_tracking_object_tracks(tracking, tracking_object); + tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); track = tracksbase->first; zero_v3(median); @@ -2455,7 +2464,7 @@ static int set_origin_exec(bContext *C, wmOperator *op) } mul_v3_fl(median, 1.0f / selected_count); - BKE_get_tracking_mat(scene, camera, mat); + BKE_tracking_get_camera_object_matrix(scene, camera, mat); mul_v3_m4v3(vec, mat, median); @@ -2507,7 +2516,7 @@ static void set_axis(Scene *scene, Object *ob, MovieClip *clip, MovieTrackingOb BKE_object_to_mat4(ob, obmat); - BKE_get_tracking_mat(scene, camera, mat); + BKE_tracking_get_camera_object_matrix(scene, camera, mat); mul_v3_m4v3(vec, mat, track->bundle_pos); copy_v3_v3(dvec, vec); @@ -2633,9 +2642,9 @@ static int set_plane_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - tracking_object = BKE_tracking_active_object(tracking); - tracksbase = BKE_tracking_object_tracks(tracking, tracking_object); - act_track = BKE_tracking_active_track(tracking); + tracking_object = BKE_tracking_object_get_active(tracking); + tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); + act_track = BKE_tracking_track_get_active(tracking); object = get_orientation_object(C); if (!object) { @@ -2644,7 +2653,7 @@ static int set_plane_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BKE_get_tracking_mat(scene, camera, mat); + BKE_tracking_get_camera_object_matrix(scene, camera, mat); /* get 3 bundles to use as reference */ track = tracksbase->first; @@ -2751,7 +2760,7 @@ static int set_axis_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); + MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); MovieTrackingTrack *track; Scene *scene = CTX_data_scene(C); Object *object; @@ -2771,7 +2780,7 @@ static int set_axis_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - tracksbase = BKE_tracking_object_tracks(tracking, tracking_object); + tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); track = tracksbase->first; while (track) { @@ -2823,12 +2832,12 @@ static int do_set_scale(bContext *C, wmOperator *op, int scale_solution) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); + MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); MovieTrackingTrack *track; Scene *scene = CTX_data_scene(C); Object *object = NULL; Object *camera = get_camera_with_movieclip(scene, clip); - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); int tot = 0; float vec[2][3], mat[4][4], scale; float dist = RNA_float_get(op->ptr, "distance"); @@ -2846,7 +2855,7 @@ static int do_set_scale(bContext *C, wmOperator *op, int scale_solution) return OPERATOR_CANCELLED; } - BKE_get_tracking_mat(scene, camera, mat); + BKE_tracking_get_camera_object_matrix(scene, camera, mat); track = tracksbase->first; while (track) { @@ -2941,7 +2950,7 @@ static int set_solution_scale_poll(bContext *C) if (clip) { MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); + MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); return (tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0; } @@ -3030,8 +3039,8 @@ static int hide_tracks_exec(bContext *C, wmOperator *op) MovieClip *clip = ED_space_clip(sc); MovieTrackingTrack *track; MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); int unselected; unselected = RNA_boolean_get(op->ptr, "unselected"); @@ -3088,7 +3097,7 @@ static int hide_tracks_clear_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track; track = tracksbase->first; @@ -3147,7 +3156,7 @@ static int detect_features_exec(bContext *C, wmOperator *op) int clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS; ImBuf *ibuf = BKE_movieclip_get_ibuf_flag(clip, &sc->user, clip_flag, MOVIECLIP_CACHE_SKIP); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track = tracksbase->first; int placement = RNA_enum_get(op->ptr, "placement"); int margin = RNA_int_get(op->ptr, "margin"); @@ -3226,7 +3235,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) int delta; if (pos <= 1) { /* jump to path */ - track = BKE_tracking_active_track(&clip->tracking); + track = BKE_tracking_track_get_active(&clip->tracking); if (!track) return OPERATOR_CANCELLED; @@ -3235,7 +3244,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) while (sc->user.framenr + delta >= SFRA && sc->user.framenr + delta <= EFRA) { int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr + delta); - MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr); if (!marker || marker->flag & MARKER_DISABLED) break; @@ -3247,7 +3256,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) if (clip->tracking.reconstruction.flag & TRACKING_RECONSTRUCTED) { int a = ED_space_clip_clip_framenr(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *object = BKE_tracking_active_object(tracking); + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); delta = pos == 3 ? 1 : -1; @@ -3256,7 +3265,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) while (a + delta >= SFRA && a + delta <= EFRA) { MovieReconstructedCamera *cam; - cam = BKE_tracking_get_reconstructed_camera(tracking, object, a); + cam = BKE_tracking_camera_get_reconstructed(tracking, object, a); if (!cam) { sc->user.framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, a); @@ -3314,10 +3323,10 @@ static int join_tracks_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *act_track, *track, *next; - act_track = BKE_tracking_active_track(tracking); + act_track = BKE_tracking_track_get_active(tracking); if (!act_track) { BKE_report(op->reports, RPT_ERROR, "No active track to join to"); @@ -3329,12 +3338,12 @@ static int join_tracks_exec(bContext *C, wmOperator *op) next = track->next; if (TRACK_VIEW_SELECTED(sc, track) && track != act_track) { - BKE_tracking_join_tracks(act_track, track); + BKE_tracking_tracks_join(act_track, track); if (tracking->stabilization.rot_track == track) tracking->stabilization.rot_track = act_track; - BKE_tracking_free_track(track); + BKE_tracking_track_free(track); BLI_freelinkN(tracksbase, track); } @@ -3368,7 +3377,7 @@ static int lock_tracks_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track = tracksbase->first; int action = RNA_enum_get(op->ptr, "action"); @@ -3421,8 +3430,8 @@ static int track_copy_color_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); - MovieTrackingTrack *track, *act_track = BKE_tracking_active_track(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + MovieTrackingTrack *track, *act_track = BKE_tracking_track_get_active(tracking); if (!act_track) return OPERATOR_CANCELLED; @@ -3468,7 +3477,7 @@ static int stabilize_2d_add_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track; MovieTrackingStabilization *stab = &tracking->stabilization; int update = 0; @@ -3518,7 +3527,7 @@ static int stabilize_2d_remove_exec(bContext *C, wmOperator *UNUSED(op)) MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingStabilization *stab = &tracking->stabilization; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track; int a = 0, update = 0; @@ -3577,14 +3586,14 @@ static int stabilize_2d_select_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); MovieTrackingTrack *track; int update = 0; track = tracksbase->first; while (track) { if (track->flag & TRACK_USE_2D_STAB) { - BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, 0); + BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); update = 1; } @@ -3620,7 +3629,7 @@ static int stabilize_2d_set_rotation_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); if (act_track) { MovieTrackingStabilization *stab = &tracking->stabilization; @@ -3750,8 +3759,8 @@ static int clean_tracks_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_tracks(tracking); - MovieTrackingTrack *track, *next, *act_track = BKE_tracking_active_track(tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + MovieTrackingTrack *track, *next, *act_track = BKE_tracking_track_get_active(tracking); int frames = RNA_int_get(op->ptr, "frames"); int action = RNA_enum_get(op->ptr, "action"); float error = RNA_float_get(op->ptr, "error"); @@ -3771,13 +3780,13 @@ static int clean_tracks_exec(bContext *C, wmOperator *op) if (!ok) { if (action == TRACKING_CLEAN_SELECT) { - BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, 0); + BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); } else if (action == TRACKING_CLEAN_DELETE_TRACK) { if (track == act_track) clip->tracking.act_track = NULL; - BKE_tracking_free_track(track); + BKE_tracking_track_free(track); BLI_freelinkN(tracksbase, track); track = NULL; } @@ -3787,7 +3796,7 @@ static int clean_tracks_exec(bContext *C, wmOperator *op) if (track == act_track) clip->tracking.act_track = NULL; - BKE_tracking_free_track(track); + BKE_tracking_track_free(track); BLI_freelinkN(tracksbase, track); } } @@ -3856,7 +3865,7 @@ static int tracking_object_new_exec(bContext *C, wmOperator *UNUSED(op)) MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - BKE_tracking_new_object(tracking, "Object"); + BKE_tracking_object_add(tracking, "Object"); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); @@ -3887,14 +3896,14 @@ static int tracking_object_remove_exec(bContext *C, wmOperator *op) MovieTracking *tracking = &clip->tracking; MovieTrackingObject *object; - object = BKE_tracking_active_object(tracking); + object = BKE_tracking_object_get_active(tracking); if (object->flag & TRACKING_OBJECT_CAMERA) { BKE_report(op->reports, RPT_WARNING, "Object used for camera tracking can't be deleted"); return OPERATOR_CANCELLED; } - BKE_tracking_remove_object(tracking, object); + BKE_tracking_object_delete(tracking, object); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); @@ -3923,7 +3932,7 @@ static int copy_tracks_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *object = BKE_tracking_active_object(tracking); + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); clear_invisible_track_selection(sc, clip); @@ -3963,7 +3972,7 @@ static int paste_tracks_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *object = BKE_tracking_active_object(tracking); + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); BKE_tracking_clipboard_paste_tracks(tracking, object); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 15473492b9d..b92d3d9d24c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1566,12 +1566,12 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D float mat[4][4], imat[4][4]; unsigned char col[4], scol[4]; int tracknr = *global_track_index; - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, tracking_object); + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); UI_GetThemeColor4ubv(TH_TEXT, col); UI_GetThemeColor4ubv(TH_SELECT, scol); - BKE_get_tracking_mat(scene, base->object, mat); + BKE_tracking_get_camera_object_matrix(scene, base->object, mat); glPushMatrix(); @@ -1587,7 +1587,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D else { float obmat[4][4]; - BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, obmat); + BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, scene->r.cfra, obmat); invert_m4_m4(imat, obmat); glMultMatrixf(imat); @@ -1685,7 +1685,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D if ((dflag & DRAW_PICKING) == 0) { if ((v3d->flag2 & V3D_SHOW_CAMERAPATH) && (tracking_object->flag & TRACKING_OBJECT_CAMERA)) { MovieTrackingReconstruction *reconstruction; - reconstruction = BKE_tracking_object_reconstruction(tracking, tracking_object); + reconstruction = BKE_tracking_object_get_reconstruction(tracking, tracking_object); if (reconstruction->camnr) { MovieReconstructedCamera *camera = reconstruction->cameras; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index d2f2fdcaa81..f9ebd4e39c1 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1303,11 +1303,11 @@ static void deselect_all_tracks(MovieTracking *tracking) object = tracking->objects.first; while (object) { - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); MovieTrackingTrack *track = tracksbase->first; while (track) { - BKE_tracking_deselect_track(track, TRACK_AREA_ALL); + BKE_tracking_track_deselect(track, TRACK_AREA_ALL); track = track->next; } @@ -1408,18 +1408,18 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese ListBase *tracksbase; MovieTrackingTrack *track; - track = BKE_tracking_indexed_track(&clip->tracking, hitresult >> 16, &tracksbase); + track = BKE_tracking_track_get_indexed(&clip->tracking, hitresult >> 16, &tracksbase); if (TRACK_SELECTED(track) && extend) { changed = 0; - BKE_tracking_deselect_track(track, TRACK_AREA_ALL); + BKE_tracking_track_deselect(track, TRACK_AREA_ALL); } else { int oldsel = TRACK_SELECTED(track) ? 1 : 0; if (!extend) deselect_all_tracks(tracking); - BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, extend); + BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, extend); if (oldsel != (TRACK_SELECTED(track) ? 1 : 0)) changed = 1; diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 5af1829af5a..1991d4bce4f 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -831,12 +831,12 @@ static void bundle_midpoint(Scene *scene, Object *ob, float vec[3]) copy_m4_m4(cammat, ob->obmat); - BKE_get_tracking_mat(scene, ob, mat); + BKE_tracking_get_camera_object_matrix(scene, ob, mat); INIT_MINMAX(min, max); for (object = tracking->objects.first; object; object = object->next) { - ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); MovieTrackingTrack *track = tracksbase->first; float obmat[4][4]; @@ -846,7 +846,7 @@ static void bundle_midpoint(Scene *scene, Object *ob, float vec[3]) else { float imat[4][4]; - BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, imat); + BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, scene->r.cfra, imat); invert_m4(imat); mult_m4_m4m4(obmat, cammat, imat); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 5a38bf607d9..fbc59f4c2cb 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5654,7 +5654,7 @@ static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d, TransDataTracking *tdt, MovieTrackingTrack *track, float aspx, float aspy) { int framenr = ED_space_clip_clip_framenr(sc); - MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_ensure(track, framenr); tdt->flag = marker->flag; marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED); @@ -5703,7 +5703,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) TransData2D *td2d; SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); MovieTrackingTrack *track; MovieTrackingMarker *marker; TransDataTracking *tdt; @@ -5716,7 +5716,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); t->total++; /* offset */ @@ -5748,7 +5748,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); trackToTransData(sc, td, td2d, tdt, track, aspx, aspy); @@ -5831,7 +5831,7 @@ static void createTransTrackingCurvesData(bContext *C, TransInfo *t) TransData2D *td2d; SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); MovieTrackingTrack *track; MovieTrackingMarker *marker, *prev_marker; TransDataTracking *tdt; @@ -5932,7 +5932,7 @@ static void cancelTransTracking(TransInfo *t) TransDataTracking *tdt = t->customData; SpaceClip *sc = t->sa->spacedata.first; MovieClip *clip = ED_space_clip(sc); - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); MovieTrackingTrack *track; MovieTrackingMarker *marker; int a, framenr = ED_space_clip_clip_framenr(sc); @@ -5941,7 +5941,7 @@ static void cancelTransTracking(TransInfo *t) track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - marker = BKE_tracking_get_marker(track, framenr); + marker = BKE_tracking_marker_get(track, framenr); marker->flag = tdt->flag; tdt++; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 8682b866742..b7857be5afb 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -641,7 +641,7 @@ static void recalcData_spaceclip(TransInfo *t) if (ED_space_clip_show_trackedit(sc)) { MovieClip *clip = ED_space_clip(sc); - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); MovieTrackingTrack *track; int framenr = sc->user.framenr; @@ -650,23 +650,23 @@ static void recalcData_spaceclip(TransInfo *t) track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (t->mode == TFM_TRANSLATION) { if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_marker(marker, CLAMP_PAT_POS); + BKE_tracking_marker_clamp(marker, CLAMP_PAT_POS); if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) - BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_POS); + BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_POS); } else if (t->mode == TFM_RESIZE) { if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_marker(marker, CLAMP_PAT_DIM); + BKE_tracking_marker_clamp(marker, CLAMP_PAT_DIM); if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) - BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_DIM); + BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_DIM); } else if (t->mode == TFM_ROTATION) { if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_marker(marker, CLAMP_PAT_POS); + BKE_tracking_marker_clamp(marker, CLAMP_PAT_POS); } } diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index c74b5569857..85dee2617d8 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -126,7 +126,7 @@ static void rna_tracking_active_object_index_range(PointerRNA *ptr, int *min, in static PointerRNA rna_tracking_active_track_get(PointerRNA *ptr) { MovieClip *clip = (MovieClip *)ptr->id.data; - MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking); return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingTrack, act_track); } @@ -135,7 +135,7 @@ static void rna_tracking_active_track_set(PointerRNA *ptr, PointerRNA value) { MovieClip *clip = (MovieClip *)ptr->id.data; MovieTrackingTrack *track = (MovieTrackingTrack *)value.data; - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); int index = BLI_findindex(tracksbase, track); if (index >= 0) @@ -169,7 +169,7 @@ void rna_trackingTrack_name_set(PointerRNA *ptr, const char *value) } } - BKE_track_unique_name(tracksbase, track); + BKE_tracking_track_unique_name(tracksbase, track); } static int rna_trackingTrack_select_get(PointerRNA *ptr) @@ -363,8 +363,8 @@ static void rna_trackingMarker_frame_set(PointerRNA *ptr, int value) MovieTrackingMarker new_marker = *marker; new_marker.framenr = value; - BKE_tracking_delete_marker(track, marker->framenr); - BKE_tracking_insert_marker(track, &new_marker); + BKE_tracking_marker_delete(track, marker->framenr); + BKE_tracking_marker_insert(track, &new_marker); } } @@ -372,14 +372,14 @@ static void rna_tracking_markerPattern_update(Main *UNUSED(bmain), Scene *UNUSED { MovieTrackingMarker *marker = (MovieTrackingMarker *)ptr->data; - BKE_tracking_clamp_marker(marker, CLAMP_PAT_DIM); + BKE_tracking_marker_clamp(marker, CLAMP_PAT_DIM); } static void rna_tracking_markerSearch_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { MovieTrackingMarker *marker = (MovieTrackingMarker *)ptr->data; - BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_DIM); + BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_DIM); } static void rna_trackingDopesheet_tagUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) @@ -402,7 +402,7 @@ static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBas BKE_movieclip_get_size(clip, &user, &width, &height); for (a = 0; a < number; a++) - BKE_tracking_add_track(tracking, tracksbase, 0, 0, frame, width, height); + BKE_tracking_track_add(tracking, tracksbase, 0, 0, frame, width, height); } static void rna_trackingTracks_add(ID *id, MovieTracking *tracking, int frame, int number) @@ -429,7 +429,7 @@ static void rna_trackingObject_tracks_add(ID *id, MovieTrackingObject *object, i static MovieTrackingObject *rna_trackingObject_new(MovieTracking *tracking, const char *name) { - MovieTrackingObject *object = BKE_tracking_new_object(tracking, name); + MovieTrackingObject *object = BKE_tracking_object_add(tracking, name); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); @@ -438,14 +438,14 @@ static MovieTrackingObject *rna_trackingObject_new(MovieTracking *tracking, cons void rna_trackingObject_remove(MovieTracking *tracking, MovieTrackingObject *object) { - BKE_tracking_remove_object(tracking, object); + BKE_tracking_object_delete(tracking, object); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); } static MovieTrackingMarker *rna_trackingMarkers_find_frame(MovieTrackingTrack *track, int framenr) { - return BKE_tracking_exact_marker(track, framenr); + return BKE_tracking_marker_get_exact(track, framenr); } static MovieTrackingMarker *rna_trackingMarkers_insert_frame(MovieTrackingTrack *track, int framenr, float *co) @@ -456,7 +456,7 @@ static MovieTrackingMarker *rna_trackingMarkers_insert_frame(MovieTrackingTrack marker.framenr = framenr; copy_v2_v2(marker.pos, co); - new_marker = BKE_tracking_insert_marker(track, &marker); + new_marker = BKE_tracking_marker_insert(track, &marker); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); @@ -468,7 +468,7 @@ void rna_trackingMarkers_delete_frame(MovieTrackingTrack *track, int framenr) if (track->markersnr == 1) return; - BKE_tracking_delete_marker(track, framenr); + BKE_tracking_marker_delete(track, framenr); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); } diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 457322929b0..5813f4d479f 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -222,7 +222,7 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree) copied back to original node */ if (lnode->storage) { if (lnode->new_node->storage) - BKE_tracking_distortion_destroy(lnode->new_node->storage); + BKE_tracking_distortion_free(lnode->new_node->storage); lnode->new_node->storage= BKE_tracking_distortion_copy(lnode->storage); } diff --git a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c index 6149285fdbc..73423e2bdd3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c +++ b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c @@ -67,15 +67,15 @@ static void compute_gradient_screen(RenderData *rd, NodeKeyingScreenData *keying float *rect = screenbuf->rect; if (keyingscreen_data->tracking_object[0]) { - MovieTrackingObject *object = BKE_tracking_named_object(tracking, keyingscreen_data->tracking_object); + MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, keyingscreen_data->tracking_object); if (!object) return; - tracksbase = BKE_tracking_object_tracks(tracking, object); + tracksbase = BKE_tracking_object_get_tracks(tracking, object); } else - tracksbase = BKE_tracking_get_tracks(tracking); + tracksbase = BKE_tracking_get_active_tracks(tracking); sites_total = BLI_countlist(tracksbase); @@ -90,7 +90,7 @@ static void compute_gradient_screen(RenderData *rd, NodeKeyingScreenData *keying i = 0; while (track) { VoronoiSite *site = &sites[i]; - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, rd->cfra); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, rd->cfra); ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE); int j; diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.c b/source/blender/nodes/composite/nodes/node_composite_movieclip.c index 9f5a7e67c96..dfd36c3990a 100644 --- a/source/blender/nodes/composite/nodes/node_composite_movieclip.c +++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.c @@ -121,7 +121,7 @@ static void node_composit_exec_movieclip(void *data, bNode *node, bNodeStack **U if (stab->flag & TRACKING_2D_STABILIZATION) { float loc[2], scale, angle; - BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, stackbuf->x, stackbuf->y, + BKE_tracking_stabilization_data_get(&clip->tracking, rd->cfra, stackbuf->x, stackbuf->y, loc, &scale, &angle); out[1]->vec[0] = loc[0]; diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c index 5def9c41e19..65fe3b251d0 100644 --- a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c +++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c @@ -73,7 +73,7 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) BKE_movieclip_get_size(clip, &user, &width, &height); if (!node->storage) - node->storage = BKE_tracking_distortion_create(); + node->storage = BKE_tracking_distortion_new(); if (node->custom1 == 0) obuf = BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 1); @@ -116,7 +116,7 @@ static const char *label(bNode *node) static void storage_free(bNode *node) { if (node->storage) - BKE_tracking_distortion_destroy(node->storage); + BKE_tracking_distortion_free(node->storage); node->storage = NULL; } diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c index 9ed04ab165c..44582d6de33 100644 --- a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c +++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c @@ -54,7 +54,7 @@ static void node_composit_exec_stabilize2d(void *data, bNode *node, bNodeStack * CompBuf *stackbuf; float loc[2], scale, angle; - BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, cbuf->x, cbuf->y, loc, &scale, &angle); + BKE_tracking_stabilization_data_get(&clip->tracking, rd->cfra, cbuf->x, cbuf->y, loc, &scale, &angle); stackbuf = node_composit_transform(cbuf, loc[0], loc[1], angle, scale, node->custom1); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index c82cae8ac92..431094c9ec4 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -373,7 +373,7 @@ void WM_exit_ext(bContext *C, const short do_python) wm_free_reports(C); /* before free_blender! - since the ListBases get freed there */ seq_free_clipboard(); /* sequencer.c */ - BKE_tracking_free_clipboard(); + BKE_tracking_clipboard_free(); free_blender(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); From 8da0a03774aa00c738b0e95126cd09affa131b17 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 11:15:48 +0000 Subject: [PATCH 339/360] 2D stabilization didn't work since clip start frame commit --- source/blender/blenkernel/intern/movieclip.c | 6 ++++-- source/blender/blenkernel/intern/tracking.c | 2 ++ source/blender/compositor/nodes/COM_MovieClipNode.cpp | 4 +++- .../operations/COM_MovieClipAttributeOperation.cpp | 4 +++- .../nodes/composite/nodes/node_composite_movieclip.c | 3 ++- .../nodes/composite/nodes/node_composite_stabilize2d.c | 3 ++- 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 52c9ec4cb59..68adb599c6c 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -773,6 +773,7 @@ static ImBuf *get_stable_cached_frame(MovieClip *clip, MovieClipUser *user, int float tloc[2], tscale, tangle; short proxy = IMB_PROXY_NONE; int render_flag = 0; + int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, framenr); if (clip->flag & MCLIP_USE_PROXY) { proxy = rendersize_to_proxy(user, clip->flag); @@ -799,7 +800,7 @@ static ImBuf *get_stable_cached_frame(MovieClip *clip, MovieClipUser *user, int stableibuf = cache->stabilized.ibuf; - BKE_tracking_stabilization_data_get(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle); + BKE_tracking_stabilization_data_get(&clip->tracking, clip_framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle); /* check for stabilization parameters */ if (tscale != cache->stabilized.scale || @@ -821,11 +822,12 @@ static ImBuf *put_stabilized_frame_to_cache(MovieClip *clip, MovieClipUser *user MovieTracking *tracking = &clip->tracking; ImBuf *stableibuf; float tloc[2], tscale, tangle; + int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, framenr); if (cache->stabilized.ibuf) IMB_freeImBuf(cache->stabilized.ibuf); - stableibuf = BKE_tracking_stabilize_frame(&clip->tracking, framenr, ibuf, tloc, &tscale, &tangle); + stableibuf = BKE_tracking_stabilize_frame(&clip->tracking, clip_framenr, ibuf, tloc, &tscale, &tangle); cache->stabilized.ibuf = stableibuf; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 43fe94d625b..dfe71c48536 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -3301,6 +3301,7 @@ static ImBuf *stabilization_allocate_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int return cacheibuf; } +/* NOTE: frame number should be in clip space, not scene space */ void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle) { @@ -3340,6 +3341,7 @@ void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, i } } +/* NOTE: frame number should be in clip space, not scene space */ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf *ibuf, float loc[2], float *scale, float *angle) { diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.cpp b/source/blender/compositor/nodes/COM_MovieClipNode.cpp index 6a325d7d885..083d1bf42b9 100644 --- a/source/blender/compositor/nodes/COM_MovieClipNode.cpp +++ b/source/blender/compositor/nodes/COM_MovieClipNode.cpp @@ -91,7 +91,9 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex if (ibuf) { if (stab->flag&TRACKING_2D_STABILIZATION) { - BKE_tracking_stabilization_data_get(&movieClip->tracking, context->getFramenumber(), ibuf->x, ibuf->y, loc, &scale, &angle); + int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(movieClip, context->getFramenumber()); + + BKE_tracking_stabilization_data_get(&movieClip->tracking, clip_framenr, ibuf->x, ibuf->y, loc, &scale, &angle); } } diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp index 5a2e58d6b21..d9f9801e2e1 100644 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp @@ -23,6 +23,7 @@ #include "COM_MovieClipAttributeOperation.h" extern "C" { #include "BKE_tracking.h" + #include "BKE_movieclip.h" } MovieClipAttributeOperation::MovieClipAttributeOperation(): NodeOperation() { @@ -41,7 +42,8 @@ void MovieClipAttributeOperation::executePixel(float *outputValue, float x, floa scale = 1.0f; angle = 0.0f; if (clip) { - BKE_tracking_stabilization_data_get(&clip->tracking, framenumber, getWidth(), getHeight(), loc, &scale, &angle); + int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, framenumber); + BKE_tracking_stabilization_data_get(&clip->tracking, clip_framenr, getWidth(), getHeight(), loc, &scale, &angle); } switch (this->attribute) { case MCA_SCALE: diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.c b/source/blender/nodes/composite/nodes/node_composite_movieclip.c index dfd36c3990a..e8f09ae08d7 100644 --- a/source/blender/nodes/composite/nodes/node_composite_movieclip.c +++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.c @@ -120,8 +120,9 @@ static void node_composit_exec_movieclip(void *data, bNode *node, bNodeStack **U if (stab->flag & TRACKING_2D_STABILIZATION) { float loc[2], scale, angle; + int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, rd->cfra); - BKE_tracking_stabilization_data_get(&clip->tracking, rd->cfra, stackbuf->x, stackbuf->y, + BKE_tracking_stabilization_data_get(&clip->tracking, clip_framenr, stackbuf->x, stackbuf->y, loc, &scale, &angle); out[1]->vec[0] = loc[0]; diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c index 44582d6de33..fabdf8c0536 100644 --- a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c +++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c @@ -53,8 +53,9 @@ static void node_composit_exec_stabilize2d(void *data, bNode *node, bNodeStack * CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA); CompBuf *stackbuf; float loc[2], scale, angle; + int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, rd->cfra); - BKE_tracking_stabilization_data_get(&clip->tracking, rd->cfra, cbuf->x, cbuf->y, loc, &scale, &angle); + BKE_tracking_stabilization_data_get(&clip->tracking, clip_framenr, cbuf->x, cbuf->y, loc, &scale, &angle); stackbuf = node_composit_transform(cbuf, loc[0], loc[1], angle, scale, node->custom1); From be3c12b75b18723c0598d2aeb5453849d8e3accb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 11:40:04 +0000 Subject: [PATCH 340/360] Move selection operators of Clip Editor into their own file --- .../blender/editors/space_clip/CMakeLists.txt | 1 + .../blender/editors/space_clip/clip_intern.h | 15 +- .../blender/editors/space_clip/tracking_ops.c | 772 ++--------------- .../editors/space_clip/tracking_select.c | 783 ++++++++++++++++++ 4 files changed, 861 insertions(+), 710 deletions(-) create mode 100644 source/blender/editors/space_clip/tracking_select.c diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt index ec5e81e4b2c..ecc4dea8b05 100644 --- a/source/blender/editors/space_clip/CMakeLists.txt +++ b/source/blender/editors/space_clip/CMakeLists.txt @@ -52,6 +52,7 @@ set(SRC clip_utils.c space_clip.c tracking_ops.c + tracking_select.c clip_intern.h ) diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index e0db3b1c995..04a941cbdf7 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -131,12 +131,7 @@ void clip_draw_cfra(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scen void clip_draw_sfra_efra(struct View2D *v2d, struct Scene *scene); /* tracking_ops.c */ -void CLIP_OT_select(struct wmOperatorType *ot); -void CLIP_OT_select_all(struct wmOperatorType *ot); -void CLIP_OT_select_border(struct wmOperatorType *ot); -void CLIP_OT_select_lasso(struct wmOperatorType *ot); -void CLIP_OT_select_circle(struct wmOperatorType *ot); -void CLIP_OT_select_grouped(struct wmOperatorType *ot); +struct MovieTrackingTrack *tracking_marker_check_slide(struct bContext *C, struct wmEvent *event); void CLIP_OT_add_marker(struct wmOperatorType *ot); void CLIP_OT_delete_track(struct wmOperatorType *ot); @@ -182,4 +177,12 @@ void CLIP_OT_tracking_object_remove(struct wmOperatorType *ot); void CLIP_OT_copy_tracks(struct wmOperatorType *ot); void CLIP_OT_paste_tracks(struct wmOperatorType *ot); +/* tracking_select.c */ +void CLIP_OT_select(struct wmOperatorType *ot); +void CLIP_OT_select_all(struct wmOperatorType *ot); +void CLIP_OT_select_border(struct wmOperatorType *ot); +void CLIP_OT_select_lasso(struct wmOperatorType *ot); +void CLIP_OT_select_circle(struct wmOperatorType *ot); +void CLIP_OT_select_grouped(struct wmOperatorType *ot); + #endif /* __CLIP_INTERN_H__ */ diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index f3a7d4ef57b..7a36528dd3a 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -79,8 +79,6 @@ #include "clip_intern.h" // own include -static float dist_to_crns(float co[2], float pos[2], float crns[4][2]); - /********************** add marker operator *********************/ static void add_marker(SpaceClip *sc, float x, float y) @@ -485,6 +483,74 @@ static void show_cursor(bContext *C) WM_cursor_set(win, CURSOR_STD); } +MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + MovieTrackingTrack *track; + int width, height; + float co[2]; + ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); + int framenr = ED_space_clip_clip_framenr(sc); + + ED_space_clip_size(sc, &width, &height); + + if (width == 0 || height == 0) + return NULL; + + ED_clip_mouse_pos(C, event, co); + + track = tracksbase->first; + while (track) { + if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); + int ok = FALSE; + + if ((marker->flag & MARKER_DISABLED) == 0) { + if (mouse_on_offset(sc, track, marker, co, width, height)) + ok = TRUE; + + if (!ok && (sc->flag & SC_SHOW_MARKER_SEARCH)) { + if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 1, width, height)) { + ok = TRUE; + } + else if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 0, width, height)) { + ok = TRUE; + } + } + + if (!ok && (sc->flag & SC_SHOW_MARKER_PATTERN)) { + /* XXX: need to be real check if affine tracking is enabled, but for now not + * sure how to do this, so assume affine tracker is always enabled */ + if (TRUE) { + int corner = get_mouse_pattern_corner(sc, marker, co, width, height); + + if (corner != -1) { + ok = TRUE; + } + } + else { + if (mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 1, width, height)) { + ok = TRUE; + } + + if (!ok && mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 0, width, height)) { + ok = TRUE; + } + } + } + + if (ok) + return track; + } + } + + track = track->next; + } + + return NULL; +} + static void *slide_marker_customdata(bContext *C, wmEvent *event) { SpaceClip *sc = CTX_wm_space_clip(C); @@ -810,708 +876,6 @@ void CLIP_OT_slide_marker(wmOperatorType *ot) "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX); } -/********************** mouse select operator *********************/ - -static int mouse_on_side(float co[2], float x1, float y1, float x2, float y2, float epsx, float epsy) -{ - if (x1 > x2) - - SWAP(float, x1, x2); - - if (y1 > y2) - SWAP(float, y1, y2); - - return (co[0] >= x1 - epsx && co[0] <= x2 + epsx) && (co[1] >= y1 - epsy && co[1] <= y2 + epsy); -} - -static int mouse_on_rect(float co[2], float pos[2], float min[2], float max[2], float epsx, float epsy) -{ - return mouse_on_side(co, pos[0] + min[0], pos[1] + min[1], pos[0] + max[0], pos[1] + min[1], epsx, epsy) || - mouse_on_side(co, pos[0] + min[0], pos[1] + min[1], pos[0] + min[0], pos[1] + max[1], epsx, epsy) || - mouse_on_side(co, pos[0] + min[0], pos[1] + max[1], pos[0] + max[0], pos[1] + max[1], epsx, epsy) || - mouse_on_side(co, pos[0] + max[0], pos[1] + min[1], pos[0] + max[0], pos[1] + max[1], epsx, epsy); -} - -static int mouse_on_crns(float co[2], float pos[2], float crns[4][2], float epsx, float epsy) -{ - float dist = dist_to_crns(co, pos, crns); - - return dist < MAX2(epsx, epsy); -} - -static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *track) -{ - int framenr = ED_space_clip_clip_framenr(sc); - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - float pat_min[2], pat_max[2]; - float epsx, epsy; - int width, height; - - ED_space_clip_size(sc, &width, &height); - - BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - - epsx = MIN4(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0], - fabsf(pat_min[0]), fabsf(pat_max[0])) / 2; - epsy = MIN4(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1], - fabsf(pat_min[1]), fabsf(pat_max[1])) / 2; - - epsx = MAX2(epsx, 2.0f / width); - epsy = MAX2(epsy, 2.0f / height); - - if (sc->flag & SC_SHOW_MARKER_SEARCH) { - if (mouse_on_rect(co, marker->pos, marker->search_min, marker->search_max, epsx, epsy)) - return TRACK_AREA_SEARCH; - } - - if ((marker->flag & MARKER_DISABLED) == 0) { - if (sc->flag & SC_SHOW_MARKER_PATTERN) - if (mouse_on_crns(co, marker->pos, marker->pattern_corners, epsx, epsy)) - return TRACK_AREA_PAT; - - epsx = 12.0f / width; - epsy = 12.0f / height; - - if (fabsf(co[0] - marker->pos[0] - track->offset[0]) < epsx && - fabsf(co[1] - marker->pos[1] - track->offset[1]) <= epsy) - { - return TRACK_AREA_POINT; - } - } - - return TRACK_AREA_NONE; -} - -static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2]) -{ - float d1, d2, d3, d4; - float p[2] = {co[0] - pos[0], co[1] - pos[1]}; - float v1[2] = {min[0], min[1]}, v2[2] = {max[0], min[1]}; - float v3[2] = {max[0], max[1]}, v4[2] = {min[0], max[1]}; - - d1 = dist_to_line_segment_v2(p, v1, v2); - d2 = dist_to_line_segment_v2(p, v2, v3); - d3 = dist_to_line_segment_v2(p, v3, v4); - d4 = dist_to_line_segment_v2(p, v4, v1); - - return MIN4(d1, d2, d3, d4); -} - -static float dist_to_crns(float co[2], float pos[2], float crns[4][2]) -{ - float d1, d2, d3, d4; - float p[2] = {co[0] - pos[0], co[1] - pos[1]}; - float *v1 = crns[0], *v2 = crns[1]; - float *v3 = crns[2], *v4 = crns[3]; - - d1 = dist_to_line_segment_v2(p, v1, v2); - d2 = dist_to_line_segment_v2(p, v2, v3); - d3 = dist_to_line_segment_v2(p, v3, v4); - d4 = dist_to_line_segment_v2(p, v4, v1); - - return MIN4(d1, d2, d3, d4); -} - -static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2]) -{ - MovieTrackingTrack *track = NULL, *cur; - float mindist = 0.0f; - int framenr = ED_space_clip_clip_framenr(sc); - - cur = tracksbase->first; - while (cur) { - MovieTrackingMarker *marker = BKE_tracking_marker_get(cur, framenr); - - if (((cur->flag & TRACK_HIDDEN) == 0) && MARKER_VISIBLE(sc, cur, marker)) { - float dist, d1, d2 = FLT_MAX, d3 = FLT_MAX; - - /* distance to marker point */ - d1 = sqrtf((co[0] - marker->pos[0] - cur->offset[0]) * (co[0] - marker->pos[0] - cur->offset[0]) + - (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); - - /* distance to pattern boundbox */ - if (sc->flag & SC_SHOW_MARKER_PATTERN) - d2 = dist_to_crns(co, marker->pos, marker->pattern_corners); - - /* distance to search boundbox */ - if (sc->flag & SC_SHOW_MARKER_SEARCH && TRACK_VIEW_SELECTED(sc, cur)) - d3 = dist_to_rect(co, marker->pos, marker->search_min, marker->search_max); - - /* choose minimal distance. useful for cases of overlapped markers. */ - dist = MIN3(d1, d2, d3); - - if (track == NULL || dist < mindist) { - track = cur; - mindist = dist; - } - } - - cur = cur->next; - } - - return track; -} - -static int mouse_select(bContext *C, float co[2], int extend) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip(sc); - MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); - MovieTrackingTrack *track = NULL; /* selected marker */ - - track = find_nearest_track(sc, tracksbase, co); - - if (track) { - int area = track_mouse_area(sc, co, track); - - if (!extend || !TRACK_VIEW_SELECTED(sc, track)) - area = TRACK_AREA_ALL; - - if (extend && TRACK_AREA_SELECTED(track, area)) { - if (track == act_track) - BKE_tracking_track_deselect(track, area); - else - clip->tracking.act_track = track; - } - else { - if (area == TRACK_AREA_POINT) - area = TRACK_AREA_ALL; - - BKE_tracking_track_select(tracksbase, track, area, extend); - clip->tracking.act_track = track; - } - } - - if (!extend) { - sc->xlockof = 0.0f; - sc->ylockof = 0.0f; - } - - BKE_tracking_dopesheet_tag_update(tracking); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); - - return OPERATOR_FINISHED; -} - -static int select_exec(bContext *C, wmOperator *op) -{ - float co[2]; - int extend; - - RNA_float_get_array(op->ptr, "location", co); - extend = RNA_boolean_get(op->ptr, "extend"); - - return mouse_select(C, co, extend); -} - -static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - float co[2]; - int extend = RNA_boolean_get(op->ptr, "extend"); - - if (!extend) { - SlideMarkerData *slidedata = slide_marker_customdata(C, event); - - if (slidedata) { - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip(sc); - - clip->tracking.act_track = slidedata->track; - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); - - MEM_freeN(slidedata); - - return OPERATOR_PASS_THROUGH; - } - } - - ED_clip_mouse_pos(C, event, co); - RNA_float_set_array(op->ptr, "location", co); - - return select_exec(C, op); -} - -void CLIP_OT_select(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select"; - ot->description = "Select tracking markers"; - ot->idname = "CLIP_OT_select"; - - /* api callbacks */ - ot->exec = select_exec; - ot->invoke = select_invoke; - //ot->poll = ED_space_clip_tracking_poll; // so mask view can Ctrl+RMB markers - ot->poll = ED_space_clip_view_clip_poll; - - /* flags */ - ot->flag = OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "extend", 0, - "Extend", "Extend selection rather than clearing the existing selection"); - RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, - "Location", "Mouse location in normalized coordinates, 0.0 to 1.0 is within the image bounds", -100.0f, 100.0f); -} - -/********************** border select operator *********************/ - -static int border_select_exec(bContext *C, wmOperator *op) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *track; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - rcti rect; - rctf rectf; - int change = FALSE, mode, extend; - int framenr = ED_space_clip_clip_framenr(sc); - - /* get rectangle from operator */ - rect.xmin = RNA_int_get(op->ptr, "xmin"); - rect.ymin = RNA_int_get(op->ptr, "ymin"); - rect.xmax = RNA_int_get(op->ptr, "xmax"); - rect.ymax = RNA_int_get(op->ptr, "ymax"); - - ED_clip_point_stable_pos(C, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); - ED_clip_point_stable_pos(C, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); - - mode = RNA_int_get(op->ptr, "gesture_mode"); - extend = RNA_boolean_get(op->ptr, "extend"); - - /* do actual selection */ - track = tracksbase->first; - while (track) { - if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - - if (MARKER_VISIBLE(sc, track, marker)) { - if (BLI_in_rctf(&rectf, marker->pos[0], marker->pos[1])) { - if (mode == GESTURE_MODAL_SELECT) - BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); - else - BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); - } - else if (!extend) { - BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); - } - - change = TRUE; - } - } - - track = track->next; - } - - if (change) { - BKE_tracking_dopesheet_tag_update(tracking); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); - - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED; -} - -void CLIP_OT_select_border(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Border Select"; - ot->description = "Select markers using border selection"; - ot->idname = "CLIP_OT_select_border"; - - /* api callbacks */ - ot->invoke = WM_border_select_invoke; - ot->exec = border_select_exec; - ot->modal = WM_border_select_modal; - ot->poll = ED_space_clip_tracking_poll; - - /* flags */ - ot->flag = OPTYPE_UNDO; - - /* properties */ - WM_operator_properties_gesture_border(ot, TRUE); -} - - -static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, short select) -{ - ARegion *ar = CTX_wm_region(C); - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *track; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - rcti rect; - int change = FALSE; - int framenr = ED_space_clip_clip_framenr(sc); - - /* get rectangle from operator */ - BLI_lasso_boundbox(&rect, mcords, moves); - - /* do actual selection */ - track = tracksbase->first; - while (track) { - if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - - if (MARKER_VISIBLE(sc, track, marker)) { - float screen_co[2]; - - /* marker in screen coords */ - ED_clip_point_stable_pos__reverse(sc, ar, marker->pos, screen_co); - - if (BLI_in_rcti(&rect, screen_co[0], screen_co[1]) && - BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED)) - { - if (select) - BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); - else - BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); - } - - change = TRUE; - } - } - - track = track->next; - } - - if (change) { - BKE_tracking_dopesheet_tag_update(tracking); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); - } - - return change; -} - -static int clip_lasso_select_exec(bContext *C, wmOperator *op) -{ - int mcords_tot; - int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); - - if (mcords) { - short select; - - select = !RNA_boolean_get(op->ptr, "deselect"); - do_lasso_select_marker(C, mcords, mcords_tot, select); - - MEM_freeN(mcords); - - return OPERATOR_FINISHED; - } - return OPERATOR_PASS_THROUGH; -} - -void CLIP_OT_select_lasso(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Lasso Select"; - ot->description = "Select markers using lasso selection"; - ot->idname = "CLIP_OT_select_lasso"; - - /* api callbacks */ - ot->invoke = WM_gesture_lasso_invoke; - ot->modal = WM_gesture_lasso_modal; - ot->exec = clip_lasso_select_exec; - ot->poll = ED_space_clip_tracking_poll; - ot->cancel = WM_gesture_lasso_cancel; - - /* flags */ - ot->flag = OPTYPE_UNDO; - - /* properties */ - RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", ""); - RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items"); - RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first"); -} - -/********************** circle select operator *********************/ - -static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2]) -{ - /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */ - float x, y; - - x = (marker->pos[0] - offset[0]) * ellipse[0]; - y = (marker->pos[1] - offset[1]) * ellipse[1]; - - return x * x + y * y < 1.0f; -} - -static int circle_select_exec(bContext *C, wmOperator *op) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip(sc); - ARegion *ar = CTX_wm_region(C); - MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *track; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - int x, y, radius, width, height, mode, change = FALSE; - float zoomx, zoomy, offset[2], ellipse[2]; - int framenr = ED_space_clip_clip_framenr(sc); - - /* get operator properties */ - x = RNA_int_get(op->ptr, "x"); - y = RNA_int_get(op->ptr, "y"); - radius = RNA_int_get(op->ptr, "radius"); - - mode = RNA_int_get(op->ptr, "gesture_mode"); - - /* compute ellipse and position in unified coordinates */ - ED_space_clip_size(sc, &width, &height); - ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); - - ellipse[0] = width * zoomx / radius; - ellipse[1] = height * zoomy / radius; - - ED_clip_point_stable_pos(C, x, y, &offset[0], &offset[1]); - - /* do selection */ - track = tracksbase->first; - while (track) { - if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - - if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) { - if (mode == GESTURE_MODAL_SELECT) - BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); - else - BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); - - change = TRUE; - } - } - - track = track->next; - } - - if (change) { - BKE_tracking_dopesheet_tag_update(tracking); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); - - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED; -} - -void CLIP_OT_select_circle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Circle Select"; - ot->description = "Select markers using circle selection"; - ot->idname = "CLIP_OT_select_circle"; - - /* api callbacks */ - ot->invoke = WM_gesture_circle_invoke; - ot->modal = WM_gesture_circle_modal; - ot->exec = circle_select_exec; - ot->poll = ED_space_clip_tracking_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); -} - -/********************** select all operator *********************/ - -static int select_all_exec(bContext *C, wmOperator *op) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *track = NULL; /* selected track */ - MovieTrackingMarker *marker; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - int action = RNA_enum_get(op->ptr, "action"); - int framenr = ED_space_clip_clip_framenr(sc); - int has_selection = FALSE; - - if (action == SEL_TOGGLE) { - action = SEL_SELECT; - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track)) { - marker = BKE_tracking_marker_get(track, framenr); - - if (MARKER_VISIBLE(sc, track, marker)) { - action = SEL_DESELECT; - break; - } - } - - track = track->next; - } - } - - track = tracksbase->first; - while (track) { - if ((track->flag & TRACK_HIDDEN) == 0) { - marker = BKE_tracking_marker_get(track, framenr); - - if (MARKER_VISIBLE(sc, track, marker)) { - switch (action) { - case SEL_SELECT: - track->flag |= SELECT; - track->pat_flag |= SELECT; - track->search_flag |= SELECT; - break; - case SEL_DESELECT: - track->flag &= ~SELECT; - track->pat_flag &= ~SELECT; - track->search_flag &= ~SELECT; - break; - case SEL_INVERT: - track->flag ^= SELECT; - track->pat_flag ^= SELECT; - track->search_flag ^= SELECT; - break; - } - } - } - - if (TRACK_VIEW_SELECTED(sc, track)) - has_selection = TRUE; - - track = track->next; - } - - if (!has_selection) - sc->flag &= ~SC_LOCK_SELECTION; - - BKE_tracking_dopesheet_tag_update(tracking); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); - - return OPERATOR_FINISHED; -} - -void CLIP_OT_select_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "(De)select All"; - ot->description = "Change selection of all tracking markers"; - ot->idname = "CLIP_OT_select_all"; - - /* api callbacks */ - ot->exec = select_all_exec; - ot->poll = ED_space_clip_tracking_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - WM_operator_properties_select_all(ot); -} - -/********************** select grouped operator *********************/ - -static int select_groped_exec(bContext *C, wmOperator *op) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip(sc); - MovieTrackingTrack *track; - MovieTrackingMarker *marker; - MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - int group = RNA_enum_get(op->ptr, "group"); - int framenr = ED_space_clip_clip_framenr(sc); - - track = tracksbase->first; - while (track) { - int ok = FALSE; - - marker = BKE_tracking_marker_get(track, framenr); - - if (group == 0) { /* Keyframed */ - ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED) == 0; - } - else if (group == 1) { /* Estimated */ - ok = marker->framenr != framenr; - } - else if (group == 2) { /* tracked */ - ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED); - } - else if (group == 3) { /* locked */ - ok = track->flag & TRACK_LOCKED; - } - else if (group == 4) { /* disabled */ - ok = marker->flag & MARKER_DISABLED; - } - else if (group == 5) { /* color */ - MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); - - if (act_track) { - ok = (track->flag & TRACK_CUSTOMCOLOR) == (act_track->flag & TRACK_CUSTOMCOLOR); - - if (ok && track->flag & TRACK_CUSTOMCOLOR) - ok = equals_v3v3(track->color, act_track->color); - } - } - else if (group == 6) { /* failed */ - ok = (track->flag & TRACK_HAS_BUNDLE) == 0; - } - - if (ok) { - track->flag |= SELECT; - if (sc->flag & SC_SHOW_MARKER_PATTERN) - track->pat_flag |= SELECT; - if (sc->flag & SC_SHOW_MARKER_SEARCH) - track->search_flag |= SELECT; - } - - track = track->next; - } - - BKE_tracking_dopesheet_tag_update(tracking); - - WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); - - return OPERATOR_FINISHED; -} - -void CLIP_OT_select_grouped(wmOperatorType *ot) -{ - static EnumPropertyItem select_group_items[] = { - {0, "KEYFRAMED", 0, "Keyframed tracks", "Select all keyframed tracks"}, - {1, "ESTIMATED", 0, "Estimated tracks", "Select all estimated tracks"}, - {2, "TRACKED", 0, "Tracked tracks", "Select all tracked tracks"}, - {3, "LOCKED", 0, "Locked tracks", "Select all locked tracks"}, - {4, "DISABLED", 0, "Disabled tracks", "Select all disabled tracks"}, - {5, "COLOR", 0, "Tracks with same color", "Select all tracks with same color as active track"}, - {6, "FAILED", 0, "Failed Tracks", "Select all tracks which failed to be reconstructed"}, - {0, NULL, 0, NULL, NULL} - }; - - /* identifiers */ - ot->name = "Select Grouped"; - ot->description = "Select all tracks from specified group"; - ot->idname = "CLIP_OT_select_grouped"; - - /* api callbacks */ - ot->exec = select_groped_exec; - ot->poll = ED_space_clip_tracking_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* proeprties */ - RNA_def_enum(ot->srna, "group", select_group_items, TRACK_CLEAR_REMAINED, "Action", "Clear action to execute"); -} - /********************** track operator *********************/ typedef struct TrackMarkersJob { diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c new file mode 100644 index 00000000000..d46eb538af9 --- /dev/null +++ b/source/blender/editors/space_clip/tracking_select.c @@ -0,0 +1,783 @@ +/* + * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/tracking_ops.c + * \ingroup spclip + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_camera_types.h" +#include "DNA_constraint_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_movieclip_types.h" +#include "DNA_object_types.h" /* SELECT */ +#include "DNA_scene_types.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_listbase.h" +#include "BLI_rect.h" +#include "BLI_lasso.h" +#include "BLI_blenlib.h" + +#include "BKE_main.h" +#include "BKE_context.h" +#include "BKE_constraint.h" +#include "BKE_movieclip.h" +#include "BKE_tracking.h" +#include "BKE_global.h" +#include "BKE_depsgraph.h" +#include "BKE_object.h" +#include "BKE_report.h" +#include "BKE_scene.h" +#include "BKE_library.h" +#include "BKE_sound.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_clip.h" +#include "ED_keyframing.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "UI_interface.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "PIL_time.h" + +#include "UI_view2d.h" + +#include "clip_intern.h" // own include + +static float dist_to_crns(float co[2], float pos[2], float crns[4][2]); + +/********************** mouse select operator *********************/ + +static int mouse_on_side(float co[2], float x1, float y1, float x2, float y2, float epsx, float epsy) +{ + if (x1 > x2) + + SWAP(float, x1, x2); + + if (y1 > y2) + SWAP(float, y1, y2); + + return (co[0] >= x1 - epsx && co[0] <= x2 + epsx) && (co[1] >= y1 - epsy && co[1] <= y2 + epsy); +} + +static int mouse_on_rect(float co[2], float pos[2], float min[2], float max[2], float epsx, float epsy) +{ + return mouse_on_side(co, pos[0] + min[0], pos[1] + min[1], pos[0] + max[0], pos[1] + min[1], epsx, epsy) || + mouse_on_side(co, pos[0] + min[0], pos[1] + min[1], pos[0] + min[0], pos[1] + max[1], epsx, epsy) || + mouse_on_side(co, pos[0] + min[0], pos[1] + max[1], pos[0] + max[0], pos[1] + max[1], epsx, epsy) || + mouse_on_side(co, pos[0] + max[0], pos[1] + min[1], pos[0] + max[0], pos[1] + max[1], epsx, epsy); +} + +static int mouse_on_crns(float co[2], float pos[2], float crns[4][2], float epsx, float epsy) +{ + float dist = dist_to_crns(co, pos, crns); + + return dist < MAX2(epsx, epsy); +} + +static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *track) +{ + int framenr = ED_space_clip_clip_framenr(sc); + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); + float pat_min[2], pat_max[2]; + float epsx, epsy; + int width, height; + + ED_space_clip_size(sc, &width, &height); + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + epsx = MIN4(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0], + fabsf(pat_min[0]), fabsf(pat_max[0])) / 2; + epsy = MIN4(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1], + fabsf(pat_min[1]), fabsf(pat_max[1])) / 2; + + epsx = MAX2(epsx, 2.0f / width); + epsy = MAX2(epsy, 2.0f / height); + + if (sc->flag & SC_SHOW_MARKER_SEARCH) { + if (mouse_on_rect(co, marker->pos, marker->search_min, marker->search_max, epsx, epsy)) + return TRACK_AREA_SEARCH; + } + + if ((marker->flag & MARKER_DISABLED) == 0) { + if (sc->flag & SC_SHOW_MARKER_PATTERN) + if (mouse_on_crns(co, marker->pos, marker->pattern_corners, epsx, epsy)) + return TRACK_AREA_PAT; + + epsx = 12.0f / width; + epsy = 12.0f / height; + + if (fabsf(co[0] - marker->pos[0] - track->offset[0]) < epsx && + fabsf(co[1] - marker->pos[1] - track->offset[1]) <= epsy) + { + return TRACK_AREA_POINT; + } + } + + return TRACK_AREA_NONE; +} + +static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2]) +{ + float d1, d2, d3, d4; + float p[2] = {co[0] - pos[0], co[1] - pos[1]}; + float v1[2] = {min[0], min[1]}, v2[2] = {max[0], min[1]}; + float v3[2] = {max[0], max[1]}, v4[2] = {min[0], max[1]}; + + d1 = dist_to_line_segment_v2(p, v1, v2); + d2 = dist_to_line_segment_v2(p, v2, v3); + d3 = dist_to_line_segment_v2(p, v3, v4); + d4 = dist_to_line_segment_v2(p, v4, v1); + + return MIN4(d1, d2, d3, d4); +} + +static float dist_to_crns(float co[2], float pos[2], float crns[4][2]) +{ + float d1, d2, d3, d4; + float p[2] = {co[0] - pos[0], co[1] - pos[1]}; + float *v1 = crns[0], *v2 = crns[1]; + float *v3 = crns[2], *v4 = crns[3]; + + d1 = dist_to_line_segment_v2(p, v1, v2); + d2 = dist_to_line_segment_v2(p, v2, v3); + d3 = dist_to_line_segment_v2(p, v3, v4); + d4 = dist_to_line_segment_v2(p, v4, v1); + + return MIN4(d1, d2, d3, d4); +} + +static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2]) +{ + MovieTrackingTrack *track = NULL, *cur; + float mindist = 0.0f; + int framenr = ED_space_clip_clip_framenr(sc); + + cur = tracksbase->first; + while (cur) { + MovieTrackingMarker *marker = BKE_tracking_marker_get(cur, framenr); + + if (((cur->flag & TRACK_HIDDEN) == 0) && MARKER_VISIBLE(sc, cur, marker)) { + float dist, d1, d2 = FLT_MAX, d3 = FLT_MAX; + + /* distance to marker point */ + d1 = sqrtf((co[0] - marker->pos[0] - cur->offset[0]) * (co[0] - marker->pos[0] - cur->offset[0]) + + (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); + + /* distance to pattern boundbox */ + if (sc->flag & SC_SHOW_MARKER_PATTERN) + d2 = dist_to_crns(co, marker->pos, marker->pattern_corners); + + /* distance to search boundbox */ + if (sc->flag & SC_SHOW_MARKER_SEARCH && TRACK_VIEW_SELECTED(sc, cur)) + d3 = dist_to_rect(co, marker->pos, marker->search_min, marker->search_max); + + /* choose minimal distance. useful for cases of overlapped markers. */ + dist = MIN3(d1, d2, d3); + + if (track == NULL || dist < mindist) { + track = cur; + mindist = dist; + } + } + + cur = cur->next; + } + + return track; +} + +static int mouse_select(bContext *C, float co[2], int extend) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + MovieTracking *tracking = &clip->tracking; + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); + MovieTrackingTrack *track = NULL; /* selected marker */ + + track = find_nearest_track(sc, tracksbase, co); + + if (track) { + int area = track_mouse_area(sc, co, track); + + if (!extend || !TRACK_VIEW_SELECTED(sc, track)) + area = TRACK_AREA_ALL; + + if (extend && TRACK_AREA_SELECTED(track, area)) { + if (track == act_track) + BKE_tracking_track_deselect(track, area); + else + clip->tracking.act_track = track; + } + else { + if (area == TRACK_AREA_POINT) + area = TRACK_AREA_ALL; + + BKE_tracking_track_select(tracksbase, track, area, extend); + clip->tracking.act_track = track; + } + } + + if (!extend) { + sc->xlockof = 0.0f; + sc->ylockof = 0.0f; + } + + BKE_tracking_dopesheet_tag_update(tracking); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); + + return OPERATOR_FINISHED; +} + +static int select_exec(bContext *C, wmOperator *op) +{ + float co[2]; + int extend; + + RNA_float_get_array(op->ptr, "location", co); + extend = RNA_boolean_get(op->ptr, "extend"); + + return mouse_select(C, co, extend); +} + +static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + int extend = RNA_boolean_get(op->ptr, "extend"); + + if (!extend) { + MovieTrackingTrack *track = tracking_marker_check_slide(C, event); + + if (track) { + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + + clip->tracking.act_track = track; + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); + + return OPERATOR_PASS_THROUGH; + } + } + + ED_clip_mouse_pos(C, event, co); + RNA_float_set_array(op->ptr, "location", co); + + return select_exec(C, op); +} + +void CLIP_OT_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select"; + ot->description = "Select tracking markers"; + ot->idname = "CLIP_OT_select"; + + /* api callbacks */ + ot->exec = select_exec; + ot->invoke = select_invoke; + //ot->poll = ED_space_clip_tracking_poll; // so mask view can Ctrl+RMB markers + ot->poll = ED_space_clip_view_clip_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "extend", 0, + "Extend", "Extend selection rather than clearing the existing selection"); + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, + "Location", "Mouse location in normalized coordinates, 0.0 to 1.0 is within the image bounds", -100.0f, 100.0f); +} + +/********************** border select operator *********************/ + +static int border_select_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + MovieTracking *tracking = &clip->tracking; + MovieTrackingTrack *track; + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + rcti rect; + rctf rectf; + int change = FALSE, mode, extend; + int framenr = ED_space_clip_clip_framenr(sc); + + /* get rectangle from operator */ + rect.xmin = RNA_int_get(op->ptr, "xmin"); + rect.ymin = RNA_int_get(op->ptr, "ymin"); + rect.xmax = RNA_int_get(op->ptr, "xmax"); + rect.ymax = RNA_int_get(op->ptr, "ymax"); + + ED_clip_point_stable_pos(C, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); + ED_clip_point_stable_pos(C, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); + + mode = RNA_int_get(op->ptr, "gesture_mode"); + extend = RNA_boolean_get(op->ptr, "extend"); + + /* do actual selection */ + track = tracksbase->first; + while (track) { + if ((track->flag & TRACK_HIDDEN) == 0) { + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); + + if (MARKER_VISIBLE(sc, track, marker)) { + if (BLI_in_rctf(&rectf, marker->pos[0], marker->pos[1])) { + if (mode == GESTURE_MODAL_SELECT) + BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); + else + BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); + } + else if (!extend) { + BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); + } + + change = TRUE; + } + } + + track = track->next; + } + + if (change) { + BKE_tracking_dopesheet_tag_update(tracking); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void CLIP_OT_select_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Border Select"; + ot->description = "Select markers using border selection"; + ot->idname = "CLIP_OT_select_border"; + + /* api callbacks */ + ot->invoke = WM_border_select_invoke; + ot->exec = border_select_exec; + ot->modal = WM_border_select_modal; + ot->poll = ED_space_clip_tracking_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_gesture_border(ot, TRUE); +} + +/********************** lasso select operator *********************/ + +static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, short select) +{ + ARegion *ar = CTX_wm_region(C); + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + MovieTracking *tracking = &clip->tracking; + MovieTrackingTrack *track; + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + rcti rect; + int change = FALSE; + int framenr = ED_space_clip_clip_framenr(sc); + + /* get rectangle from operator */ + BLI_lasso_boundbox(&rect, mcords, moves); + + /* do actual selection */ + track = tracksbase->first; + while (track) { + if ((track->flag & TRACK_HIDDEN) == 0) { + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); + + if (MARKER_VISIBLE(sc, track, marker)) { + float screen_co[2]; + + /* marker in screen coords */ + ED_clip_point_stable_pos__reverse(sc, ar, marker->pos, screen_co); + + if (BLI_in_rcti(&rect, screen_co[0], screen_co[1]) && + BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED)) + { + if (select) + BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); + else + BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); + } + + change = TRUE; + } + } + + track = track->next; + } + + if (change) { + BKE_tracking_dopesheet_tag_update(tracking); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); + } + + return change; +} + +static int clip_lasso_select_exec(bContext *C, wmOperator *op) +{ + int mcords_tot; + int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + + if (mcords) { + short select; + + select = !RNA_boolean_get(op->ptr, "deselect"); + do_lasso_select_marker(C, mcords, mcords_tot, select); + + MEM_freeN(mcords); + + return OPERATOR_FINISHED; + } + return OPERATOR_PASS_THROUGH; +} + +void CLIP_OT_select_lasso(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Lasso Select"; + ot->description = "Select markers using lasso selection"; + ot->idname = "CLIP_OT_select_lasso"; + + /* api callbacks */ + ot->invoke = WM_gesture_lasso_invoke; + ot->modal = WM_gesture_lasso_modal; + ot->exec = clip_lasso_select_exec; + ot->poll = ED_space_clip_tracking_poll; + ot->cancel = WM_gesture_lasso_cancel; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", ""); + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items"); + RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first"); +} + +/********************** circle select operator *********************/ + +static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2]) +{ + /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */ + float x, y; + + x = (marker->pos[0] - offset[0]) * ellipse[0]; + y = (marker->pos[1] - offset[1]) * ellipse[1]; + + return x * x + y * y < 1.0f; +} + +static int circle_select_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + ARegion *ar = CTX_wm_region(C); + MovieTracking *tracking = &clip->tracking; + MovieTrackingTrack *track; + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + int x, y, radius, width, height, mode, change = FALSE; + float zoomx, zoomy, offset[2], ellipse[2]; + int framenr = ED_space_clip_clip_framenr(sc); + + /* get operator properties */ + x = RNA_int_get(op->ptr, "x"); + y = RNA_int_get(op->ptr, "y"); + radius = RNA_int_get(op->ptr, "radius"); + + mode = RNA_int_get(op->ptr, "gesture_mode"); + + /* compute ellipse and position in unified coordinates */ + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + + ellipse[0] = width * zoomx / radius; + ellipse[1] = height * zoomy / radius; + + ED_clip_point_stable_pos(C, x, y, &offset[0], &offset[1]); + + /* do selection */ + track = tracksbase->first; + while (track) { + if ((track->flag & TRACK_HIDDEN) == 0) { + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); + + if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) { + if (mode == GESTURE_MODAL_SELECT) + BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); + else + BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); + + change = TRUE; + } + } + + track = track->next; + } + + if (change) { + BKE_tracking_dopesheet_tag_update(tracking); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void CLIP_OT_select_circle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Circle Select"; + ot->description = "Select markers using circle selection"; + ot->idname = "CLIP_OT_select_circle"; + + /* api callbacks */ + ot->invoke = WM_gesture_circle_invoke; + ot->modal = WM_gesture_circle_modal; + ot->exec = circle_select_exec; + ot->poll = ED_space_clip_tracking_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); +} + +/********************** select all operator *********************/ + +static int select_all_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + MovieTracking *tracking = &clip->tracking; + MovieTrackingTrack *track = NULL; /* selected track */ + MovieTrackingMarker *marker; + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + int action = RNA_enum_get(op->ptr, "action"); + int framenr = ED_space_clip_clip_framenr(sc); + int has_selection = FALSE; + + if (action == SEL_TOGGLE) { + action = SEL_SELECT; + track = tracksbase->first; + while (track) { + if (TRACK_VIEW_SELECTED(sc, track)) { + marker = BKE_tracking_marker_get(track, framenr); + + if (MARKER_VISIBLE(sc, track, marker)) { + action = SEL_DESELECT; + break; + } + } + + track = track->next; + } + } + + track = tracksbase->first; + while (track) { + if ((track->flag & TRACK_HIDDEN) == 0) { + marker = BKE_tracking_marker_get(track, framenr); + + if (MARKER_VISIBLE(sc, track, marker)) { + switch (action) { + case SEL_SELECT: + track->flag |= SELECT; + track->pat_flag |= SELECT; + track->search_flag |= SELECT; + break; + case SEL_DESELECT: + track->flag &= ~SELECT; + track->pat_flag &= ~SELECT; + track->search_flag &= ~SELECT; + break; + case SEL_INVERT: + track->flag ^= SELECT; + track->pat_flag ^= SELECT; + track->search_flag ^= SELECT; + break; + } + } + } + + if (TRACK_VIEW_SELECTED(sc, track)) + has_selection = TRUE; + + track = track->next; + } + + if (!has_selection) + sc->flag &= ~SC_LOCK_SELECTION; + + BKE_tracking_dopesheet_tag_update(tracking); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_select_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "(De)select All"; + ot->description = "Change selection of all tracking markers"; + ot->idname = "CLIP_OT_select_all"; + + /* api callbacks */ + ot->exec = select_all_exec; + ot->poll = ED_space_clip_tracking_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + WM_operator_properties_select_all(ot); +} + +/********************** select grouped operator *********************/ + +static int select_groped_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + MovieTrackingTrack *track; + MovieTrackingMarker *marker; + MovieTracking *tracking = &clip->tracking; + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + int group = RNA_enum_get(op->ptr, "group"); + int framenr = ED_space_clip_clip_framenr(sc); + + track = tracksbase->first; + while (track) { + int ok = FALSE; + + marker = BKE_tracking_marker_get(track, framenr); + + if (group == 0) { /* Keyframed */ + ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED) == 0; + } + else if (group == 1) { /* Estimated */ + ok = marker->framenr != framenr; + } + else if (group == 2) { /* tracked */ + ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED); + } + else if (group == 3) { /* locked */ + ok = track->flag & TRACK_LOCKED; + } + else if (group == 4) { /* disabled */ + ok = marker->flag & MARKER_DISABLED; + } + else if (group == 5) { /* color */ + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); + + if (act_track) { + ok = (track->flag & TRACK_CUSTOMCOLOR) == (act_track->flag & TRACK_CUSTOMCOLOR); + + if (ok && track->flag & TRACK_CUSTOMCOLOR) + ok = equals_v3v3(track->color, act_track->color); + } + } + else if (group == 6) { /* failed */ + ok = (track->flag & TRACK_HAS_BUNDLE) == 0; + } + + if (ok) { + track->flag |= SELECT; + if (sc->flag & SC_SHOW_MARKER_PATTERN) + track->pat_flag |= SELECT; + if (sc->flag & SC_SHOW_MARKER_SEARCH) + track->search_flag |= SELECT; + } + + track = track->next; + } + + BKE_tracking_dopesheet_tag_update(tracking); + + WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_select_grouped(wmOperatorType *ot) +{ + static EnumPropertyItem select_group_items[] = { + {0, "KEYFRAMED", 0, "Keyframed tracks", "Select all keyframed tracks"}, + {1, "ESTIMATED", 0, "Estimated tracks", "Select all estimated tracks"}, + {2, "TRACKED", 0, "Tracked tracks", "Select all tracked tracks"}, + {3, "LOCKED", 0, "Locked tracks", "Select all locked tracks"}, + {4, "DISABLED", 0, "Disabled tracks", "Select all disabled tracks"}, + {5, "COLOR", 0, "Tracks with same color", "Select all tracks with same color as active track"}, + {6, "FAILED", 0, "Failed Tracks", "Select all tracks which failed to be reconstructed"}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Select Grouped"; + ot->description = "Select all tracks from specified group"; + ot->idname = "CLIP_OT_select_grouped"; + + /* api callbacks */ + ot->exec = select_groped_exec; + ot->poll = ED_space_clip_tracking_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* proeprties */ + RNA_def_enum(ot->srna, "group", select_group_items, TRACK_CLEAR_REMAINED, "Action", "Clear action to execute"); +} From fa3dd67b42adc12cc227bfd353a3f6469e82eaf6 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 11:42:09 +0000 Subject: [PATCH 341/360] Fix potential memory leak in marker sliding operator --- source/blender/editors/space_clip/tracking_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 7a36528dd3a..de2bf8241d7 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -581,7 +581,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) SLIDE_ACTION_POS, width, height); } - if (sc->flag & SC_SHOW_MARKER_SEARCH) { + if (!customdata && (sc->flag & SC_SHOW_MARKER_SEARCH)) { if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 1, width, height)) { customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, SLIDE_ACTION_OFFSET, width, height); From 82473f67b358cc76c6e60ced68d73d7dac06a7b0 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 11:53:51 +0000 Subject: [PATCH 342/360] Core matte input for keying node This matte could be used to force alpha be at high values in areas where algorithm detects it as edge or background color. --- source/blender/compositor/nodes/COM_KeyingNode.cpp | 2 ++ .../blender/compositor/operations/COM_KeyingOperation.cpp | 8 ++++++++ .../blender/compositor/operations/COM_KeyingOperation.h | 1 + .../blender/nodes/composite/nodes/node_composite_keying.c | 1 + 4 files changed, 12 insertions(+) diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index b1bde9643df..75a2fe96646 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -157,6 +157,7 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext * InputSocket *inputImage = this->getInputSocket(0); InputSocket *inputScreen = this->getInputSocket(1); InputSocket *inputGarbageMatte = this->getInputSocket(2); + InputSocket *inputCoreMatte = this->getInputSocket(3); OutputSocket *outputImage = this->getOutputSocket(0); OutputSocket *outputMatte = this->getOutputSocket(1); OutputSocket *outputEdges = this->getOutputSocket(2); @@ -172,6 +173,7 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext * inputScreen->relinkConnections(keyingOperation->getInputSocket(1), 1, graph); inputGarbageMatte->relinkConnections(keyingOperation->getInputSocket(2), 2, graph); + inputCoreMatte->relinkConnections(keyingOperation->getInputSocket(3), 3, graph); if (keying_data->blur_pre) { /* chroma preblur operation for input of keying operation */ diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp index 599989d52dc..e04c79f6713 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp @@ -57,6 +57,7 @@ KeyingOperation::KeyingOperation(): NodeOperation() this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); this->screenBalance = 0.5f; @@ -64,6 +65,7 @@ KeyingOperation::KeyingOperation(): NodeOperation() this->pixelReader = NULL; this->screenReader = NULL; this->garbageReader = NULL; + this->coreReader = NULL; } void KeyingOperation::initExecution() @@ -71,6 +73,7 @@ void KeyingOperation::initExecution() this->pixelReader = this->getInputSocketReader(0); this->screenReader = this->getInputSocketReader(1); this->garbageReader = this->getInputSocketReader(2); + this->coreReader = this->getInputSocketReader(3); } void KeyingOperation::deinitExecution() @@ -78,6 +81,7 @@ void KeyingOperation::deinitExecution() this->pixelReader = NULL; this->screenReader = NULL; this->garbageReader = NULL; + this->coreReader = NULL; } void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) @@ -85,10 +89,12 @@ void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler float pixelColor[4]; float screenColor[4]; float garbageValue[4]; + float coreValue[4]; this->pixelReader->read(pixelColor, x, y, sampler, inputBuffers); this->screenReader->read(screenColor, x, y, sampler, inputBuffers); this->garbageReader->read(garbageValue, x, y, sampler, inputBuffers); + this->coreReader->read(coreValue, x, y, sampler, inputBuffers); int primary_channel = get_pixel_primary_channel(screenColor); @@ -108,6 +114,8 @@ void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler } color[0] *= (1.0f - garbageValue[0]); + + color[0] = MAX2(color[0], coreValue[0]); } bool KeyingOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h index 657a1ff807c..8d0e7851ee5 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.h +++ b/source/blender/compositor/operations/COM_KeyingOperation.h @@ -39,6 +39,7 @@ protected: SocketReader *pixelReader; SocketReader *screenReader; SocketReader *garbageReader; + SocketReader *coreReader; float screenBalance; diff --git a/source/blender/nodes/composite/nodes/node_composite_keying.c b/source/blender/nodes/composite/nodes/node_composite_keying.c index 31a8a0d67a6..f37c3686e2b 100644 --- a/source/blender/nodes/composite/nodes/node_composite_keying.c +++ b/source/blender/nodes/composite/nodes/node_composite_keying.c @@ -49,6 +49,7 @@ static bNodeSocketTemplate cmp_node_keying_in[] = { { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_RGBA, 1, "Key Color", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_FLOAT, 1, "Garbage Matte", 0.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_FLOAT, 1, "Core Matte", 0.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; From d0ebb1df5761caec51ab73bfab41940e08d01aa0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 13:35:24 +0000 Subject: [PATCH 343/360] fix for using un-initialized memory in the new compositor for the split view node. --- source/blender/compositor/COM_defines.h | 2 ++ source/blender/compositor/intern/COM_ExecutionGroup.cpp | 2 +- source/blender/compositor/nodes/COM_SplitViewerNode.cpp | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h index d59388c9206..57b73c836df 100644 --- a/source/blender/compositor/COM_defines.h +++ b/source/blender/compositor/COM_defines.h @@ -101,6 +101,8 @@ typedef enum OrderOfChunks { COM_TO_RULE_OF_THIRDS = 3 } OrderOfChunks; +#define COM_ORDER_OF_CHUNKS_DEFAULT COM_TO_CENTER_OUT + #define COM_RULE_OF_THIRDS_DIVIDER 100.0f #define COM_NUMBER_OF_CHANNELS 4 diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index 7a53af7f58c..aaca97d8479 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -229,7 +229,7 @@ void ExecutionGroup::execute(ExecutionSystem *graph) NodeOperation *operation = this->getOutputNodeOperation(); float centerX = 0.5; float centerY = 0.5; - int chunkorder = COM_TO_CENTER_OUT; + OrderOfChunks chunkorder = COM_ORDER_OF_CHUNKS_DEFAULT; if (operation->isViewerOperation()) { ViewerBaseOperation *viewer = (ViewerBaseOperation*)operation; diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp index 8bf9fd2bf06..a93b066e1e9 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp @@ -41,6 +41,7 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont splitViewerOperation->setImage(image); splitViewerOperation->setImageUser(imageUser); splitViewerOperation->setActive((this->getbNode()->flag & NODE_DO_OUTPUT) && this->isInActiveGroup()); + splitViewerOperation->setChunkOrder(COM_ORDER_OF_CHUNKS_DEFAULT); splitViewerOperation->setSplitPercentage(this->getbNode()->custom1); splitViewerOperation->setXSplit(!this->getbNode()->custom2); image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph); From e11692bc73576ff2942f4e65b89bf75f4e29f301 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 13:56:54 +0000 Subject: [PATCH 344/360] fix for other uninitialized values for the split viewer node as well as incorrect frees for gaussian blue nodes. --- .../blender/compositor/nodes/COM_SplitViewerNode.cpp | 10 +++++++++- .../operations/COM_GaussianBokehBlurOperation.cpp | 2 +- .../operations/COM_GaussianXBlurOperation.cpp | 2 +- .../operations/COM_GaussianYBlurOperation.cpp | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp index a93b066e1e9..d7f61caf456 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp @@ -38,11 +38,19 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont ImageUser * imageUser = (ImageUser*) this->getbNode()->storage; if (image1Socket->isConnected() && image2Socket->isConnected()) { SplitViewerOperation *splitViewerOperation = new SplitViewerOperation(); + splitViewerOperation->setColorManagement(context->getScene()->r.color_mgt_flag & R_COLOR_MANAGEMENT); + splitViewerOperation->setColorPredivide(context->getScene()->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); splitViewerOperation->setImage(image); splitViewerOperation->setImageUser(imageUser); splitViewerOperation->setActive((this->getbNode()->flag & NODE_DO_OUTPUT) && this->isInActiveGroup()); - splitViewerOperation->setChunkOrder(COM_ORDER_OF_CHUNKS_DEFAULT); splitViewerOperation->setSplitPercentage(this->getbNode()->custom1); + + /* defaults - the viewer node has these options but not exposed for split view + * we could use the split to define an area of interest on one axis at least */ + splitViewerOperation->setChunkOrder(COM_ORDER_OF_CHUNKS_DEFAULT); + splitViewerOperation->setCenterX(0.5f); + splitViewerOperation->setCenterY(0.5f); + splitViewerOperation->setXSplit(!this->getbNode()->custom2); image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph); image2Socket->relinkConnections(splitViewerOperation->getInputSocket(1), 1, graph); diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index b5ae54299eb..b38ed28cd6a 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -152,7 +152,7 @@ void GaussianBokehBlurOperation::executePixel(float *color, int x, int y, Memory void GaussianBokehBlurOperation::deinitExecution() { BlurBaseOperation::deinitExecution(); - delete this->gausstab; + delete [] this->gausstab; this->gausstab = NULL; } diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp index 8edbf8f0617..09a2a70ead3 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp @@ -110,7 +110,7 @@ void GaussianXBlurOperation::executePixel(float *color, int x, int y, MemoryBuff void GaussianXBlurOperation::deinitExecution() { BlurBaseOperation::deinitExecution(); - delete this->gausstab; + delete [] this->gausstab; this->gausstab = NULL; } diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp index 7143cc02615..ace817194f3 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -105,7 +105,7 @@ void GaussianYBlurOperation::executePixel(float *color, int x, int y, MemoryBuff void GaussianYBlurOperation::deinitExecution() { BlurBaseOperation::deinitExecution(); - delete this->gausstab; + delete [] this->gausstab; this->gausstab = NULL; } From fb278a501e2c64f4ecba541545465975eebb8dcc Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 14:11:05 +0000 Subject: [PATCH 345/360] Ensure enums in DNA files has got explicit values See http://wiki.blender.org/index.php/Dev:Doc/CodeStyle#Macros.2C_Enums.2C_Inline_functions --- source/blender/makesdna/DNA_ID.h | 4 +- source/blender/makesdna/DNA_action_types.h | 2 +- source/blender/makesdna/DNA_anim_types.h | 30 ++-- source/blender/makesdna/DNA_armature_types.h | 16 +- source/blender/makesdna/DNA_boid_types.h | 56 +++--- source/blender/makesdna/DNA_brush_types.h | 28 +-- source/blender/makesdna/DNA_color_types.h | 14 +- .../blender/makesdna/DNA_constraint_types.h | 136 +++++++-------- source/blender/makesdna/DNA_curve_types.h | 20 +-- source/blender/makesdna/DNA_mask_types.h | 6 +- source/blender/makesdna/DNA_modifier_types.h | 110 ++++++------ source/blender/makesdna/DNA_object_force.h | 28 +-- .../blender/makesdna/DNA_packedFile_types.h | 20 +-- source/blender/makesdna/DNA_screen_types.h | 14 +- source/blender/makesdna/DNA_sound_types.h | 4 +- source/blender/makesdna/DNA_space_types.h | 162 +++++++++--------- source/blender/makesdna/DNA_tracking_types.h | 2 +- 17 files changed, 326 insertions(+), 326 deletions(-) diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index b6fc4f58bd7..95eadc23ef4 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -139,8 +139,8 @@ typedef struct Library { } Library; enum eIconSizes { - ICON_SIZE_ICON, - ICON_SIZE_PREVIEW + ICON_SIZE_ICON = 0, + ICON_SIZE_PREVIEW = 1 }; #define NUM_ICON_SIZES (ICON_SIZE_PREVIEW + 1) diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 08d5743bb88..ea012090bbd 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -373,7 +373,7 @@ typedef enum ePose_Flags { /* bPose->iksolver and bPose->ikparam->iksolver */ typedef enum ePose_IKSolverType { IKSOLVER_LEGACY = 0, - IKSOLVER_ITASC + IKSOLVER_ITASC = 1 } ePose_IKSolverType; /* header for all bPose->ikparam structures */ diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index fd4b86a4155..55fb3322806 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -72,15 +72,15 @@ typedef struct FModifier { */ typedef enum eFModifier_Types { FMODIFIER_TYPE_NULL = 0, - FMODIFIER_TYPE_GENERATOR, - FMODIFIER_TYPE_FN_GENERATOR, - FMODIFIER_TYPE_ENVELOPE, - FMODIFIER_TYPE_CYCLES, - FMODIFIER_TYPE_NOISE, - FMODIFIER_TYPE_FILTER, /* unimplemented - for applying: fft, high/low pass filters, etc. */ - FMODIFIER_TYPE_PYTHON, - FMODIFIER_TYPE_LIMITS, - FMODIFIER_TYPE_STEPPED, + FMODIFIER_TYPE_GENERATOR = 1, + FMODIFIER_TYPE_FN_GENERATOR = 2, + FMODIFIER_TYPE_ENVELOPE = 3, + FMODIFIER_TYPE_CYCLES = 4, + FMODIFIER_TYPE_NOISE = 5, + FMODIFIER_TYPE_FILTER = 6, /* unimplemented - for applying: fft, high/low pass filters, etc. */ + FMODIFIER_TYPE_PYTHON = 7, + FMODIFIER_TYPE_LIMITS = 8, + FMODIFIER_TYPE_STEPPED = 9, /* NOTE: all new modifiers must be added above this line */ FMODIFIER_NUM_TYPES @@ -120,7 +120,7 @@ typedef struct FMod_Generator { /* generator modes */ typedef enum eFMod_Generator_Modes { FCM_GENERATOR_POLYNOMIAL = 0, - FCM_GENERATOR_POLYNOMIAL_FACTORISED + FCM_GENERATOR_POLYNOMIAL_FACTORISED = 1 } eFMod_Generator_Modes; @@ -156,11 +156,11 @@ typedef struct FMod_FunctionGenerator { /* 'function' generator types */ typedef enum eFMod_Generator_Functions { FCM_GENERATOR_FN_SIN = 0, - FCM_GENERATOR_FN_COS, - FCM_GENERATOR_FN_TAN, - FCM_GENERATOR_FN_SQRT, - FCM_GENERATOR_FN_LN, - FCM_GENERATOR_FN_SINC + FCM_GENERATOR_FN_COS = 1, + FCM_GENERATOR_FN_TAN = 2, + FCM_GENERATOR_FN_SQRT = 3, + FCM_GENERATOR_FN_LN = 4, + FCM_GENERATOR_FN_SINC = 5 } eFMod_Generator_Functions; diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 7faeccd2a32..cc08d0e92bd 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -135,16 +135,16 @@ typedef enum eArmature_Flag { /* armature->drawtype */ typedef enum eArmature_Drawtype { ARM_OCTA = 0, - ARM_LINE, - ARM_B_BONE, - ARM_ENVELOPE, - ARM_WIRE + ARM_LINE = 1, + ARM_B_BONE = 2, + ARM_ENVELOPE = 3, + ARM_WIRE = 4 } eArmature_Drawtype; /* armature->gevertdeformer */ typedef enum eArmature_VertDeformer { - ARM_VDEF_BLENDER, - ARM_VDEF_BGE_CPU + ARM_VDEF_BLENDER = 0, + ARM_VDEF_BGE_CPU = 1 } eArmature_VertDeformer; /* armature->deformflag */ @@ -170,8 +170,8 @@ typedef enum eArmature_PathFlag { // XXX depreceated... old animation system (armature only viz) typedef enum eArmature_GhostType { ARM_GHOST_CUR = 0, - ARM_GHOST_RANGE, - ARM_GHOST_KEYS + ARM_GHOST_RANGE = 1, + ARM_GHOST_KEYS = 2 } eArmature_GhostType; /* bone->flag */ diff --git a/source/blender/makesdna/DNA_boid_types.h b/source/blender/makesdna/DNA_boid_types.h index 698667ff33c..ce5fc4b0c3c 100644 --- a/source/blender/makesdna/DNA_boid_types.h +++ b/source/blender/makesdna/DNA_boid_types.h @@ -36,18 +36,18 @@ typedef enum BoidRuleType { eBoidRuleType_None = 0, - eBoidRuleType_Goal, /* go to goal assigned object or loudest assigned signal source */ - eBoidRuleType_Avoid, /* get away from assigned object or loudest assigned signal source */ - eBoidRuleType_AvoidCollision, /* manoeuver to avoid collisions with other boids and deflector object in near future */ - eBoidRuleType_Separate, /* keep from going through other boids */ - eBoidRuleType_Flock, /* move to center of neighbors and match their velocity */ - eBoidRuleType_FollowLeader, /* follow a boid or assigned object */ - eBoidRuleType_AverageSpeed, /* maintain speed, flight level or wander*/ - eBoidRuleType_Fight, /* go to closest enemy and attack when in range */ - //eBoidRuleType_Protect, /* go to enemy closest to target and attack when in range */ - //eBoidRuleType_Hide, /* find a deflector move to it's other side from closest enemy */ - //eBoidRuleType_FollowPath, /* move along a assigned curve or closest curve in a group */ - //eBoidRuleType_FollowWall, /* move next to a deflector object's in direction of it's tangent */ + eBoidRuleType_Goal = 1, /* go to goal assigned object or loudest assigned signal source */ + eBoidRuleType_Avoid = 2, /* get away from assigned object or loudest assigned signal source */ + eBoidRuleType_AvoidCollision = 3, /* manoeuver to avoid collisions with other boids and deflector object in near future */ + eBoidRuleType_Separate = 4, /* keep from going through other boids */ + eBoidRuleType_Flock = 5, /* move to center of neighbors and match their velocity */ + eBoidRuleType_FollowLeader = 6, /* follow a boid or assigned object */ + eBoidRuleType_AverageSpeed = 7, /* maintain speed, flight level or wander*/ + eBoidRuleType_Fight = 8, /* go to closest enemy and attack when in range */ + //eBoidRuleType_Protect = 9, /* go to enemy closest to target and attack when in range */ + //eBoidRuleType_Hide = 10, /* find a deflector move to it's other side from closest enemy */ + //eBoidRuleType_FollowPath = 11, /* move along a assigned curve or closest curve in a group */ + //eBoidRuleType_FollowWall = 12, /* move next to a deflector object's in direction of it's tangent */ NUM_BOID_RULE_TYPES } BoidRuleType; @@ -98,10 +98,10 @@ typedef struct BoidRuleFight { typedef enum BoidMode { eBoidMode_InAir = 0, - eBoidMode_OnLand, - eBoidMode_Climbing, - eBoidMode_Falling, - eBoidMode_Liftoff, + eBoidMode_OnLand = 1, + eBoidMode_Climbing = 2, + eBoidMode_Falling = 3, + eBoidMode_Liftoff = 4, NUM_BOID_MODES } BoidMode; @@ -114,20 +114,20 @@ typedef struct BoidData { // planned for near future //typedef enum BoidConditionMode { // eBoidConditionType_Then = 0, -// eBoidConditionType_And, -// eBoidConditionType_Or, +// eBoidConditionType_And = 1, +// eBoidConditionType_Or = 2, // NUM_BOID_CONDITION_MODES //} BoidConditionMode; //typedef enum BoidConditionType { // eBoidConditionType_None = 0, -// eBoidConditionType_Signal, -// eBoidConditionType_NoSignal, -// eBoidConditionType_HealthBelow, -// eBoidConditionType_HealthAbove, -// eBoidConditionType_See, -// eBoidConditionType_NotSee, -// eBoidConditionType_StateTime, -// eBoidConditionType_Touching, +// eBoidConditionType_Signal = 1, +// eBoidConditionType_NoSignal = 2, +// eBoidConditionType_HealthBelow = 3, +// eBoidConditionType_HealthAbove = 4, +// eBoidConditionType_See = 5, +// eBoidConditionType_NotSee = 6, +// eBoidConditionType_StateTime = 7, +// eBoidConditionType_Touching = 8, // NUM_BOID_CONDITION_TYPES //} BoidConditionType; //typedef struct BoidCondition { @@ -142,8 +142,8 @@ typedef struct BoidData { typedef enum BoidRulesetType { eBoidRulesetType_Fuzzy = 0, - eBoidRulesetType_Random, - eBoidRulesetType_Average, + eBoidRulesetType_Random = 1, + eBoidRulesetType_Average = 2, NUM_BOID_RULESET_TYPES } BoidRulesetType; #define BOIDSTATE_CURRENT 1 diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 0cef9aa03b7..cc26ee479d7 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -174,26 +174,26 @@ typedef enum BrushSculptTool { /* direction that the brush displaces along */ enum { - SCULPT_DISP_DIR_AREA, - SCULPT_DISP_DIR_VIEW, - SCULPT_DISP_DIR_X, - SCULPT_DISP_DIR_Y, - SCULPT_DISP_DIR_Z + SCULPT_DISP_DIR_AREA = 0, + SCULPT_DISP_DIR_VIEW = 1, + SCULPT_DISP_DIR_X = 2, + SCULPT_DISP_DIR_Y = 3, + SCULPT_DISP_DIR_Z = 4 }; enum { - PAINT_BLEND_MIX, - PAINT_BLEND_ADD, - PAINT_BLEND_SUB, - PAINT_BLEND_MUL, - PAINT_BLEND_BLUR, - PAINT_BLEND_LIGHTEN, - PAINT_BLEND_DARKEN + PAINT_BLEND_MIX = 0, + PAINT_BLEND_ADD = 1, + PAINT_BLEND_SUB = 2, + PAINT_BLEND_MUL = 3, + PAINT_BLEND_BLUR = 4, + PAINT_BLEND_LIGHTEN = 5, + PAINT_BLEND_DARKEN = 6 }; typedef enum { - BRUSH_MASK_DRAW, - BRUSH_MASK_SMOOTH + BRUSH_MASK_DRAW = 0, + BRUSH_MASK_SMOOTH = 1 } BrushMaskTool; #define MAX_BRUSH_PIXEL_RADIUS 200 diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h index 99e2a123fe7..1f8fdd20dda 100644 --- a/source/blender/makesdna/DNA_color_types.h +++ b/source/blender/makesdna/DNA_color_types.h @@ -86,13 +86,13 @@ typedef struct CurveMapping { /* cumapping->preset */ typedef enum CurveMappingPreset { - CURVE_PRESET_LINE, - CURVE_PRESET_SHARP, - CURVE_PRESET_SMOOTH, - CURVE_PRESET_MAX, - CURVE_PRESET_MID9, - CURVE_PRESET_ROUND, - CURVE_PRESET_ROOT, + CURVE_PRESET_LINE = 0, + CURVE_PRESET_SHARP = 1, + CURVE_PRESET_SMOOTH = 2, + CURVE_PRESET_MAX = 3, + CURVE_PRESET_MID9 = 4, + CURVE_PRESET_ROUND = 5, + CURVE_PRESET_ROOT = 6, } CurveMappingPreset; /* histogram->mode */ diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 6ca9a95400d..40362424532 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -104,9 +104,9 @@ typedef enum B_CONSTRAINT_TARGET_FLAG { /* bConstraintTarget/bConstraintOb -> type */ typedef enum B_CONSTRAINT_OB_TYPE { CONSTRAINT_OBTYPE_OBJECT = 1, /* string is "" */ - CONSTRAINT_OBTYPE_BONE, /* string is bone-name */ - CONSTRAINT_OBTYPE_VERT, /* string is vertex-group name */ - CONSTRAINT_OBTYPE_CV /* string is vertex-group name - is not available until curves get vgroups */ + CONSTRAINT_OBTYPE_BONE = 2, /* string is bone-name */ + CONSTRAINT_OBTYPE_VERT = 3, /* string is vertex-group name */ + CONSTRAINT_OBTYPE_CV = 4 /* string is vertex-group name - is not available until curves get vgroups */ } B_CONSTRAINT_OB_TYPE; @@ -152,7 +152,7 @@ typedef struct bKinematicConstraint { typedef enum B_CONSTRAINT_IK_TYPE { CONSTRAINT_IK_COPYPOSE = 0, /* 'standard' IK constraint: match position and/or orientation of target */ - CONSTRAINT_IK_DISTANCE /* maintain distance with target */ + CONSTRAINT_IK_DISTANCE = 1 /* maintain distance with target */ } B_CONSTRAINT_IK_TYPE; @@ -444,34 +444,34 @@ typedef struct bObjectSolverConstraint { */ typedef enum eBConstraint_Types { CONSTRAINT_TYPE_NULL = 0, /* Invalid/legacy constraint */ - CONSTRAINT_TYPE_CHILDOF, /* Unimplemented non longer :) - during constraints recode, Aligorith */ - CONSTRAINT_TYPE_TRACKTO, - CONSTRAINT_TYPE_KINEMATIC, - CONSTRAINT_TYPE_FOLLOWPATH, - CONSTRAINT_TYPE_ROTLIMIT, /* Unimplemented no longer :) - Aligorith */ - CONSTRAINT_TYPE_LOCLIMIT, /* Unimplemented no longer :) - Aligorith */ - CONSTRAINT_TYPE_SIZELIMIT, /* Unimplemented no longer :) - Aligorith */ - CONSTRAINT_TYPE_ROTLIKE, - CONSTRAINT_TYPE_LOCLIKE, - CONSTRAINT_TYPE_SIZELIKE, - CONSTRAINT_TYPE_PYTHON, /* Unimplemented no longer :) - Aligorith. Scripts */ - CONSTRAINT_TYPE_ACTION, - CONSTRAINT_TYPE_LOCKTRACK, /* New Tracking constraint that locks an axis in place - theeth */ - CONSTRAINT_TYPE_DISTLIMIT, /* limit distance */ - CONSTRAINT_TYPE_STRETCHTO, /* claiming this to be mine :) is in tuhopuu bjornmose */ - CONSTRAINT_TYPE_MINMAX, /* floor constraint */ - CONSTRAINT_TYPE_RIGIDBODYJOINT, /* rigidbody constraint */ - CONSTRAINT_TYPE_CLAMPTO, /* clampto constraint */ - CONSTRAINT_TYPE_TRANSFORM, /* transformation (loc/rot/size -> loc/rot/size) constraint */ - CONSTRAINT_TYPE_SHRINKWRAP, /* shrinkwrap (loc/rot) constraint */ - CONSTRAINT_TYPE_DAMPTRACK, /* New Tracking constraint that minimises twisting */ - CONSTRAINT_TYPE_SPLINEIK, /* Spline-IK - Align 'n' bones to a curve */ - CONSTRAINT_TYPE_TRANSLIKE, /* Copy transform matrix */ - CONSTRAINT_TYPE_SAMEVOL, /* Maintain volume during scaling */ - CONSTRAINT_TYPE_PIVOT, /* Pivot Constraint */ - CONSTRAINT_TYPE_FOLLOWTRACK, /* Follow Track Constraint */ - CONSTRAINT_TYPE_CAMERASOLVER, /* Camera Solver Constraint */ - CONSTRAINT_TYPE_OBJECTSOLVER, /* Object Solver Constraint */ + CONSTRAINT_TYPE_CHILDOF = 1, /* Unimplemented non longer :) - during constraints recode, Aligorith */ + CONSTRAINT_TYPE_TRACKTO = 2, + CONSTRAINT_TYPE_KINEMATIC = 3, + CONSTRAINT_TYPE_FOLLOWPATH = 4, + CONSTRAINT_TYPE_ROTLIMIT = 5, /* Unimplemented no longer :) - Aligorith */ + CONSTRAINT_TYPE_LOCLIMIT = 6, /* Unimplemented no longer :) - Aligorith */ + CONSTRAINT_TYPE_SIZELIMIT = 7, /* Unimplemented no longer :) - Aligorith */ + CONSTRAINT_TYPE_ROTLIKE = 8, + CONSTRAINT_TYPE_LOCLIKE = 9, + CONSTRAINT_TYPE_SIZELIKE = 10, + CONSTRAINT_TYPE_PYTHON = 11, /* Unimplemented no longer :) - Aligorith. Scripts */ + CONSTRAINT_TYPE_ACTION = 12, + CONSTRAINT_TYPE_LOCKTRACK = 13, /* New Tracking constraint that locks an axis in place - theeth */ + CONSTRAINT_TYPE_DISTLIMIT = 14, /* limit distance */ + CONSTRAINT_TYPE_STRETCHTO = 15, /* claiming this to be mine :) is in tuhopuu bjornmose */ + CONSTRAINT_TYPE_MINMAX = 16, /* floor constraint */ + CONSTRAINT_TYPE_RIGIDBODYJOINT = 17, /* rigidbody constraint */ + CONSTRAINT_TYPE_CLAMPTO = 18, /* clampto constraint */ + CONSTRAINT_TYPE_TRANSFORM = 19, /* transformation (loc/rot/size -> loc/rot/size) constraint */ + CONSTRAINT_TYPE_SHRINKWRAP = 20, /* shrinkwrap (loc/rot) constraint */ + CONSTRAINT_TYPE_DAMPTRACK = 21, /* New Tracking constraint that minimises twisting */ + CONSTRAINT_TYPE_SPLINEIK = 22, /* Spline-IK - Align 'n' bones to a curve */ + CONSTRAINT_TYPE_TRANSLIKE = 23, /* Copy transform matrix */ + CONSTRAINT_TYPE_SAMEVOL = 24, /* Maintain volume during scaling */ + CONSTRAINT_TYPE_PIVOT = 25, /* Pivot Constraint */ + CONSTRAINT_TYPE_FOLLOWTRACK = 26, /* Follow Track Constraint */ + CONSTRAINT_TYPE_CAMERASOLVER = 27, /* Camera Solver Constraint */ + CONSTRAINT_TYPE_OBJECTSOLVER = 28, /* Object Solver Constraint */ /* NOTE: no constraints are allowed to be added after this */ NUM_CONSTRAINT_TYPES @@ -504,13 +504,13 @@ typedef enum eBConstraint_SpaceTypes { /* for objects (relative to parent/without parent influence), * for bones (along normals of bone, without parent/restpositions) */ - CONSTRAINT_SPACE_LOCAL, /* = 1 */ + CONSTRAINT_SPACE_LOCAL = 1, /* for posechannels - pose space */ - CONSTRAINT_SPACE_POSE, /* = 2 */ + CONSTRAINT_SPACE_POSE = 2, /* for posechannels - local with parent */ - CONSTRAINT_SPACE_PARLOCAL, /* = 3 */ + CONSTRAINT_SPACE_PARLOCAL = 3, /* for files from between 2.43-2.46 (should have been parlocal) */ - CONSTRAINT_SPACE_INVALID /* = 4. do not exchange for anything! */ + CONSTRAINT_SPACE_INVALID = 4 /* do not exchange for anything! */ } eBConstraint_SpaceTypes; /* bConstraintChannel.flag */ @@ -557,8 +557,8 @@ typedef enum eCopyScale_Flags { /* bSameVolumeConstraint.flag */ typedef enum eSameVolume_Modes { SAMEVOL_X = 0, - SAMEVOL_Y, - SAMEVOL_Z + SAMEVOL_Y = 1, + SAMEVOL_Z = 2 } eSameVolume_Modes; /* bActionConstraint.flag */ @@ -569,26 +569,26 @@ typedef enum eActionConstraint_Flags { /* Locked-Axis Values (Locked Track) */ typedef enum eLockAxis_Modes { - LOCK_X = 0, - LOCK_Y, - LOCK_Z + LOCK_X = 0, + LOCK_Y = 1, + LOCK_Z = 2 } eLockAxis_Modes; /* Up-Axis Values (TrackTo and Locked Track) */ typedef enum eUpAxis_Modes { - UP_X = 0, - UP_Y, - UP_Z + UP_X = 0, + UP_Y = 1, + UP_Z = 2 } eUpAxis_Modes; /* Tracking axis (TrackTo, Locked Track, Damped Track) and minmax (floor) constraint */ typedef enum eTrackToAxis_Modes { TRACK_X = 0, - TRACK_Y, - TRACK_Z, - TRACK_nX, - TRACK_nY, - TRACK_nZ + TRACK_Y = 1, + TRACK_Z = 2, + TRACK_nX = 3, + TRACK_nY = 4, + TRACK_nZ = 5 } eTrackToAxis_Modes; /* FollowPath flags */ @@ -606,24 +606,24 @@ typedef enum eTrackTo_Flags { /* Strech To Constraint -> volmode */ typedef enum eStretchTo_VolMode { VOLUME_XZ = 0, - VOLUME_X, - VOLUME_Z, - NO_VOLUME + VOLUME_X = 1, + VOLUME_Z = 2, + NO_VOLUME = 3 } eStretchTo_VolMode; /* Stretch To Constraint -> plane mode */ typedef enum eStretchTo_PlaneMode { PLANE_X = 0, - PLANE_Y, - PLANE_Z + PLANE_Y = 1, + PLANE_Z = 2 } eStretchTo_PlaneMode; /* Clamp-To Constraint ->flag */ typedef enum eClampTo_Modes { CLAMPTO_AUTO = 0, - CLAMPTO_X, - CLAMPTO_Y, - CLAMPTO_Z + CLAMPTO_X = 1, + CLAMPTO_Y = 2, + CLAMPTO_Z = 3 } eClampTo_Modes; /* ClampTo Constraint ->flag2 */ @@ -673,9 +673,9 @@ typedef enum eSplineIK_XZScaleModes { /* no x/z scaling */ CONSTRAINT_SPLINEIK_XZS_NONE = 0, /* bones in the chain should take their x/z scales from the original scaling */ - CONSTRAINT_SPLINEIK_XZS_ORIGINAL, + CONSTRAINT_SPLINEIK_XZS_ORIGINAL = 1, /* x/z scales are the inverse of the y-scale */ - CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC + CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC = 2 } eSplineIK_XZScaleModes; /* MinMax (floor) flags */ @@ -721,9 +721,9 @@ typedef enum eDistLimit_Flag { /* bDistLimitConstraint->mode */ typedef enum eDistLimit_Modes { - LIMITDIST_INSIDE = 0, - LIMITDIST_OUTSIDE, - LIMITDIST_ONSURFACE + LIMITDIST_INSIDE = 0, + LIMITDIST_OUTSIDE = 1, + LIMITDIST_ONSURFACE = 2 } eDistLimit_Modes; /* python constraint -> flag */ @@ -753,18 +753,18 @@ typedef enum ePivotConstraint_Axis { PIVOTCON_AXIS_NONE = -1, /* consider -ve x-axis rotations */ - PIVOTCON_AXIS_X_NEG, + PIVOTCON_AXIS_X_NEG = 0, /* consider -ve y-axis rotations */ - PIVOTCON_AXIS_Y_NEG, + PIVOTCON_AXIS_Y_NEG = 1, /* consider -ve z-axis rotations */ - PIVOTCON_AXIS_Z_NEG, + PIVOTCON_AXIS_Z_NEG = 2, /* consider +ve x-axis rotations */ - PIVOTCON_AXIS_X, + PIVOTCON_AXIS_X = 3, /* consider +ve y-axis rotations */ - PIVOTCON_AXIS_Y, + PIVOTCON_AXIS_Y = 4, /* consider +ve z-axis rotations */ - PIVOTCON_AXIS_Z + PIVOTCON_AXIS_Z = 5 } ePivotConstraint_Axis; /* settings for Pivot Constraint in general */ diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index da8458d587e..f5c0148d9d0 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -315,26 +315,26 @@ typedef struct Curve { /* h1 h2 (beztriple) */ typedef enum eBezTriple_Handle { - HD_FREE = 0, - HD_AUTO, - HD_VECT, - HD_ALIGN, - HD_AUTO_ANIM /* auto-clamped handles for animation */ + HD_FREE = 0, + HD_AUTO = 1, + HD_VECT = 2, + HD_ALIGN = 3, + HD_AUTO_ANIM = 4 /* auto-clamped handles for animation */ } eBezTriple_Handle; /* interpolation modes (used only for BezTriple->ipo) */ typedef enum eBezTriple_Interpolation { BEZT_IPO_CONST = 0, /* constant interpolation */ - BEZT_IPO_LIN, /* linear interpolation */ - BEZT_IPO_BEZ /* bezier interpolation */ + BEZT_IPO_LIN = 1, /* linear interpolation */ + BEZT_IPO_BEZ = 2 /* bezier interpolation */ } eBezTriple_Interpolation; /* types of keyframe (used only for BezTriple->hide when BezTriple is used in F-Curves) */ typedef enum eBezTriple_KeyframeType { BEZT_KEYTYPE_KEYFRAME = 0, /* default - 'proper' Keyframe */ - BEZT_KEYTYPE_EXTREME, /* 'extreme' keyframe */ - BEZT_KEYTYPE_BREAKDOWN, /* 'breakdown' keyframe */ - BEZT_KEYTYPE_JITTER, /* 'jitter' keyframe (for adding 'filler' secondary motion) */ + BEZT_KEYTYPE_EXTREME = 1, /* 'extreme' keyframe */ + BEZT_KEYTYPE_BREAKDOWN = 2, /* 'breakdown' keyframe */ + BEZT_KEYTYPE_JITTER = 3, /* 'jitter' keyframe (for adding 'filler' secondary motion) */ } eBezTriple_KeyframeType; /* checks if the given BezTriple is selected */ diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index 20701f9adc0..52fedd72e86 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -155,9 +155,9 @@ typedef struct MaskLayer { /* SpaceClip->mask_draw_type */ enum { MASK_DT_OUTLINE = 0, - MASK_DT_DASH, - MASK_DT_BLACK, - MASK_DT_WHITE + MASK_DT_DASH = 1, + MASK_DT_BLACK = 2, + MASK_DT_WHITE = 3 }; /* masklay->blend */ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index cf8b08549f6..4172db90c05 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -35,49 +35,49 @@ * (ONLY ADD NEW ITEMS AT THE END) */ typedef enum ModifierType { - eModifierType_None = 0, - eModifierType_Subsurf, - eModifierType_Lattice, - eModifierType_Curve, - eModifierType_Build, - eModifierType_Mirror, - eModifierType_Decimate, - eModifierType_Wave, - eModifierType_Armature, - eModifierType_Hook, - eModifierType_Softbody, - eModifierType_Boolean, - eModifierType_Array, - eModifierType_EdgeSplit, - eModifierType_Displace, - eModifierType_UVProject, - eModifierType_Smooth, - eModifierType_Cast, - eModifierType_MeshDeform, - eModifierType_ParticleSystem, - eModifierType_ParticleInstance, - eModifierType_Explode, - eModifierType_Cloth, - eModifierType_Collision, - eModifierType_Bevel, - eModifierType_Shrinkwrap, - eModifierType_Fluidsim, - eModifierType_Mask, - eModifierType_SimpleDeform, - eModifierType_Multires, - eModifierType_Surface, - eModifierType_Smoke, - eModifierType_ShapeKey, - eModifierType_Solidify, - eModifierType_Screw, - eModifierType_Warp, - eModifierType_WeightVGEdit, - eModifierType_WeightVGMix, - eModifierType_WeightVGProximity, - eModifierType_Ocean, - eModifierType_DynamicPaint, - eModifierType_Remesh, - eModifierType_Skin, + eModifierType_None = 0, + eModifierType_Subsurf = 1, + eModifierType_Lattice = 2, + eModifierType_Curve = 3, + eModifierType_Build = 4, + eModifierType_Mirror = 5, + eModifierType_Decimate = 6, + eModifierType_Wave = 7, + eModifierType_Armature = 8, + eModifierType_Hook = 9, + eModifierType_Softbody = 10, + eModifierType_Boolean = 11, + eModifierType_Array = 12, + eModifierType_EdgeSplit = 13, + eModifierType_Displace = 14, + eModifierType_UVProject = 15, + eModifierType_Smooth = 16, + eModifierType_Cast = 17, + eModifierType_MeshDeform = 18, + eModifierType_ParticleSystem = 19, + eModifierType_ParticleInstance = 20, + eModifierType_Explode = 21, + eModifierType_Cloth = 22, + eModifierType_Collision = 23, + eModifierType_Bevel = 24, + eModifierType_Shrinkwrap = 25, + eModifierType_Fluidsim = 26, + eModifierType_Mask = 27, + eModifierType_SimpleDeform = 28, + eModifierType_Multires = 29, + eModifierType_Surface = 30, + eModifierType_Smoke = 31, + eModifierType_ShapeKey = 32, + eModifierType_Solidify = 33, + eModifierType_Screw = 34, + eModifierType_Warp = 35, + eModifierType_WeightVGEdit = 36, + eModifierType_WeightVGMix = 37, + eModifierType_WeightVGProximity = 38, + eModifierType_Ocean = 39, + eModifierType_DynamicPaint = 40, + eModifierType_Remesh = 41, + eModifierType_Skin = 42, NUM_MODIFIER_TYPES } ModifierType; @@ -327,19 +327,19 @@ typedef struct DisplaceModifierData { /* DisplaceModifierData->direction */ enum { - MOD_DISP_DIR_X, - MOD_DISP_DIR_Y, - MOD_DISP_DIR_Z, - MOD_DISP_DIR_NOR, - MOD_DISP_DIR_RGB_XYZ, + MOD_DISP_DIR_X = 0, + MOD_DISP_DIR_Y = 1, + MOD_DISP_DIR_Z = 2, + MOD_DISP_DIR_NOR = 3, + MOD_DISP_DIR_RGB_XYZ = 4, }; /* DisplaceModifierData->texmapping */ enum { - MOD_DISP_MAP_LOCAL, - MOD_DISP_MAP_GLOBAL, - MOD_DISP_MAP_OBJECT, - MOD_DISP_MAP_UV + MOD_DISP_MAP_LOCAL = 0, + MOD_DISP_MAP_GLOBAL = 1, + MOD_DISP_MAP_OBJECT = 2, + MOD_DISP_MAP_UV = 3 }; typedef struct UVProjectModifierData { @@ -509,9 +509,9 @@ typedef struct SurfaceModifierData { } SurfaceModifierData; typedef enum { - eBooleanModifierOp_Intersect, - eBooleanModifierOp_Union, - eBooleanModifierOp_Difference, + eBooleanModifierOp_Intersect = 0, + eBooleanModifierOp_Union = 1, + eBooleanModifierOp_Difference = 2, } BooleanModifierOp; typedef struct BooleanModifierData { ModifierData modifier; diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index cc212dd6d06..854087b3b5b 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -40,20 +40,20 @@ extern "C" { /* pd->forcefield: Effector Fields types */ typedef enum PFieldType { - PFIELD_NULL = 0, /* (this is used for general effector weight) */ - PFIELD_FORCE, /* Force away/towards a point depending on force strength */ - PFIELD_VORTEX, /* Force around the effector normal */ - PFIELD_MAGNET, /* Force from the cross product of effector normal and point velocity */ - PFIELD_WIND, /* Force away and towards a point depending which side of the effector */ - /* normal the point is */ - PFIELD_GUIDE, /* Force along curve for dynamics, a shaping curve for hair paths */ - PFIELD_TEXTURE, /* Force based on texture values calculated at point coordinates */ - PFIELD_HARMONIC, /* Force of a harmonic (damped) oscillator */ - PFIELD_CHARGE, /* Force away/towards a point depending on point charge */ - PFIELD_LENNARDJ, /* Force due to a Lennard-Jones potential */ - PFIELD_BOID, /* Defines predator / goal for boids */ - PFIELD_TURBULENCE, /* Force defined by BLI_gTurbulence */ - PFIELD_DRAG, /* Linear & quadratic drag */ + PFIELD_NULL = 0, /* (this is used for general effector weight) */ + PFIELD_FORCE = 1, /* Force away/towards a point depending on force strength */ + PFIELD_VORTEX = 2, /* Force around the effector normal */ + PFIELD_MAGNET = 3, /* Force from the cross product of effector normal and point velocity */ + PFIELD_WIND = 4, /* Force away and towards a point depending which side of the effector */ + /* normal the point is */ + PFIELD_GUIDE = 5, /* Force along curve for dynamics, a shaping curve for hair paths */ + PFIELD_TEXTURE = 6, /* Force based on texture values calculated at point coordinates */ + PFIELD_HARMONIC = 7, /* Force of a harmonic (damped) oscillator */ + PFIELD_CHARGE = 8, /* Force away/towards a point depending on point charge */ + PFIELD_LENNARDJ = 9, /* Force due to a Lennard-Jones potential */ + PFIELD_BOID = 10, /* Defines predator / goal for boids */ + PFIELD_TURBULENCE = 11, /* Force defined by BLI_gTurbulence */ + PFIELD_DRAG = 12, /* Linear & quadratic drag */ NUM_PFIELD_TYPES } PFieldType; diff --git a/source/blender/makesdna/DNA_packedFile_types.h b/source/blender/makesdna/DNA_packedFile_types.h index 339ac0f8c0d..f01e89d18c9 100644 --- a/source/blender/makesdna/DNA_packedFile_types.h +++ b/source/blender/makesdna/DNA_packedFile_types.h @@ -43,18 +43,18 @@ typedef struct PackedFile { enum PF_FileStatus { PF_EQUAL = 0, - PF_DIFFERS, - PF_NOFILE, + PF_DIFFERS = 1, + PF_NOFILE = 2, - PF_WRITE_ORIGINAL, - PF_WRITE_LOCAL, - PF_USE_LOCAL, - PF_USE_ORIGINAL, - PF_KEEP, - PF_REMOVE, - PF_NOOP, + PF_WRITE_ORIGINAL = 3, + PF_WRITE_LOCAL = 4, + PF_USE_LOCAL = 5, + PF_USE_ORIGINAL = 6, + PF_KEEP = 7, + PF_REMOVE = 8, + PF_NOOP = 9, - PF_ASK + PF_ASK = 10 }; #endif /* PACKEDFILE_TYPES_H */ diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 75d9b91e9c8..34fb7ce60be 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -225,13 +225,13 @@ typedef struct ARegion { /* Do NOT change order, append on end. Types are hardcoded needed */ enum { RGN_TYPE_WINDOW = 0, - RGN_TYPE_HEADER, - RGN_TYPE_CHANNELS, - RGN_TYPE_TEMPORARY, - RGN_TYPE_UI, - RGN_TYPE_TOOLS, - RGN_TYPE_TOOL_PROPS, - RGN_TYPE_PREVIEW + RGN_TYPE_HEADER = 1, + RGN_TYPE_CHANNELS = 2, + RGN_TYPE_TEMPORARY = 3, + RGN_TYPE_UI = 4, + RGN_TYPE_TOOLS = 5, + RGN_TYPE_TOOL_PROPS = 6, + RGN_TYPE_PREVIEW = 7 }; /* region alignment */ diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h index 6f67f1fd3c9..6dc45e4a6de 100644 --- a/source/blender/makesdna/DNA_sound_types.h +++ b/source/blender/makesdna/DNA_sound_types.h @@ -104,8 +104,8 @@ typedef struct bSound { typedef enum eSound_Type { SOUND_TYPE_INVALID = -1, SOUND_TYPE_FILE = 0, - SOUND_TYPE_BUFFER, - SOUND_TYPE_LIMITER + SOUND_TYPE_BUFFER = 1, + SOUND_TYPE_LIMITER = 2 } eSound_Type; #endif diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 6a95628b650..2f6ea861cba 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -167,18 +167,18 @@ typedef struct SpaceButs { /* buts->mainb new */ typedef enum eSpaceButtons_Context { BCONTEXT_RENDER = 0, - BCONTEXT_SCENE, - BCONTEXT_WORLD, - BCONTEXT_OBJECT, - BCONTEXT_DATA, - BCONTEXT_MATERIAL, - BCONTEXT_TEXTURE, - BCONTEXT_PARTICLE, - BCONTEXT_PHYSICS, - BCONTEXT_BONE, - BCONTEXT_MODIFIER, - BCONTEXT_CONSTRAINT, - BCONTEXT_BONE_CONSTRAINT, + BCONTEXT_SCENE = 1, + BCONTEXT_WORLD = 2, + BCONTEXT_OBJECT = 3, + BCONTEXT_DATA = 4, + BCONTEXT_MATERIAL = 5, + BCONTEXT_TEXTURE = 6, + BCONTEXT_PARTICLE = 7, + BCONTEXT_PHYSICS = 8, + BCONTEXT_BONE = 9, + BCONTEXT_MODIFIER = 10, + BCONTEXT_CONSTRAINT = 11, + BCONTEXT_BONE_CONSTRAINT = 12, /* always as last... */ BCONTEXT_TOT @@ -194,17 +194,17 @@ typedef enum eSpaceButtons_Context { /* sbuts->texture_context */ typedef enum eSpaceButtons_Texture_Context { SB_TEXC_MAT_OR_LAMP = 0, - SB_TEXC_WORLD, - SB_TEXC_BRUSH, - SB_TEXC_PARTICLES, + SB_TEXC_WORLD = 1, + SB_TEXC_BRUSH = 2, + SB_TEXC_PARTICLES = 3, } eSpaceButtons_Texture_Context; /* sbuts->align */ typedef enum eSpaceButtons_Align { BUT_FREE = 0, - BUT_HORIZONTAL, - BUT_VERTICAL, - BUT_AUTO, + BUT_HORIZONTAL = 1, + BUT_VERTICAL = 2, + BUT_AUTO = 3, } eSpaceButtons_Align; /* sbuts->scaflag */ @@ -256,19 +256,19 @@ typedef enum eSpaceOutliner_Flag { /* SpaceOops->outlinevis */ typedef enum eSpaceOutliner_Mode { SO_ALL_SCENES = 0, - SO_CUR_SCENE, - SO_VISIBLE, - SO_SELECTED, - SO_ACTIVE, - SO_SAME_TYPE, - SO_GROUPS, - SO_LIBRARIES, - SO_VERSE_SESSION, - SO_VERSE_MS, - SO_SEQUENCE, - SO_DATABLOCKS, - SO_USERDEF, - SO_KEYMAP, + SO_CUR_SCENE = 1, + SO_VISIBLE = 2, + SO_SELECTED = 3, + SO_ACTIVE = 4, + SO_SAME_TYPE = 5, + SO_GROUPS = 6, + SO_LIBRARIES = 7, + SO_VERSE_SESSION = 8, + SO_VERSE_MS = 9, + SO_SEQUENCE = 10, + SO_DATABLOCKS = 11, + SO_USERDEF = 12, + SO_KEYMAP = 13, } eSpaceOutliner_Mode; /* SpaceOops->storeflag */ @@ -351,7 +351,7 @@ typedef enum eGraphEdit_Mode { /* all animation curves (from all over Blender) */ SIPO_MODE_ANIMATION = 0, /* drivers only */ - SIPO_MODE_DRIVERS, + SIPO_MODE_DRIVERS = 1, } eGraphEdit_Mode; @@ -479,10 +479,10 @@ typedef struct SpaceSeq { /* sseq->mainb */ typedef enum eSpaceSeq_RegionType { SEQ_DRAW_SEQUENCE = 0, - SEQ_DRAW_IMG_IMBUF, - SEQ_DRAW_IMG_WAVEFORM, - SEQ_DRAW_IMG_VECTORSCOPE, - SEQ_DRAW_IMG_HISTOGRAM, + SEQ_DRAW_IMG_IMBUF = 1, + SEQ_DRAW_IMG_WAVEFORM = 2, + SEQ_DRAW_IMG_VECTORSCOPE = 3, + SEQ_DRAW_IMG_HISTOGRAM = 4, } eSpaceSeq_RegionType; /* sseq->flag */ @@ -498,8 +498,8 @@ typedef enum eSpaceSeq_Flag { /* sseq->view */ typedef enum eSpaceSeq_Displays { SEQ_VIEW_SEQUENCE = 1, - SEQ_VIEW_PREVIEW, - SEQ_VIEW_SEQUENCE_PREVIEW, + SEQ_VIEW_PREVIEW = 2, + SEQ_VIEW_SEQUENCE_PREVIEW = 3, } eSpaceSeq_Dispays; /* sseq->render_size */ @@ -579,18 +579,18 @@ typedef struct SpaceFile { /* FileSelectParams.display */ enum FileDisplayTypeE { FILE_DEFAULTDISPLAY = 0, - FILE_SHORTDISPLAY, - FILE_LONGDISPLAY, - FILE_IMGDISPLAY + FILE_SHORTDISPLAY = 1, + FILE_LONGDISPLAY = 2, + FILE_IMGDISPLAY = 3 }; /* FileSelectParams.sort */ enum FileSortTypeE { FILE_SORT_NONE = 0, FILE_SORT_ALPHA = 1, - FILE_SORT_EXTENSION, - FILE_SORT_TIME, - FILE_SORT_SIZE + FILE_SORT_EXTENSION = 2, + FILE_SORT_TIME = 3, + FILE_SORT_SIZE = 4 }; /* these values need to be hardcoded in structs, dna does not recognize defines */ @@ -613,7 +613,7 @@ enum FileSortTypeE { /* filesel op property -> action */ typedef enum eFileSel_Action { FILE_OPENFILE = 0, - FILE_SAVE, + FILE_SAVE = 1, } eFileSel_Action; /* sfile->params->flag and simasel->flag */ @@ -695,15 +695,15 @@ typedef struct SpaceImage { /* SpaceImage->dt_uv */ typedef enum eSpaceImage_UVDT { SI_UVDT_OUTLINE = 0, - SI_UVDT_DASH, - SI_UVDT_BLACK, - SI_UVDT_WHITE, + SI_UVDT_DASH = 1, + SI_UVDT_BLACK = 2, + SI_UVDT_WHITE = 3, } eSpaceImage_UVDT; /* SpaceImage->dt_uvstretch */ typedef enum eSpaceImage_UVDT_Stretch { SI_UVDT_STRETCH_ANGLE = 0, - SI_UVDT_STRETCH_AREA, + SI_UVDT_STRETCH_AREA = 1, } eSpaceImage_UVDT_Stretch; /* SpaceImage->sticky @@ -885,14 +885,14 @@ typedef enum eSpaceNode_Flag { /* snode->texfrom */ typedef enum eSpaceNode_TexFrom { SNODE_TEX_OBJECT = 0, - SNODE_TEX_WORLD, - SNODE_TEX_BRUSH, + SNODE_TEX_WORLD = 1, + SNODE_TEX_BRUSH = 2, } eSpaceNode_TexFrom; /* snode->shaderfrom */ typedef enum eSpaceNode_ShaderFrom { SNODE_SHADER_OBJECT = 0, - SNODE_SHADER_WORLD, + SNODE_SHADER_WORLD = 1, } eSpaceNode_ShaderFrom; /* Game Logic Editor ===================================== */ @@ -930,9 +930,9 @@ typedef struct ConsoleLine { /* ConsoleLine.type */ typedef enum eConsoleLine_Type { CONSOLE_LINE_OUTPUT = 0, - CONSOLE_LINE_INPUT, - CONSOLE_LINE_INFO, /* autocomp feedback */ - CONSOLE_LINE_ERROR + CONSOLE_LINE_INPUT = 1, + CONSOLE_LINE_INFO = 2, /* autocomp feedback */ + CONSOLE_LINE_ERROR = 3 } eConsoleLine_Type; @@ -1044,16 +1044,16 @@ typedef enum eSpaceClip_Flag { /* SpaceClip->mode */ typedef enum eSpaceClip_Mode { SC_MODE_TRACKING = 0, - SC_MODE_RECONSTRUCTION, - SC_MODE_DISTORTION, - SC_MODE_MASKEDIT, + SC_MODE_RECONSTRUCTION = 1, + SC_MODE_DISTORTION = 2, + SC_MODE_MASKEDIT = 3, } eSpaceClip_Mode; /* SpaceClip->view */ typedef enum eSpaceClip_View { SC_VIEW_CLIP = 0, - SC_VIEW_GRAPH, - SC_VIEW_DOPESHEET, + SC_VIEW_GRAPH = 1, + SC_VIEW_DOPESHEET = 2, } eSpaceClip_View; /* SpaceClip->gpencil_src */ @@ -1072,27 +1072,27 @@ typedef enum eSpaceClip_GPencil_Source { /* space types, moved from DNA_screen_types.h */ /* Do NOT change order, append on end. types are hardcoded needed */ typedef enum eSpace_Type { - SPACE_EMPTY, - SPACE_VIEW3D, - SPACE_IPO, - SPACE_OUTLINER, - SPACE_BUTS, - SPACE_FILE, - SPACE_IMAGE, - SPACE_INFO, - SPACE_SEQ, - SPACE_TEXT, - SPACE_IMASEL, /* deprecated */ - SPACE_SOUND, /* Deprecated */ - SPACE_ACTION, - SPACE_NLA, - SPACE_SCRIPT, /* Deprecated */ - SPACE_TIME, - SPACE_NODE, - SPACE_LOGIC, - SPACE_CONSOLE, - SPACE_USERPREF, - SPACE_CLIP, + SPACE_EMPTY = 0, + SPACE_VIEW3D = 1, + SPACE_IPO = 2, + SPACE_OUTLINER = 3, + SPACE_BUTS = 4, + SPACE_FILE = 5, + SPACE_IMAGE = 6, + SPACE_INFO = 7, + SPACE_SEQ = 8, + SPACE_TEXT = 9, + SPACE_IMASEL = 10, /* deprecated */ + SPACE_SOUND = 11, /* Deprecated */ + SPACE_ACTION = 12, + SPACE_NLA = 13, + SPACE_SCRIPT = 14, /* Deprecated */ + SPACE_TIME = 15, + SPACE_NODE = 16, + SPACE_LOGIC = 17, + SPACE_CONSOLE = 18, + SPACE_USERPREF = 19, + SPACE_CLIP = 20, SPACEICONMAX = SPACE_CLIP } eSpace_Type; diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index e1e7408fe14..1ab64ed1cc1 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -271,7 +271,7 @@ typedef struct MovieTracking { /* MovieTrackingCamera->units */ enum { CAMERA_UNITS_PX = 0, - CAMERA_UNITS_MM + CAMERA_UNITS_MM = 1 }; /* MovieTrackingMarker->flag */ From b52c2f2bed83b9fafe9eaef7db74bf2806659a00 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 14:11:23 +0000 Subject: [PATCH 346/360] Style cleanup --- .../blender/editors/space_clip/clip_buttons.c | 3 ++- .../blender/editors/space_clip/clip_editor.c | 22 +++++++++---------- .../editors/space_clip/clip_graph_draw.c | 3 ++- .../blender/editors/space_clip/clip_utils.c | 14 +++++++----- .../blender/editors/space_clip/tracking_ops.c | 3 ++- .../editors/space_clip/tracking_select.c | 2 +- 6 files changed, 26 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 3a12156b803..9b3d713d040 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -165,7 +165,8 @@ void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname) block = uiLayoutAbsoluteBlock(layout); - scopes->track_preview_height = (scopes->track_preview_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->track_preview_height; + scopes->track_preview_height = + (scopes->track_preview_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->track_preview_height; uiDefBut(block, TRACKPREVIEW, 0, "", rect.xmin, rect.ymin, rect.xmax - rect.xmin, scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 275cb782bbd..0bad9f86ea1 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -113,7 +113,7 @@ int ED_space_clip_maskedit_mask_poll(bContext *C) MovieClip *clip = CTX_data_edit_movieclip(C); if (clip) { - SpaceClip *sc= CTX_wm_space_clip(C); + SpaceClip *sc = CTX_wm_space_clip(C); return sc->mask != NULL; } @@ -250,12 +250,12 @@ void ED_space_clip_mask_aspect(SpaceClip *sc, float *aspx, float *aspy) #endif if (*aspx < *aspy) { - *aspy= *aspy / *aspx; - *aspx= 1.0f; + *aspy = *aspy / *aspx; + *aspx = 1.0f; } else { - *aspx= *aspx / *aspy; - *aspy= 1.0f; + *aspx = *aspx / *aspy; + *aspy = 1.0f; } } @@ -297,12 +297,12 @@ void ED_space_clip_aspect_dimension_aware(SpaceClip *sc, float *aspx, float *asp *aspy *= (float)h; if (*aspx < *aspy) { - *aspy= *aspy / *aspx; - *aspx= 1.0f; + *aspy = *aspy / *aspx; + *aspx = 1.0f; } else { - *aspx= *aspx / *aspy; - *aspy= 1.0f; + *aspx = *aspx / *aspy; + *aspy = 1.0f; } } @@ -679,11 +679,11 @@ void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask) { sc->mask = mask; - if (sc->mask && sc->mask->id.us==0) { + if (sc->mask && sc->mask->id.us == 0) { sc->clip->id.us = 1; } if (C) { - WM_event_add_notifier(C, NC_MASK|NA_SELECTED, mask); + WM_event_add_notifier(C, NC_MASK | NA_SELECTED, mask); } } diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 6290adf6620..323594ea469 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -88,7 +88,8 @@ static void draw_curve_knot(float x, float y, float xscale, float yscale, float } static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track), - MovieTrackingMarker *UNUSED(marker), int UNUSED(coord), int scene_framenr, float val) + MovieTrackingMarker *UNUSED(marker), int UNUSED(coord), + int scene_framenr, float val) { glVertex2f(scene_framenr, val); } diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 8dda1255e56..3f8fd5966ec 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -64,9 +64,10 @@ #include "clip_intern.h" // own include void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack *track, void *userdata, - void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), - void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord), - void (*segment_end)(void *userdata)) + void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, + int scene_framenr, float val), + void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord), + void (*segment_end)(void *userdata)) { MovieClip *clip = ED_space_clip(sc); int width, height, coord; @@ -122,9 +123,10 @@ void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack } void clip_graph_tracking_values_iterate(SpaceClip *sc, int selected_only, int include_hidden, void *userdata, - void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), - void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord), - void (*segment_end)(void *userdata)) + void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int coord, int scene_framenr, float val), + void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord), + void (*segment_end)(void *userdata)) { MovieClip *clip = ED_space_clip(sc); MovieTracking *tracking = &clip->tracking; diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index de2bf8241d7..ef5308ea694 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1801,7 +1801,8 @@ static int set_origin_exec(bContext *C, wmOperator *op) int selected_count = count_selected_bundles(C); if (selected_count == 0) { - BKE_report(op->reports, RPT_ERROR, "At least one track with bundle should be selected to define origin position"); + BKE_report(op->reports, RPT_ERROR, + "At least one track with bundle should be selected to define origin position"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index d46eb538af9..47c52ee7fdf 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/space_clip/tracking_ops.c +/** \file blender/editors/space_clip/tracking_select.c * \ingroup spclip */ From 40a726e048ba545221e22a19343c5152d9074f9f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 14:26:27 +0000 Subject: [PATCH 347/360] Code deduplicaiton in motion tracking slide operator --- .../blender/editors/space_clip/clip_intern.h | 3 +- .../blender/editors/space_clip/tracking_ops.c | 94 +++++++------------ .../editors/space_clip/tracking_select.c | 2 +- 3 files changed, 38 insertions(+), 61 deletions(-) diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index 04a941cbdf7..5bc195a1ae2 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -131,7 +131,8 @@ void clip_draw_cfra(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scen void clip_draw_sfra_efra(struct View2D *v2d, struct Scene *scene); /* tracking_ops.c */ -struct MovieTrackingTrack *tracking_marker_check_slide(struct bContext *C, struct wmEvent *event); +struct MovieTrackingTrack *tracking_marker_check_slide(struct bContext *C, struct wmEvent *event, + int *area_r, int *action_r, int *corner_r); void CLIP_OT_add_marker(struct wmOperatorType *ot); void CLIP_OT_delete_track(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index ef5308ea694..69c2101d0f7 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -483,7 +483,7 @@ static void show_cursor(bContext *C) WM_cursor_set(win, CURSOR_STD); } -MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event) +MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event, int *area_r, int *action_r, int *corner_r) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); @@ -492,6 +492,7 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event) float co[2]; ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); int framenr = ED_space_clip_clip_framenr(sc); + int action = -1, area = 0, corner = -1; ED_space_clip_size(sc, &width, &height); @@ -507,14 +508,21 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event) int ok = FALSE; if ((marker->flag & MARKER_DISABLED) == 0) { - if (mouse_on_offset(sc, track, marker, co, width, height)) + if (mouse_on_offset(sc, track, marker, co, width, height)) { + area = TRACK_AREA_POINT; + action = SLIDE_ACTION_POS; ok = TRUE; + } if (!ok && (sc->flag & SC_SHOW_MARKER_SEARCH)) { if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 1, width, height)) { + area = TRACK_AREA_SEARCH; + action = SLIDE_ACTION_OFFSET; ok = TRUE; } else if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 0, width, height)) { + area = TRACK_AREA_SEARCH; + action = SLIDE_ACTION_SIZE; ok = TRUE; } } @@ -523,25 +531,42 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event) /* XXX: need to be real check if affine tracking is enabled, but for now not * sure how to do this, so assume affine tracker is always enabled */ if (TRUE) { - int corner = get_mouse_pattern_corner(sc, marker, co, width, height); + int current_corner = get_mouse_pattern_corner(sc, marker, co, width, height); - if (corner != -1) { + if (current_corner != -1) { + area = TRACK_AREA_PAT; + action = SLIDE_ACTION_POS; + corner = current_corner; ok = TRUE; } } else { if (mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 1, width, height)) { + area = TRACK_AREA_PAT; + action = SLIDE_ACTION_OFFSET; ok = TRUE; } if (!ok && mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 0, width, height)) { + area = TRACK_AREA_PAT; + action = SLIDE_ACTION_SIZE; ok = TRUE; } } } - if (ok) + if (ok) { + if (area_r) + *area_r = area; + + if (action_r) + *action_r = action; + + if (corner_r) + *corner_r = corner; + return track; + } } } @@ -554,13 +579,12 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event) static void *slide_marker_customdata(bContext *C, wmEvent *event) { SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip(sc); MovieTrackingTrack *track; int width, height; float co[2]; void *customdata = NULL; - ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); int framenr = ED_space_clip_clip_framenr(sc); + int area, action, corner; ED_space_clip_size(sc, &width, &height); @@ -569,59 +593,11 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) ED_clip_mouse_pos(C, event, co); - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); + track = tracking_marker_check_slide(C, event, &area, &action, &corner); + if (track) { + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - if ((marker->flag & MARKER_DISABLED) == 0) { - if (!customdata) { - if (mouse_on_offset(sc, track, marker, co, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_POINT, 0, - SLIDE_ACTION_POS, width, height); - } - - if (!customdata && (sc->flag & SC_SHOW_MARKER_SEARCH)) { - if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 1, width, height)) { - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, - SLIDE_ACTION_OFFSET, width, height); - } - else if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 0, width, height)) { - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, - SLIDE_ACTION_SIZE, width, height); - } - } - - if (!customdata && (sc->flag & SC_SHOW_MARKER_PATTERN)) { - /* XXX: need to be real check if affine tracking is enabled, but for now not - * sure how to do this, so assume affine tracker is always enabled */ - if (TRUE) { - int corner = get_mouse_pattern_corner(sc, marker, co, width, height); - - if (corner != -1) { - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, corner, - SLIDE_ACTION_POS, width, height); - } - } - else { - if (mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 1, width, height)) { - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, - SLIDE_ACTION_OFFSET, width, height); - } - - if (!customdata && mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 0, width, height)) { - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, - SLIDE_ACTION_SIZE, width, height); - } - } - } - - if (customdata) - break; - } - } - - track = track->next; + customdata = create_slide_marker_data(sc, track, marker, event, area, corner, action, width, height); } return customdata; diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 47c52ee7fdf..640af498c1f 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -284,7 +284,7 @@ static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) int extend = RNA_boolean_get(op->ptr, "extend"); if (!extend) { - MovieTrackingTrack *track = tracking_marker_check_slide(C, event); + MovieTrackingTrack *track = tracking_marker_check_slide(C, event, NULL, NULL, NULL); if (track) { SpaceClip *sc = CTX_wm_space_clip(C); From 4f80c3464fab5d79a06ab5b56b2bea6fc72acef7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 14:40:01 +0000 Subject: [PATCH 348/360] fix for building without libmv --- source/blender/blenkernel/intern/tracking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index dfe71c48536..7edc240ff0a 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1425,8 +1425,8 @@ void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking * } #else (void) distortion; - (void) width; - (void) height; + (void) calibration_width; + (void) calibration_height; (void) camera; (void) aspy; #endif From f04546018f44ccaa038526cefc5fd2a212b2c20d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 14:45:49 +0000 Subject: [PATCH 349/360] style cleanup --- .../compositor/nodes/COM_SplitViewerNode.cpp | 8 +-- .../compositor/nodes/COM_ViewLevelsNode.cpp | 12 ++-- .../compositor/nodes/COM_ViewerNode.cpp | 8 +-- .../operations/COM_SplitViewerOperation.cpp | 24 ++++---- .../operations/COM_ViewerBaseOperation.cpp | 4 +- .../operations/COM_ViewerOperation.cpp | 22 +++---- .../composite/nodes/node_composite_viewer.c | 60 +++++++++---------- 7 files changed, 69 insertions(+), 69 deletions(-) diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp index d7f61caf456..7e8a218cbc1 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp @@ -26,16 +26,16 @@ #include "COM_SplitViewerOperation.h" #include "COM_ExecutionSystem.h" -SplitViewerNode::SplitViewerNode(bNode *editorNode): Node(editorNode) +SplitViewerNode::SplitViewerNode(bNode *editorNode) : Node(editorNode) { } -void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *image1Socket = this->getInputSocket(0); InputSocket *image2Socket = this->getInputSocket(1); - Image *image = (Image*)this->getbNode()->id; - ImageUser * imageUser = (ImageUser*) this->getbNode()->storage; + Image *image = (Image *)this->getbNode()->id; + ImageUser *imageUser = (ImageUser *) this->getbNode()->storage; if (image1Socket->isConnected() && image2Socket->isConnected()) { SplitViewerOperation *splitViewerOperation = new SplitViewerOperation(); splitViewerOperation->setColorManagement(context->getScene()->r.color_mgt_flag & R_COLOR_MANAGEMENT); diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp index cedf81e3f2a..a7974efe954 100644 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp @@ -26,21 +26,21 @@ #include "COM_CalculateMeanOperation.h" #include "COM_CalculateStandardDeviationOperation.h" -ViewLevelsNode::ViewLevelsNode(bNode *editorNode): Node(editorNode) +ViewLevelsNode::ViewLevelsNode(bNode *editorNode) : Node(editorNode) { } -void ViewLevelsNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void ViewLevelsNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { - InputSocket * input = this->getInputSocket(0); + InputSocket *input = this->getInputSocket(0); bool firstOperationConnected = false; if (input->isConnected()) { OutputSocket *inputSocket = input->getConnection()->getFromSocket(); // add preview to inputSocket; - OutputSocket * socket = this->getOutputSocket(0); + OutputSocket *socket = this->getOutputSocket(0); if (socket->isConnected()) { // calculate mean operation - CalculateMeanOperation * operation = new CalculateMeanOperation(); + CalculateMeanOperation *operation = new CalculateMeanOperation(); input->relinkConnections(operation->getInputSocket(0), 0, graph); firstOperationConnected = true; operation->setSetting(this->getbNode()->custom1); @@ -51,7 +51,7 @@ void ViewLevelsNode::convertToOperations(ExecutionSystem *graph, CompositorConte socket = this->getOutputSocket(1); if (socket->isConnected()) { // calculate standard deviation operation - CalculateStandardDeviationOperation * operation = new CalculateStandardDeviationOperation(); + CalculateStandardDeviationOperation *operation = new CalculateStandardDeviationOperation(); if (firstOperationConnected) { addLink(graph, inputSocket, operation->getInputSocket(0)); } diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp index 67c0df4d6a3..79c76f2e89e 100644 --- a/source/blender/compositor/nodes/COM_ViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp @@ -26,16 +26,16 @@ #include "COM_ViewerOperation.h" #include "COM_ExecutionSystem.h" -ViewerNode::ViewerNode(bNode *editorNode): Node(editorNode) +ViewerNode::ViewerNode(bNode *editorNode) : Node(editorNode) { } -void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context)\ +void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *imageSocket = this->getInputSocket(0); InputSocket *alphaSocket = this->getInputSocket(1); - Image *image = (Image*)this->getbNode()->id; - ImageUser * imageUser = (ImageUser*) this->getbNode()->storage; + Image *image = (Image *)this->getbNode()->id; + ImageUser *imageUser = (ImageUser *) this->getbNode()->storage; bNode *editorNode = this->getbNode(); if (imageSocket->isConnected()) { ViewerOperation *viewerOperation = new ViewerOperation(); diff --git a/source/blender/compositor/operations/COM_SplitViewerOperation.cpp b/source/blender/compositor/operations/COM_SplitViewerOperation.cpp index 4601bebb49f..2735f182406 100644 --- a/source/blender/compositor/operations/COM_SplitViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_SplitViewerOperation.cpp @@ -60,7 +60,7 @@ void SplitViewerOperation::deinitExecution() } -void SplitViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) +void SplitViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers) { float *buffer = this->outputBuffer; unsigned char *bufferDisplay = this->outputBufferDisplay; @@ -70,15 +70,15 @@ void SplitViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me int y1 = rect->ymin; int x2 = rect->xmax; int y2 = rect->ymax; - int offset = (y1*this->getWidth() + x1 ) * 4; + int offset = (y1 * this->getWidth() + x1) * 4; int x; int y; - int perc = xSplit?this->splitPercentage*getWidth()/100.0f:this->splitPercentage*getHeight()/100.0f; - for (y = y1 ; y < y2 ; y++) { - for (x = x1 ; x < x2 ; x++) { + int perc = xSplit ? this->splitPercentage *getWidth() / 100.0f : this->splitPercentage *getHeight() / 100.0f; + for (y = y1; y < y2; y++) { + for (x = x1; x < x2; x++) { bool image1; float srgb[4]; - image1 = xSplit?x>perc:y>perc; + image1 = xSplit ? x > perc : y > perc; if (image1) { image1Input->read(&(buffer[offset]), x, y, COM_PS_NEAREST, memoryBuffers); } @@ -88,21 +88,21 @@ void SplitViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me /// @todo: linear conversion only when scene color management is selected, also check predivide. if (this->doColorManagement) { if (this->doColorPredivide) { - linearrgb_to_srgb_predivide_v4(srgb, buffer+offset); + linearrgb_to_srgb_predivide_v4(srgb, buffer + offset); } else { - linearrgb_to_srgb_v4(srgb, buffer+offset); + linearrgb_to_srgb_v4(srgb, buffer + offset); } } else { - copy_v4_v4(srgb, buffer+offset); + copy_v4_v4(srgb, buffer + offset); } - F4TOCHAR4(srgb, bufferDisplay+offset); + rgba_float_to_uchar(bufferDisplay + offset, srgb); - offset +=4; + offset += 4; } - offset += (this->getWidth()-(x2-x1))*4; + offset += (this->getWidth() - (x2 - x1)) * 4; } updateImage(rect); } diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp index 809c688195f..a8aa84e84f9 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp @@ -74,13 +74,13 @@ void ViewerBaseOperation::initImage() /* now we combine the input with ibuf */ this->outputBuffer = ibuf->rect_float; - this->outputBufferDisplay = (unsigned char*)ibuf->rect; + this->outputBufferDisplay = (unsigned char *)ibuf->rect; BKE_image_release_ibuf(this->image, this->lock); } void ViewerBaseOperation:: updateImage(rcti *rect) { - WM_main_add_notifier(NC_WINDOW|ND_DRAW, NULL); + WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL); } void ViewerBaseOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp index 3bec1ef48f5..cf7bf3fdc9d 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp @@ -64,7 +64,7 @@ void ViewerOperation::deinitExecution() } -void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) +void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers) { float *buffer = this->outputBuffer; unsigned char *bufferDisplay = this->outputBufferDisplay; @@ -73,36 +73,36 @@ void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryB const int y1 = rect->ymin; const int x2 = rect->xmax; const int y2 = rect->ymax; - const int offsetadd = (this->getWidth()-(x2-x1))*4; - int offset = (y1*this->getWidth() + x1 ) * 4; + const int offsetadd = (this->getWidth() - (x2 - x1)) * 4; + int offset = (y1 * this->getWidth() + x1) * 4; float alpha[4], srgb[4]; int x; int y; bool breaked = false; - for (y = y1 ; y < y2 && (!breaked) ; y++) { - for (x = x1 ; x < x2; x++) { + for (y = y1; y < y2 && (!breaked); y++) { + for (x = x1; x < x2; x++) { imageInput->read(&(buffer[offset]), x, y, COM_PS_NEAREST, memoryBuffers); if (alphaInput != NULL) { alphaInput->read(alpha, x, y, COM_PS_NEAREST, memoryBuffers); - buffer[offset+3] = alpha[0]; + buffer[offset + 3] = alpha[0]; } /// @todo: linear conversion only when scene color management is selected, also check predivide. if (this->doColorManagement) { if (this->doColorPredivide) { - linearrgb_to_srgb_predivide_v4(srgb, buffer+offset); + linearrgb_to_srgb_predivide_v4(srgb, buffer + offset); } else { - linearrgb_to_srgb_v4(srgb, buffer+offset); + linearrgb_to_srgb_v4(srgb, buffer + offset); } } else { - copy_v4_v4(srgb, buffer+offset); + copy_v4_v4(srgb, buffer + offset); } - F4TOCHAR4(srgb, bufferDisplay+offset); + rgba_float_to_uchar(bufferDisplay + offset, srgb); - offset +=4; + offset += 4; } if (isBreaked()) { breaked = true; diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.c b/source/blender/nodes/composite/nodes/node_composite_viewer.c index 1fc9399e876..e97863a9463 100644 --- a/source/blender/nodes/composite/nodes/node_composite_viewer.c +++ b/source/blender/nodes/composite/nodes/node_composite_viewer.c @@ -34,11 +34,11 @@ /* **************** VIEWER ******************** */ -static bNodeSocketTemplate cmp_node_viewer_in[]= { - { SOCK_RGBA, 1, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, - { SOCK_FLOAT, 1, N_("Z"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_viewer_in[] = { + { SOCK_RGBA, 1, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, N_("Z"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, + { -1, 0, "" } }; @@ -47,9 +47,9 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, /* image assigned to output */ /* stack order input sockets: col, alpha, z */ - if (node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */ - RenderData *rd= data; - Image *ima= (Image *)node->id; + if (node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */ + RenderData *rd = data; + Image *ima = (Image *)node->id; ImBuf *ibuf; CompBuf *cbuf, *tbuf; int rectx, recty; @@ -58,8 +58,8 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, BKE_image_user_frame_calc(node->storage, rd->cfra, 0); /* always returns for viewer image, but we check nevertheless */ - ibuf= BKE_image_acquire_ibuf(ima, node->storage, &lock); - if (ibuf==NULL) { + ibuf = BKE_image_acquire_ibuf(ima, node->storage, &lock); + if (ibuf == NULL) { printf("node_composit_exec_viewer error\n"); BKE_image_release_ibuf(ima, lock); return; @@ -71,28 +71,28 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, IMB_freezbuffloatImBuf(ibuf); /* get size */ - tbuf= in[0]->data?in[0]->data:(in[1]->data?in[1]->data:in[2]->data); - if (tbuf==NULL) { - rectx= 320; recty= 256; + tbuf = in[0]->data ? in[0]->data : (in[1]->data ? in[1]->data : in[2]->data); + if (tbuf == NULL) { + rectx = 320; recty = 256; } else { - rectx= tbuf->x; - recty= tbuf->y; + rectx = tbuf->x; + recty = tbuf->y; } /* make ibuf, and connect to ima */ - ibuf->x= rectx; - ibuf->y= recty; + ibuf->x = rectx; + ibuf->y = recty; imb_addrectfloatImBuf(ibuf); - ima->ok= IMA_OK_LOADED; + ima->ok = IMA_OK_LOADED; /* now we combine the input with ibuf */ - cbuf= alloc_compbuf(rectx, recty, CB_RGBA, 0); /* no alloc*/ - cbuf->rect= ibuf->rect_float; + cbuf = alloc_compbuf(rectx, recty, CB_RGBA, 0); /* no alloc*/ + cbuf->rect = ibuf->rect_float; /* when no alpha, we can simply copy */ - if (in[1]->data==NULL) { + if (in[1]->data == NULL) { composit1_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, do_copy_rgba, CB_RGBA); } else @@ -100,14 +100,14 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, /* zbuf option */ if (in[2]->data) { - CompBuf *zbuf= alloc_compbuf(rectx, recty, CB_VAL, 1); - ibuf->zbuf_float= zbuf->rect; + CompBuf *zbuf = alloc_compbuf(rectx, recty, CB_VAL, 1); + ibuf->zbuf_float = zbuf->rect; ibuf->mall |= IB_zbuffloat; composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value, CB_VAL); /* free compbuf, but not the rect */ - zbuf->malloc= 0; + zbuf->malloc = 0; free_compbuf(zbuf); } @@ -122,13 +122,13 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, } } -static void node_composit_init_viewer(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +static void node_composit_init_viewer(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) { - ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user"); - node->storage= iuser; - iuser->sfra= 1; - iuser->fie_ima= 2; - iuser->ok= 1; + ImageUser *iuser = MEM_callocN(sizeof(ImageUser), "node image user"); + node->storage = iuser; + iuser->sfra = 1; + iuser->fie_ima = 2; + iuser->ok = 1; node->custom3 = 0.5f; node->custom4 = 0.5f; } From 77ec3ae9d100ba32e3bd32e2208cf2686b2c6ded Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 15 Jun 2012 15:01:32 +0000 Subject: [PATCH 350/360] Fix more of #31789: cycles border render going out of view giving wrong result. --- .../editors/space_view3d/view3d_draw.c | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 1f7dfef3871..fcb4f97bcbe 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2830,13 +2830,17 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw cliprct.ymin += ar->winrct.ymin; cliprct.ymax += ar->winrct.ymin; - cliprct.xmin = MAX2(cliprct.xmin, ar->winrct.xmin); - cliprct.ymin = MAX2(cliprct.ymin, ar->winrct.ymin); - cliprct.xmax = MIN2(cliprct.xmax, ar->winrct.xmax); - cliprct.ymax = MIN2(cliprct.ymax, ar->winrct.ymax); + cliprct.xmin = CLAMPIS(cliprct.xmin, ar->winrct.xmin, ar->winrct.xmax); + cliprct.ymin = CLAMPIS(cliprct.ymin, ar->winrct.ymin, ar->winrct.ymax); + cliprct.xmax = CLAMPIS(cliprct.xmax, ar->winrct.xmin, ar->winrct.xmax); + cliprct.ymax = CLAMPIS(cliprct.ymax, ar->winrct.ymin, ar->winrct.ymax); - glGetIntegerv(GL_SCISSOR_BOX, scissor); - glScissor(cliprct.xmin, cliprct.ymin, cliprct.xmax - cliprct.xmin, cliprct.ymax - cliprct.ymin); + if(cliprct.xmax > cliprct.xmin && cliprct.ymax > cliprct.ymin) { + glGetIntegerv(GL_SCISSOR_BOX, scissor); + glScissor(cliprct.xmin, cliprct.ymin, cliprct.xmax - cliprct.xmin, cliprct.ymax - cliprct.ymin); + } + else + return 0; } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); @@ -2847,11 +2851,6 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw else fdrawcheckerboard(0, 0, ar->winx, ar->winy); - if (draw_border) { - /* restore scissor as it was before */ - glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); - } - /* render result draw */ type = rv3d->render_engine->type; type->view_draw(rv3d->render_engine, C); @@ -2859,6 +2858,11 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw if (v3d->flag & V3D_DISPBGPICS) view3d_draw_bgpic(scene, ar, v3d, TRUE, TRUE); + if (draw_border) { + /* restore scissor as it was before */ + glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); + } + return 1; } From 2ca89f7add1949295ac58de6697534d44508bca3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 15:04:56 +0000 Subject: [PATCH 351/360] style cleanup --- .../compositor/nodes/COM_DilateErodeNode.cpp | 14 +- .../operations/COM_DilateErodeOperation.cpp | 170 +++++++++--------- .../composite/nodes/node_composite_dilate.c | 72 ++++---- 3 files changed, 128 insertions(+), 128 deletions(-) diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp index 0619bb5133e..fe9e97a3e4b 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp @@ -27,11 +27,11 @@ #include "COM_AntiAliasOperation.h" #include "BLI_math.h" -DilateErodeNode::DilateErodeNode(bNode *editorNode): Node(editorNode) +DilateErodeNode::DilateErodeNode(bNode *editorNode) : Node(editorNode) { } -void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { bNode *editorNode = this->getbNode(); @@ -43,7 +43,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); if (editorNode->custom3 < 2.0f) { - AntiAliasOperation * antiAlias = new AntiAliasOperation(); + AntiAliasOperation *antiAlias = new AntiAliasOperation(); addLink(graph, operation->getOutputSocket(), antiAlias->getInputSocket(0)); this->getOutputSocket(0)->relinkConnections(antiAlias->getOutputSocket(0)); graph->addOperation(antiAlias); @@ -55,14 +55,14 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont } else if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE) { if (editorNode->custom2 > 0) { - DilateDistanceOperation * operation = new DilateDistanceOperation(); + DilateDistanceOperation *operation = new DilateDistanceOperation(); operation->setDistance(editorNode->custom2); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); graph->addOperation(operation); } else { - ErodeDistanceOperation * operation = new ErodeDistanceOperation(); + ErodeDistanceOperation *operation = new ErodeDistanceOperation(); operation->setDistance(-editorNode->custom2); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); @@ -71,14 +71,14 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont } else { if (editorNode->custom2 > 0) { - DilateStepOperation * operation = new DilateStepOperation(); + DilateStepOperation *operation = new DilateStepOperation(); operation->setIterations(editorNode->custom2); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); graph->addOperation(operation); } else { - ErodeStepOperation * operation = new ErodeStepOperation(); + ErodeStepOperation *operation = new ErodeStepOperation(); operation->setIterations(-editorNode->custom2); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp index bdd7362952a..17b043009ac 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp @@ -24,7 +24,7 @@ #include "BLI_math.h" // DilateErode Distance Threshold -DilateErodeThresholdOperation::DilateErodeThresholdOperation(): NodeOperation() +DilateErodeThresholdOperation::DilateErodeThresholdOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -38,11 +38,11 @@ void DilateErodeThresholdOperation::initExecution() { this->inputProgram = this->getInputSocketReader(0); if (this->distance < 0.0f) { - this->scope = - this->distance + this->inset; + this->scope = -this->distance + this->inset; } else { - if (this->inset*2 > this->distance) { - this->scope = max(this->inset*2 - this->distance, this->distance); + if (this->inset * 2 > this->distance) { + this->scope = max(this->inset * 2 - this->distance, this->distance); } else { this->scope = distance; @@ -67,45 +67,45 @@ void DilateErodeThresholdOperation::executePixel(float *color, int x, int y, Mem float pixelvalue; const float rd = scope * scope; const float inset = this->inset; - float mindist = rd*2; + float mindist = rd * 2; - MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); rcti *rect = inputBuffer->getRect(); const int minx = max(x - scope, rect->xmin); const int miny = max(y - scope, rect->ymin); const int maxx = min(x + scope, rect->xmax); const int maxy = min(y + scope, rect->ymax); - const int bufferWidth = rect->xmax-rect->xmin; + const int bufferWidth = rect->xmax - rect->xmin; int offset; this->inputProgram->read(inputValue, x, y, inputBuffers, NULL); - if (inputValue[0]>sw) { - for (int yi = miny ; yiymin)*bufferWidth+(minx-rect->xmin))*4; - for (int xi = minx ; xi sw) { + for (int yi = miny; yi < maxy; yi++) { + offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; + for (int xi = minx; xi < maxx; xi++) { + if (buffer[offset] < sw) { + const float dx = xi - x; + const float dy = yi - y; + const float dis = dx * dx + dy * dy; mindist = min(mindist, dis); } - offset +=4; + offset += 4; } } pixelvalue = -sqrtf(mindist); } else { - for (int yi = miny ; yiymin)*bufferWidth+(minx-rect->xmin))*4; - for (int xi = minx ; xisw) { - const float dx = xi-x; - const float dy = yi-y; - const float dis = dx*dx+dy*dy; + for (int yi = miny; yi < maxy; yi++) { + offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; + for (int xi = minx; xi < maxx; xi++) { + if (buffer[offset] > sw) { + const float dx = xi - x; + const float dy = yi - y; + const float dis = dx * dx + dy * dy; mindist = min(mindist, dis); } - offset +=4; + offset += 4; } } @@ -119,7 +119,7 @@ void DilateErodeThresholdOperation::executePixel(float *color, int x, int y, Mem color[0] = 1.0f; } else { - color[0] = delta/inset; + color[0] = delta / inset; } } else { @@ -127,13 +127,13 @@ void DilateErodeThresholdOperation::executePixel(float *color, int x, int y, Mem } } else { - const float delta = -distance+pixelvalue; + const float delta = -distance + pixelvalue; if (delta < 0.0f) { if (delta < -inset) { color[0] = 1.0f; } else { - color[0] = (-delta)/inset; + color[0] = (-delta) / inset; } } else { @@ -160,7 +160,7 @@ bool DilateErodeThresholdOperation::determineDependingAreaOfInterest(rcti *input } // Dilate Distance -DilateDistanceOperation::DilateDistanceOperation(): NodeOperation() +DilateDistanceOperation::DilateDistanceOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -189,28 +189,28 @@ void DilateDistanceOperation::executePixel(float *color, int x, int y, MemoryBuf const float distance = this->distance; float mindist = distance * distance; - MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); rcti *rect = inputBuffer->getRect(); const int minx = max(x - scope, rect->xmin); const int miny = max(y - scope, rect->ymin); const int maxx = min(x + scope, rect->xmax); const int maxy = min(y + scope, rect->ymax); - const int bufferWidth = rect->xmax-rect->xmin; + const int bufferWidth = rect->xmax - rect->xmin; int offset; float value = 0.0f; - for (int yi = miny ; yiymin)*bufferWidth+(minx-rect->xmin))*4; - for (int xi = minx ; xiymin) * bufferWidth + (minx - rect->xmin)) * 4; + for (int xi = minx; xi < maxx; xi++) { + const float dx = xi - x; + const float dy = yi - y; + const float dis = dx * dx + dy * dy; if (dis <= mindist) { value = max(buffer[offset], value); } - offset +=4; + offset += 4; } } color[0] = value; @@ -235,14 +235,14 @@ bool DilateDistanceOperation::determineDependingAreaOfInterest(rcti *input, Read static cl_kernel dilateKernel = 0; void DilateDistanceOperation::executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, - MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, - MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, - list *clKernelsToCleanUp) + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, + list *clKernelsToCleanUp) { if (!dilateKernel) { dilateKernel = COM_clCreateKernel(program, "dilateKernel", NULL); } - cl_int distanceSquared = this->distance*this->distance; + cl_int distanceSquared = this->distance * this->distance; cl_int scope = this->scope; COM_clAttachMemoryBufferToKernelParameter(context, dilateKernel, 0, 2, clMemToCleanUp, inputMemoryBuffers, this->inputProgram); @@ -264,28 +264,28 @@ void ErodeDistanceOperation::executePixel(float *color, int x, int y, MemoryBuff const float distance = this->distance; float mindist = distance * distance; - MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); rcti *rect = inputBuffer->getRect(); const int minx = max(x - scope, rect->xmin); const int miny = max(y - scope, rect->ymin); const int maxx = min(x + scope, rect->xmax); const int maxy = min(y + scope, rect->ymax); - const int bufferWidth = rect->xmax-rect->xmin; + const int bufferWidth = rect->xmax - rect->xmin; int offset; float value = 1.0f; - for (int yi = miny ; yiymin)*bufferWidth+(minx-rect->xmin))*4; - for (int xi = minx ; xiymin) * bufferWidth + (minx - rect->xmin)) * 4; + for (int xi = minx; xi < maxx; xi++) { + const float dx = xi - x; + const float dy = yi - y; + const float dis = dx * dx + dy * dy; if (dis <= mindist) { value = min(buffer[offset], value); } - offset +=4; + offset += 4; } } color[0] = value; @@ -293,14 +293,14 @@ void ErodeDistanceOperation::executePixel(float *color, int x, int y, MemoryBuff static cl_kernel erodeKernel = 0; void ErodeDistanceOperation::executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, - MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, - MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, - list *clKernelsToCleanUp) + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list *clMemToCleanUp, + list *clKernelsToCleanUp) { if (!erodeKernel) { erodeKernel = COM_clCreateKernel(program, "erodeKernel", NULL); } - cl_int distanceSquared = this->distance*this->distance; + cl_int distanceSquared = this->distance * this->distance; cl_int scope = this->scope; COM_clAttachMemoryBufferToKernelParameter(context, erodeKernel, 0, 2, clMemToCleanUp, inputMemoryBuffers, this->inputProgram); @@ -313,7 +313,7 @@ void ErodeDistanceOperation::executeOpenCL(cl_context context, cl_program progra } // Dilate step -DilateStepOperation::DilateStepOperation(): NodeOperation() +DilateStepOperation::DilateStepOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -334,37 +334,37 @@ void *DilateStepOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryB } lockMutex(); if (this->cached_buffer == NULL) { - MemoryBuffer *buffer = (MemoryBuffer*)inputProgram->initializeTileData(NULL, memoryBuffers); + MemoryBuffer *buffer = (MemoryBuffer *)inputProgram->initializeTileData(NULL, memoryBuffers); float *rectf = buffer->convertToValueBuffer(); int x, y, i; float *p; int bwidth = buffer->getWidth(); int bheight = buffer->getHeight(); - for (i = 0 ; i < this->iterations ; i ++) { - for (y=0; y < bheight; y++) { - for (x=0; x < bwidth-1; x++) { - p = rectf + (bwidth*y + x); + for (i = 0; i < this->iterations; i++) { + for (y = 0; y < bheight; y++) { + for (x = 0; x < bwidth - 1; x++) { + p = rectf + (bwidth * y + x); *p = MAX2(*p, *(p + 1)); } } - for (y=0; y < bheight; y++) { - for (x=bwidth-1; x >= 1; x--) { - p = rectf + (bwidth*y + x); + for (y = 0; y < bheight; y++) { + for (x = bwidth - 1; x >= 1; x--) { + p = rectf + (bwidth * y + x); *p = MAX2(*p, *(p - 1)); } } - for (x=0; x < bwidth; x++) { - for (y=0; y < bheight-1; y++) { - p = rectf + (bwidth*y + x); + for (x = 0; x < bwidth; x++) { + for (y = 0; y < bheight - 1; y++) { + p = rectf + (bwidth * y + x); *p = MAX2(*p, *(p + bwidth)); } } - for (x=0; x < bwidth; x++) { - for (y=bheight-1; y >= 1; y--) { - p = rectf + (bwidth*y + x); + for (x = 0; x < bwidth; x++) { + for (y = bheight - 1; y >= 1; y--) { + p = rectf + (bwidth * y + x); *p = MAX2(*p, *(p - bwidth)); } } @@ -378,7 +378,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryB void DilateStepOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { - color[0] = this->cached_buffer[y*this->getWidth()+x]; + color[0] = this->cached_buffer[y * this->getWidth() + x]; } void DilateStepOperation::deinitExecution() @@ -409,7 +409,7 @@ bool DilateStepOperation::determineDependingAreaOfInterest(rcti *input, ReadBuff } // Erode step -ErodeStepOperation::ErodeStepOperation(): DilateStepOperation() +ErodeStepOperation::ErodeStepOperation() : DilateStepOperation() { } @@ -420,37 +420,37 @@ void *ErodeStepOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBu } lockMutex(); if (this->cached_buffer == NULL) { - MemoryBuffer *buffer = (MemoryBuffer*)inputProgram->initializeTileData(NULL, memoryBuffers); + MemoryBuffer *buffer = (MemoryBuffer *)inputProgram->initializeTileData(NULL, memoryBuffers); float *rectf = buffer->convertToValueBuffer(); int x, y, i; float *p; int bwidth = buffer->getWidth(); int bheight = buffer->getHeight(); - for (i = 0 ; i < this->iterations ; i ++) { - for (y=0; y < bheight; y++) { - for (x=0; x < bwidth-1; x++) { - p = rectf + (bwidth*y + x); + for (i = 0; i < this->iterations; i++) { + for (y = 0; y < bheight; y++) { + for (x = 0; x < bwidth - 1; x++) { + p = rectf + (bwidth * y + x); *p = MIN2(*p, *(p + 1)); } } - for (y=0; y < bheight; y++) { - for (x=bwidth-1; x >= 1; x--) { - p = rectf + (bwidth*y + x); + for (y = 0; y < bheight; y++) { + for (x = bwidth - 1; x >= 1; x--) { + p = rectf + (bwidth * y + x); *p = MIN2(*p, *(p - 1)); } } - for (x=0; x < bwidth; x++) { - for (y=0; y < bheight-1; y++) { - p = rectf + (bwidth*y + x); + for (x = 0; x < bwidth; x++) { + for (y = 0; y < bheight - 1; y++) { + p = rectf + (bwidth * y + x); *p = MIN2(*p, *(p + bwidth)); } } - for (x=0; x < bwidth; x++) { - for (y=bheight-1; y >= 1; y--) { - p = rectf + (bwidth*y + x); + for (x = 0; x < bwidth; x++) { + for (y = bheight - 1; y >= 1; y--) { + p = rectf + (bwidth * y + x); *p = MIN2(*p, *(p - bwidth)); } } diff --git a/source/blender/nodes/composite/nodes/node_composite_dilate.c b/source/blender/nodes/composite/nodes/node_composite_dilate.c index 8363d5928bf..ec7aaccdbe2 100644 --- a/source/blender/nodes/composite/nodes/node_composite_dilate.c +++ b/source/blender/nodes/composite/nodes/node_composite_dilate.c @@ -35,13 +35,13 @@ /* **************** Dilate/Erode ******************** */ -static bNodeSocketTemplate cmp_node_dilateerode_in[]= { - { SOCK_FLOAT, 1, N_("Mask"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_dilateerode_in[] = { + { SOCK_FLOAT, 1, N_("Mask"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + { -1, 0, "" } }; -static bNodeSocketTemplate cmp_node_dilateerode_out[]= { - { SOCK_FLOAT, 0, N_("Mask")}, - { -1, 0, "" } +static bNodeSocketTemplate cmp_node_dilateerode_out[] = { + { SOCK_FLOAT, 0, N_("Mask")}, + { -1, 0, "" } }; static void morpho_dilate(CompBuf *cbuf) @@ -49,30 +49,30 @@ static void morpho_dilate(CompBuf *cbuf) int x, y; float *p, *rectf = cbuf->rect; - for (y=0; y < cbuf->y; y++) { - for (x=0; x < cbuf->x-1; x++) { - p = rectf + cbuf->x*y + x; + for (y = 0; y < cbuf->y; y++) { + for (x = 0; x < cbuf->x - 1; x++) { + p = rectf + cbuf->x * y + x; *p = MAX2(*p, *(p + 1)); } } - for (y=0; y < cbuf->y; y++) { - for (x=cbuf->x-1; x >= 1; x--) { - p = rectf + cbuf->x*y + x; + for (y = 0; y < cbuf->y; y++) { + for (x = cbuf->x - 1; x >= 1; x--) { + p = rectf + cbuf->x * y + x; *p = MAX2(*p, *(p - 1)); } } - for (x=0; x < cbuf->x; x++) { - for (y=0; y < cbuf->y-1; y++) { - p = rectf + cbuf->x*y + x; + for (x = 0; x < cbuf->x; x++) { + for (y = 0; y < cbuf->y - 1; y++) { + p = rectf + cbuf->x * y + x; *p = MAX2(*p, *(p + cbuf->x)); } } - for (x=0; x < cbuf->x; x++) { - for (y=cbuf->y-1; y >= 1; y--) { - p = rectf + cbuf->x*y + x; + for (x = 0; x < cbuf->x; x++) { + for (y = cbuf->y - 1; y >= 1; y--) { + p = rectf + cbuf->x * y + x; *p = MAX2(*p, *(p - cbuf->x)); } } @@ -83,30 +83,30 @@ static void morpho_erode(CompBuf *cbuf) int x, y; float *p, *rectf = cbuf->rect; - for (y=0; y < cbuf->y; y++) { - for (x=0; x < cbuf->x-1; x++) { - p = rectf + cbuf->x*y + x; + for (y = 0; y < cbuf->y; y++) { + for (x = 0; x < cbuf->x - 1; x++) { + p = rectf + cbuf->x * y + x; *p = MIN2(*p, *(p + 1)); } } - for (y=0; y < cbuf->y; y++) { - for (x=cbuf->x-1; x >= 1; x--) { - p = rectf + cbuf->x*y + x; + for (y = 0; y < cbuf->y; y++) { + for (x = cbuf->x - 1; x >= 1; x--) { + p = rectf + cbuf->x * y + x; *p = MIN2(*p, *(p - 1)); } } - for (x=0; x < cbuf->x; x++) { - for (y=0; y < cbuf->y-1; y++) { - p = rectf + cbuf->x*y + x; + for (x = 0; x < cbuf->x; x++) { + for (y = 0; y < cbuf->y - 1; y++) { + p = rectf + cbuf->x * y + x; *p = MIN2(*p, *(p + cbuf->x)); } } - for (x=0; x < cbuf->x; x++) { - for (y=cbuf->y-1; y >= 1; y--) { - p = rectf + cbuf->x*y + x; + for (x = 0; x < cbuf->x; x++) { + for (y = cbuf->y - 1; y >= 1; y--) { + p = rectf + cbuf->x * y + x; *p = MIN2(*p, *(p - cbuf->x)); } } @@ -117,18 +117,18 @@ static void node_composit_exec_dilateerode(void *UNUSED(data), bNode *node, bNod { /* stack order in: mask */ /* stack order out: mask */ - if (out[0]->hasoutput==0) + if (out[0]->hasoutput == 0) return; /* input no image? then only color operation */ - if (in[0]->data==NULL) { + if (in[0]->data == NULL) { out[0]->vec[0] = out[0]->vec[1] = out[0]->vec[2] = 0.0f; out[0]->vec[3] = 0.0f; } else { /* make output size of input image */ - CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_VAL); - CompBuf *stackbuf= dupalloc_compbuf(cbuf); + CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_VAL); + CompBuf *stackbuf = dupalloc_compbuf(cbuf); short i; if (node->custom2 > 0) { // positive, dilate @@ -140,10 +140,10 @@ static void node_composit_exec_dilateerode(void *UNUSED(data), bNode *node, bNod morpho_erode(stackbuf); } - if (cbuf!=in[0]->data) + if (cbuf != in[0]->data) free_compbuf(cbuf); - out[0]->data= stackbuf; + out[0]->data = stackbuf; } } From 927fc897cf8d7e6c18571dee2b79b596b5aaffa7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 15:55:37 +0000 Subject: [PATCH 352/360] minor optimizations for dilate --- .../operations/COM_DilateErodeOperation.cpp | 12 ++++++------ .../operations/COM_OpenCLKernels.cl | 2 +- .../composite/nodes/node_composite_dilate.c | 19 +++++++++---------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp index 17b043009ac..f6d794fe564 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp @@ -82,11 +82,11 @@ void DilateErodeThresholdOperation::executePixel(float *color, int x, int y, Mem this->inputProgram->read(inputValue, x, y, inputBuffers, NULL); if (inputValue[0] > sw) { for (int yi = miny; yi < maxy; yi++) { + const float dy = yi - y; offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; for (int xi = minx; xi < maxx; xi++) { if (buffer[offset] < sw) { const float dx = xi - x; - const float dy = yi - y; const float dis = dx * dx + dy * dy; mindist = min(mindist, dis); } @@ -97,11 +97,11 @@ void DilateErodeThresholdOperation::executePixel(float *color, int x, int y, Mem } else { for (int yi = miny; yi < maxy; yi++) { + const float dy = yi - y; offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; for (int xi = minx; xi < maxx; xi++) { if (buffer[offset] > sw) { const float dx = xi - x; - const float dy = yi - y; const float dis = dx * dx + dy * dy; mindist = min(mindist, dis); } @@ -187,7 +187,7 @@ void *DilateDistanceOperation::initializeTileData(rcti *rect, MemoryBuffer **mem void DilateDistanceOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { const float distance = this->distance; - float mindist = distance * distance; + const float mindist = distance * distance; MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); @@ -202,10 +202,10 @@ void DilateDistanceOperation::executePixel(float *color, int x, int y, MemoryBuf float value = 0.0f; for (int yi = miny; yi < maxy; yi++) { + const float dy = yi - y; offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; for (int xi = minx; xi < maxx; xi++) { const float dx = xi - x; - const float dy = yi - y; const float dis = dx * dx + dy * dy; if (dis <= mindist) { value = max(buffer[offset], value); @@ -262,7 +262,7 @@ ErodeDistanceOperation::ErodeDistanceOperation() : DilateDistanceOperation() void ErodeDistanceOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { const float distance = this->distance; - float mindist = distance * distance; + const float mindist = distance * distance; MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); @@ -277,10 +277,10 @@ void ErodeDistanceOperation::executePixel(float *color, int x, int y, MemoryBuff float value = 1.0f; for (int yi = miny; yi < maxy; yi++) { + const float dy = yi - y; offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; for (int xi = minx; xi < maxx; xi++) { const float dx = xi - x; - const float dy = yi - y; const float dis = dx * dx + dy * dy; if (dis <= mindist) { value = min(buffer[offset], value); diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl index e1f175b318a..0f8e543de7f 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl @@ -68,9 +68,9 @@ __kernel void dilateKernel(__read_only image2d_t inputImage, __write_only image int2 inputXy; for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny ++, inputXy.y++) { + const float deltaY = (realCoordinate.y - ny); for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx ++, inputXy.x++) { const float deltaX = (realCoordinate.x - nx); - const float deltaY = (realCoordinate.y - ny); const float measuredDistance = deltaX*deltaX+deltaY*deltaY; if (measuredDistance <= distanceSquared) { value = max(value, read_imagef(inputImage, SAMPLER_NEAREST, inputXy).s0); diff --git a/source/blender/nodes/composite/nodes/node_composite_dilate.c b/source/blender/nodes/composite/nodes/node_composite_dilate.c index ec7aaccdbe2..2f139831cc9 100644 --- a/source/blender/nodes/composite/nodes/node_composite_dilate.c +++ b/source/blender/nodes/composite/nodes/node_composite_dilate.c @@ -52,28 +52,28 @@ static void morpho_dilate(CompBuf *cbuf) for (y = 0; y < cbuf->y; y++) { for (x = 0; x < cbuf->x - 1; x++) { p = rectf + cbuf->x * y + x; - *p = MAX2(*p, *(p + 1)); + *p = maxf(*p, *(p + 1)); } } for (y = 0; y < cbuf->y; y++) { for (x = cbuf->x - 1; x >= 1; x--) { p = rectf + cbuf->x * y + x; - *p = MAX2(*p, *(p - 1)); + *p = maxf(*p, *(p - 1)); } } for (x = 0; x < cbuf->x; x++) { for (y = 0; y < cbuf->y - 1; y++) { p = rectf + cbuf->x * y + x; - *p = MAX2(*p, *(p + cbuf->x)); + *p = maxf(*p, *(p + cbuf->x)); } } for (x = 0; x < cbuf->x; x++) { for (y = cbuf->y - 1; y >= 1; y--) { p = rectf + cbuf->x * y + x; - *p = MAX2(*p, *(p - cbuf->x)); + *p = maxf(*p, *(p - cbuf->x)); } } } @@ -86,28 +86,28 @@ static void morpho_erode(CompBuf *cbuf) for (y = 0; y < cbuf->y; y++) { for (x = 0; x < cbuf->x - 1; x++) { p = rectf + cbuf->x * y + x; - *p = MIN2(*p, *(p + 1)); + *p = minf(*p, *(p + 1)); } } for (y = 0; y < cbuf->y; y++) { for (x = cbuf->x - 1; x >= 1; x--) { p = rectf + cbuf->x * y + x; - *p = MIN2(*p, *(p - 1)); + *p = minf(*p, *(p - 1)); } } for (x = 0; x < cbuf->x; x++) { for (y = 0; y < cbuf->y - 1; y++) { p = rectf + cbuf->x * y + x; - *p = MIN2(*p, *(p + cbuf->x)); + *p = minf(*p, *(p + cbuf->x)); } } for (x = 0; x < cbuf->x; x++) { for (y = cbuf->y - 1; y >= 1; y--) { p = rectf + cbuf->x * y + x; - *p = MIN2(*p, *(p - cbuf->x)); + *p = minf(*p, *(p - cbuf->x)); } } @@ -122,8 +122,7 @@ static void node_composit_exec_dilateerode(void *UNUSED(data), bNode *node, bNod /* input no image? then only color operation */ if (in[0]->data == NULL) { - out[0]->vec[0] = out[0]->vec[1] = out[0]->vec[2] = 0.0f; - out[0]->vec[3] = 0.0f; + zero_v4(out[0]->vec); } else { /* make output size of input image */ From 4b8c51d4931673daad4047ca690cebd532abc345 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 16:07:23 +0000 Subject: [PATCH 353/360] Remove unused code and correct comment for track mask AA Tip: XXX should be used for such kind of crap which is bad for release disabled AA for mask is not such a case. --- source/blender/blenkernel/intern/tracking.c | 17 +++---------- source/blender/editors/space_clip/clip_draw.c | 25 +++++-------------- 2 files changed, 9 insertions(+), 33 deletions(-) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 7edc240ff0a..b32400586a8 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -831,7 +831,7 @@ static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track) } static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height, - MovieTrackingMarker *marker, bGPDlayer *layer, + MovieTrackingMarker *marker, bGPDlayer *layer, float *mask, int mask_width, int mask_height) { bGPDframe *frame = layer->frames.first; @@ -853,7 +853,8 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height fp[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height / mask_height; } - PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height, FALSE /* XXX- TODO: make on/off for AA*/); + /* TODO: add an option to control wether AA is enabled or not */ + PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height, FALSE); MEM_freeN(mask_points); } @@ -2869,18 +2870,6 @@ static void reconstruct_update_solve_cb(void *customdata, double progress, const } #endif -#if 0 -static int solve_reconstruction_testbreak_cb(void *customdata) -{ - ReconstructProgressData *progressdata = customdata; - - if (progressdata->stop && *progressdata->stop) - return TRUE; - - return G.afbreek; -} -#endif - void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *stop, short *do_update, float *progress, char *stats_message, int message_size) { diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index ec709443cfb..9b0c5f6296d 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -811,6 +811,8 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo } if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) { + int i; + if (!outline) { if (track->pat_flag & SELECT) glColor3fv(scol); @@ -818,25 +820,10 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo glColor3fv(col); } - /* XXX: need to be real check if affine tracking is enabled, but for now not - * sure how to do this, so assume affine tracker is always enabled */ - if (TRUE) { - int i; - - /* pattern's corners sliding squares */ - for (i = 0; i < 4; i++) { - draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1], - patdx / 1.5f, patdy / 1.5f, outline, px); - } - } - else { - /* pattern offset square */ - draw_marker_slide_square(marker->pattern_corners[3][0], marker->pattern_corners[3][1], - patdx, patdy, outline, px); - - /* pattern re-sizing triangle */ - draw_marker_slide_triangle(marker->pattern_corners[1][0], marker->pattern_corners[1][1], - patdx, patdy, outline, px); + /* pattern's corners sliding squares */ + for (i = 0; i < 4; i++) { + draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1], + patdx / 1.5f, patdy / 1.5f, outline, px); } } From 5a9285a5c96914b61703634b69cc6ef040347683 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 16:07:33 +0000 Subject: [PATCH 354/360] Reshuffle code in tracking marker's slide operator, should be easier to follow the code now. y --- .../blender/editors/space_clip/tracking_ops.c | 162 ++++++++---------- 1 file changed, 70 insertions(+), 92 deletions(-) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 69c2101d0f7..14df63e4661 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -254,17 +254,21 @@ void CLIP_OT_delete_marker(wmOperatorType *ot) #define SLIDE_ACTION_OFFSET 2 typedef struct { - int area, action; + short area, action; MovieTrackingTrack *track; MovieTrackingMarker *marker; int mval[2]; int width, height; float *min, *max, *pos, *offset, (*corners)[2]; - float smin[2], smax[2], spos[2], soff[2], scorners[4][2]; - float (*smarkers)[2]; + float spos[2]; - int lock, accurate, scale; + short lock, accurate, scale; + + /* data to restore on cancel */ + float old_search_min[2], old_search_max[2], old_pos[2], old_offset[2]; + float old_corners[4][2]; + float (*old_markers)[2]; } SlideMarkerData; static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track, @@ -284,8 +288,6 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra if (area == TRACK_AREA_POINT) { data->pos = marker->pos; data->offset = track->offset; - copy_v2_v2(data->spos, marker->pos); - copy_v2_v2(data->soff, track->offset); } else if (area == TRACK_AREA_PAT) { if (action == SLIDE_ACTION_SIZE) { @@ -297,16 +299,13 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra data->pos = marker->pos; data->offset = track->offset; - copy_v2_v2(data->soff, track->offset); - - data->smarkers = MEM_callocN(sizeof(*data->smarkers) * track->markersnr, "slide marekrs"); + data->old_markers = MEM_callocN(sizeof(*data->old_markers) * track->markersnr, "slide marekrs"); for (a = 0; a < track->markersnr; a++) - copy_v2_v2(data->smarkers[a], track->markers[a].pos); + copy_v2_v2(data->old_markers[a], track->markers[a].pos); } else if (action == SLIDE_ACTION_POS) { data->corners = marker->pattern_corners; data->pos = marker->pattern_corners[corner]; - copy_v2_v2(data->spos, data->pos); } } @@ -315,18 +314,6 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra data->max = marker->search_max; } - if ((area == TRACK_AREA_SEARCH) || - (area == TRACK_AREA_PAT && action != SLIDE_ACTION_OFFSET)) - { - if (data->corners) { - memcpy(data->scorners, data->corners, sizeof(data->scorners)); - } - else { - copy_v2_v2(data->smin, data->min); - copy_v2_v2(data->smax, data->max); - } - } - data->mval[0] = event->mval[0]; data->mval[1] = event->mval[1]; @@ -336,6 +323,13 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra if (action == SLIDE_ACTION_SIZE) data->lock = 1; + /* backup marker's settings */ + memcpy(data->old_corners, marker->pattern_corners, sizeof(data->old_corners)); + copy_v2_v2(data->old_search_min, marker->search_min); + copy_v2_v2(data->old_search_max, marker->search_max); + copy_v2_v2(data->old_pos, marker->pos); + copy_v2_v2(data->old_offset, track->offset); + return data; } @@ -629,40 +623,27 @@ static int slide_marker_invoke(bContext *C, wmOperator *op, wmEvent *event) static void cancel_mouse_slide(SlideMarkerData *data) { - /* cancel sliding */ - if (data->area == TRACK_AREA_POINT) { - if (data->action == SLIDE_ACTION_OFFSET) - copy_v2_v2(data->offset, data->soff); - else - copy_v2_v2(data->pos, data->spos); - } - else { - if ((data->action == SLIDE_ACTION_SIZE) || - (data->action == SLIDE_ACTION_POS && data->area == TRACK_AREA_PAT)) - { - if (data->corners) { - memcpy(data->corners, data->scorners, sizeof(data->scorners)); - } - else { - copy_v2_v2(data->min, data->smin); - copy_v2_v2(data->max, data->smax); - } - } - else { - int a; + MovieTrackingTrack *track = data->track; + MovieTrackingMarker *marker = data->marker; - for (a = 0; a < data->track->markersnr; a++) - copy_v2_v2(data->track->markers[a].pos, data->smarkers[a]); + memcpy(marker->pattern_corners, data->old_corners, sizeof(marker->pattern_corners)); + copy_v2_v2(marker->search_min, data->old_search_min); + copy_v2_v2(marker->search_max, data->old_search_max); + copy_v2_v2(marker->pos, data->old_pos); + copy_v2_v2(track->offset, data->old_offset); - copy_v2_v2(data->offset, data->soff); - } + if (data->old_markers) { + int a; + + for (a = 0; a < data->track->markersnr; a++) + copy_v2_v2(data->track->markers[a].pos, data->old_markers[a]); } } static void free_slide_data(SlideMarkerData *data) { - if (data->smarkers) - MEM_freeN(data->smarkers); + if (data->old_markers) + MEM_freeN(data->old_markers); MEM_freeN(data); } @@ -709,63 +690,41 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) if (data->area == TRACK_AREA_POINT) { if (data->action == SLIDE_ACTION_OFFSET) { - data->offset[0] = data->soff[0] + dx; - data->offset[1] = data->soff[1] + dy; + data->offset[0] = data->old_offset[0] + dx; + data->offset[1] = data->old_offset[1] + dy; } else { - data->pos[0] = data->spos[0] + dx; - data->pos[1] = data->spos[1] + dy; + data->pos[0] = data->old_pos[0] + dx; + data->pos[1] = data->old_pos[1] + dy; } WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); DAG_id_tag_update(&sc->clip->id, 0); } - else { + else if (data->area == TRACK_AREA_PAT) { if (data->action == SLIDE_ACTION_SIZE) { - if (data->corners) { - data->corners[0][0] = data->scorners[0][0] - dx; - data->corners[0][1] = data->scorners[0][1] + dy; + data->corners[0][0] = data->old_corners[0][0] - dx; + data->corners[0][1] = data->old_corners[0][1] + dy; - data->corners[1][0] = data->scorners[1][0] + dx; - data->corners[1][1] = data->scorners[1][1] + dy; + data->corners[1][0] = data->old_corners[1][0] + dx; + data->corners[1][1] = data->old_corners[1][1] + dy; - data->corners[2][0] = data->scorners[2][0] + dx; - data->corners[2][1] = data->scorners[2][1] - dy; + data->corners[2][0] = data->old_corners[2][0] + dx; + data->corners[2][1] = data->old_corners[2][1] - dy; - data->corners[3][0] = data->scorners[3][0] - dx; - data->corners[3][1] = data->scorners[3][1] - dy; - } - else { - data->min[0] = data->smin[0] - dx; - data->max[0] = data->smax[0] + dx; + data->corners[3][0] = data->old_corners[3][0] - dx; + data->corners[3][1] = data->old_corners[3][1] - dy; - data->min[1] = data->smin[1] + dy; - data->max[1] = data->smax[1] - dy; - } - - if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_marker_clamp(data->marker, CLAMP_SEARCH_DIM); - else - BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM); + BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM); } else if (data->action == SLIDE_ACTION_OFFSET) { float d[2] = {dx, dy}; + int a; - if (data->area == TRACK_AREA_SEARCH) { - add_v2_v2v2(data->min, data->smin, d); - add_v2_v2v2(data->max, data->smax, d); - } - else { - int a; + for (a = 0; a < data->track->markersnr; a++) + add_v2_v2v2(data->track->markers[a].pos, data->old_markers[a], d); - for (a = 0; a < data->track->markersnr; a++) - add_v2_v2v2(data->track->markers[a].pos, data->smarkers[a], d); - - sub_v2_v2v2(data->offset, data->soff, d); - } - - if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_marker_clamp(data->marker, CLAMP_SEARCH_POS); + sub_v2_v2v2(data->offset, data->old_offset, d); } else if (data->action == SLIDE_ACTION_POS) { if (data->scale) { @@ -775,7 +734,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) int a; for (a = 0; a < 4; a++) { - mul_v2_v2fl(data->corners[a], data->scorners[a], scale); + mul_v2_v2fl(data->corners[a], data->old_corners[a], scale); } } } @@ -785,7 +744,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) copy_v2_v2(spos, data->pos); /* corners might've been scaled before, restore their original position */ - memcpy(data->corners, data->scorners, sizeof(data->scorners)); + memcpy(data->corners, data->old_corners, sizeof(data->old_corners)); data->pos[0] = data->spos[0] + dx; data->pos[1] = data->spos[1] + dy; @@ -799,6 +758,25 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM); } } + else if (data->area == TRACK_AREA_SEARCH) { + if (data->action == SLIDE_ACTION_SIZE) { + data->min[0] = data->old_search_min[0] - dx; + data->max[0] = data->old_search_max[0] + dx; + + data->min[1] = data->old_search_min[1] + dy; + data->max[1] = data->old_search_max[1] - dy; + + BKE_tracking_marker_clamp(data->marker, CLAMP_SEARCH_DIM); + } + else if (data->area == TRACK_AREA_SEARCH) { + float d[2] = {dx, dy}; + + add_v2_v2v2(data->min, data->old_search_min, d); + add_v2_v2v2(data->max, data->old_search_max, d); + } + + BKE_tracking_marker_clamp(data->marker, CLAMP_SEARCH_POS); + } data->marker->flag &= ~MARKER_TRACKED; From 687b6e5447855311522cc42ed980c9df3400b1c4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 17:41:12 +0000 Subject: [PATCH 355/360] style cleanup: remaining nodes in intern/ --- .../compositor/intern/COM_CPUDevice.cpp | 4 +- .../compositor/intern/COM_ChannelInfo.cpp | 4 +- .../compositor/intern/COM_ChunkOrder.cpp | 2 +- .../intern/COM_ChunkOrderHotspot.cpp | 6 +- .../compositor/intern/COM_Converter.cpp | 572 +++++++++--------- .../compositor/intern/COM_ExecutionGroup.cpp | 210 +++---- .../compositor/intern/COM_ExecutionSystem.cpp | 95 ++- .../intern/COM_ExecutionSystemHelper.cpp | 133 ++-- .../compositor/intern/COM_InputSocket.cpp | 72 +-- .../compositor/intern/COM_MemoryBuffer.cpp | 190 +++--- source/blender/compositor/intern/COM_Node.cpp | 32 +- .../compositor/intern/COM_NodeOperation.cpp | 61 +- .../compositor/intern/COM_OpenCLDevice.cpp | 6 +- .../compositor/intern/COM_OutputSocket.cpp | 17 +- .../COM_SingleThreadedNodeOperation.cpp | 2 +- .../blender/compositor/intern/COM_Socket.cpp | 6 +- .../intern/COM_SocketConnection.cpp | 12 +- .../compositor/intern/COM_WorkScheduler.cpp | 52 +- 18 files changed, 739 insertions(+), 737 deletions(-) diff --git a/source/blender/compositor/intern/COM_CPUDevice.cpp b/source/blender/compositor/intern/COM_CPUDevice.cpp index f151afd75be..95462b3c384 100644 --- a/source/blender/compositor/intern/COM_CPUDevice.cpp +++ b/source/blender/compositor/intern/COM_CPUDevice.cpp @@ -25,11 +25,11 @@ void CPUDevice::execute(WorkPackage *work) { const unsigned int chunkNumber = work->getChunkNumber(); - ExecutionGroup * executionGroup = work->getExecutionGroup(); + ExecutionGroup *executionGroup = work->getExecutionGroup(); rcti rect; executionGroup->determineChunkRect(&rect, chunkNumber); - MemoryBuffer ** inputBuffers = executionGroup->getInputBuffersCPU(); + MemoryBuffer **inputBuffers = executionGroup->getInputBuffersCPU(); executionGroup->getOutputNodeOperation()->executeRegion(&rect, chunkNumber, inputBuffers); diff --git a/source/blender/compositor/intern/COM_ChannelInfo.cpp b/source/blender/compositor/intern/COM_ChannelInfo.cpp index 7dafee5f955..f2fa62006d5 100644 --- a/source/blender/compositor/intern/COM_ChannelInfo.cpp +++ b/source/blender/compositor/intern/COM_ChannelInfo.cpp @@ -25,8 +25,8 @@ #include /** - * @brief create new ChannelInfo instance and sets the defaults. - */ + * @brief create new ChannelInfo instance and sets the defaults. + */ ChannelInfo::ChannelInfo() { this->number = 0; diff --git a/source/blender/compositor/intern/COM_ChunkOrder.cpp b/source/blender/compositor/intern/COM_ChunkOrder.cpp index 387e4a6ba70..02c28a1997a 100644 --- a/source/blender/compositor/intern/COM_ChunkOrder.cpp +++ b/source/blender/compositor/intern/COM_ChunkOrder.cpp @@ -35,7 +35,7 @@ void ChunkOrder::determineDistance(ChunkOrderHotspot **hotspots, unsigned int nu { unsigned int index; double distance = MAXFLOAT; - for (index = 0 ; index < numberOfHotspots ; index ++) { + for (index = 0; index < numberOfHotspots; index++) { ChunkOrderHotspot *hotspot = hotspots[index]; double ndistance = hotspot->determineDistance(this->x, this->y); if (ndistance < distance) { diff --git a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp index 0ab08ec5810..96568092b72 100644 --- a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp +++ b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp @@ -32,9 +32,9 @@ ChunkOrderHotspot::ChunkOrderHotspot(int x, int y, float addition) double ChunkOrderHotspot::determineDistance(int x, int y) { - int dx = x-this->x; - int dy = y-this->y; - double result = sqrt((double)(dx*dx+dy*dy)); + int dx = x - this->x; + int dy = y - this->y; + double result = sqrt((double)(dx * dx + dy * dy)); result += (double)this->addition; return result; } diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 9731555039c..fa30d965938 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -117,7 +117,7 @@ Node *Converter::convert(bNode *bNode) { - Node * node; + Node *node; if (bNode->flag & NODE_MUTED) { node = new MuteNode(bNode); @@ -125,244 +125,244 @@ Node *Converter::convert(bNode *bNode) } switch (bNode->type) { - case CMP_NODE_COMPOSITE: - node = new CompositorNode(bNode); - break; - case CMP_NODE_R_LAYERS: - node = new RenderLayersNode(bNode); - break; - case CMP_NODE_TEXTURE: - node = new TextureNode(bNode); - break; - case CMP_NODE_RGBTOBW: - node = new ColourToBWNode(bNode); - break; - case CMP_NODE_MIX_RGB: - node = new MixNode(bNode); - break; - case CMP_NODE_TRANSLATE: - node = new TranslateNode(bNode); - break; - case CMP_NODE_SCALE: - node = new ScaleNode(bNode); - break; - case CMP_NODE_ROTATE: - node = new RotateNode(bNode); - break; - case CMP_NODE_FLIP: - node = new FlipNode(bNode); - break; - case CMP_NODE_FILTER: - node = new FilterNode(bNode); - break; - case CMP_NODE_ID_MASK: - node = new IDMaskNode(bNode); - break; - case CMP_NODE_BRIGHTCONTRAST: - node = new BrightnessNode(bNode); - break; - case CMP_NODE_SEPRGBA: - node = new SeparateRGBANode(bNode); - break; - case CMP_NODE_COMBRGBA: - node = new CombineRGBANode(bNode); - break; - case CMP_NODE_SEPHSVA: - node = new SeparateHSVANode(bNode); - break; - case CMP_NODE_COMBHSVA: - node = new CombineHSVANode(bNode); - break; - case CMP_NODE_SEPYUVA: - node = new SeparateYUVANode(bNode); - break; - case CMP_NODE_COMBYUVA: - node = new CombineYUVANode(bNode); - break; - case CMP_NODE_SEPYCCA: - node = new SeparateYCCANode(bNode); - break; - case CMP_NODE_COMBYCCA: - node = new CombineYCCANode(bNode); - break; - case CMP_NODE_ALPHAOVER: - node = new AlphaOverNode(bNode); - break; - case CMP_NODE_COLORBALANCE: - node = new ColorBalanceNode(bNode); - break; - case CMP_NODE_VIEWER: - node = new ViewerNode(bNode); - break; - case CMP_NODE_SPLITVIEWER: - node = new SplitViewerNode(bNode); - break; - case CMP_NODE_INVERT: - node = new InvertNode(bNode); - break; - case NODE_GROUP: - node = new GroupNode(bNode); - break; - case CMP_NODE_NORMAL: - node = new NormalNode(bNode); - break; - case CMP_NODE_NORMALIZE: - node = new NormalizeNode(bNode); - break; - case CMP_NODE_IMAGE: - node = new ImageNode(bNode); - break; - case CMP_NODE_SETALPHA: - node = new SetAlphaNode(bNode); - break; - case CMP_NODE_PREMULKEY: - node = new ConvertAlphaNode(bNode); - break; - case CMP_NODE_MATH: - node = new MathNode(bNode); - break; - case CMP_NODE_HUE_SAT: - node = new HueSaturationValueNode(bNode); - break; - case CMP_NODE_COLORCORRECTION: - node = new ColorCorrectionNode(bNode); - break; - case CMP_NODE_MASK_BOX: - node = new BoxMaskNode(bNode); - break; - case CMP_NODE_MASK_ELLIPSE: - node = new EllipseMaskNode(bNode); - break; - case CMP_NODE_GAMMA: - node = new GammaNode(bNode); - break; - case CMP_NODE_CURVE_RGB: - node = new ColorCurveNode(bNode); - break; - case CMP_NODE_CURVE_VEC: - node = new VectorCurveNode(bNode); - break; - case CMP_NODE_HUECORRECT: - node = new HueSaturationValueCorrectNode(bNode); - break; - case CMP_NODE_MAP_UV: - node = new MapUVNode(bNode); - break; - case CMP_NODE_DISPLACE: - node = new DisplaceNode(bNode); - break; - case CMP_NODE_VALTORGB: - node = new ColorRampNode(bNode); - break; - case CMP_NODE_DIFF_MATTE: - node = new DifferenceMatteNode(bNode); - break; - case CMP_NODE_LUMA_MATTE: - node = new LuminanceMatteNode(bNode); - break; - case CMP_NODE_DIST_MATTE: - node = new DistanceMatteNode(bNode); - break; - case CMP_NODE_CHROMA_MATTE: - node = new ChromaMatteNode(bNode); - break; - case CMP_NODE_COLOR_MATTE: - node = new ColorMatteNode(bNode); - break; - case CMP_NODE_CHANNEL_MATTE: - node = new ChannelMatteNode(bNode); - break; - case CMP_NODE_BLUR: - node = new BlurNode(bNode); - break; - case CMP_NODE_BOKEHIMAGE: - node = new BokehImageNode(bNode); - break; - case CMP_NODE_BOKEHBLUR: - node = new BokehBlurNode(bNode); - break; - case CMP_NODE_DILATEERODE: - node = new DilateErodeNode(bNode); - break; - case CMP_NODE_LENSDIST: - node = new LensDistortionNode(bNode); - break; - case CMP_NODE_RGB: - node = new ColorNode(bNode); - break; - case CMP_NODE_VALUE: - node = new ValueNode(bNode); - break; - case CMP_NODE_TIME: - node = new TimeNode(bNode); - break; - case CMP_NODE_DBLUR: - node = new DirectionalBlurNode(bNode); - break; - case CMP_NODE_ZCOMBINE: - node = new ZCombineNode(bNode); - break; - case CMP_NODE_TONEMAP: - node = new TonemapNode(bNode); - break; - case CMP_NODE_SWITCH: - node = new SwitchNode(bNode); - break; - case CMP_NODE_GLARE: - node = new GlareNode(bNode); - break; - case CMP_NODE_MOVIECLIP: - node = new MovieClipNode(bNode); - break; - case CMP_NODE_COLOR_SPILL: - node = new ColorSpillNode(bNode); - break; -case CMP_NODE_OUTPUT_FILE: - node = new OutputFileNode(bNode); - break; - case CMP_NODE_MAP_VALUE: - node = new MapValueNode(bNode); - break; - case CMP_NODE_TRANSFORM: - node = new TransformNode(bNode); - break; - case CMP_NODE_STABILIZE2D: - node = new Stabilize2dNode(bNode); - break; - case CMP_NODE_BILATERALBLUR: - node = new BilateralBlurNode(bNode); - break; - case CMP_NODE_VECBLUR: - node = new VectorBlurNode(bNode); - break; - case CMP_NODE_MOVIEDISTORTION: - node = new MovieDistortionNode(bNode); - break; - case CMP_NODE_VIEW_LEVELS: - node = new ViewLevelsNode(bNode); - break; - case CMP_NODE_DEFOCUS: - node = new DefocusNode(bNode); - break; - case CMP_NODE_DOUBLEEDGEMASK: - node = new DoubleEdgeMaskNode(bNode); - break; - case CMP_NODE_CROP: - node = new CropNode(bNode); - break; - case CMP_NODE_MASK: - node = new MaskNode(bNode); - break; - case CMP_NODE_KEYINGSCREEN: - node = new KeyingScreenNode(bNode); - break; - case CMP_NODE_KEYING: - node = new KeyingNode(bNode); - break; - /* not inplemented yet */ - default: - node = new MuteNode(bNode); - break; + case CMP_NODE_COMPOSITE: + node = new CompositorNode(bNode); + break; + case CMP_NODE_R_LAYERS: + node = new RenderLayersNode(bNode); + break; + case CMP_NODE_TEXTURE: + node = new TextureNode(bNode); + break; + case CMP_NODE_RGBTOBW: + node = new ColourToBWNode(bNode); + break; + case CMP_NODE_MIX_RGB: + node = new MixNode(bNode); + break; + case CMP_NODE_TRANSLATE: + node = new TranslateNode(bNode); + break; + case CMP_NODE_SCALE: + node = new ScaleNode(bNode); + break; + case CMP_NODE_ROTATE: + node = new RotateNode(bNode); + break; + case CMP_NODE_FLIP: + node = new FlipNode(bNode); + break; + case CMP_NODE_FILTER: + node = new FilterNode(bNode); + break; + case CMP_NODE_ID_MASK: + node = new IDMaskNode(bNode); + break; + case CMP_NODE_BRIGHTCONTRAST: + node = new BrightnessNode(bNode); + break; + case CMP_NODE_SEPRGBA: + node = new SeparateRGBANode(bNode); + break; + case CMP_NODE_COMBRGBA: + node = new CombineRGBANode(bNode); + break; + case CMP_NODE_SEPHSVA: + node = new SeparateHSVANode(bNode); + break; + case CMP_NODE_COMBHSVA: + node = new CombineHSVANode(bNode); + break; + case CMP_NODE_SEPYUVA: + node = new SeparateYUVANode(bNode); + break; + case CMP_NODE_COMBYUVA: + node = new CombineYUVANode(bNode); + break; + case CMP_NODE_SEPYCCA: + node = new SeparateYCCANode(bNode); + break; + case CMP_NODE_COMBYCCA: + node = new CombineYCCANode(bNode); + break; + case CMP_NODE_ALPHAOVER: + node = new AlphaOverNode(bNode); + break; + case CMP_NODE_COLORBALANCE: + node = new ColorBalanceNode(bNode); + break; + case CMP_NODE_VIEWER: + node = new ViewerNode(bNode); + break; + case CMP_NODE_SPLITVIEWER: + node = new SplitViewerNode(bNode); + break; + case CMP_NODE_INVERT: + node = new InvertNode(bNode); + break; + case NODE_GROUP: + node = new GroupNode(bNode); + break; + case CMP_NODE_NORMAL: + node = new NormalNode(bNode); + break; + case CMP_NODE_NORMALIZE: + node = new NormalizeNode(bNode); + break; + case CMP_NODE_IMAGE: + node = new ImageNode(bNode); + break; + case CMP_NODE_SETALPHA: + node = new SetAlphaNode(bNode); + break; + case CMP_NODE_PREMULKEY: + node = new ConvertAlphaNode(bNode); + break; + case CMP_NODE_MATH: + node = new MathNode(bNode); + break; + case CMP_NODE_HUE_SAT: + node = new HueSaturationValueNode(bNode); + break; + case CMP_NODE_COLORCORRECTION: + node = new ColorCorrectionNode(bNode); + break; + case CMP_NODE_MASK_BOX: + node = new BoxMaskNode(bNode); + break; + case CMP_NODE_MASK_ELLIPSE: + node = new EllipseMaskNode(bNode); + break; + case CMP_NODE_GAMMA: + node = new GammaNode(bNode); + break; + case CMP_NODE_CURVE_RGB: + node = new ColorCurveNode(bNode); + break; + case CMP_NODE_CURVE_VEC: + node = new VectorCurveNode(bNode); + break; + case CMP_NODE_HUECORRECT: + node = new HueSaturationValueCorrectNode(bNode); + break; + case CMP_NODE_MAP_UV: + node = new MapUVNode(bNode); + break; + case CMP_NODE_DISPLACE: + node = new DisplaceNode(bNode); + break; + case CMP_NODE_VALTORGB: + node = new ColorRampNode(bNode); + break; + case CMP_NODE_DIFF_MATTE: + node = new DifferenceMatteNode(bNode); + break; + case CMP_NODE_LUMA_MATTE: + node = new LuminanceMatteNode(bNode); + break; + case CMP_NODE_DIST_MATTE: + node = new DistanceMatteNode(bNode); + break; + case CMP_NODE_CHROMA_MATTE: + node = new ChromaMatteNode(bNode); + break; + case CMP_NODE_COLOR_MATTE: + node = new ColorMatteNode(bNode); + break; + case CMP_NODE_CHANNEL_MATTE: + node = new ChannelMatteNode(bNode); + break; + case CMP_NODE_BLUR: + node = new BlurNode(bNode); + break; + case CMP_NODE_BOKEHIMAGE: + node = new BokehImageNode(bNode); + break; + case CMP_NODE_BOKEHBLUR: + node = new BokehBlurNode(bNode); + break; + case CMP_NODE_DILATEERODE: + node = new DilateErodeNode(bNode); + break; + case CMP_NODE_LENSDIST: + node = new LensDistortionNode(bNode); + break; + case CMP_NODE_RGB: + node = new ColorNode(bNode); + break; + case CMP_NODE_VALUE: + node = new ValueNode(bNode); + break; + case CMP_NODE_TIME: + node = new TimeNode(bNode); + break; + case CMP_NODE_DBLUR: + node = new DirectionalBlurNode(bNode); + break; + case CMP_NODE_ZCOMBINE: + node = new ZCombineNode(bNode); + break; + case CMP_NODE_TONEMAP: + node = new TonemapNode(bNode); + break; + case CMP_NODE_SWITCH: + node = new SwitchNode(bNode); + break; + case CMP_NODE_GLARE: + node = new GlareNode(bNode); + break; + case CMP_NODE_MOVIECLIP: + node = new MovieClipNode(bNode); + break; + case CMP_NODE_COLOR_SPILL: + node = new ColorSpillNode(bNode); + break; + case CMP_NODE_OUTPUT_FILE: + node = new OutputFileNode(bNode); + break; + case CMP_NODE_MAP_VALUE: + node = new MapValueNode(bNode); + break; + case CMP_NODE_TRANSFORM: + node = new TransformNode(bNode); + break; + case CMP_NODE_STABILIZE2D: + node = new Stabilize2dNode(bNode); + break; + case CMP_NODE_BILATERALBLUR: + node = new BilateralBlurNode(bNode); + break; + case CMP_NODE_VECBLUR: + node = new VectorBlurNode(bNode); + break; + case CMP_NODE_MOVIEDISTORTION: + node = new MovieDistortionNode(bNode); + break; + case CMP_NODE_VIEW_LEVELS: + node = new ViewLevelsNode(bNode); + break; + case CMP_NODE_DEFOCUS: + node = new DefocusNode(bNode); + break; + case CMP_NODE_DOUBLEEDGEMASK: + node = new DoubleEdgeMaskNode(bNode); + break; + case CMP_NODE_CROP: + node = new CropNode(bNode); + break; + case CMP_NODE_MASK: + node = new MaskNode(bNode); + break; + case CMP_NODE_KEYINGSCREEN: + node = new KeyingScreenNode(bNode); + break; + case CMP_NODE_KEYING: + node = new KeyingNode(bNode); + break; + /* not inplemented yet */ + default: + node = new MuteNode(bNode); + break; } return node; } @@ -372,7 +372,7 @@ void Converter::convertDataType(SocketConnection *connection, ExecutionSystem *s InputSocket *inputSocket = connection->getToSocket(); DataType fromDatatype = outputSocket->getDataType(); DataType toDatatype = inputSocket->getDataType(); - NodeOperation * converter = NULL; + NodeOperation *converter = NULL; if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_COLOR) { converter = new ConvertValueToColourProg(); } @@ -402,68 +402,68 @@ void Converter::convertResolution(SocketConnection *connection, ExecutionSystem { InputSocketResizeMode mode = connection->getToSocket()->getResizeMode(); - NodeOperation * toOperation = (NodeOperation*)connection->getToNode(); + NodeOperation *toOperation = (NodeOperation *)connection->getToNode(); const float toWidth = toOperation->getWidth(); const float toHeight = toOperation->getHeight(); - NodeOperation * fromOperation = (NodeOperation*)connection->getFromNode(); + NodeOperation *fromOperation = (NodeOperation *)connection->getFromNode(); const float fromWidth = fromOperation->getWidth(); const float fromHeight = fromOperation->getHeight(); bool doCenter = false; bool doScale = false; - float addX= (toWidth-fromWidth)/2.0f; - float addY = (toHeight-fromHeight)/2.0f; - float scaleX=0; - float scaleY=0; + float addX = (toWidth - fromWidth) / 2.0f; + float addY = (toHeight - fromHeight) / 2.0f; + float scaleX = 0; + float scaleY = 0; switch (mode) { - case COM_SC_NO_RESIZE: - break; - case COM_SC_CENTER: - doCenter = true; - break; - case COM_SC_FIT_WIDTH: - doCenter = true; - doScale = true; - scaleX = scaleY = toWidth/fromWidth; - break; - case COM_SC_FIT_HEIGHT: - doCenter = true; - doScale = true; - scaleX = scaleY = toHeight/fromHeight; - break; - case COM_SC_FIT: - doCenter = true; - doScale = true; - scaleX = toWidth/fromWidth; - scaleY = toHeight/fromHeight; - if (scaleX < scaleY) { - scaleX = scaleY; - } - else { - scaleY = scaleX; - } - break; - case COM_SC_STRETCH: - doCenter = true; - doScale = true; - scaleX = toWidth/fromWidth; - scaleY = toHeight/fromHeight; - break; + case COM_SC_NO_RESIZE: + break; + case COM_SC_CENTER: + doCenter = true; + break; + case COM_SC_FIT_WIDTH: + doCenter = true; + doScale = true; + scaleX = scaleY = toWidth / fromWidth; + break; + case COM_SC_FIT_HEIGHT: + doCenter = true; + doScale = true; + scaleX = scaleY = toHeight / fromHeight; + break; + case COM_SC_FIT: + doCenter = true; + doScale = true; + scaleX = toWidth / fromWidth; + scaleY = toHeight / fromHeight; + if (scaleX < scaleY) { + scaleX = scaleY; + } + else { + scaleY = scaleX; + } + break; + case COM_SC_STRETCH: + doCenter = true; + doScale = true; + scaleX = toWidth / fromWidth; + scaleY = toHeight / fromHeight; + break; } if (doCenter) { NodeOperation *first = NULL; SocketConnection *c; - ScaleOperation * scaleOperation = NULL; + ScaleOperation *scaleOperation = NULL; if (doScale) { scaleOperation = new ScaleOperation(); first = scaleOperation; - SetValueOperation * sxop = new SetValueOperation(); + SetValueOperation *sxop = new SetValueOperation(); sxop->setValue(scaleX); c = ExecutionSystemHelper::addLink(system->getConnections(), sxop->getOutputSocket(), scaleOperation->getInputSocket(1)); c->setIgnoreResizeCheck(true); - SetValueOperation * syop = new SetValueOperation(); + SetValueOperation *syop = new SetValueOperation(); syop->setValue(scaleY); c = ExecutionSystemHelper::addLink(system->getConnections(), syop->getOutputSocket(), scaleOperation->getInputSocket(2)); c->setIgnoreResizeCheck(true); @@ -479,13 +479,13 @@ void Converter::convertResolution(SocketConnection *connection, ExecutionSystem c->setIgnoreResizeCheck(true); } - TranslateOperation * translateOperation = new TranslateOperation(); + TranslateOperation *translateOperation = new TranslateOperation(); if (!first) first = translateOperation; - SetValueOperation * xop = new SetValueOperation(); + SetValueOperation *xop = new SetValueOperation(); xop->setValue(addX); c = ExecutionSystemHelper::addLink(system->getConnections(), xop->getOutputSocket(), translateOperation->getInputSocket(1)); c->setIgnoreResizeCheck(true); - SetValueOperation * yop = new SetValueOperation(); + SetValueOperation *yop = new SetValueOperation(); yop->setValue(addY); c = ExecutionSystemHelper::addLink(system->getConnections(), yop->getOutputSocket(), translateOperation->getInputSocket(2)); c->setIgnoreResizeCheck(true); @@ -503,7 +503,7 @@ void Converter::convertResolution(SocketConnection *connection, ExecutionSystem c->setIgnoreResizeCheck(true); } - InputSocket * inputSocket = connection->getToSocket(); + InputSocket *inputSocket = connection->getToSocket(); inputSocket->relinkConnections(first->getInputSocket(0)); c = ExecutionSystemHelper::addLink(system->getConnections(), translateOperation->getOutputSocket(), inputSocket); c->setIgnoreResizeCheck(true); diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index aaca97d8479..2a790da0354 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -65,7 +65,7 @@ CompositorPriority ExecutionGroup::getRenderPriotrity() bool ExecutionGroup::containsOperation(NodeOperation *operation) { - for (vector::const_iterator iterator = this->operations.begin() ; iterator != this->operations.end() ; ++iterator) { + for (vector::const_iterator iterator = this->operations.begin(); iterator != this->operations.end(); ++iterator) { NodeOperation *inListOperation = *iterator; if (inListOperation == operation) { return true; @@ -81,10 +81,10 @@ const bool ExecutionGroup::isComplex() const bool ExecutionGroup::canContainOperation(NodeOperation *operation) { - if (!this->initialized) {return true;} - if (operation->isReadBufferOperation()) {return true;} - if (operation->isWriteBufferOperation()) {return false;} - if (operation->isSetOperation()) {return true;} + if (!this->initialized) { return true; } + if (operation->isReadBufferOperation()) { return true; } + if (operation->isWriteBufferOperation()) { return false; } + if (operation->isSetOperation()) { return true; } if (!this->isComplex()) { return (!operation->isComplex()); @@ -106,16 +106,16 @@ void ExecutionGroup::addOperation(ExecutionSystem *system, NodeOperation *operat } this->operations.push_back(operation); if (operation->isReadBufferOperation()) { - ReadBufferOperation *readOperation = (ReadBufferOperation*)operation; + ReadBufferOperation *readOperation = (ReadBufferOperation *)operation; WriteBufferOperation *writeOperation = readOperation->getMemoryProxy()->getWriteBufferOperation(); this->addOperation(system, writeOperation); } else { unsigned int index; - for (index = 0 ; index < operation->getNumberOfInputSockets(); index ++) { - InputSocket * inputSocket = operation->getInputSocket(index); + for (index = 0; index < operation->getNumberOfInputSockets(); index++) { + InputSocket *inputSocket = operation->getInputSocket(index); if (inputSocket->isConnected()) { - NodeOperation *node = (NodeOperation*)inputSocket->getConnection()->getFromNode(); + NodeOperation *node = (NodeOperation *)inputSocket->getConnection()->getFromNode(); this->addOperation(system, node); } } @@ -123,7 +123,7 @@ void ExecutionGroup::addOperation(ExecutionSystem *system, NodeOperation *operat } else { if (operation->isWriteBufferOperation()) { - WriteBufferOperation * writeoperation = (WriteBufferOperation*)operation; + WriteBufferOperation *writeoperation = (WriteBufferOperation *)operation; if (writeoperation->getMemoryProxy()->getExecutor() == NULL) { ExecutionGroup *newGroup = new ExecutionGroup(); writeoperation->getMemoryProxy()->setExecutor(newGroup); @@ -150,7 +150,7 @@ void ExecutionGroup::initExecution() this->chunkExecutionStates = NULL; if (this->numberOfChunks != 0) { this->chunkExecutionStates = new ChunkExecutionState[numberOfChunks]; - for (index = 0 ; index < numberOfChunks ; index ++) { + for (index = 0; index < numberOfChunks; index++) { this->chunkExecutionStates[index] = COM_ES_NOT_SCHEDULED; } } @@ -158,10 +158,10 @@ void ExecutionGroup::initExecution() unsigned int maxNumber = 0; - for (index = 0 ; index < this->operations.size(); index ++) { + for (index = 0; index < this->operations.size(); index++) { NodeOperation *operation = this->operations[index]; if (operation->isReadBufferOperation()) { - ReadBufferOperation *readOperation = (ReadBufferOperation*)operation; + ReadBufferOperation *readOperation = (ReadBufferOperation *)operation; this->cachedReadOperations.push_back(readOperation); maxNumber = max(maxNumber, readOperation->getOffset()); } @@ -207,15 +207,15 @@ void ExecutionGroup::determineNumberOfChunks() } /** - * this method is called for the top execution groups. containing the compositor node or the preview node or the viewer node) - */ + * this method is called for the top execution groups. containing the compositor node or the preview node or the viewer node) + */ void ExecutionGroup::execute(ExecutionSystem *graph) { CompositorContext& context = graph->getContext(); const bNodeTree *bTree = context.getbNodeTree(); - if (this->width == 0 || this->height == 0) {return;} /// @note: break out... no pixels to calculate. - if (bTree->test_break && bTree->test_break(bTree->tbh)) {return;} /// @note: early break out for blur and preview nodes - if (this->numberOfChunks == 0) {return;} /// @note: early break out + if (this->width == 0 || this->height == 0) {return; } /// @note: break out... no pixels to calculate. + if (bTree->test_break && bTree->test_break(bTree->tbh)) {return; } /// @note: early break out for blur and preview nodes + if (this->numberOfChunks == 0) {return; } /// @note: early break out unsigned int chunkNumber; this->chunksFinished = 0; @@ -223,7 +223,7 @@ void ExecutionGroup::execute(ExecutionSystem *graph) unsigned int index; unsigned int *chunkOrder = new unsigned int[this->numberOfChunks]; - for (chunkNumber = 0 ; chunkNumbernumberOfChunks ; chunkNumber++) { + for (chunkNumber = 0; chunkNumber < this->numberOfChunks; chunkNumber++) { chunkOrder[chunkNumber] = chunkNumber; } NodeOperation *operation = this->getOutputNodeOperation(); @@ -232,29 +232,29 @@ void ExecutionGroup::execute(ExecutionSystem *graph) OrderOfChunks chunkorder = COM_ORDER_OF_CHUNKS_DEFAULT; if (operation->isViewerOperation()) { - ViewerBaseOperation *viewer = (ViewerBaseOperation*)operation; + ViewerBaseOperation *viewer = (ViewerBaseOperation *)operation; centerX = viewer->getCenterX(); centerY = viewer->getCenterY(); chunkorder = viewer->getChunkOrder(); } switch (chunkorder) { - case COM_TO_RANDOM: - for (index = 0 ; index < 2 * numberOfChunks ; index ++) { - int index1 = rand()%numberOfChunks; - int index2 = rand()%numberOfChunks; - int s = chunkOrder[index1]; - chunkOrder[index1] = chunkOrder[index2]; - chunkOrder[index2] = s; - } - break; - case COM_TO_CENTER_OUT: + case COM_TO_RANDOM: + for (index = 0; index < 2 * numberOfChunks; index++) { + int index1 = rand() % numberOfChunks; + int index2 = rand() % numberOfChunks; + int s = chunkOrder[index1]; + chunkOrder[index1] = chunkOrder[index2]; + chunkOrder[index2] = s; + } + break; + case COM_TO_CENTER_OUT: { - ChunkOrderHotspot **hotspots = new ChunkOrderHotspot*[1]; - hotspots[0] = new ChunkOrderHotspot(this->width*centerX, this->height*centerY, 0.0f); + ChunkOrderHotspot **hotspots = new ChunkOrderHotspot *[1]; + hotspots[0] = new ChunkOrderHotspot(this->width * centerX, this->height * centerY, 0.0f); rcti rect; ChunkOrder *chunkOrders = new ChunkOrder[this->numberOfChunks]; - for (index = 0 ; index < this->numberOfChunks; index ++) { + for (index = 0; index < this->numberOfChunks; index++) { determineChunkRect(&rect, index); chunkOrders[index].setChunkNumber(index); chunkOrders[index].setX(rect.xmin); @@ -262,8 +262,8 @@ void ExecutionGroup::execute(ExecutionSystem *graph) chunkOrders[index].determineDistance(hotspots, 1); } - sort(&chunkOrders[0], &chunkOrders[numberOfChunks-1]); - for (index = 0 ; index < numberOfChunks; index ++) { + sort(&chunkOrders[0], &chunkOrders[numberOfChunks - 1]); + for (index = 0; index < numberOfChunks; index++) { chunkOrder[index] = chunkOrders[index].getChunkNumber(); } @@ -272,29 +272,29 @@ void ExecutionGroup::execute(ExecutionSystem *graph) delete[] chunkOrders; } break; - case COM_TO_RULE_OF_THIRDS: + case COM_TO_RULE_OF_THIRDS: { - ChunkOrderHotspot **hotspots = new ChunkOrderHotspot*[9]; - unsigned int tx = this->width/6; - unsigned int ty = this->height/6; - unsigned int mx = this->width/2; - unsigned int my = this->height/2; - unsigned int bx = mx+2*tx; - unsigned int by = my+2*ty; + ChunkOrderHotspot **hotspots = new ChunkOrderHotspot *[9]; + unsigned int tx = this->width / 6; + unsigned int ty = this->height / 6; + unsigned int mx = this->width / 2; + unsigned int my = this->height / 2; + unsigned int bx = mx + 2 * tx; + unsigned int by = my + 2 * ty; - float addition = numberOfChunks/COM_RULE_OF_THIRDS_DIVIDER; - hotspots[0] = new ChunkOrderHotspot(mx, my, addition*0); - hotspots[1] = new ChunkOrderHotspot(tx, my, addition*1); - hotspots[2] = new ChunkOrderHotspot(bx, my, addition*2); - hotspots[3] = new ChunkOrderHotspot(bx, by, addition*3); - hotspots[4] = new ChunkOrderHotspot(tx, ty, addition*4); - hotspots[5] = new ChunkOrderHotspot(bx, ty, addition*5); - hotspots[6] = new ChunkOrderHotspot(tx, by, addition*6); - hotspots[7] = new ChunkOrderHotspot(mx, ty, addition*7); - hotspots[8] = new ChunkOrderHotspot(mx, by, addition*8); + float addition = numberOfChunks / COM_RULE_OF_THIRDS_DIVIDER; + hotspots[0] = new ChunkOrderHotspot(mx, my, addition * 0); + hotspots[1] = new ChunkOrderHotspot(tx, my, addition * 1); + hotspots[2] = new ChunkOrderHotspot(bx, my, addition * 2); + hotspots[3] = new ChunkOrderHotspot(bx, by, addition * 3); + hotspots[4] = new ChunkOrderHotspot(tx, ty, addition * 4); + hotspots[5] = new ChunkOrderHotspot(bx, ty, addition * 5); + hotspots[6] = new ChunkOrderHotspot(tx, by, addition * 6); + hotspots[7] = new ChunkOrderHotspot(mx, ty, addition * 7); + hotspots[8] = new ChunkOrderHotspot(mx, by, addition * 8); rcti rect; ChunkOrder *chunkOrders = new ChunkOrder[this->numberOfChunks]; - for (index = 0 ; index < this->numberOfChunks; index ++) { + for (index = 0; index < this->numberOfChunks; index++) { determineChunkRect(&rect, index); chunkOrders[index].setChunkNumber(index); chunkOrders[index].setX(rect.xmin); @@ -304,7 +304,7 @@ void ExecutionGroup::execute(ExecutionSystem *graph) sort(&chunkOrders[0], &chunkOrders[numberOfChunks]); - for (index = 0 ; index < numberOfChunks; index ++) { + for (index = 0; index < numberOfChunks; index++) { chunkOrder[index] = chunkOrders[index].getChunkNumber(); } @@ -321,40 +321,40 @@ void ExecutionGroup::execute(ExecutionSystem *graph) delete[] chunkOrders; } break; - case COM_TO_TOP_DOWN: - default: - break; + case COM_TO_TOP_DOWN: + default: + break; } bool breaked = false; bool finished = false; unsigned int startIndex = 0; - const int maxNumberEvaluated = BLI_system_thread_count()*2; + const int maxNumberEvaluated = BLI_system_thread_count() * 2; while (!finished && !breaked) { - unsigned int index; + unsigned int index; bool startEvaluated = false; finished = true; int numberEvaluated = 0; - for (index = startIndex ; index < numberOfChunks && numberEvaluated < maxNumberEvaluated; index ++) { + for (index = startIndex; index < numberOfChunks && numberEvaluated < maxNumberEvaluated; index++) { int chunkNumber = chunkOrder[index]; - int yChunk = chunkNumber/this->numberOfXChunks; - int xChunk = chunkNumber - (yChunk*this->numberOfXChunks); + int yChunk = chunkNumber / this->numberOfXChunks; + int xChunk = chunkNumber - (yChunk * this->numberOfXChunks); const ChunkExecutionState state = this->chunkExecutionStates[chunkNumber]; if (state == COM_ES_NOT_SCHEDULED) { scheduleChunkWhenPossible(graph, xChunk, yChunk); - finished=false; + finished = false; startEvaluated = true; numberEvaluated++; } else if (state == COM_ES_SCHEDULED) { - finished=false; + finished = false; startEvaluated = true; numberEvaluated++; } else if (state == COM_ES_EXECUTED && !startEvaluated) { - startIndex = index+1; + startIndex = index + 1; } } @@ -368,39 +368,39 @@ void ExecutionGroup::execute(ExecutionSystem *graph) delete[] chunkOrder; } -MemoryBuffer** ExecutionGroup::getInputBuffersCPU() +MemoryBuffer **ExecutionGroup::getInputBuffersCPU() { - vector memoryproxies; + vector memoryproxies; unsigned int index; this->determineDependingMemoryProxies(&memoryproxies); - MemoryBuffer **memoryBuffers = new MemoryBuffer*[this->cachedMaxReadBufferOffset]; - for (index = 0 ; index < this->cachedMaxReadBufferOffset ; index ++) { + MemoryBuffer **memoryBuffers = new MemoryBuffer *[this->cachedMaxReadBufferOffset]; + for (index = 0; index < this->cachedMaxReadBufferOffset; index++) { memoryBuffers[index] = NULL; } - for (index = 0 ; index < this->cachedReadOperations.size(); index ++) { - ReadBufferOperation *readOperation = (ReadBufferOperation*)this->cachedReadOperations[index]; + for (index = 0; index < this->cachedReadOperations.size(); index++) { + ReadBufferOperation *readOperation = (ReadBufferOperation *)this->cachedReadOperations[index]; memoryBuffers[readOperation->getOffset()] = readOperation->getMemoryProxy()->getBuffer(); } return memoryBuffers; } -MemoryBuffer** ExecutionGroup::getInputBuffersOpenCL(int chunkNumber) +MemoryBuffer **ExecutionGroup::getInputBuffersOpenCL(int chunkNumber) { rcti rect; - vector memoryproxies; + vector memoryproxies; unsigned int index; determineChunkRect(&rect, chunkNumber); this->determineDependingMemoryProxies(&memoryproxies); - MemoryBuffer **memoryBuffers = new MemoryBuffer*[this->cachedMaxReadBufferOffset]; - for (index = 0 ; index < this->cachedMaxReadBufferOffset ; index ++) { + MemoryBuffer **memoryBuffers = new MemoryBuffer *[this->cachedMaxReadBufferOffset]; + for (index = 0; index < this->cachedMaxReadBufferOffset; index++) { memoryBuffers[index] = NULL; } rcti output; - for (index = 0 ; index < this->cachedReadOperations.size(); index ++) { - ReadBufferOperation *readOperation = (ReadBufferOperation*)this->cachedReadOperations[index]; - MemoryProxy * memoryProxy = readOperation->getMemoryProxy(); + for (index = 0; index < this->cachedReadOperations.size(); index++) { + ReadBufferOperation *readOperation = (ReadBufferOperation *)this->cachedReadOperations[index]; + MemoryProxy *memoryProxy = readOperation->getMemoryProxy(); this->determineDependingAreaOfInterest(&rect, readOperation, &output); MemoryBuffer *memoryBuffer = memoryProxy->getExecutor()->constructConsolidatedMemoryBuffer(memoryProxy, &output); memoryBuffers[readOperation->getOffset()] = memoryBuffer; @@ -410,21 +410,21 @@ MemoryBuffer** ExecutionGroup::getInputBuffersOpenCL(int chunkNumber) MemoryBuffer *ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *rect) { - MemoryBuffer* imageBuffer = memoryProxy->getBuffer(); - MemoryBuffer* result = new MemoryBuffer(memoryProxy, rect); + MemoryBuffer *imageBuffer = memoryProxy->getBuffer(); + MemoryBuffer *result = new MemoryBuffer(memoryProxy, rect); result->copyContentFrom(imageBuffer); return result; } -void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer** memoryBuffers) +void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer **memoryBuffers) { if (this->chunkExecutionStates[chunkNumber] == COM_ES_SCHEDULED) this->chunkExecutionStates[chunkNumber] = COM_ES_EXECUTED; this->chunksFinished++; if (memoryBuffers) { - for (unsigned int index = 0 ; index < this->cachedMaxReadBufferOffset; index ++) { - MemoryBuffer * buffer = memoryBuffers[index]; + for (unsigned int index = 0; index < this->cachedMaxReadBufferOffset; index++) { + MemoryBuffer *buffer = memoryBuffers[index]; if (buffer) { if (buffer->isTemporarily()) { memoryBuffers[index] = NULL; @@ -437,12 +437,12 @@ void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer** memo if (bTree) { // status report is only performed for top level Execution Groups. float progress = chunksFinished; - progress/=numberOfChunks; + progress /= numberOfChunks; bTree->progress(bTree->prh, progress); } } -inline void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk ) const +inline void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk) const { if (singleThreaded) { BLI_init_rcti(rect, 0, this->width, 0, this->height); @@ -464,9 +464,9 @@ void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int chunkNumb MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int chunkNumber, rcti *rect) { // we asume that this method is only called from complex execution groups. - NodeOperation * operation = this->getOutputNodeOperation(); + NodeOperation *operation = this->getOutputNodeOperation(); if (operation->isWriteBufferOperation()) { - WriteBufferOperation *writeOperation = (WriteBufferOperation*)operation; + WriteBufferOperation *writeOperation = (WriteBufferOperation *)operation; MemoryBuffer *buffer = new MemoryBuffer(writeOperation->getMemoryProxy(), rect); return buffer; } @@ -474,7 +474,7 @@ MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int chunkNumber, rcti *rect) } -bool ExecutionGroup::scheduleAreaWhenPossible(ExecutionSystem * graph, rcti *area) +bool ExecutionGroup::scheduleAreaWhenPossible(ExecutionSystem *graph, rcti *area) { if (singleThreaded) { return scheduleChunkWhenPossible(graph, 0, 0); @@ -485,14 +485,14 @@ bool ExecutionGroup::scheduleAreaWhenPossible(ExecutionSystem * graph, rcti *are float chunkSizef = this->chunkSize; int indexx, indexy; - const int minxchunk = floor(area->xmin/chunkSizef); - const int maxxchunk = ceil((area->xmax-1)/chunkSizef); - const int minychunk = floor(area->ymin/chunkSizef); - const int maxychunk = ceil((area->ymax-1)/chunkSizef); + const int minxchunk = floor(area->xmin / chunkSizef); + const int maxxchunk = ceil((area->xmax - 1) / chunkSizef); + const int minychunk = floor(area->ymin / chunkSizef); + const int maxychunk = ceil((area->ymax - 1) / chunkSizef); bool result = true; - for (indexx = max(minxchunk, 0); indexx= (int)this->numberOfXChunks) { return true; @@ -520,7 +520,7 @@ bool ExecutionGroup::scheduleChunkWhenPossible(ExecutionSystem * graph, int xChu if (yChunk < 0 || yChunk >= (int)this->numberOfYChunks) { return true; } - int chunkNumber = yChunk*this->numberOfXChunks + xChunk; + int chunkNumber = yChunk * this->numberOfXChunks + xChunk; // chunk is already executed if (this->chunkExecutionStates[chunkNumber] == COM_ES_EXECUTED) { return true; @@ -532,7 +532,7 @@ bool ExecutionGroup::scheduleChunkWhenPossible(ExecutionSystem * graph, int xChu } // chunk is nor executed nor scheduled. - vector memoryProxies; + vector memoryProxies; this->determineDependingMemoryProxies(&memoryProxies); rcti rect; @@ -541,10 +541,10 @@ bool ExecutionGroup::scheduleChunkWhenPossible(ExecutionSystem * graph, int xChu bool canBeExecuted = true; rcti area; - for (index = 0 ; index < cachedReadOperations.size() ; index ++) { - ReadBufferOperation * readOperation = (ReadBufferOperation*)cachedReadOperations[index]; + for (index = 0; index < cachedReadOperations.size(); index++) { + ReadBufferOperation *readOperation = (ReadBufferOperation *)cachedReadOperations[index]; BLI_init_rcti(&area, 0, 0, 0, 0); - MemoryProxy * memoryProxy = memoryProxies[index]; + MemoryProxy *memoryProxy = memoryProxies[index]; determineDependingAreaOfInterest(&rect, readOperation, &area); ExecutionGroup *group = memoryProxy->getExecutor(); @@ -565,16 +565,16 @@ bool ExecutionGroup::scheduleChunkWhenPossible(ExecutionSystem * graph, int xChu return false; } -void ExecutionGroup::determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti *output) +void ExecutionGroup::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { this->getOutputNodeOperation()->determineDependingAreaOfInterest(input, readOperation, output); } -void ExecutionGroup::determineDependingMemoryProxies(vector *memoryProxies) +void ExecutionGroup::determineDependingMemoryProxies(vector *memoryProxies) { unsigned int index; - for (index = 0 ; index < this->cachedReadOperations.size() ; index ++) { - ReadBufferOperation * readOperation = (ReadBufferOperation*) this->cachedReadOperations[index]; + for (index = 0; index < this->cachedReadOperations.size(); index++) { + ReadBufferOperation *readOperation = (ReadBufferOperation *) this->cachedReadOperations[index]; memoryProxies->push_back(readOperation->getMemoryProxy()); } } diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 7ea97b3fa39..7250a851f7b 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -42,8 +42,8 @@ ExecutionSystem::ExecutionSystem(bNodeTree *editingtree, bool rendering) { context.setbNodeTree(editingtree); - bNode* gnode; - for (gnode = (bNode*)editingtree->nodes.first ; gnode ; gnode = (bNode*)gnode->next) { + bNode *gnode; + for (gnode = (bNode *)editingtree->nodes.first; gnode; gnode = (bNode *)gnode->next) { if (gnode->type == NODE_GROUP && gnode->typeinfo->group_edit_get(gnode)) { context.setActivegNode(gnode); break; @@ -60,19 +60,19 @@ ExecutionSystem::ExecutionSystem(bNodeTree *editingtree, bool rendering) context.setRendering(rendering); context.setHasActiveOpenCLDevices(WorkScheduler::hasGPUDevices() && (editingtree->flag & NTREE_COM_OPENCL)); - Node *mainOutputNode=NULL; + Node *mainOutputNode = NULL; mainOutputNode = ExecutionSystemHelper::addbNodeTree(*this, 0, editingtree, NULL); if (mainOutputNode) { - context.setScene((Scene*)mainOutputNode->getbNode()->id); + context.setScene((Scene *)mainOutputNode->getbNode()->id); this->convertToOperations(); this->groupOperations(); /* group operations in ExecutionGroups */ unsigned int index; unsigned int resolution[2]; - for (index = 0 ; index < this->groups.size(); index ++) { - resolution[0]=0; - resolution[1]=0; + for (index = 0; index < this->groups.size(); index++) { + resolution[0] = 0; + resolution[1] = 0; ExecutionGroup *executionGroup = groups[index]; executionGroup->determineResolution(resolution); } @@ -111,24 +111,24 @@ ExecutionSystem::~ExecutionSystem() void ExecutionSystem::execute() { unsigned int order = 0; - for (vector::iterator iter = this->operations.begin(); iter != operations.end(); ++iter) { + for (vector::iterator iter = this->operations.begin(); iter != operations.end(); ++iter) { NodeBase *node = *iter; - NodeOperation *operation = (NodeOperation*) node; + NodeOperation *operation = (NodeOperation *) node; if (operation->isReadBufferOperation()) { - ReadBufferOperation * readOperation = (ReadBufferOperation*)operation; + ReadBufferOperation *readOperation = (ReadBufferOperation *)operation; readOperation->setOffset(order); - order ++; + order++; } } unsigned int index; - for (index = 0 ; index < this->operations.size() ; index ++) { - NodeOperation * operation = this->operations[index]; + for (index = 0; index < this->operations.size(); index++) { + NodeOperation *operation = this->operations[index]; operation->setbNodeTree(this->context.getbNodeTree()); operation->initExecution(); } - for (index = 0 ; index < this->groups.size() ; index ++) { - ExecutionGroup * executionGroup = this->groups[index]; + for (index = 0; index < this->groups.size(); index++) { + ExecutionGroup *executionGroup = this->groups[index]; executionGroup->setChunksize(context.getChunksize()); executionGroup->initExecution(); } @@ -142,12 +142,12 @@ void ExecutionSystem::execute() WorkScheduler::finish(); WorkScheduler::stop(); - for (index = 0 ; index < this->operations.size() ; index ++) { - NodeOperation * operation = this->operations[index]; + for (index = 0; index < this->operations.size(); index++) { + NodeOperation *operation = this->operations[index]; operation->deinitExecution(); } - for (index = 0 ; index < this->groups.size() ; index ++) { - ExecutionGroup * executionGroup = this->groups[index]; + for (index = 0; index < this->groups.size(); index++) { + ExecutionGroup *executionGroup = this->groups[index]; executionGroup->deinitExecution(); } } @@ -155,10 +155,10 @@ void ExecutionSystem::execute() void ExecutionSystem::executeGroups(CompositorPriority priority) { unsigned int index; - vector executionGroups; + vector executionGroups; this->findOutputExecutionGroup(&executionGroups, priority); - for (index = 0 ; index < executionGroups.size(); index ++) { + for (index = 0; index < executionGroups.size(); index++) { ExecutionGroup *group = executionGroups[index]; group->execute(this); } @@ -175,15 +175,15 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) // for every input add write and read operation if input is not a read operation // only add read operation to other links when they are attached to buffered operations. unsigned int index; - for (index = 0 ; index < operation->getNumberOfInputSockets();index++) { + for (index = 0; index < operation->getNumberOfInputSockets(); index++) { InputSocket *inputsocket = operation->getInputSocket(index); if (inputsocket->isConnected()) { SocketConnection *connection = inputsocket->getConnection(); - NodeOperation *otherEnd = (NodeOperation*)connection->getFromNode(); + NodeOperation *otherEnd = (NodeOperation *)connection->getFromNode(); if (!otherEnd->isReadBufferOperation()) { // check of other end already has write operation OutputSocket *fromsocket = connection->getFromSocket(); - WriteBufferOperation * writeoperation = fromsocket->findAttachedWriteBufferOperation(); + WriteBufferOperation *writeoperation = fromsocket->findAttachedWriteBufferOperation(); if (writeoperation == NULL) { writeoperation = new WriteBufferOperation(); writeoperation->setbNodeTree(this->getContext().getbNodeTree()); @@ -201,11 +201,11 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) } } /* - link the outputsocket to a write operation - link the writeoperation to a read operation - link the read operation to the next node. - */ - OutputSocket * outputsocket = operation->getOutputSocket(); + * link the outputsocket to a write operation + * link the writeoperation to a read operation + * link the read operation to the next node. + */ + OutputSocket *outputsocket = operation->getOutputSocket(); if (outputsocket->isConnected()) { int index; WriteBufferOperation *writeOperation; @@ -214,8 +214,8 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) this->addOperation(writeOperation); ExecutionSystemHelper::addLink(this->getConnections(), outputsocket, writeOperation->getInputSocket(0)); writeOperation->readResolutionFromInputSocket(); - for (index = 0 ; index < outputsocket->getNumberOfConnections()-1;index ++) { - SocketConnection * connection = outputsocket->getConnection(index); + for (index = 0; index < outputsocket->getNumberOfConnections() - 1; index++) { + SocketConnection *connection = outputsocket->getConnection(index); ReadBufferOperation *readoperation = new ReadBufferOperation(); readoperation->setMemoryProxy(writeOperation->getMemoryProxy()); connection->setFromSocket(readoperation->getOutputSocket()); @@ -230,11 +230,11 @@ void ExecutionSystem::convertToOperations() { unsigned int index; for (index = 0; index < this->nodes.size(); index++) { - Node *node = (Node*)this->nodes[index]; + Node *node = (Node *)this->nodes[index]; node->convertToOperations(this, &this->context); } - for (index = 0 ; index < this->connections.size(); index ++) { + for (index = 0; index < this->connections.size(); index++) { SocketConnection *connection = this->connections[index]; if (connection->isValid()) { if (connection->getFromSocket()->getDataType() != connection->getToSocket()->getDataType()) { @@ -244,27 +244,27 @@ void ExecutionSystem::convertToOperations() } // determine all resolutions of the operations (Width/Height) - for (index = 0 ; index < this->operations.size(); index ++) { + for (index = 0; index < this->operations.size(); index++) { NodeOperation *operation = this->operations[index]; if (operation->isOutputOperation(context.isRendering()) && !operation->isPreviewOperation()) { - unsigned int resolution[2] = {0,0}; - unsigned int preferredResolution[2] = {0,0}; + unsigned int resolution[2] = {0, 0}; + unsigned int preferredResolution[2] = {0, 0}; operation->determineResolution(resolution, preferredResolution); operation->setResolution(resolution); } } - for (index = 0 ; index < this->operations.size(); index ++) { + for (index = 0; index < this->operations.size(); index++) { NodeOperation *operation = this->operations[index]; if (operation->isOutputOperation(context.isRendering()) && operation->isPreviewOperation()) { - unsigned int resolution[2] = {0,0}; - unsigned int preferredResolution[2] = {0,0}; + unsigned int resolution[2] = {0, 0}; + unsigned int preferredResolution[2] = {0, 0}; operation->determineResolution(resolution, preferredResolution); operation->setResolution(resolution); } } // add convert resolution operations when needed. - for (index = 0 ; index < this->connections.size(); index ++) { + for (index = 0; index < this->connections.size(); index++) { SocketConnection *connection = this->connections[index]; if (connection->isValid()) { if (connection->needsResolutionConversion()) { @@ -272,13 +272,12 @@ void ExecutionSystem::convertToOperations() } } } - } void ExecutionSystem::groupOperations() { - vector outputOperations; - NodeOperation * operation; + vector outputOperations; + NodeOperation *operation; unsigned int index; // surround complex operations with ReadBufferOperation and WriteBufferOperation for (index = 0; index < this->operations.size(); index++) { @@ -288,7 +287,7 @@ void ExecutionSystem::groupOperations() } } ExecutionSystemHelper::findOutputNodeOperations(&outputOperations, this->getOperations(), this->context.isRendering()); - for (vector::iterator iter = outputOperations.begin(); iter != outputOperations.end(); ++iter) { + for (vector::iterator iter = outputOperations.begin(); iter != outputOperations.end(); ++iter) { operation = *iter; ExecutionGroup *group = new ExecutionGroup(); group->addOperation(this, operation); @@ -303,10 +302,10 @@ void ExecutionSystem::addSocketConnection(SocketConnection *connection) } -void ExecutionSystem::findOutputExecutionGroup(vector *result, CompositorPriority priority) const +void ExecutionSystem::findOutputExecutionGroup(vector *result, CompositorPriority priority) const { unsigned int index; - for (index = 0 ; index < this->groups.size() ; index ++) { + for (index = 0; index < this->groups.size(); index++) { ExecutionGroup *group = this->groups[index]; if (group->isOutputExecutionGroup() && group->getRenderPriotrity() == priority) { result->push_back(group); @@ -314,10 +313,10 @@ void ExecutionSystem::findOutputExecutionGroup(vector *result, } } -void ExecutionSystem::findOutputExecutionGroup(vector *result) const +void ExecutionSystem::findOutputExecutionGroup(vector *result) const { unsigned int index; - for (index = 0 ; index < this->groups.size() ; index ++) { + for (index = 0; index < this->groups.size(); index++) { ExecutionGroup *group = this->groups[index]; if (group->isOutputExecutionGroup()) { result->push_back(group); diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp index 2d889e269e0..bcb606316ab 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp @@ -37,38 +37,38 @@ #include "COM_ReadBufferOperation.h" #include "COM_ViewerBaseOperation.h" -Node *ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree * tree, bNode *groupnode) +Node *ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree, bNode *groupnode) { - vector& nodes = system.getNodes(); - vector& links = system.getConnections(); + vector& nodes = system.getNodes(); + vector& links = system.getConnections(); Node *mainnode = NULL; - const bNode * activeGroupNode = system.getContext().getActivegNode(); + const bNode *activeGroupNode = system.getContext().getActivegNode(); bool isActiveGroup = activeGroupNode == groupnode; /* add all nodes of the tree to the node list */ - bNode *node = (bNode*)tree->nodes.first; + bNode *node = (bNode *)tree->nodes.first; while (node != NULL) { Node *execnode = addNode(nodes, node, isActiveGroup); if (node->type == CMP_NODE_COMPOSITE) { mainnode = execnode; } - node = (bNode*)node->next; + node = (bNode *)node->next; } - NodeRange node_range(nodes.begin()+nodes_start, nodes.end()); + NodeRange node_range(nodes.begin() + nodes_start, nodes.end()); /* add all nodelinks of the tree to the link list */ - bNodeLink *nodelink = (bNodeLink*)tree->links.first; + bNodeLink *nodelink = (bNodeLink *)tree->links.first; while (nodelink != NULL) { addNodeLink(node_range, links, nodelink); - nodelink = (bNodeLink*)nodelink->next; + nodelink = (bNodeLink *)nodelink->next; } /* Expand group nodes */ - for (unsigned int i=nodes_start; i < nodes.size(); ++i) { + for (unsigned int i = nodes_start; i < nodes.size(); ++i) { Node *execnode = nodes[i]; if (execnode->isGroupNode()) { - GroupNode * groupNode = (GroupNode*)execnode; + GroupNode *groupNode = (GroupNode *)execnode; groupNode->ungroup(system); } } @@ -76,15 +76,15 @@ Node *ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_sta return mainnode; } -void ExecutionSystemHelper::addNode(vector& nodes, Node *node) +void ExecutionSystemHelper::addNode(vector& nodes, Node *node) { nodes.push_back(node); } -Node *ExecutionSystemHelper::addNode(vector& nodes, bNode *bNode, bool inActiveGroup) +Node *ExecutionSystemHelper::addNode(vector& nodes, bNode *bNode, bool inActiveGroup) { Converter converter; - Node * node; + Node *node; node = converter.convert(bNode); node->setIsInActiveGroup(inActiveGroup); if (node != NULL) { @@ -93,21 +93,21 @@ Node *ExecutionSystemHelper::addNode(vector& nodes, bNode *bNode, bool in } return NULL; } -void ExecutionSystemHelper::addOperation(vector& operations, NodeOperation *operation) +void ExecutionSystemHelper::addOperation(vector& operations, NodeOperation *operation) { operations.push_back(operation); } -void ExecutionSystemHelper::addExecutionGroup(vector& executionGroups, ExecutionGroup *executionGroup) +void ExecutionSystemHelper::addExecutionGroup(vector& executionGroups, ExecutionGroup *executionGroup) { executionGroups.push_back(executionGroup); } -void ExecutionSystemHelper::findOutputNodeOperations(vector* result, vector& operations, bool rendering) +void ExecutionSystemHelper::findOutputNodeOperations(vector *result, vector& operations, bool rendering) { unsigned int index; - for (index = 0 ; index < operations.size() ; index ++) { + for (index = 0; index < operations.size(); index++) { NodeOperation *operation = operations[index]; if (operation->isOutputOperation(rendering)) { result->push_back(operation); @@ -118,18 +118,18 @@ void ExecutionSystemHelper::findOutputNodeOperations(vector* res static InputSocket *find_input(NodeRange &node_range, bNode *bnode, bNodeSocket *bsocket) { if (bnode != NULL) { - for (NodeIterator it=node_range.first; it!=node_range.second; ++it) { + for (NodeIterator it = node_range.first; it != node_range.second; ++it) { Node *node = *it; if (node->getbNode() == bnode) return node->findInputSocketBybNodeSocket(bsocket); } } else { - for (NodeIterator it=node_range.first; it!=node_range.second; ++it) { + for (NodeIterator it = node_range.first; it != node_range.second; ++it) { Node *node = *it; if (node->isProxyNode()) { InputSocket *proxySocket = node->getInputSocket(0); - if (proxySocket->getbNodeSocket()==bsocket) + if (proxySocket->getbNodeSocket() == bsocket) return proxySocket; } } @@ -139,29 +139,29 @@ static InputSocket *find_input(NodeRange &node_range, bNode *bnode, bNodeSocket static OutputSocket *find_output(NodeRange &node_range, bNode *bnode, bNodeSocket *bsocket) { if (bnode != NULL) { - for (NodeIterator it=node_range.first; it!=node_range.second; ++it) { + for (NodeIterator it = node_range.first; it != node_range.second; ++it) { Node *node = *it; if (node->getbNode() == bnode) return node->findOutputSocketBybNodeSocket(bsocket); } } else { - for (NodeIterator it=node_range.first; it!=node_range.second; ++it) { + for (NodeIterator it = node_range.first; it != node_range.second; ++it) { Node *node = *it; if (node->isProxyNode()) { OutputSocket *proxySocket = node->getOutputSocket(0); - if (proxySocket->getbNodeSocket()==bsocket) + if (proxySocket->getbNodeSocket() == bsocket) return proxySocket; } } } return NULL; } -SocketConnection *ExecutionSystemHelper::addNodeLink(NodeRange &node_range, vector& links, bNodeLink *bNodeLink) +SocketConnection *ExecutionSystemHelper::addNodeLink(NodeRange &node_range, vector& links, bNodeLink *bNodeLink) { /// @note: cyclic lines will be ignored. This has been copied from node.c if (bNodeLink->tonode != 0 && bNodeLink->fromnode != 0) { - if (!(bNodeLink->fromnode->level >= bNodeLink->tonode->level && bNodeLink->tonode->level!=0xFFF)) { // only add non cyclic lines! so execution will procede + if (!(bNodeLink->fromnode->level >= bNodeLink->tonode->level && bNodeLink->tonode->level != 0xFFF)) { // only add non cyclic lines! so execution will procede return NULL; } } @@ -178,9 +178,9 @@ SocketConnection *ExecutionSystemHelper::addNodeLink(NodeRange &node_range, vect return connection; } -SocketConnection *ExecutionSystemHelper::addLink(vector& links, OutputSocket *fromSocket, InputSocket *toSocket) +SocketConnection *ExecutionSystemHelper::addLink(vector& links, OutputSocket *fromSocket, InputSocket *toSocket) { - SocketConnection * newconnection = new SocketConnection(); + SocketConnection *newconnection = new SocketConnection(); newconnection->setFromSocket(fromSocket); newconnection->setToSocket(toSocket); fromSocket->addConnection(newconnection); @@ -199,12 +199,12 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) printf("-- BEGIN COMPOSITOR DUMP --\r\n"); printf("digraph compositorexecution {\r\n"); tot = system->getNodes().size(); - for (int i = 0 ; i < tot ; i ++) { + for (int i = 0; i < tot; i++) { node = system->getNodes()[i]; printf("// NODE: %s\r\n", node->getbNode()->typeinfo->name); } tot = system->getOperations().size(); - for (int i = 0 ; i < tot ; i ++) { + for (int i = 0; i < tot; i++) { operation = system->getOperations()[i]; printf("// OPERATION: %p\r\n", operation); printf("\t\"O_%p\"", operation); @@ -212,32 +212,33 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) tot2 = operation->getNumberOfInputSockets(); if (tot2 != 0) { printf("{"); - for (int j = 0 ; j < tot2 ; j ++) { + for (int j = 0; j < tot2; j++) { InputSocket *socket = operation->getInputSocket(j); if (j != 0) { printf("|"); } printf("", socket); switch (socket->getDataType()) { - case COM_DT_VALUE: - printf("Value"); - break; - case COM_DT_VECTOR: - printf("Vector"); - break; - case COM_DT_COLOR: - printf("Color"); - break; + case COM_DT_VALUE: + printf("Value"); + break; + case COM_DT_VECTOR: + printf("Vector"); + break; + case COM_DT_COLOR: + printf("Color"); + break; } } printf("}"); printf("|"); } if (operation->isViewerOperation()) { - ViewerBaseOperation * viewer = (ViewerBaseOperation*)operation; + ViewerBaseOperation *viewer = (ViewerBaseOperation *)operation; if (viewer->isActiveViewerOutput()) { printf("Active viewer"); - } else { + } + else { printf("Viewer"); } } @@ -261,22 +262,22 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) if (tot2 != 0) { printf("|"); printf("{"); - for (int j = 0 ; j < tot2 ; j ++) { + for (int j = 0; j < tot2; j++) { OutputSocket *socket = operation->getOutputSocket(j); if (j != 0) { printf("|"); } printf("", socket); switch (socket->getDataType()) { - case COM_DT_VALUE: - printf("Value"); - break; - case COM_DT_VECTOR: - printf("Vector"); - break; - case COM_DT_COLOR: - printf("Color"); - break; + case COM_DT_VALUE: + printf("Value"); + break; + case COM_DT_VECTOR: + printf("Vector"); + break; + case COM_DT_COLOR: + printf("Color"); + break; } } printf("}"); @@ -285,7 +286,7 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) printf("\r\n"); } tot = system->getExecutionGroups().size(); - for (int i = 0 ; i < tot ; i ++) { + for (int i = 0; i < tot; i++) { group = system->getExecutionGroups()[i]; printf("// GROUP: %d\r\n", i); printf("subgraph {\r\n"); @@ -294,16 +295,16 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) printf("}\r\n"); } tot = system->getOperations().size(); - for (int i = 0 ; i < tot ; i ++) { + for (int i = 0; i < tot; i++) { operation = system->getOperations()[i]; if (operation->isReadBufferOperation()) { - ReadBufferOperation * read = (ReadBufferOperation*)operation; - WriteBufferOperation * write = read->getMemoryProxy()->getWriteBufferOperation(); + ReadBufferOperation *read = (ReadBufferOperation *)operation; + WriteBufferOperation *write = read->getMemoryProxy()->getWriteBufferOperation(); printf("\t\"O_%p\" -> \"O_%p\" [style=dotted]\r\n", write, read); } } tot = system->getConnections().size(); - for (int i = 0 ; i < tot ; i ++) { + for (int i = 0; i < tot; i++) { connection = system->getConnections()[i]; printf("// CONNECTION: %p.%p -> %p.%p\r\n", connection->getFromNode(), connection->getFromSocket(), connection->getToNode(), connection->getToSocket()); printf("\t\"O_%p\":\"OUT_%p\" -> \"O_%p\":\"IN_%p\"", connection->getFromNode(), connection->getFromSocket(), connection->getToNode(), connection->getToSocket()); @@ -312,15 +313,15 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) } else { switch (connection->getFromSocket()->getDataType()) { - case COM_DT_VALUE: - printf(" [color=grey]"); - break; - case COM_DT_VECTOR: - printf(" [color=blue]"); - break; - case COM_DT_COLOR: - printf(" [color=orange]"); - break; + case COM_DT_VALUE: + printf(" [color=grey]"); + break; + case COM_DT_VECTOR: + printf(" [color=blue]"); + break; + case COM_DT_COLOR: + printf(" [color=orange]"); + break; } } printf("\r\n"); diff --git a/source/blender/compositor/intern/COM_InputSocket.cpp b/source/blender/compositor/intern/COM_InputSocket.cpp index c9705ad69fb..3ca74f157b4 100644 --- a/source/blender/compositor/intern/COM_InputSocket.cpp +++ b/source/blender/compositor/intern/COM_InputSocket.cpp @@ -25,18 +25,18 @@ #include "COM_SocketConnection.h" #include "COM_ExecutionSystem.h" -InputSocket::InputSocket(DataType datatype) :Socket(datatype) +InputSocket::InputSocket(DataType datatype) : Socket(datatype) { this->connection = NULL; this->resizeMode = COM_SC_CENTER; } -InputSocket::InputSocket(DataType datatype, InputSocketResizeMode resizeMode) :Socket(datatype) +InputSocket::InputSocket(DataType datatype, InputSocketResizeMode resizeMode) : Socket(datatype) { this->connection = NULL; this->resizeMode = resizeMode; } -InputSocket::InputSocket(InputSocket *from) :Socket(from->getDataType()) +InputSocket::InputSocket(InputSocket *from) : Socket(from->getDataType()) { this->connection = NULL; this->resizeMode = from->getResizeMode(); @@ -54,7 +54,7 @@ SocketConnection *InputSocket::getConnection() return this->connection; } -void InputSocket::determineResolution(unsigned int resolution[],unsigned int preferredResolution[]) +void InputSocket::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { if (this->isConnected()) { this->connection->getFromSocket()->determineResolution(resolution, preferredResolution); @@ -78,22 +78,22 @@ void InputSocket::relinkConnections(InputSocket *relinkToSocket) void InputSocket::relinkConnectionsDuplicate(InputSocket *relinkToSocket, int editorNodeInputSocketIndex, ExecutionSystem *graph) { if (!this->isConnected()) { - Node *node = (Node*)this->getNode(); + Node *node = (Node *)this->getNode(); switch (this->getDataType()) { - case COM_DT_COLOR: - node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex); - break; - case COM_DT_VECTOR: - node->addSetVectorOperation(graph, relinkToSocket, editorNodeInputSocketIndex); - break; - case COM_DT_VALUE: - node->addSetValueOperation(graph, relinkToSocket, editorNodeInputSocketIndex); - break; + case COM_DT_COLOR: + node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex); + break; + case COM_DT_VECTOR: + node->addSetVectorOperation(graph, relinkToSocket, editorNodeInputSocketIndex); + break; + case COM_DT_VALUE: + node->addSetValueOperation(graph, relinkToSocket, editorNodeInputSocketIndex); + break; } return; } - SocketConnection * newConnection = new SocketConnection(); - OutputSocket * fromSocket = this->getConnection()->getFromSocket(); + SocketConnection *newConnection = new SocketConnection(); + OutputSocket *fromSocket = this->getConnection()->getFromSocket(); newConnection->setToSocket(relinkToSocket); newConnection->setFromSocket(fromSocket); relinkToSocket->setConnection(newConnection); @@ -107,17 +107,17 @@ void InputSocket::relinkConnections(InputSocket *relinkToSocket, int editorNode relinkConnections(relinkToSocket); } else { - Node *node = (Node*)this->getNode(); + Node *node = (Node *)this->getNode(); switch (this->getDataType()) { - case COM_DT_COLOR: - node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex); - break; - case COM_DT_VECTOR: - node->addSetVectorOperation(graph, relinkToSocket, editorNodeInputSocketIndex); - break; - case COM_DT_VALUE: - node->addSetValueOperation(graph, relinkToSocket, editorNodeInputSocketIndex); - break; + case COM_DT_COLOR: + node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex); + break; + case COM_DT_VECTOR: + node->addSetVectorOperation(graph, relinkToSocket, editorNodeInputSocketIndex); + break; + case COM_DT_VALUE: + node->addSetValueOperation(graph, relinkToSocket, editorNodeInputSocketIndex); + break; } } } @@ -140,7 +140,7 @@ SocketReader *InputSocket::getReader() NodeOperation *InputSocket::getOperation() const { if (isConnected()) { - return (NodeOperation*)this->connection->getFromSocket()->getNode(); + return (NodeOperation *)this->connection->getFromSocket()->getNode(); } else { return NULL; @@ -156,14 +156,14 @@ float *InputSocket::getStaticValues() static float default_null = 0.0f; switch (this->getDataType()) { - case COM_DT_VALUE: - return &((bNodeSocketValueFloat*)b_socket->default_value)->value; - case COM_DT_COLOR: - return ((bNodeSocketValueRGBA*)b_socket->default_value)->value; - case COM_DT_VECTOR: - return ((bNodeSocketValueVector*)b_socket->default_value)->value; - default: - /* XXX this should never happen, just added to please the compiler */ - return &default_null; + case COM_DT_VALUE: + return &((bNodeSocketValueFloat *)b_socket->default_value)->value; + case COM_DT_COLOR: + return ((bNodeSocketValueRGBA *)b_socket->default_value)->value; + case COM_DT_VECTOR: + return ((bNodeSocketValueVector *)b_socket->default_value)->value; + default: + /* XXX this should never happen, just added to please the compiler */ + return &default_null; } } diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp index 90f6d4a738d..ceed53c4c0d 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp @@ -32,30 +32,30 @@ unsigned int MemoryBuffer::determineBufferSize() int MemoryBuffer::getWidth() const { - return this->rect.xmax-this->rect.xmin; + return this->rect.xmax - this->rect.xmin; } int MemoryBuffer::getHeight() const { - return this->rect.ymax-this->rect.ymin; + return this->rect.ymax - this->rect.ymin; } -MemoryBuffer::MemoryBuffer(MemoryProxy * memoryProxy, unsigned int chunkNumber, rcti *rect) +MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect) { BLI_init_rcti(&this->rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); this->memoryProxy = memoryProxy; this->chunkNumber = chunkNumber; - this->buffer = (float*)MEM_mallocN(sizeof(float)*determineBufferSize()*COM_NUMBER_OF_CHANNELS, "COM_MemoryBuffer"); + this->buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, "COM_MemoryBuffer"); this->state = COM_MB_ALLOCATED; this->datatype = COM_DT_COLOR; this->chunkWidth = this->rect.xmax - this->rect.xmin; } -MemoryBuffer::MemoryBuffer(MemoryProxy * memoryProxy, rcti *rect) +MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect) { BLI_init_rcti(&this->rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); this->memoryProxy = memoryProxy; this->chunkNumber = -1; - this->buffer = (float*)MEM_mallocN(sizeof(float)*determineBufferSize()*COM_NUMBER_OF_CHANNELS, "COM_MemoryBuffer"); + this->buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, "COM_MemoryBuffer"); this->state = COM_MB_TEMPORARILY; this->datatype = COM_DT_COLOR; this->chunkWidth = this->rect.xmax - this->rect.xmin; @@ -63,12 +63,12 @@ MemoryBuffer::MemoryBuffer(MemoryProxy * memoryProxy, rcti *rect) MemoryBuffer *MemoryBuffer::duplicate() { MemoryBuffer *result = new MemoryBuffer(this->memoryProxy, &this->rect); - memcpy(result->buffer, this->buffer, this->determineBufferSize()*COM_NUMBER_OF_CHANNELS*sizeof(float)); + memcpy(result->buffer, this->buffer, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float)); return result; } void MemoryBuffer::clear() { - memset(this->buffer, 0, this->determineBufferSize()*COM_NUMBER_OF_CHANNELS*sizeof(float)); + memset(this->buffer, 0, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float)); } float *MemoryBuffer::convertToValueBuffer() @@ -81,7 +81,7 @@ float *MemoryBuffer::convertToValueBuffer() const float *fp_src = this->buffer; float *fp_dst = result; - for (i = 0; i < size ; i++, fp_dst++, fp_src += COM_NUMBER_OF_CHANNELS) { + for (i = 0; i < size; i++, fp_dst++, fp_src += COM_NUMBER_OF_CHANNELS) { *fp_dst = *fp_src; } @@ -110,17 +110,17 @@ void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer) int otherOffset; - for (otherY = minY ; otherYrect.ymin) * otherBuffer->chunkWidth + minX-otherBuffer->rect.xmin)*COM_NUMBER_OF_CHANNELS; - offset = ((otherY - this->rect.ymin) * this->chunkWidth + minX-this->rect.xmin)*COM_NUMBER_OF_CHANNELS; - memcpy(&this->buffer[offset], &otherBuffer->buffer[otherOffset], (maxX-minX) * COM_NUMBER_OF_CHANNELS*sizeof(float)); + for (otherY = minY; otherY < maxY; otherY++) { + otherOffset = ((otherY - otherBuffer->rect.ymin) * otherBuffer->chunkWidth + minX - otherBuffer->rect.xmin) * COM_NUMBER_OF_CHANNELS; + offset = ((otherY - this->rect.ymin) * this->chunkWidth + minX - this->rect.xmin) * COM_NUMBER_OF_CHANNELS; + memcpy(&this->buffer[offset], &otherBuffer->buffer[otherOffset], (maxX - minX) * COM_NUMBER_OF_CHANNELS * sizeof(float)); } } void MemoryBuffer::read(float result[4], int x, int y) { - if (x>=this->rect.xmin && x < this->rect.xmax && - y>=this->rect.ymin && y < this->rect.ymax) + if (x >= this->rect.xmin && x < this->rect.xmax && + y >= this->rect.ymin && y < this->rect.ymax) { const int dx = x - this->rect.xmin; const int dy = y - this->rect.ymin; @@ -173,84 +173,84 @@ void MemoryBuffer::readCubic(float result[4], float x, float y) read(color3, x2, y1); read(color4, x2, y2); - color1[0] = color1[0]*mvaluey + color2[0]*valuey; - color1[1] = color1[1]*mvaluey + color2[1]*valuey; - color1[2] = color1[2]*mvaluey + color2[2]*valuey; - color1[3] = color1[3]*mvaluey + color2[3]*valuey; - - color3[0] = color3[0]*mvaluey + color4[0]*valuey; - color3[1] = color3[1]*mvaluey + color4[1]*valuey; - color3[2] = color3[2]*mvaluey + color4[2]*valuey; - color3[3] = color3[3]*mvaluey + color4[3]*valuey; - - result[0] = color1[0]*mvaluex + color3[0]*valuex; - result[1] = color1[1]*mvaluex + color3[1]*valuex; - result[2] = color1[2]*mvaluex + color3[2]*valuex; - result[3] = color1[3]*mvaluex + color3[3]*valuex; + color1[0] = color1[0] * mvaluey + color2[0] * valuey; + color1[1] = color1[1] * mvaluey + color2[1] * valuey; + color1[2] = color1[2] * mvaluey + color2[2] * valuey; + color1[3] = color1[3] * mvaluey + color2[3] * valuey; + + color3[0] = color3[0] * mvaluey + color4[0] * valuey; + color3[1] = color3[1] * mvaluey + color4[1] * valuey; + color3[2] = color3[2] * mvaluey + color4[2] * valuey; + color3[3] = color3[3] * mvaluey + color4[3] * valuey; + + result[0] = color1[0] * mvaluex + color3[0] * valuex; + result[1] = color1[1] * mvaluex + color3[1] * valuex; + result[2] = color1[2] * mvaluex + color3[2] * valuex; + result[3] = color1[3] * mvaluex + color3[3] * valuex; } // table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2 // used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible #define EWA_MAXIDX 255 -static float EWA_WTS[EWA_MAXIDX + 1] = -{ 1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f, - 0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f, - 0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f, - 0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f, - 0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f, - 0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f, - 0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f, - 0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f, - 0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f, - 0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f, - 0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f, - 0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f, - 0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f, - 0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f, - 0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f, - 0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f, - 0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f, - 0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f, - 0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f, - 0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f, - 0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f, - 0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f, - 0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f, - 0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f, - 0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f, - 0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f, - 0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f, - 0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f, - 0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f, - 0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f, - 0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f, - 0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f +static float EWA_WTS[EWA_MAXIDX + 1] = { + 1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f, + 0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f, + 0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f, + 0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f, + 0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f, + 0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f, + 0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f, + 0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f, + 0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f, + 0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f, + 0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f, + 0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f, + 0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f, + 0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f, + 0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f, + 0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f, + 0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f, + 0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f, + 0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f, + 0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f, + 0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f, + 0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f, + 0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f, + 0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f, + 0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f, + 0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f, + 0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f, + 0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f, + 0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f, + 0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f, + 0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f, + 0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f }; static void radangle2imp(float a2, float b2, float th, float *A, float *B, float *C, float *F) { float ct2 = cosf(th); - const float st2 = 1.f - ct2*ct2; // <- sin(th)^2 + const float st2 = 1.f - ct2 * ct2; // <- sin(th)^2 ct2 *= ct2; - *A = a2*st2 + b2*ct2; - *B = (b2 - a2)*sinf(2.f*th); - *C = a2*ct2 + b2*st2; - *F = a2*b2; + *A = a2 * st2 + b2 * ct2; + *B = (b2 - a2) * sinf(2.f * th); + *C = a2 * ct2 + b2 * st2; + *F = a2 * b2; } // all tests here are done to make sure possible overflows are hopefully minimized static void imp2radangle(float A, float B, float C, float F, float *a, float *b, float *th, float *ecc) { - if (F <= 1e-5f) { // use arbitrary major radius, zero minor, infinite eccentricity + if (F <= 1e-5f) { // use arbitrary major radius, zero minor, infinite eccentricity *a = sqrtf(A > C ? A : C); *b = 0.f; *ecc = 1e10f; - *th = 0.5f*(atan2f(B, A - C) + (float)M_PI); + *th = 0.5f * (atan2f(B, A - C) + (float)M_PI); } else { - const float AmC = A - C, ApC = A + C, F2 = F*2.f; - const float r = sqrtf(AmC*AmC + B*B); + const float AmC = A - C, ApC = A + C, F2 = F * 2.f; + const float r = sqrtf(AmC * AmC + B * B); float d = ApC - r; *a = (d <= 0.f) ? sqrtf(A > C ? A : C) : sqrtf(F2 / d); d = ApC + r; @@ -263,7 +263,7 @@ static void imp2radangle(float A, float B, float C, float F, float *a, float *b, *ecc = *a / *b; } // incr theta by 0.5*pi (angle of major axis) - *th = 0.5f*(atan2f(B, AmC) + (float)M_PI); + *th = 0.5f * (atan2f(B, AmC) + (float)M_PI); } } @@ -280,11 +280,11 @@ void MemoryBuffer::readEWA(float result[4], float fx, float fy, float dx, float // scaling dxt/dyt by full resolution can cause overflow because of huge A/B/C and esp. F values, // scaling by aspect ratio alone does the opposite, so try something in between instead... const float ff2 = width, ff = sqrtf(ff2), q = height / ff; - const float Ux = dx*ff, Vx = dx*q, Uy = dy*ff, Vy = dy*q; - float A = Vx*Vx + Vy*Vy; - float B = -2.f*(Ux*Vx + Uy*Vy); - float C = Ux*Ux + Uy*Uy; - float F = A*C - B*B*0.25f; + const float Ux = dx * ff, Vx = dx * q, Uy = dy * ff, Vy = dy * q; + float A = Vx * Vx + Vy * Vy; + float B = -2.f * (Ux * Vx + Uy * Vy); + float C = Ux * Ux + Uy * Uy; + float F = A * C - B * B * 0.25f; float a, b, th, ecc, a2, b2, ue, ve, U0, V0, DDQ, U, ac1, ac2, BU, d; int u, v, u1, u2, v1, v2; // The so-called 'high' quality ewa method simply adds a constant of 1 to both A & C, @@ -294,13 +294,13 @@ void MemoryBuffer::readEWA(float result[4], float fx, float fy, float dx, float // Use a different radius based on interpolation switch, just enough to anti-alias when interpolation is off, // and slightly larger to make result a bit smoother than bilinear interpolation when interpolation is on // (minimum values: const float rmin = intpol ? 1.f : 0.5f;) - const float rmin = 1.5625f/ff2; + const float rmin = 1.5625f / ff2; imp2radangle(A, B, C, F, &a, &b, &th, &ecc); - if ((b2 = b*b) < rmin) { - if ((a2 = a*a) < rmin) { + if ((b2 = b * b) < rmin) { + if ((a2 = a * a) < rmin) { B = 0.f; A = C = rmin; - F = A*C; + F = A * C; } else { b2 = rmin; @@ -308,9 +308,9 @@ void MemoryBuffer::readEWA(float result[4], float fx, float fy, float dx, float } } - ue = ff*sqrtf(C); - ve = ff*sqrtf(A); - d = (float)(EWA_MAXIDX + 1) / (F*ff2); + ue = ff * sqrtf(C); + ve = ff * sqrtf(A); + d = (float)(EWA_MAXIDX + 1) / (F * ff2); A *= d; B *= d; C *= d; @@ -323,24 +323,24 @@ void MemoryBuffer::readEWA(float result[4], float fx, float fy, float dx, float v2 = (int)(ceilf(V0 + ve)); U0 -= 0.5f; V0 -= 0.5f; - DDQ = 2.f*A; + DDQ = 2.f * A; U = u1 - U0; - ac1 = A*(2.f*U + 1.f); - ac2 = A*U*U; - BU = B*U; + ac1 = A * (2.f * U + 1.f); + ac2 = A * U * U; + BU = B * U; d = result[0] = result[1] = result[2] = result[3] = 0.f; - for (v=v1; v<=v2; ++v) { + for (v = v1; v <= v2; ++v) { const float V = v - V0; - float DQ = ac1 + B*V; - float Q = (C*V + BU)*V + ac2; - for (u=u1; u<=u2; ++u) { + float DQ = ac1 + B * V; + float Q = (C * V + BU) * V + ac2; + for (u = u1; u <= u2; ++u) { if (Q < (float)(EWA_MAXIDX + 1)) { float tc[4]; const float wt = EWA_WTS[(Q < 0.f) ? 0 : (unsigned int)Q]; read(tc, clipuv(u, width), clipuv(v, height)); madd_v3_v3fl(result, tc, wt); - result[3] += result[3] ? tc[3]*wt : 0.f; + result[3] += result[3] ? tc[3] * wt : 0.f; d += wt; } Q += DQ; @@ -349,10 +349,10 @@ void MemoryBuffer::readEWA(float result[4], float fx, float fy, float dx, float } // d should hopefully never be zero anymore - d = 1.f/d; + d = 1.f / d; result[0] *= d; result[1] *= d; result[2] *= d; // clipping can be ignored if alpha used, texr->ta already includes filtered edge - result[3] = result[3] ? result[3] *d : 1.f; + result[3] = result[3] ? result[3] * d : 1.f; } diff --git a/source/blender/compositor/intern/COM_Node.cpp b/source/blender/compositor/intern/COM_Node.cpp index 2324eacd26c..62e030b777c 100644 --- a/source/blender/compositor/intern/COM_Node.cpp +++ b/source/blender/compositor/intern/COM_Node.cpp @@ -43,23 +43,23 @@ Node::Node(bNode *editorNode, bool create_sockets) this->editorNode = editorNode; if (create_sockets) { - bNodeSocket * input = (bNodeSocket*)editorNode->inputs.first; + bNodeSocket *input = (bNodeSocket *)editorNode->inputs.first; while (input != NULL) { DataType dt = COM_DT_VALUE; if (input->type == SOCK_RGBA) dt = COM_DT_COLOR; if (input->type == SOCK_VECTOR) dt = COM_DT_VECTOR; this->addInputSocket(dt, (InputSocketResizeMode)input->resizemode, input); - input = (bNodeSocket*)input->next; + input = (bNodeSocket *)input->next; } - bNodeSocket *output = (bNodeSocket*)editorNode->outputs.first; + bNodeSocket *output = (bNodeSocket *)editorNode->outputs.first; while (output != NULL) { DataType dt = COM_DT_VALUE; if (output->type == SOCK_RGBA) dt = COM_DT_COLOR; if (output->type == SOCK_VECTOR) dt = COM_DT_VECTOR; this->addOutputSocket(dt, output); - output = (bNodeSocket*)output->next; + output = (bNodeSocket *)output->next; } } } @@ -75,9 +75,9 @@ bNode *Node::getbNode() void Node::addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket*)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); SetValueOperation *operation = new SetValueOperation(); - bNodeSocketValueFloat *val = (bNodeSocketValueFloat*)bSock->default_value; + bNodeSocketValueFloat *val = (bNodeSocketValueFloat *)bSock->default_value; operation->setValue(val->value); this->addLink(graph, operation->getOutputSocket(), inputsocket); graph->addOperation(operation); @@ -118,9 +118,9 @@ SocketConnection *Node::addLink(ExecutionSystem *graph, OutputSocket *outputSock void Node::addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket*)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); SetColorOperation *operation = new SetColorOperation(); - bNodeSocketValueRGBA *val = (bNodeSocketValueRGBA*)bSock->default_value; + bNodeSocketValueRGBA *val = (bNodeSocketValueRGBA *)bSock->default_value; operation->setChannel1(val->value[0]); operation->setChannel2(val->value[1]); operation->setChannel3(val->value[2]); @@ -131,8 +131,8 @@ void Node::addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket void Node::addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket*)this->getEditorInputSocket(editorNodeInputSocketIndex); - bNodeSocketValueVector *val = (bNodeSocketValueVector*)bSock->default_value; + bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocketValueVector *val = (bNodeSocketValueVector *)bSock->default_value; SetVectorOperation *operation = new SetVectorOperation(); operation->setX(val->value[0]); operation->setY(val->value[1]); @@ -143,7 +143,7 @@ void Node::addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocke bNodeSocket *Node::getEditorInputSocket(int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket*)this->getbNode()->inputs.first; + bNodeSocket *bSock = (bNodeSocket *)this->getbNode()->inputs.first; int index = 0; while (bSock != NULL) { if (index == editorNodeInputSocketIndex) { @@ -156,7 +156,7 @@ bNodeSocket *Node::getEditorInputSocket(int editorNodeInputSocketIndex) } bNodeSocket *Node::getEditorOutputSocket(int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket*)this->getbNode()->outputs.first; + bNodeSocket *bSock = (bNodeSocket *)this->getbNode()->outputs.first; int index = 0; while (bSock != NULL) { if (index == editorNodeInputSocketIndex) { @@ -170,9 +170,9 @@ bNodeSocket *Node::getEditorOutputSocket(int editorNodeInputSocketIndex) InputSocket *Node::findInputSocketBybNodeSocket(bNodeSocket *socket) { - vector &inputsockets = this->getInputSockets(); + vector &inputsockets = this->getInputSockets(); unsigned int index; - for (index = 0 ; index < inputsockets.size(); index ++) { + for (index = 0; index < inputsockets.size(); index++) { InputSocket *input = inputsockets[index]; if (input->getbNodeSocket() == socket) { return input; @@ -183,9 +183,9 @@ InputSocket *Node::findInputSocketBybNodeSocket(bNodeSocket *socket) OutputSocket *Node::findOutputSocketBybNodeSocket(bNodeSocket *socket) { - vector &outputsockets = this->getOutputSockets(); + vector &outputsockets = this->getOutputSockets(); unsigned int index; - for (index = 0 ; index < outputsockets.size(); index ++) { + for (index = 0; index < outputsockets.size(); index++) { OutputSocket *output = outputsockets[index]; if (output->getbNodeSocket() == socket) { return output; diff --git a/source/blender/compositor/intern/COM_NodeOperation.cpp b/source/blender/compositor/intern/COM_NodeOperation.cpp index 148ad48ba3a..1c05c2a3ae8 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.cpp +++ b/source/blender/compositor/intern/COM_NodeOperation.cpp @@ -41,9 +41,9 @@ void NodeOperation::determineResolution(unsigned int resolution[], unsigned int { unsigned int temp[2]; unsigned int temp2[2]; - vector &inputsockets = this->getInputSockets(); + vector &inputsockets = this->getInputSockets(); - for (unsigned int index = 0 ; index < inputsockets.size();index++) { + for (unsigned int index = 0; index < inputsockets.size(); index++) { InputSocket *inputSocket = inputsockets[index]; if (inputSocket->isConnected()) { if (index == this->resolutionInputSocketIndex) { @@ -54,7 +54,7 @@ void NodeOperation::determineResolution(unsigned int resolution[], unsigned int } } } - for (unsigned int index = 0 ; index < inputsockets.size();index++) { + for (unsigned int index = 0; index < inputsockets.size(); index++) { InputSocket *inputSocket = inputsockets[index]; if (inputSocket->isConnected()) { if (index != resolutionInputSocketIndex) { @@ -103,10 +103,10 @@ NodeOperation *NodeOperation::getInputOperation(unsigned int inputSocketIndex) return this->getInputSocket(inputSocketIndex)->getOperation(); } -void NodeOperation::getConnectedInputSockets(vector *sockets) +void NodeOperation::getConnectedInputSockets(vector *sockets) { - vector &inputsockets = this->getInputSockets(); - for (vector::iterator iterator = inputsockets.begin() ; iterator!= inputsockets.end() ; iterator++) { + vector &inputsockets = this->getInputSockets(); + for (vector::iterator iterator = inputsockets.begin(); iterator != inputsockets.end(); iterator++) { InputSocket *socket = *iterator; if (socket->isConnected()) { sockets->push_back(socket); @@ -114,7 +114,7 @@ void NodeOperation::getConnectedInputSockets(vector *sockets) } } -bool NodeOperation::determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti *output) +bool NodeOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { if (this->isInputNode()) { BLI_init_rcti(output, input->xmin, input->xmax, input->ymin, input->ymax); @@ -122,12 +122,12 @@ bool NodeOperation::determineDependingAreaOfInterest(rcti * input, ReadBufferOpe } else { unsigned int index; - vector &inputsockets = this->getInputSockets(); + vector &inputsockets = this->getInputSockets(); - for (index = 0 ; index < inputsockets.size() ; index++) { + for (index = 0; index < inputsockets.size(); index++) { InputSocket *inputsocket = inputsockets[index]; if (inputsocket->isConnected()) { - NodeOperation *inputoperation = (NodeOperation*)inputsocket->getConnection()->getFromNode(); + NodeOperation *inputoperation = (NodeOperation *)inputsocket->getConnection()->getFromNode(); bool result = inputoperation->determineDependingAreaOfInterest(input, readOperation, output); if (result) { return true; @@ -138,24 +138,24 @@ bool NodeOperation::determineDependingAreaOfInterest(rcti * input, ReadBufferOpe } } -cl_mem NodeOperation::COM_clAttachMemoryBufferToKernelParameter(cl_context context, cl_kernel kernel, int parameterIndex, int offsetIndex, list *cleanup, MemoryBuffer **inputMemoryBuffers, SocketReader* reader) +cl_mem NodeOperation::COM_clAttachMemoryBufferToKernelParameter(cl_context context, cl_kernel kernel, int parameterIndex, int offsetIndex, list *cleanup, MemoryBuffer **inputMemoryBuffers, SocketReader *reader) { cl_int error; - MemoryBuffer* result = (MemoryBuffer*)reader->initializeTileData(NULL, inputMemoryBuffers); + MemoryBuffer *result = (MemoryBuffer *)reader->initializeTileData(NULL, inputMemoryBuffers); const cl_image_format imageFormat = { CL_RGBA, CL_FLOAT }; - cl_mem clBuffer = clCreateImage2D(context, CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR, &imageFormat, result->getWidth(), + cl_mem clBuffer = clCreateImage2D(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, &imageFormat, result->getWidth(), result->getHeight(), 0, result->getBuffer(), &error); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } if (error == CL_SUCCESS) cleanup->push_back(clBuffer); error = clSetKernelArg(kernel, parameterIndex, sizeof(cl_mem), &clBuffer); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } COM_clAttachMemoryBufferOffsetToKernelParameter(kernel, offsetIndex, result); return clBuffer; @@ -165,11 +165,11 @@ void NodeOperation::COM_clAttachMemoryBufferOffsetToKernelParameter(cl_kernel ke { if (offsetIndex != -1) { cl_int error; - rcti* rect = memoryBuffer->getRect(); + rcti *rect = memoryBuffer->getRect(); cl_int2 offset = {rect->xmin, rect->ymin}; error = clSetKernelArg(kernel, offsetIndex, sizeof(cl_int2), &offset); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } } } @@ -180,7 +180,7 @@ void NodeOperation::COM_clAttachSizeToKernelParameter(cl_kernel kernel, int offs cl_int2 offset = {this->getWidth(), this->getHeight()}; error = clSetKernelArg(kernel, offsetIndex, sizeof(cl_int2), &offset); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } } } @@ -193,10 +193,10 @@ void NodeOperation::COM_clAttachOutputMemoryBufferToKernelParameter(cl_kernel ke void NodeOperation::COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer *outputMemoryBuffer) { cl_int error; - const size_t size[] = {outputMemoryBuffer->getWidth(),outputMemoryBuffer->getHeight()}; + const size_t size[] = {outputMemoryBuffer->getWidth(), outputMemoryBuffer->getHeight()}; error = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, size, 0, 0, 0, NULL); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } } void NodeOperation::COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer *outputMemoryBuffer, int offsetIndex) { @@ -210,17 +210,19 @@ void NodeOperation::COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, cl_int2 offset; bool breaked = false; - for (offsety = 0 ; offsety < height && (!breaked); offsety+=localSize) { + for (offsety = 0; offsety < height && (!breaked); offsety += localSize) { offset[1] = offsety; - if (offsety+localSize < height) { + if (offsety + localSize < height) { size[1] = localSize; - } else { + } + else { size[1] = height - offsety; } - for (offsetx = 0 ; offsetx < width && (!breaked) ; offsetx+=localSize) { - if (offsetx+localSize < width) { + for (offsetx = 0; offsetx < width && (!breaked); offsetx += localSize) { + if (offsetx + localSize < width) { size[0] = localSize; - } else { + } + else { size[0] = width - offsetx; } offset[0] = offsetx; @@ -228,7 +230,7 @@ void NodeOperation::COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, error = clSetKernelArg(kernel, offsetIndex, sizeof(cl_int2), &offset); if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } error = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, size, 0, 0, 0, NULL); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } clFlush(queue); if (isBreaked()) { breaked = false; @@ -240,9 +242,8 @@ void NodeOperation::COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, cl_kernel NodeOperation::COM_clCreateKernel(cl_program program, const char *kernelname, list *clKernelsToCleanUp) { cl_int error; - cl_kernel kernel = clCreateKernel(program, kernelname, &error) ; - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); - } + cl_kernel kernel = clCreateKernel(program, kernelname, &error); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } else { if (clKernelsToCleanUp) clKernelsToCleanUp->push_back(kernel); } diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp index e6d3789b06d..9d005804098 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp +++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp @@ -49,12 +49,12 @@ void OpenCLDevice::deinitialize() void OpenCLDevice::execute(WorkPackage *work) { const unsigned int chunkNumber = work->getChunkNumber(); - ExecutionGroup * executionGroup = work->getExecutionGroup(); + ExecutionGroup *executionGroup = work->getExecutionGroup(); rcti rect; executionGroup->determineChunkRect(&rect, chunkNumber); - MemoryBuffer ** inputBuffers = executionGroup->getInputBuffersOpenCL(chunkNumber); - MemoryBuffer * outputBuffer = executionGroup->allocateOutputBuffer(chunkNumber, &rect); + MemoryBuffer **inputBuffers = executionGroup->getInputBuffersOpenCL(chunkNumber); + MemoryBuffer *outputBuffer = executionGroup->allocateOutputBuffer(chunkNumber, &rect); executionGroup->getOutputNodeOperation()->executeOpenCLRegion(this->context, this->program, this->queue, &rect, chunkNumber, inputBuffers, outputBuffer); diff --git a/source/blender/compositor/intern/COM_OutputSocket.cpp b/source/blender/compositor/intern/COM_OutputSocket.cpp index 77bad3c006f..da08b512003 100644 --- a/source/blender/compositor/intern/COM_OutputSocket.cpp +++ b/source/blender/compositor/intern/COM_OutputSocket.cpp @@ -25,22 +25,23 @@ #include "COM_SocketConnection.h" #include "COM_NodeOperation.h" -OutputSocket::OutputSocket(DataType datatype) :Socket(datatype) +OutputSocket::OutputSocket(DataType datatype) : Socket(datatype) { } int OutputSocket::isOutputSocket() const { return true; } -const int OutputSocket::isConnected() const { return this->connections.size()!=0; } +const int OutputSocket::isConnected() const { return this->connections.size() != 0; } void OutputSocket::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { NodeBase *node = this->getNode(); if (node->isOperation()) { - NodeOperation *operation = (NodeOperation*)node; + NodeOperation *operation = (NodeOperation *)node; if (operation->isResolutionSet()) { resolution[0] = operation->getWidth(); resolution[1] = operation->getHeight(); - } else { + } + else { operation->determineResolution(resolution, preferredResolution); operation->setResolution(resolution); } @@ -63,7 +64,7 @@ void OutputSocket::relinkConnections(OutputSocket *relinkToSocket, bool single) } else { unsigned int index; - for (index = 0 ; index < this->connections.size();index ++) { + for (index = 0; index < this->connections.size(); index++) { SocketConnection *connection = this->connections[index]; connection->setFromSocket(relinkToSocket); relinkToSocket->addConnection(connection); @@ -92,13 +93,13 @@ void OutputSocket::clearConnections() WriteBufferOperation *OutputSocket::findAttachedWriteBufferOperation() const { unsigned int index; - for (index = 0 ; index < this->connections.size();index++) { + for (index = 0; index < this->connections.size(); index++) { SocketConnection *connection = this->connections[index]; NodeBase *node = connection->getToNode(); if (node->isOperation()) { - NodeOperation *operation = (NodeOperation*)node; + NodeOperation *operation = (NodeOperation *)node; if (operation->isWriteBufferOperation()) { - return (WriteBufferOperation*)operation; + return (WriteBufferOperation *)operation; } } } diff --git a/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp b/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp index 9ea90809de4..01043664412 100644 --- a/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp +++ b/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp @@ -22,7 +22,7 @@ #include "COM_SingleThreadedNodeOperation.h" -SingleThreadedNodeOperation::SingleThreadedNodeOperation(): NodeOperation() +SingleThreadedNodeOperation::SingleThreadedNodeOperation() : NodeOperation() { this->cachedInstance = NULL; setComplex(true); diff --git a/source/blender/compositor/intern/COM_Socket.cpp b/source/blender/compositor/intern/COM_Socket.cpp index af9ad1967a5..11739a4e9c5 100644 --- a/source/blender/compositor/intern/COM_Socket.cpp +++ b/source/blender/compositor/intern/COM_Socket.cpp @@ -38,6 +38,6 @@ DataType Socket::getDataType() const int Socket::isInputSocket() const { return false; } int Socket::isOutputSocket() const { return false; } -const int Socket::isConnected() const {return false;} -void Socket::setNode(NodeBase *node) {this->node = node;} -NodeBase *Socket::getNode() const {return this->node;} +const int Socket::isConnected() const { return false; } +void Socket::setNode(NodeBase *node) { this->node = node; } +NodeBase *Socket::getNode() const { return this->node; } diff --git a/source/blender/compositor/intern/COM_SocketConnection.cpp b/source/blender/compositor/intern/COM_SocketConnection.cpp index 9f0c736392a..1edeb6158b9 100644 --- a/source/blender/compositor/intern/COM_SocketConnection.cpp +++ b/source/blender/compositor/intern/COM_SocketConnection.cpp @@ -38,7 +38,7 @@ void SocketConnection::setFromSocket(OutputSocket *fromsocket) this->fromSocket = fromsocket; } -OutputSocket *SocketConnection::getFromSocket() const {return this->fromSocket;} +OutputSocket *SocketConnection::getFromSocket() const { return this->fromSocket; } void SocketConnection::setToSocket(InputSocket *tosocket) { if (tosocket == NULL) { @@ -47,7 +47,7 @@ void SocketConnection::setToSocket(InputSocket *tosocket) this->toSocket = tosocket; } -InputSocket *SocketConnection::getToSocket() const {return this->toSocket;} +InputSocket *SocketConnection::getToSocket() const { return this->toSocket; } NodeBase *SocketConnection::getFromNode() const { @@ -79,10 +79,10 @@ bool SocketConnection::isValid() const bool SocketConnection::needsResolutionConversion() const { - if (this->ignoreResizeCheck) {return false;} - NodeOperation *fromOperation = (NodeOperation*)this->getFromNode(); - NodeOperation *toOperation = (NodeOperation*)this->getToNode(); - if (this->toSocket->getResizeMode() == COM_SC_NO_RESIZE) {return false;} + if (this->ignoreResizeCheck) { return false; } + NodeOperation *fromOperation = (NodeOperation *)this->getFromNode(); + NodeOperation *toOperation = (NodeOperation *)this->getToNode(); + if (this->toSocket->getResizeMode() == COM_SC_NO_RESIZE) { return false; } const unsigned int fromWidth = fromOperation->getWidth(); const unsigned int fromHeight = fromOperation->getHeight(); const unsigned int toWidth = toOperation->getWidth(); diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp index ba8bfe55310..fb7a8f8a764 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cpp +++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp @@ -40,19 +40,19 @@ /// @brief list of all CPUDevices. for every hardware thread an instance of CPUDevice is created -static vector cpudevices; +static vector cpudevices; #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE /// @brief list of all thread for every CPUDevice in cpudevices a thread exists static ListBase cputhreads; /// @brief all scheduled work for the cpu -static ThreadQueue * cpuqueue; -static ThreadQueue * gpuqueue; +static ThreadQueue *cpuqueue; +static ThreadQueue *gpuqueue; #ifdef COM_OPENCL_ENABLED static cl_context context; static cl_program program; /// @brief list of all OpenCLDevices. for every OpenCL GPU device an instance of OpenCLDevice is created -static vector gpudevices; +static vector gpudevices; /// @brief list of all thread for every GPUDevice in cpudevices a thread exists static ListBase gputhreads; /// @brief all scheduled work for the gpu @@ -66,10 +66,10 @@ static bool openclActive = false; #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE void *WorkScheduler::thread_execute_cpu(void *data) { - Device *device = (Device*)data; + Device *device = (Device *)data; WorkPackage *work; - while ((work = (WorkPackage*)BLI_thread_queue_pop(cpuqueue))) { + while ((work = (WorkPackage *)BLI_thread_queue_pop(cpuqueue))) { device->execute(work); delete work; } @@ -79,10 +79,10 @@ void *WorkScheduler::thread_execute_cpu(void *data) void *WorkScheduler::thread_execute_gpu(void *data) { - Device *device = (Device*)data; + Device *device = (Device *)data; WorkPackage *work; - while ((work = (WorkPackage*)BLI_thread_queue_pop(gpuqueue))) { + while ((work = (WorkPackage *)BLI_thread_queue_pop(gpuqueue))) { device->execute(work); delete work; } @@ -120,7 +120,7 @@ void WorkScheduler::start(CompositorContext &context) unsigned int index; cpuqueue = BLI_thread_queue_init(); BLI_init_threads(&cputhreads, thread_execute_cpu, cpudevices.size()); - for (index = 0 ; index < cpudevices.size() ; index ++) { + for (index = 0; index < cpudevices.size(); index++) { Device *device = cpudevices[index]; BLI_insert_thread(&cputhreads, device); } @@ -128,7 +128,7 @@ void WorkScheduler::start(CompositorContext &context) if (context.getHasActiveOpenCLDevices()) { gpuqueue = BLI_thread_queue_init(); BLI_init_threads(&gputhreads, thread_execute_gpu, gpudevices.size()); - for (index = 0 ; index < gpudevices.size() ; index ++) { + for (index = 0; index < gpudevices.size(); index++) { Device *device = gpudevices[index]; BLI_insert_thread(&gputhreads, device); } @@ -178,7 +178,7 @@ bool WorkScheduler::hasGPUDevices() { #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE #ifdef COM_OPENCL_ENABLED - return gpudevices.size()>0; + return gpudevices.size() > 0; #else return 0; #endif @@ -197,7 +197,7 @@ void WorkScheduler::initialize() #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE int numberOfCPUThreads = BLI_system_thread_count(); - for (int index = 0 ; index < numberOfCPUThreads ; index ++) { + for (int index = 0; index < numberOfCPUThreads; index++) { CPUDevice *device = new CPUDevice(); device->initialize(); cpudevices.push_back(device); @@ -209,13 +209,13 @@ void WorkScheduler::initialize() cl_uint numberOfPlatforms = 0; cl_int error; error = clGetPlatformIDs(0, 0, &numberOfPlatforms); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } if (G.f & G_DEBUG) printf("%d number of platforms\n", numberOfPlatforms); cl_platform_id *platforms = new cl_platform_id[numberOfPlatforms]; error = clGetPlatformIDs(numberOfPlatforms, platforms, 0); unsigned int indexPlatform; cl_uint totalNumberOfDevices = 0; - for (indexPlatform = 0 ; indexPlatform < numberOfPlatforms ; indexPlatform ++) { + for (indexPlatform = 0; indexPlatform < numberOfPlatforms; indexPlatform++) { cl_platform_id platform = platforms[indexPlatform]; cl_uint numberOfDevices; clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, 0, &numberOfDevices); @@ -224,16 +224,16 @@ void WorkScheduler::initialize() cl_device_id *cldevices = new cl_device_id[totalNumberOfDevices]; unsigned int numberOfDevicesReceived = 0; - for (indexPlatform = 0 ; indexPlatform < numberOfPlatforms ; indexPlatform ++) { + for (indexPlatform = 0; indexPlatform < numberOfPlatforms; indexPlatform++) { cl_platform_id platform = platforms[indexPlatform]; cl_uint numberOfDevices; clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, 0, &numberOfDevices); - clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numberOfDevices, cldevices+numberOfDevicesReceived*sizeof (cl_device_id), 0); + clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numberOfDevices, cldevices + numberOfDevicesReceived * sizeof (cl_device_id), 0); numberOfDevicesReceived += numberOfDevices; } if (totalNumberOfDevices > 0) { context = clCreateContext(NULL, totalNumberOfDevices, cldevices, clContextError, NULL, &error); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } program = clCreateProgramWithSource(context, 1, &clkernelstoh_COM_OpenCLKernels_cl, 0, &error); error = clBuildProgram(program, totalNumberOfDevices, cldevices, 0, 0, 0); if (error != CL_SUCCESS) { @@ -241,10 +241,10 @@ void WorkScheduler::initialize() size_t ret_val_size = 0; printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); error2 = clGetProgramBuildInfo(program, cldevices[0], CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size); - if (error2 != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } - char *build_log = new char[ret_val_size+1]; + if (error2 != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + char *build_log = new char[ret_val_size + 1]; error2 = clGetProgramBuildInfo(program, cldevices[0], CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL); - if (error2 != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error2 != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } build_log[ret_val_size] = '\0'; printf("%s", build_log); delete build_log; @@ -252,11 +252,11 @@ void WorkScheduler::initialize() } else { unsigned int indexDevices; - for (indexDevices = 0 ; indexDevices < totalNumberOfDevices ; indexDevices ++) { + for (indexDevices = 0; indexDevices < totalNumberOfDevices; indexDevices++) { cl_device_id device = cldevices[indexDevices]; OpenCLDevice *clDevice = new OpenCLDevice(context, device, program); clDevice->initialize(), - gpudevices.push_back(clDevice); + gpudevices.push_back(clDevice); if (G.f & G_DEBUG) { char resultString[32]; error = clGetDeviceInfo(device, CL_DEVICE_NAME, 32, resultString, 0); @@ -267,8 +267,8 @@ void WorkScheduler::initialize() } } } - delete [] cldevices; - delete [] platforms; + delete[] cldevices; + delete[] platforms; } #endif #endif @@ -278,14 +278,14 @@ void WorkScheduler::deinitialize() { #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE Device *device; - while (cpudevices.size()>0) { + while (cpudevices.size() > 0) { device = cpudevices.back(); cpudevices.pop_back(); device->deinitialize(); delete device; } #ifdef COM_OPENCL_ENABLED - while (gpudevices.size()>0) { + while (gpudevices.size() > 0) { device = gpudevices.back(); gpudevices.pop_back(); device->deinitialize(); From cde4d7284891b07f4a221868f15b4b90a6b42585 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 17:57:39 +0000 Subject: [PATCH 356/360] style cleanup: more nodes --- .../compositor/intern/COM_NodeBase.cpp | 1 + .../compositor/intern/COM_NodeOperation.cpp | 2 + .../compositor/intern/COM_OutputSocket.cpp | 1 + .../compositor/nodes/COM_AlphaOverNode.cpp | 6 +- .../nodes/COM_BilateralBlurNode.cpp | 1 + .../blender/compositor/nodes/COM_BlurNode.cpp | 1 + .../compositor/nodes/COM_BokehBlurNode.cpp | 1 + .../compositor/nodes/COM_BokehImageNode.cpp | 7 +- .../compositor/nodes/COM_BoxMaskNode.cpp | 7 +- .../compositor/nodes/COM_BrightnessNode.cpp | 5 +- .../compositor/nodes/COM_ChannelMatteNode.cpp | 38 +++--- .../compositor/nodes/COM_ChromaMatteNode.cpp | 8 +- .../compositor/nodes/COM_ColorBalanceNode.cpp | 18 +-- .../nodes/COM_ColorCorrectionNode.cpp | 13 +- .../compositor/nodes/COM_ColorCurveNode.cpp | 16 +-- .../compositor/nodes/COM_ColorMatteNode.cpp | 8 +- .../compositor/nodes/COM_ColorNode.cpp | 7 +- .../compositor/nodes/COM_ColorRampNode.cpp | 10 +- .../compositor/nodes/COM_ColorSpillNode.cpp | 10 +- .../compositor/nodes/COM_ColorToBWNode.cpp | 5 +- .../compositor/nodes/COM_CombineHSVANode.cpp | 5 +- .../compositor/nodes/COM_CombineRGBANode.cpp | 6 +- .../compositor/nodes/COM_CombineYCCANode.cpp | 3 +- .../compositor/nodes/COM_CombineYUVANode.cpp | 3 +- .../compositor/nodes/COM_CompositorNode.cpp | 5 +- .../compositor/nodes/COM_ConvertAlphaNode.cpp | 2 +- .../blender/compositor/nodes/COM_CropNode.cpp | 5 +- .../compositor/nodes/COM_DefocusNode.cpp | 19 +-- .../nodes/COM_DifferenceMatteNode.cpp | 14 ++- .../compositor/nodes/COM_DilateErodeNode.cpp | 1 + .../nodes/COM_DirectionalBlurNode.cpp | 1 + .../compositor/nodes/COM_DisplaceNode.cpp | 5 +- .../nodes/COM_DistanceMatteNode.cpp | 8 +- .../nodes/COM_DoubleEdgeMaskNode.cpp | 5 +- .../compositor/nodes/COM_EllipseMaskNode.cpp | 7 +- .../compositor/nodes/COM_FilterNode.cpp | 69 +++++----- .../blender/compositor/nodes/COM_FlipNode.cpp | 27 ++-- .../compositor/nodes/COM_GammaNode.cpp | 5 +- .../compositor/nodes/COM_GlareNode.cpp | 45 +++---- .../compositor/nodes/COM_GroupNode.cpp | 26 ++-- .../COM_HueSaturationValueCorrectNode.cpp | 13 +- .../nodes/COM_HueSaturationValueNode.cpp | 13 +- .../compositor/nodes/COM_IDMaskNode.cpp | 9 +- .../compositor/nodes/COM_ImageNode.cpp | 76 +++++------ .../compositor/nodes/COM_InvertNode.cpp | 5 +- .../compositor/nodes/COM_KeyingNode.cpp | 5 +- .../compositor/nodes/COM_KeyingScreenNode.cpp | 5 +- .../nodes/COM_LensDistortionNode.cpp | 7 +- .../nodes/COM_LuminanceMatteNode.cpp | 8 +- .../compositor/nodes/COM_MapUVNode.cpp | 5 +- .../compositor/nodes/COM_MapValueNode.cpp | 7 +- .../blender/compositor/nodes/COM_MaskNode.cpp | 7 +- .../blender/compositor/nodes/COM_MathNode.cpp | 38 +++--- .../blender/compositor/nodes/COM_MixNode.cpp | 118 +++++++++--------- .../compositor/nodes/COM_MovieClipNode.cpp | 21 ++-- .../nodes/COM_MovieDistortionNode.cpp | 7 +- .../blender/compositor/nodes/COM_MuteNode.cpp | 17 +-- .../compositor/nodes/COM_NormalNode.cpp | 14 ++- .../compositor/nodes/COM_NormalizeNode.cpp | 5 +- .../compositor/nodes/COM_OutputFileNode.cpp | 19 +-- .../compositor/nodes/COM_RenderLayersNode.cpp | 9 +- .../compositor/nodes/COM_RotateNode.cpp | 21 ++-- .../compositor/nodes/COM_ScaleNode.cpp | 1 + .../compositor/nodes/COM_SeparateHSVANode.cpp | 5 +- .../compositor/nodes/COM_SeparateRGBANode.cpp | 5 +- .../compositor/nodes/COM_SeparateYCCANode.cpp | 3 +- .../compositor/nodes/COM_SeparateYUVANode.cpp | 3 +- .../compositor/nodes/COM_SetAlphaNode.cpp | 2 +- .../compositor/nodes/COM_SocketProxyNode.cpp | 62 ++++----- .../compositor/nodes/COM_SplitViewerNode.cpp | 1 + .../compositor/nodes/COM_Stabilize2dNode.cpp | 11 +- .../compositor/nodes/COM_SwitchNode.cpp | 7 +- .../compositor/nodes/COM_TextureNode.cpp | 7 +- .../blender/compositor/nodes/COM_TimeNode.cpp | 9 +- .../compositor/nodes/COM_TonemapNode.cpp | 9 +- .../compositor/nodes/COM_TransformNode.cpp | 29 ++--- .../compositor/nodes/COM_TranslateNode.cpp | 3 +- .../compositor/nodes/COM_ValueNode.cpp | 7 +- .../compositor/nodes/COM_VectorBlurNode.cpp | 1 + .../compositor/nodes/COM_VectorCurveNode.cpp | 7 +- .../compositor/nodes/COM_ViewLevelsNode.cpp | 2 + .../compositor/nodes/COM_ViewerNode.cpp | 1 + .../compositor/nodes/COM_ZCombineNode.cpp | 8 +- .../operations/COM_AlphaOverKeyOperation.cpp | 1 + .../COM_AlphaOverPremultiplyOperation.cpp | 1 + ...OM_CalculateStandardDeviationOperation.cpp | 1 + .../COM_ConvolutionEdgeFilterOperation.cpp | 1 + .../operations/COM_CropOperation.cpp | 2 + .../operations/COM_DilateErodeOperation.cpp | 2 + .../operations/COM_MixAddOperation.cpp | 1 + .../operations/COM_MixBlendOperation.cpp | 1 + .../operations/COM_MixBurnOperation.cpp | 1 + .../operations/COM_MixColorOperation.cpp | 1 + .../operations/COM_MixDarkenOperation.cpp | 1 + .../operations/COM_MixDifferenceOperation.cpp | 1 + .../operations/COM_MixDivideOperation.cpp | 1 + .../operations/COM_MixDodgeOperation.cpp | 1 + .../operations/COM_MixGlareOperation.cpp | 1 + .../operations/COM_MixHueOperation.cpp | 1 + .../operations/COM_MixLightenOperation.cpp | 1 + .../COM_MixLinearLightOperation.cpp | 1 + .../operations/COM_MixMultiplyOperation.cpp | 1 + .../operations/COM_MixOverlayOperation.cpp | 1 + .../operations/COM_MixSaturationOperation.cpp | 1 + .../operations/COM_MixScreenOperation.cpp | 1 + .../operations/COM_MixSoftLightOperation.cpp | 1 + .../operations/COM_MixSubtractOperation.cpp | 1 + .../operations/COM_MixValueOperation.cpp | 1 + .../operations/COM_NormalizeOperation.cpp | 1 + .../operations/COM_TonemapOperation.cpp | 1 + 110 files changed, 593 insertions(+), 474 deletions(-) diff --git a/source/blender/compositor/intern/COM_NodeBase.cpp b/source/blender/compositor/intern/COM_NodeBase.cpp index 5ffe9bdd26a..42946d7315e 100644 --- a/source/blender/compositor/intern/COM_NodeBase.cpp +++ b/source/blender/compositor/intern/COM_NodeBase.cpp @@ -31,6 +31,7 @@ NodeBase::NodeBase() { + /* pass */ } diff --git a/source/blender/compositor/intern/COM_NodeOperation.cpp b/source/blender/compositor/intern/COM_NodeOperation.cpp index 1c05c2a3ae8..114d9f44cef 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.cpp +++ b/source/blender/compositor/intern/COM_NodeOperation.cpp @@ -69,6 +69,7 @@ void NodeOperation::setResolutionInputSocketIndex(unsigned int index) } void NodeOperation::initExecution() { + /* pass */ } void NodeOperation::initMutex() @@ -93,6 +94,7 @@ void NodeOperation::deinitMutex() void NodeOperation::deinitExecution() { + /* pass */ } SocketReader *NodeOperation::getInputSocketReader(unsigned int inputSocketIndex) { diff --git a/source/blender/compositor/intern/COM_OutputSocket.cpp b/source/blender/compositor/intern/COM_OutputSocket.cpp index da08b512003..484254fe6de 100644 --- a/source/blender/compositor/intern/COM_OutputSocket.cpp +++ b/source/blender/compositor/intern/COM_OutputSocket.cpp @@ -27,6 +27,7 @@ OutputSocket::OutputSocket(DataType datatype) : Socket(datatype) { + /* pass */ } int OutputSocket::isOutputSocket() const { return true; } diff --git a/source/blender/compositor/nodes/COM_AlphaOverNode.cpp b/source/blender/compositor/nodes/COM_AlphaOverNode.cpp index eb3cd821172..4f3ed36aadb 100644 --- a/source/blender/compositor/nodes/COM_AlphaOverNode.cpp +++ b/source/blender/compositor/nodes/COM_AlphaOverNode.cpp @@ -31,7 +31,7 @@ #include "COM_SetValueOperation.h" #include "DNA_material_types.h" // the ramp types -void AlphaOverNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void AlphaOverNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *valueSocket = this->getInputSocket(0); InputSocket *color1Socket = this->getInputSocket(1); @@ -40,8 +40,8 @@ void AlphaOverNode::convertToOperations(ExecutionSystem *graph, CompositorContex bNode *editorNode = this->getbNode(); MixBaseOperation *convertProg; - NodeTwoFloats *ntf = (NodeTwoFloats*)editorNode->storage; - if (ntf->x!= 0.0f) { + NodeTwoFloats *ntf = (NodeTwoFloats *)editorNode->storage; + if (ntf->x != 0.0f) { AlphaOverMixedOperation *mixOperation = new AlphaOverMixedOperation(); mixOperation->setX(ntf->x); convertProg = mixOperation; diff --git a/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp b/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp index 6baa04ff7c2..f96a92068f4 100644 --- a/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp @@ -28,6 +28,7 @@ BilateralBlurNode::BilateralBlurNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } void BilateralBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index fe93768161c..1b541d81c33 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -31,6 +31,7 @@ BlurNode::BlurNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp index ee0119230f4..296056b6c48 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp @@ -32,6 +32,7 @@ BokehBlurNode::BokehBlurNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } void BokehBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.cpp b/source/blender/compositor/nodes/COM_BokehImageNode.cpp index f498fa11e30..75f5e07d552 100644 --- a/source/blender/compositor/nodes/COM_BokehImageNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehImageNode.cpp @@ -25,15 +25,16 @@ #include "COM_BokehImageOperation.h" #include "COM_ExecutionSystem.h" -BokehImageNode::BokehImageNode(bNode *editorNode): Node(editorNode) +BokehImageNode::BokehImageNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void BokehImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void BokehImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { BokehImageOperation *operation = new BokehImageOperation(); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); graph->addOperation(operation); - operation->setData((NodeBokehImage*)this->getbNode()->storage); + operation->setData((NodeBokehImage *)this->getbNode()->storage); addPreviewOperation(graph, operation->getOutputSocket(0)); } diff --git a/source/blender/compositor/nodes/COM_BoxMaskNode.cpp b/source/blender/compositor/nodes/COM_BoxMaskNode.cpp index e99252663d0..789ff265a5c 100644 --- a/source/blender/compositor/nodes/COM_BoxMaskNode.cpp +++ b/source/blender/compositor/nodes/COM_BoxMaskNode.cpp @@ -25,15 +25,16 @@ #include "COM_BoxMaskOperation.h" #include "COM_ExecutionSystem.h" -BoxMaskNode::BoxMaskNode(bNode *editorNode): Node(editorNode) +BoxMaskNode::BoxMaskNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void BoxMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void BoxMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { BoxMaskOperation *operation; operation = new BoxMaskOperation(); - operation->setData((NodeBoxMask*)this->getbNode()->storage); + operation->setData((NodeBoxMask *)this->getbNode()->storage); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.cpp b/source/blender/compositor/nodes/COM_BrightnessNode.cpp index 9ccb58a45de..1e1fbdbc301 100644 --- a/source/blender/compositor/nodes/COM_BrightnessNode.cpp +++ b/source/blender/compositor/nodes/COM_BrightnessNode.cpp @@ -25,11 +25,12 @@ #include "COM_BrightnessOperation.h" #include "COM_ExecutionSystem.h" -BrightnessNode::BrightnessNode(bNode *editorNode): Node(editorNode) +BrightnessNode::BrightnessNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void BrightnessNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void BrightnessNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { BrightnessOperation *operation = new BrightnessOperation(); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp b/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp index f1d5b8d39cc..69f39639660 100644 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp @@ -27,8 +27,10 @@ #include "COM_ConvertRGBToYUVOperation.h" #include "COM_SetAlphaOperation.h" -ChannelMatteNode::ChannelMatteNode(bNode *editorNode): Node(editorNode) -{} +ChannelMatteNode::ChannelMatteNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} void ChannelMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { @@ -36,30 +38,30 @@ void ChannelMatteNode::convertToOperations(ExecutionSystem *graph, CompositorCon OutputSocket *outputSocketImage = this->getOutputSocket(0); OutputSocket *outputSocketMatte = this->getOutputSocket(1); - NodeOperation *convert=NULL; + NodeOperation *convert = NULL; bNode *node = this->getbNode(); /* colorspace */ switch (node->custom1) { - case CMP_NODE_CHANNEL_MATTE_CS_RGB: - break; - case CMP_NODE_CHANNEL_MATTE_CS_HSV: /*HSV*/ - convert = new ConvertRGBToHSVOperation(); - break; - case CMP_NODE_CHANNEL_MATTE_CS_YUV: /*YUV*/ - convert = new ConvertRGBToYUVOperation(); - break; - case CMP_NODE_CHANNEL_MATTE_CS_YCC: /*YCC*/ - convert = new ConvertRGBToYCCOperation(); - ((ConvertRGBToYCCOperation *)convert)->setMode(0); /* BLI_YCC_ITU_BT601 */ - break; - default: - break; + case CMP_NODE_CHANNEL_MATTE_CS_RGB: + break; + case CMP_NODE_CHANNEL_MATTE_CS_HSV: /*HSV*/ + convert = new ConvertRGBToHSVOperation(); + break; + case CMP_NODE_CHANNEL_MATTE_CS_YUV: /*YUV*/ + convert = new ConvertRGBToYUVOperation(); + break; + case CMP_NODE_CHANNEL_MATTE_CS_YCC: /*YCC*/ + convert = new ConvertRGBToYCCOperation(); + ((ConvertRGBToYCCOperation *)convert)->setMode(0); /* BLI_YCC_ITU_BT601 */ + break; + default: + break; } ChannelMatteOperation *operation = new ChannelMatteOperation(); /* pass the ui properties to the operation */ - operation->setSettings((NodeChroma*)node->storage, node->custom2); + operation->setSettings((NodeChroma *)node->storage, node->custom2); SetAlphaOperation *operationAlpha = new SetAlphaOperation(); diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp b/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp index 82059ed8493..0fb09157351 100644 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp @@ -25,8 +25,10 @@ #include "COM_ConvertRGBToYCCOperation.h" #include "COM_SetAlphaOperation.h" -ChromaMatteNode::ChromaMatteNode(bNode *editorNode): Node(editorNode) -{} +ChromaMatteNode::ChromaMatteNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} void ChromaMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { @@ -42,7 +44,7 @@ void ChromaMatteNode::convertToOperations(ExecutionSystem *graph, CompositorCont ChromaMatteOperation *operation = new ChromaMatteOperation(); bNode *editorsnode = getbNode(); - operation->setSettings((NodeChroma*)editorsnode->storage); + operation->setSettings((NodeChroma *)editorsnode->storage); inputSocketImage->relinkConnections(operationRGBToYCC_Image->getInputSocket(0), 0, graph); inputSocketKey->relinkConnections(operationRGBToYCC_Key->getInputSocket(0), 0, graph); diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp b/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp index 7b852678191..d85b1ec1de1 100644 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp @@ -27,10 +27,12 @@ #include "BKE_node.h" #include "COM_MixBlendOperation.h" -ColorBalanceNode::ColorBalanceNode(bNode *editorNode): Node(editorNode) +ColorBalanceNode::ColorBalanceNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void ColorBalanceNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) + +void ColorBalanceNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *inputSocket = this->getInputSocket(0); InputSocket *inputImageSocket = this->getInputSocket(1); @@ -38,16 +40,16 @@ void ColorBalanceNode::convertToOperations(ExecutionSystem *graph, CompositorCon bNode *node = this->getbNode(); NodeColorBalance *n = (NodeColorBalance *)node->storage; - NodeOperation*operation; + NodeOperation *operation; if (node->custom1 == 0) { ColorBalanceLGGOperation *operationLGG = new ColorBalanceLGGOperation(); { - int c; + int c; - for (c = 0; c < 3; c++) { - n->lift_lgg[c] = 2.0f - n->lift[c]; - n->gamma_inv[c] = (n->gamma[c] != 0.0f) ? 1.0f/n->gamma[c] : 1000000.0f; - } + for (c = 0; c < 3; c++) { + n->lift_lgg[c] = 2.0f - n->lift[c]; + n->gamma_inv[c] = (n->gamma[c] != 0.0f) ? 1.0f / n->gamma[c] : 1000000.0f; + } } operationLGG->setGain(n->gain); diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp b/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp index 4909f1b9895..41b3bebbd7b 100644 --- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp @@ -25,20 +25,21 @@ #include "COM_ColorCorrectionOperation.h" #include "COM_ExecutionSystem.h" -ColorCorrectionNode::ColorCorrectionNode(bNode *editorNode): Node(editorNode) +ColorCorrectionNode::ColorCorrectionNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void ColorCorrectionNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void ColorCorrectionNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { ColorCorrectionOperation *operation = new ColorCorrectionOperation(); bNode *editorNode = getbNode(); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); - operation->setData((NodeColorCorrection*)editorNode->storage); - operation->setRedChannelEnabled((editorNode->custom1&1)>0); - operation->setGreenChannelEnabled((editorNode->custom1&2)>0); - operation->setBlueChannelEnabled((editorNode->custom1&4)>0); + operation->setData((NodeColorCorrection *)editorNode->storage); + operation->setRedChannelEnabled((editorNode->custom1 & 1) > 0); + operation->setGreenChannelEnabled((editorNode->custom1 & 2) > 0); + operation->setBlueChannelEnabled((editorNode->custom1 & 4) > 0); graph->addOperation(operation); } diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp index 0d331ed9b05..9ae11c22b6a 100644 --- a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp @@ -25,11 +25,12 @@ #include "COM_ColorCurveOperation.h" #include "COM_ExecutionSystem.h" -ColorCurveNode::ColorCurveNode(bNode *editorNode): Node(editorNode) +ColorCurveNode::ColorCurveNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void ColorCurveNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void ColorCurveNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { if (this->getInputSocket(2)->isConnected() || this->getInputSocket(3)->isConnected()) { ColorCurveOperation *operation = new ColorCurveOperation(); @@ -41,21 +42,22 @@ void ColorCurveNode::convertToOperations(ExecutionSystem *graph, CompositorConte this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); - operation->setCurveMapping((CurveMapping*)this->getbNode()->storage); + operation->setCurveMapping((CurveMapping *)this->getbNode()->storage); graph->addOperation(operation); - } else { + } + else { ConstantLevelColorCurveOperation *operation = new ConstantLevelColorCurveOperation(); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); - bNodeSocketValueRGBA *val = (bNodeSocketValueRGBA*)this->getInputSocket(2)->getbNodeSocket()->default_value; + bNodeSocketValueRGBA *val = (bNodeSocketValueRGBA *)this->getInputSocket(2)->getbNodeSocket()->default_value; operation->setBlackLevel(val->value); - val = (bNodeSocketValueRGBA*)this->getInputSocket(3)->getbNodeSocket()->default_value; + val = (bNodeSocketValueRGBA *)this->getInputSocket(3)->getbNodeSocket()->default_value; operation->setWhiteLevel(val->value); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); - operation->setCurveMapping((CurveMapping*)this->getbNode()->storage); + operation->setCurveMapping((CurveMapping *)this->getbNode()->storage); graph->addOperation(operation); } diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.cpp b/source/blender/compositor/nodes/COM_ColorMatteNode.cpp index ad117e1ca2c..38ab6ba8da2 100644 --- a/source/blender/compositor/nodes/COM_ColorMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorMatteNode.cpp @@ -25,8 +25,10 @@ #include "COM_ConvertRGBToHSVOperation.h" #include "COM_SetAlphaOperation.h" -ColorMatteNode::ColorMatteNode(bNode *editorNode): Node(editorNode) -{} +ColorMatteNode::ColorMatteNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} void ColorMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { @@ -40,7 +42,7 @@ void ColorMatteNode::convertToOperations(ExecutionSystem *graph, CompositorConte ColorMatteOperation *operation = new ColorMatteOperation(); bNode *editorsnode = getbNode(); - operation->setSettings((NodeChroma*)editorsnode->storage); + operation->setSettings((NodeChroma *)editorsnode->storage); inputSocketImage->relinkConnections(operationRGBToHSV_Image->getInputSocket(0), 0, graph); inputSocketKey->relinkConnections(operationRGBToHSV_Key->getInputSocket(0), 1, graph); diff --git a/source/blender/compositor/nodes/COM_ColorNode.cpp b/source/blender/compositor/nodes/COM_ColorNode.cpp index f5fcb0177f7..65480c7aeb2 100644 --- a/source/blender/compositor/nodes/COM_ColorNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorNode.cpp @@ -25,15 +25,16 @@ #include "COM_SetColorOperation.h" #include "COM_ExecutionSystem.h" -ColorNode::ColorNode(bNode *editorNode): Node(editorNode) +ColorNode::ColorNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void ColorNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void ColorNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { SetColorOperation *operation = new SetColorOperation(); bNodeSocket *socket = this->getEditorOutputSocket(0); - bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA*)socket->default_value; + bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA *)socket->default_value; this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); operation->setChannels(dval->value); graph->addOperation(operation); diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.cpp b/source/blender/compositor/nodes/COM_ColorRampNode.cpp index c6090120467..a79c7885ae4 100644 --- a/source/blender/compositor/nodes/COM_ColorRampNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorRampNode.cpp @@ -27,10 +27,12 @@ #include "COM_SeparateChannelOperation.h" #include "DNA_texture_types.h" -ColorRampNode::ColorRampNode(bNode *editorNode): Node(editorNode) -{} +ColorRampNode::ColorRampNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} -void ColorRampNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void ColorRampNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *inputSocket = this->getInputSocket(0); OutputSocket *outputSocket = this->getOutputSocket(0); @@ -46,7 +48,7 @@ void ColorRampNode::convertToOperations(ExecutionSystem *graph, CompositorContex operation2->setChannel(3); graph->addOperation(operation2); } - operation->setColorBand((ColorBand*)editorNode->storage); + operation->setColorBand((ColorBand *)editorNode->storage); inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); graph->addOperation(operation); } diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.cpp b/source/blender/compositor/nodes/COM_ColorSpillNode.cpp index 503ca3c8bd3..0e586955ff8 100644 --- a/source/blender/compositor/nodes/COM_ColorSpillNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorSpillNode.cpp @@ -24,8 +24,10 @@ #include "BKE_node.h" #include "COM_ColorSpillOperation.h" -ColorSpillNode::ColorSpillNode(bNode *editorNode): Node(editorNode) -{} +ColorSpillNode::ColorSpillNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} void ColorSpillNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { @@ -45,8 +47,8 @@ void ColorSpillNode::convertToOperations(ExecutionSystem *graph, CompositorConte // Average color spill operation = new ColorSpillAverageOperation(); } - operation->setSettings((NodeColorspill*)editorsnode->storage); - operation->setSpillChannel(editorsnode->custom1-1); // Channel for spilling + operation->setSettings((NodeColorspill *)editorsnode->storage); + operation->setSpillChannel(editorsnode->custom1 - 1); // Channel for spilling inputSocketImage->relinkConnections(operation->getInputSocket(0), 0, graph); diff --git a/source/blender/compositor/nodes/COM_ColorToBWNode.cpp b/source/blender/compositor/nodes/COM_ColorToBWNode.cpp index ed2869d35f2..430f317eae2 100644 --- a/source/blender/compositor/nodes/COM_ColorToBWNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorToBWNode.cpp @@ -25,11 +25,12 @@ #include "COM_ConvertColorToBWOperation.h" #include "COM_ExecutionSystem.h" -ColourToBWNode::ColourToBWNode(bNode *editorNode): Node(editorNode) +ColourToBWNode::ColourToBWNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void ColourToBWNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void ColourToBWNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *colourSocket = this->getInputSocket(0); OutputSocket *valueSocket = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_CombineHSVANode.cpp b/source/blender/compositor/nodes/COM_CombineHSVANode.cpp index a0f46ad6b6c..beba41fade9 100644 --- a/source/blender/compositor/nodes/COM_CombineHSVANode.cpp +++ b/source/blender/compositor/nodes/COM_CombineHSVANode.cpp @@ -28,11 +28,12 @@ #include "COM_SetValueOperation.h" #include "COM_ConvertHSVToRGBOperation.h" -CombineHSVANode::CombineHSVANode(bNode *editorNode): CombineRGBANode(editorNode) +CombineHSVANode::CombineHSVANode(bNode *editorNode) : CombineRGBANode(editorNode) { + /* pass */ } -void CombineHSVANode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void CombineHSVANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { ConvertHSVToRGBOperation *operation = new ConvertHSVToRGBOperation(); OutputSocket *outputSocket = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_CombineRGBANode.cpp b/source/blender/compositor/nodes/COM_CombineRGBANode.cpp index e6fcc48ac5b..a8cdd8c2950 100644 --- a/source/blender/compositor/nodes/COM_CombineRGBANode.cpp +++ b/source/blender/compositor/nodes/COM_CombineRGBANode.cpp @@ -29,12 +29,12 @@ #include "DNA_material_types.h" // the ramp types -CombineRGBANode::CombineRGBANode(bNode *editorNode): Node(editorNode) +CombineRGBANode::CombineRGBANode(bNode *editorNode) : Node(editorNode) { + /* pass */ } - -void CombineRGBANode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void CombineRGBANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *inputRSocket = this->getInputSocket(0); InputSocket *inputGSocket = this->getInputSocket(1); diff --git a/source/blender/compositor/nodes/COM_CombineYCCANode.cpp b/source/blender/compositor/nodes/COM_CombineYCCANode.cpp index ad6203ea85a..5319eb84184 100644 --- a/source/blender/compositor/nodes/COM_CombineYCCANode.cpp +++ b/source/blender/compositor/nodes/COM_CombineYCCANode.cpp @@ -22,8 +22,9 @@ #include "COM_CombineYCCANode.h" #include "COM_ConvertYCCToRGBOperation.h" -CombineYCCANode::CombineYCCANode(bNode *editorNode): CombineRGBANode(editorNode) +CombineYCCANode::CombineYCCANode(bNode *editorNode) : CombineRGBANode(editorNode) { + /* pass */ } void CombineYCCANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_CombineYUVANode.cpp b/source/blender/compositor/nodes/COM_CombineYUVANode.cpp index ea92a40f803..48c2c6ca649 100644 --- a/source/blender/compositor/nodes/COM_CombineYUVANode.cpp +++ b/source/blender/compositor/nodes/COM_CombineYUVANode.cpp @@ -22,8 +22,9 @@ #include "COM_CombineYUVANode.h" #include "COM_ConvertYUVToRGBOperation.h" -CombineYUVANode::CombineYUVANode(bNode *editorNode): CombineRGBANode(editorNode) +CombineYUVANode::CombineYUVANode(bNode *editorNode) : CombineRGBANode(editorNode) { + /* pass */ } void CombineYUVANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_CompositorNode.cpp b/source/blender/compositor/nodes/COM_CompositorNode.cpp index e2cc34bb6ce..fccb92ddd8b 100644 --- a/source/blender/compositor/nodes/COM_CompositorNode.cpp +++ b/source/blender/compositor/nodes/COM_CompositorNode.cpp @@ -24,11 +24,12 @@ #include "COM_CompositorOperation.h" #include "COM_ExecutionSystem.h" -CompositorNode::CompositorNode(bNode *editorNode): Node(editorNode) +CompositorNode::CompositorNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void CompositorNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void CompositorNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *imageSocket = this->getInputSocket(0); InputSocket *alphaSocket = this->getInputSocket(1); diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp b/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp index 0b4326a17ca..70aeee8fc27 100644 --- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp +++ b/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp @@ -24,7 +24,7 @@ #include "COM_ConvertKeyToPremulOperation.h" #include "COM_ExecutionSystem.h" -void ConvertAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void ConvertAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { NodeOperation *operation = NULL; bNode *node = this->getbNode(); diff --git a/source/blender/compositor/nodes/COM_CropNode.cpp b/source/blender/compositor/nodes/COM_CropNode.cpp index c58fcc874cb..b80a3e088f2 100644 --- a/source/blender/compositor/nodes/COM_CropNode.cpp +++ b/source/blender/compositor/nodes/COM_CropNode.cpp @@ -26,12 +26,13 @@ CropNode::CropNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void CropNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void CropNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { bNode *node = getbNode(); - NodeTwoXYs *cropSettings = (NodeTwoXYs*)node->storage; + NodeTwoXYs *cropSettings = (NodeTwoXYs *)node->storage; bool relative = (bool)node->custom2; bool cropImage = (bool)node->custom1; CropBaseOperation *operation; diff --git a/source/blender/compositor/nodes/COM_DefocusNode.cpp b/source/blender/compositor/nodes/COM_DefocusNode.cpp index e4e19fdbe27..d1f90b490ad 100644 --- a/source/blender/compositor/nodes/COM_DefocusNode.cpp +++ b/source/blender/compositor/nodes/COM_DefocusNode.cpp @@ -33,16 +33,17 @@ #include "COM_SetValueOperation.h" #include "COM_GammaCorrectOperation.h" -DefocusNode::DefocusNode(bNode *editorNode): Node(editorNode) +DefocusNode::DefocusNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { bNode *node = this->getbNode(); - Scene *scene = (Scene*)node->id; - Object *camob = (scene)? scene->camera: NULL; - NodeDefocus *data = (NodeDefocus*)node->storage; + Scene *scene = (Scene *)node->id; + Object *camob = (scene) ? scene->camera : NULL; + NodeDefocus *data = (NodeDefocus *)node->storage; NodeOperation *radiusOperation; if (data->no_zbuf) { @@ -74,11 +75,11 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext } BokehImageOperation *bokeh = new BokehImageOperation(); - NodeBokehImage * bokehdata = new NodeBokehImage(); + NodeBokehImage *bokehdata = new NodeBokehImage(); bokehdata->angle = data->rotation; bokehdata->rounding = 0.0f; bokehdata->flaps = data->bktype; - if (data->bktype<3) { + if (data->bktype < 3) { bokehdata->flaps = 5; bokehdata->rounding = 1.0f; } @@ -96,8 +97,8 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext addLink(graph, bokeh->getOutputSocket(), operation->getInputSocket(1)); addLink(graph, radiusOperation->getOutputSocket(), operation->getInputSocket(2)); if (data->gamco) { - GammaCorrectOperation * correct = new GammaCorrectOperation(); - GammaUncorrectOperation * inverse = new GammaUncorrectOperation(); + GammaCorrectOperation *correct = new GammaCorrectOperation(); + GammaUncorrectOperation *inverse = new GammaUncorrectOperation(); this->getInputSocket(0)->relinkConnections(correct->getInputSocket(0), 0, graph); addLink(graph, correct->getOutputSocket(), operation->getInputSocket(0)); addLink(graph, operation->getOutputSocket(), inverse->getInputSocket(0)); diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp b/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp index 596fefff77c..6dca049a6ae 100644 --- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp @@ -25,10 +25,12 @@ #include "COM_DifferenceMatteOperation.h" #include "COM_SetAlphaOperation.h" -DifferenceMatteNode::DifferenceMatteNode(bNode *editorNode): Node(editorNode) -{} +DifferenceMatteNode::DifferenceMatteNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} -void DifferenceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void DifferenceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *inputSocket = this->getInputSocket(0); InputSocket *inputSocket2 = this->getInputSocket(1); @@ -36,15 +38,15 @@ void DifferenceMatteNode::convertToOperations(ExecutionSystem *graph, Compositor OutputSocket *outputSocketMatte = this->getOutputSocket(1); bNode *editorNode = this->getbNode(); - DifferenceMatteOperation * operationSet = new DifferenceMatteOperation(); - operationSet->setSettings((NodeChroma*)editorNode->storage); + DifferenceMatteOperation *operationSet = new DifferenceMatteOperation(); + operationSet->setSettings((NodeChroma *)editorNode->storage); inputSocket->relinkConnections(operationSet->getInputSocket(0), 0, graph); inputSocket2->relinkConnections(operationSet->getInputSocket(1), 1, graph); outputSocketMatte->relinkConnections(operationSet->getOutputSocket(0)); graph->addOperation(operationSet); - SetAlphaOperation * operation = new SetAlphaOperation(); + SetAlphaOperation *operation = new SetAlphaOperation(); addLink(graph, operationSet->getInputSocket(0)->getConnection()->getFromSocket(), operation->getInputSocket(0)); addLink(graph, operationSet->getOutputSocket(), operation->getInputSocket(1)); outputSocketImage->relinkConnections(operation->getOutputSocket()); diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp index fe9e97a3e4b..6ee5b2a2b0d 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp @@ -29,6 +29,7 @@ DilateErodeNode::DilateErodeNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp b/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp index d096ef977f8..dee0e6a88da 100644 --- a/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp @@ -28,6 +28,7 @@ DirectionalBlurNode::DirectionalBlurNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } void DirectionalBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_DisplaceNode.cpp b/source/blender/compositor/nodes/COM_DisplaceNode.cpp index 9604db378bc..41fbfd61981 100644 --- a/source/blender/compositor/nodes/COM_DisplaceNode.cpp +++ b/source/blender/compositor/nodes/COM_DisplaceNode.cpp @@ -24,11 +24,12 @@ #include "COM_DisplaceSimpleOperation.h" #include "COM_ExecutionSystem.h" -DisplaceNode::DisplaceNode(bNode *editorNode): Node(editorNode) +DisplaceNode::DisplaceNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void DisplaceNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void DisplaceNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { NodeOperation *operation; if (context->getQuality() == COM_QUALITY_LOW) diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp b/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp index 20a55ae195c..d6730ef6a00 100644 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp @@ -24,8 +24,10 @@ #include "COM_DistanceMatteOperation.h" #include "COM_SetAlphaOperation.h" -DistanceMatteNode::DistanceMatteNode(bNode *editorNode): Node(editorNode) -{} +DistanceMatteNode::DistanceMatteNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} void DistanceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { @@ -36,7 +38,7 @@ void DistanceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorCo DistanceMatteOperation *operation = new DistanceMatteOperation(); bNode *editorsnode = getbNode(); - operation->setSettings((NodeChroma*)editorsnode->storage); + operation->setSettings((NodeChroma *)editorsnode->storage); inputSocketImage->relinkConnections(operation->getInputSocket(0), 0, graph); inputSocketKey->relinkConnections(operation->getInputSocket(1), 1, graph); diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp index ab9e101dad8..57c319e7630 100644 --- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp +++ b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp @@ -25,11 +25,12 @@ #include "DNA_scene_types.h" #include "COM_ExecutionSystem.h" -DoubleEdgeMaskNode::DoubleEdgeMaskNode(bNode *editorNode): Node(editorNode) +DoubleEdgeMaskNode::DoubleEdgeMaskNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void DoubleEdgeMaskNode::convertToOperations(ExecutionSystem *system, CompositorContext * context) +void DoubleEdgeMaskNode::convertToOperations(ExecutionSystem *system, CompositorContext *context) { DoubleEdgeMaskOperation *operation; bNode *bnode = this->getbNode(); diff --git a/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp b/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp index f5003c4be94..23410c6a115 100644 --- a/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp +++ b/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp @@ -25,15 +25,16 @@ #include "COM_EllipseMaskOperation.h" #include "COM_ExecutionSystem.h" -EllipseMaskNode::EllipseMaskNode(bNode *editorNode): Node(editorNode) +EllipseMaskNode::EllipseMaskNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void EllipseMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void EllipseMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { EllipseMaskOperation *operation; operation = new EllipseMaskOperation(); - operation->setData((NodeEllipseMask*)this->getbNode()->storage); + operation->setData((NodeEllipseMask *)this->getbNode()->storage); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); diff --git a/source/blender/compositor/nodes/COM_FilterNode.cpp b/source/blender/compositor/nodes/COM_FilterNode.cpp index 7700bceb4ab..23f87805821 100644 --- a/source/blender/compositor/nodes/COM_FilterNode.cpp +++ b/source/blender/compositor/nodes/COM_FilterNode.cpp @@ -27,11 +27,12 @@ #include "BKE_node.h" #include "COM_MixBlendOperation.h" -FilterNode::FilterNode(bNode *editorNode): Node(editorNode) +FilterNode::FilterNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void FilterNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void FilterNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *inputSocket = this->getInputSocket(0); InputSocket *inputImageSocket = this->getInputSocket(1); @@ -39,38 +40,38 @@ void FilterNode::convertToOperations(ExecutionSystem *graph, CompositorContext * ConvolutionFilterOperation *operation = NULL; switch (this->getbNode()->custom1) { - case CMP_FILT_SOFT: - operation = new ConvolutionFilterOperation(); - operation->set3x3Filter(1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f); - break; - case CMP_FILT_SHARP: - operation = new ConvolutionFilterOperation(); - operation->set3x3Filter(-1,-1,-1,-1,9,-1,-1,-1,-1); - break; - case CMP_FILT_LAPLACE: - operation = new ConvolutionFilterOperation(); - operation->set3x3Filter(-1/8.0f, -1/8.0f, -1/8.0f, -1/8.0f, 1.0f, -1/8.0f, -1/8.0f, -1/8.0f, -1/8.0f); - break; - case CMP_FILT_SOBEL: - operation = new ConvolutionEdgeFilterOperation(); - operation->set3x3Filter(1,2,1,0,0,0,-1,-2,-1); - break; - case CMP_FILT_PREWITT: - operation = new ConvolutionEdgeFilterOperation(); - operation->set3x3Filter(1,1,1,0,0,0,-1,-1,-1); - break; - case CMP_FILT_KIRSCH: - operation = new ConvolutionEdgeFilterOperation(); - operation->set3x3Filter(5,5,5,-3,-3,-3,-2,-2,-2); - break; - case CMP_FILT_SHADOW: - operation = new ConvolutionFilterOperation(); - operation->set3x3Filter(1,2,1,0,1,0,-1,-2,-1); - break; - default: - operation = new ConvolutionFilterOperation(); - operation->set3x3Filter(0,0,0,0,1,0,0,0,0); - break; + case CMP_FILT_SOFT: + operation = new ConvolutionFilterOperation(); + operation->set3x3Filter(1 / 16.0f, 2 / 16.0f, 1 / 16.0f, 2 / 16.0f, 4 / 16.0f, 2 / 16.0f, 1 / 16.0f, 2 / 16.0f, 1 / 16.0f); + break; + case CMP_FILT_SHARP: + operation = new ConvolutionFilterOperation(); + operation->set3x3Filter(-1, -1, -1, -1, 9, -1, -1, -1, -1); + break; + case CMP_FILT_LAPLACE: + operation = new ConvolutionFilterOperation(); + operation->set3x3Filter(-1 / 8.0f, -1 / 8.0f, -1 / 8.0f, -1 / 8.0f, 1.0f, -1 / 8.0f, -1 / 8.0f, -1 / 8.0f, -1 / 8.0f); + break; + case CMP_FILT_SOBEL: + operation = new ConvolutionEdgeFilterOperation(); + operation->set3x3Filter(1, 2, 1, 0, 0, 0, -1, -2, -1); + break; + case CMP_FILT_PREWITT: + operation = new ConvolutionEdgeFilterOperation(); + operation->set3x3Filter(1, 1, 1, 0, 0, 0, -1, -1, -1); + break; + case CMP_FILT_KIRSCH: + operation = new ConvolutionEdgeFilterOperation(); + operation->set3x3Filter(5, 5, 5, -3, -3, -3, -2, -2, -2); + break; + case CMP_FILT_SHADOW: + operation = new ConvolutionFilterOperation(); + operation->set3x3Filter(1, 2, 1, 0, 1, 0, -1, -2, -1); + break; + default: + operation = new ConvolutionFilterOperation(); + operation->set3x3Filter(0, 0, 0, 0, 1, 0, 0, 0, 0); + break; } inputImageSocket->relinkConnections(operation->getInputSocket(0), 1, graph); diff --git a/source/blender/compositor/nodes/COM_FlipNode.cpp b/source/blender/compositor/nodes/COM_FlipNode.cpp index 0830c757833..a50297aae1a 100644 --- a/source/blender/compositor/nodes/COM_FlipNode.cpp +++ b/source/blender/compositor/nodes/COM_FlipNode.cpp @@ -27,26 +27,27 @@ FlipNode::FlipNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void FlipNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void FlipNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *inputSocket = this->getInputSocket(0); OutputSocket *outputSocket = this->getOutputSocket(0); FlipOperation *operation = new FlipOperation(); switch (this->getbNode()->custom1) { - case 0: /// @TODO: I didn't find any constants in the old implementation, should I introduce them. - operation->setFlipX(true); - operation->setFlipY(false); - break; - case 1: - operation->setFlipX(false); - operation->setFlipY(true); - break; - case 2: - operation->setFlipX(true); - operation->setFlipY(true); - break; + case 0: /// @TODO: I didn't find any constants in the old implementation, should I introduce them. + operation->setFlipX(true); + operation->setFlipY(false); + break; + case 1: + operation->setFlipX(false); + operation->setFlipY(true); + break; + case 2: + operation->setFlipX(true); + operation->setFlipY(true); + break; } inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); diff --git a/source/blender/compositor/nodes/COM_GammaNode.cpp b/source/blender/compositor/nodes/COM_GammaNode.cpp index 58b05607618..52699c83bf9 100644 --- a/source/blender/compositor/nodes/COM_GammaNode.cpp +++ b/source/blender/compositor/nodes/COM_GammaNode.cpp @@ -25,11 +25,12 @@ #include "COM_GammaOperation.h" #include "COM_ExecutionSystem.h" -GammaNode::GammaNode(bNode *editorNode): Node(editorNode) +GammaNode::GammaNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void GammaNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void GammaNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { GammaOperation *operation = new GammaOperation(); diff --git a/source/blender/compositor/nodes/COM_GlareNode.cpp b/source/blender/compositor/nodes/COM_GlareNode.cpp index dcb8f3a3a4c..7b34fa4d286 100644 --- a/source/blender/compositor/nodes/COM_GlareNode.cpp +++ b/source/blender/compositor/nodes/COM_GlareNode.cpp @@ -31,36 +31,37 @@ #include "COM_GlareGhostOperation.h" #include "COM_GlareFogGlowOperation.h" -GlareNode::GlareNode(bNode *editorNode): Node(editorNode) +GlareNode::GlareNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void GlareNode::convertToOperations(ExecutionSystem *system, CompositorContext * context)\ -{ +void GlareNode::convertToOperations(ExecutionSystem *system, CompositorContext *context) \ + { bNode *node = this->getbNode(); - NodeGlare *glare = (NodeGlare*)node->storage; + NodeGlare *glare = (NodeGlare *)node->storage; - GlareBaseOperation * glareoperation = NULL; + GlareBaseOperation *glareoperation = NULL; switch (glare->type) { - default: - case 3: - glareoperation = new GlareGhostOperation(); - break; - case 2: // streaks - glareoperation = new GlareStreaksOperation(); - break; - case 1: // fog glow - glareoperation = new GlareFogGlowOperation(); - break; - case 0: // simple star - glareoperation = new GlareSimpleStarOperation(); - break; + default: + case 3: + glareoperation = new GlareGhostOperation(); + break; + case 2: // streaks + glareoperation = new GlareStreaksOperation(); + break; + case 1: // fog glow + glareoperation = new GlareFogGlowOperation(); + break; + case 0: // simple star + glareoperation = new GlareSimpleStarOperation(); + break; } GlareThresholdOperation *thresholdOperation = new GlareThresholdOperation(); - SetValueOperation * mixvalueoperation = new SetValueOperation(); - MixGlareOperation * mixoperation = new MixGlareOperation(); + SetValueOperation *mixvalueoperation = new SetValueOperation(); + MixGlareOperation *mixoperation = new MixGlareOperation(); mixoperation->getInputSocket(2)->setResizeMode(COM_SC_FIT); this->getInputSocket(0)->relinkConnections(thresholdOperation->getInputSocket(0), 0, system); @@ -72,7 +73,7 @@ void GlareNode::convertToOperations(ExecutionSystem *system, CompositorContext * thresholdOperation->setGlareSettings(glare); glareoperation->setGlareSettings(glare); - mixvalueoperation->setValue(0.5f+glare->mix*0.5f); + mixvalueoperation->setValue(0.5f + glare->mix * 0.5f); mixoperation->setResolutionInputSocketIndex(1); system->addOperation(glareoperation); @@ -80,4 +81,4 @@ void GlareNode::convertToOperations(ExecutionSystem *system, CompositorContext * system->addOperation(mixvalueoperation); system->addOperation(mixoperation); -} + } diff --git a/source/blender/compositor/nodes/COM_GroupNode.cpp b/source/blender/compositor/nodes/COM_GroupNode.cpp index 8a8c1db86b4..e5255b6bb87 100644 --- a/source/blender/compositor/nodes/COM_GroupNode.cpp +++ b/source/blender/compositor/nodes/COM_GroupNode.cpp @@ -24,44 +24,46 @@ #include "COM_SocketProxyNode.h" #include "COM_ExecutionSystemHelper.h" -GroupNode::GroupNode(bNode *editorNode): Node(editorNode) +GroupNode::GroupNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void GroupNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void GroupNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { + /* pass */ } void GroupNode::ungroup(ExecutionSystem &system) { - bNode * bnode = this->getbNode(); - vector &inputsockets = this->getInputSockets(); - vector &outputsockets = this->getOutputSockets(); + bNode *bnode = this->getbNode(); + vector &inputsockets = this->getInputSockets(); + vector &outputsockets = this->getOutputSockets(); unsigned int index; /* get the node list size _before_ adding proxy nodes, so they are available for linking */ int nodes_start = system.getNodes().size(); - for (index = 0 ; index < inputsockets.size();index ++) { - InputSocket * inputSocket = inputsockets[index]; + for (index = 0; index < inputsockets.size(); index++) { + InputSocket *inputSocket = inputsockets[index]; bNodeSocket *editorInput = inputSocket->getbNodeSocket(); if (editorInput->groupsock) { - SocketProxyNode * proxy = new SocketProxyNode(bnode, editorInput, editorInput->groupsock); + SocketProxyNode *proxy = new SocketProxyNode(bnode, editorInput, editorInput->groupsock); inputSocket->relinkConnections(proxy->getInputSocket(0), index, &system); ExecutionSystemHelper::addNode(system.getNodes(), proxy); } } - for (index = 0 ; index < outputsockets.size();index ++) { - OutputSocket * outputSocket = outputsockets[index]; + for (index = 0; index < outputsockets.size(); index++) { + OutputSocket *outputSocket = outputsockets[index]; bNodeSocket *editorOutput = outputSocket->getbNodeSocket(); if (editorOutput->groupsock) { - SocketProxyNode * proxy = new SocketProxyNode(bnode, editorOutput->groupsock, editorOutput); + SocketProxyNode *proxy = new SocketProxyNode(bnode, editorOutput->groupsock, editorOutput); outputSocket->relinkConnections(proxy->getOutputSocket(0)); ExecutionSystemHelper::addNode(system.getNodes(), proxy); } } - bNodeTree *subtree = (bNodeTree*)bnode->id; + bNodeTree *subtree = (bNodeTree *)bnode->id; ExecutionSystemHelper::addbNodeTree(system, nodes_start, subtree, bnode); } diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp index ae96a8c9fb8..6057a7f0e6c 100644 --- a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp +++ b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp @@ -33,23 +33,24 @@ #include "DNA_node_types.h" #include "COM_HueSaturationValueCorrectOperation.h" -HueSaturationValueCorrectNode::HueSaturationValueCorrectNode(bNode *editorNode): Node(editorNode) +HueSaturationValueCorrectNode::HueSaturationValueCorrectNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void HueSaturationValueCorrectNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void HueSaturationValueCorrectNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *valueSocket = this->getInputSocket(0); InputSocket *colourSocket = this->getInputSocket(1); OutputSocket *outputSocket = this->getOutputSocket(0); bNode *editorsnode = getbNode(); - CurveMapping *storage = (CurveMapping*)editorsnode->storage; + CurveMapping *storage = (CurveMapping *)editorsnode->storage; if (colourSocket->isConnected() && outputSocket->isConnected()) { - ConvertRGBToHSVOperation * rgbToHSV = new ConvertRGBToHSVOperation(); - ConvertHSVToRGBOperation * hsvToRGB = new ConvertHSVToRGBOperation(); + ConvertRGBToHSVOperation *rgbToHSV = new ConvertRGBToHSVOperation(); + ConvertHSVToRGBOperation *hsvToRGB = new ConvertHSVToRGBOperation(); HueSaturationValueCorrectOperation *changeHSV = new HueSaturationValueCorrectOperation(); - MixBlendOperation * blend = new MixBlendOperation(); + MixBlendOperation *blend = new MixBlendOperation(); colourSocket->relinkConnections(rgbToHSV->getInputSocket(0), 1, graph); addLink(graph, rgbToHSV->getOutputSocket(), changeHSV->getInputSocket(0)); diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp b/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp index 32c7d4719a4..ef501317e48 100644 --- a/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp +++ b/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp @@ -32,22 +32,23 @@ #include "COM_ChangeHSVOperation.h" #include "DNA_node_types.h" -HueSaturationValueNode::HueSaturationValueNode(bNode *editorNode): Node(editorNode) +HueSaturationValueNode::HueSaturationValueNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void HueSaturationValueNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void HueSaturationValueNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *valueSocket = this->getInputSocket(0); InputSocket *colourSocket = this->getInputSocket(1); OutputSocket *outputSocket = this->getOutputSocket(0); bNode *editorsnode = getbNode(); - NodeHueSat *storage = (NodeHueSat*)editorsnode->storage; + NodeHueSat *storage = (NodeHueSat *)editorsnode->storage; - ConvertRGBToHSVOperation * rgbToHSV = new ConvertRGBToHSVOperation(); - ConvertHSVToRGBOperation * hsvToRGB = new ConvertHSVToRGBOperation(); + ConvertRGBToHSVOperation *rgbToHSV = new ConvertRGBToHSVOperation(); + ConvertHSVToRGBOperation *hsvToRGB = new ConvertHSVToRGBOperation(); ChangeHSVOperation *changeHSV = new ChangeHSVOperation(); - MixBlendOperation * blend = new MixBlendOperation(); + MixBlendOperation *blend = new MixBlendOperation(); colourSocket->relinkConnections(rgbToHSV->getInputSocket(0), 0, graph); addLink(graph, rgbToHSV->getOutputSocket(), changeHSV->getInputSocket(0)); diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.cpp b/source/blender/compositor/nodes/COM_IDMaskNode.cpp index 82d3ae8ca29..4005e5d2900 100644 --- a/source/blender/compositor/nodes/COM_IDMaskNode.cpp +++ b/source/blender/compositor/nodes/COM_IDMaskNode.cpp @@ -26,10 +26,11 @@ #include "COM_ExecutionSystem.h" #include "COM_AntiAliasOperation.h" -IDMaskNode::IDMaskNode(bNode *editorNode): Node(editorNode) +IDMaskNode::IDMaskNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void IDMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void IDMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { bNode *bnode = this->getbNode(); IDMaskOperation *operation; @@ -37,11 +38,11 @@ void IDMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * operation->setObjectIndex(bnode->custom1); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); - if (bnode->custom2==0 || context->getScene()->r.scemode & R_FULL_SAMPLE) { + if (bnode->custom2 == 0 || context->getScene()->r.scemode & R_FULL_SAMPLE) { this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); } else { - AntiAliasOperation * antiAliasOperation = new AntiAliasOperation(); + AntiAliasOperation *antiAliasOperation = new AntiAliasOperation(); addLink(graph, operation->getOutputSocket(), antiAliasOperation->getInputSocket(0)); this->getOutputSocket(0)->relinkConnections(antiAliasOperation->getOutputSocket(0)); graph->addOperation(antiAliasOperation); diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index cfd530173a9..addde140b9f 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -28,25 +28,27 @@ #include "BKE_node.h" #include "BLI_utildefines.h" -ImageNode::ImageNode(bNode *editorNode): Node(editorNode) +ImageNode::ImageNode(bNode *editorNode) : Node(editorNode) { + /* pass */ + } NodeOperation *ImageNode::doMultilayerCheck(ExecutionSystem *system, RenderLayer *rl, Image *image, ImageUser *user, int framenumber, int outputsocketIndex, int pass, DataType datatype) { OutputSocket *outputSocket = this->getOutputSocket(outputsocketIndex); - MultilayerBaseOperation * operation = NULL; + MultilayerBaseOperation *operation = NULL; switch (datatype) { - case COM_DT_VALUE: - operation = new MultilayerValueOperation(pass); - break; - case COM_DT_VECTOR: - operation = new MultilayerVectorOperation(pass); - break; - case COM_DT_COLOR: - operation = new MultilayerColorOperation(pass); - break; - default: - break; + case COM_DT_VALUE: + operation = new MultilayerValueOperation(pass); + break; + case COM_DT_VECTOR: + operation = new MultilayerVectorOperation(pass); + break; + case COM_DT_COLOR: + operation = new MultilayerColorOperation(pass); + break; + default: + break; } operation->setImage(image); operation->setRenderLayer(rl); @@ -57,52 +59,52 @@ NodeOperation *ImageNode::doMultilayerCheck(ExecutionSystem *system, RenderLayer return operation; } -void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { /// Image output OutputSocket *outputImage = this->getOutputSocket(0); bNode *editorNode = this->getbNode(); - Image *image = (Image*)editorNode->id; - ImageUser *imageuser = (ImageUser*)editorNode->storage; + Image *image = (Image *)editorNode->id; + ImageUser *imageuser = (ImageUser *)editorNode->storage; int framenumber = context->getFramenumber(); int numberOfOutputs = this->getNumberOfOutputSockets(); BKE_image_user_frame_calc(imageuser, context->getFramenumber(), 0); /* force a load, we assume iuser index will be set OK anyway */ - if (image && image->type==IMA_TYPE_MULTILAYER) { + if (image && image->type == IMA_TYPE_MULTILAYER) { BKE_image_get_ibuf(image, imageuser); if (image->rr) { - RenderLayer *rl = (RenderLayer*)BLI_findlink(&image->rr->layers, imageuser->layer); + RenderLayer *rl = (RenderLayer *)BLI_findlink(&image->rr->layers, imageuser->layer); if (rl) { - OutputSocket * socket; + OutputSocket *socket; int index; - for (index = 0 ; index < numberOfOutputs ; index ++) { + for (index = 0; index < numberOfOutputs; index++) { socket = this->getOutputSocket(index); if (socket->isConnected() || index == 0) { bNodeSocket *bnodeSocket = socket->getbNodeSocket(); - NodeImageLayer *storage = (NodeImageLayer*)bnodeSocket->storage; + NodeImageLayer *storage = (NodeImageLayer *)bnodeSocket->storage; int passindex = storage->pass_index; RenderPass *rpass = (RenderPass *)BLI_findlink(&rl->passes, passindex); if (rpass) { - NodeOperation * operation = NULL; + NodeOperation *operation = NULL; imageuser->pass = passindex; switch (rpass->channels) { - case 1: - operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_VALUE); - break; - /* using image operations for both 3 and 4 channels (RGB and RGBA respectively) */ - /* XXX any way to detect actual vector images? */ - case 3: - operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_VECTOR); - break; - case 4: - operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_COLOR); - break; - - default: - /* XXX add a dummy operation? */ - break; + case 1: + operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_VALUE); + break; + /* using image operations for both 3 and 4 channels (RGB and RGBA respectively) */ + /* XXX any way to detect actual vector images? */ + case 3: + operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_VECTOR); + break; + case 4: + operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_COLOR); + break; + + default: + /* XXX add a dummy operation? */ + break; } if (index == 0 && operation) { addPreviewOperation(graph, operation->getOutputSocket()); diff --git a/source/blender/compositor/nodes/COM_InvertNode.cpp b/source/blender/compositor/nodes/COM_InvertNode.cpp index 5d039239fbe..c468bda1b67 100644 --- a/source/blender/compositor/nodes/COM_InvertNode.cpp +++ b/source/blender/compositor/nodes/COM_InvertNode.cpp @@ -26,11 +26,12 @@ #include "COM_ExecutionSystem.h" #include "BKE_node.h" -InvertNode::InvertNode(bNode *editorNode): Node(editorNode) +InvertNode::InvertNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void InvertNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void InvertNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InvertOperation *operation = new InvertOperation(); bNode *node = this->getbNode(); diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index 75a2fe96646..50c1903982e 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -41,8 +41,9 @@ #include "COM_SetAlphaOperation.h" -KeyingNode::KeyingNode(bNode *editorNode): Node(editorNode) +KeyingNode::KeyingNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } OutputSocket *KeyingNode::setupPreBlur(ExecutionSystem *graph, InputSocket *inputImage, int size, OutputSocket **originalImage) @@ -189,7 +190,7 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext * postprocessedMatte = keyingOperation->getOutputSocket(); - if (keying_data->clip_black > 0.0f || keying_data->clip_white< 1.0f) { + if (keying_data->clip_black > 0.0f || keying_data->clip_white < 1.0f) { postprocessedMatte = setupClip(graph, postprocessedMatte, keying_data->edge_kernel_radius, keying_data->edge_kernel_tolerance, keying_data->clip_black, keying_data->clip_white, false); diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp index ad58adae48b..0fb8d45d066 100644 --- a/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp @@ -29,11 +29,12 @@ extern "C" { #include "DNA_movieclip_types.h" } -KeyingScreenNode::KeyingScreenNode(bNode *editorNode): Node(editorNode) +KeyingScreenNode::KeyingScreenNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void KeyingScreenNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void KeyingScreenNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { OutputSocket *outputScreen = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp index e55dd5e64d8..03034e34eb7 100644 --- a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp +++ b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp @@ -26,14 +26,15 @@ #include "COM_ProjectorLensDistortionOperation.h" #include "COM_ScreenLensDistortionOperation.h" -LensDistortionNode::LensDistortionNode(bNode *editorNode): Node(editorNode) +LensDistortionNode::LensDistortionNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void LensDistortionNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void LensDistortionNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { bNode *editorNode = this->getbNode(); - NodeLensDist * data = (NodeLensDist*)editorNode->storage; + NodeLensDist *data = (NodeLensDist *)editorNode->storage; if (data->proj) { ProjectorLensDistortionOperation *operation = new ProjectorLensDistortionOperation(); diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp b/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp index 37976216106..be949e2cacb 100644 --- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp @@ -25,8 +25,10 @@ #include "COM_ConvertRGBToYUVOperation.h" #include "COM_SetAlphaOperation.h" -LuminanceMatteNode::LuminanceMatteNode(bNode *editorNode): Node(editorNode) -{} +LuminanceMatteNode::LuminanceMatteNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} void LuminanceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { @@ -37,7 +39,7 @@ void LuminanceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorC ConvertRGBToYUVOperation *rgbToYUV = new ConvertRGBToYUVOperation(); LuminanceMatteOperation *operationSet = new LuminanceMatteOperation(); bNode *editorsnode = getbNode(); - operationSet->setSettings((NodeChroma*)editorsnode->storage); + operationSet->setSettings((NodeChroma *)editorsnode->storage); inputSocket->relinkConnections(rgbToYUV->getInputSocket(0), 0, graph); addLink(graph, rgbToYUV->getOutputSocket(), operationSet->getInputSocket(0)); diff --git a/source/blender/compositor/nodes/COM_MapUVNode.cpp b/source/blender/compositor/nodes/COM_MapUVNode.cpp index e0e7e2594ed..447b8239a93 100644 --- a/source/blender/compositor/nodes/COM_MapUVNode.cpp +++ b/source/blender/compositor/nodes/COM_MapUVNode.cpp @@ -23,11 +23,12 @@ #include "COM_MapUVOperation.h" #include "COM_ExecutionSystem.h" -MapUVNode::MapUVNode(bNode *editorNode): Node(editorNode) +MapUVNode::MapUVNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void MapUVNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void MapUVNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { MapUVOperation *operation = new MapUVOperation(); diff --git a/source/blender/compositor/nodes/COM_MapValueNode.cpp b/source/blender/compositor/nodes/COM_MapValueNode.cpp index f56662b1d64..ba2fc804f42 100644 --- a/source/blender/compositor/nodes/COM_MapValueNode.cpp +++ b/source/blender/compositor/nodes/COM_MapValueNode.cpp @@ -25,15 +25,16 @@ #include "COM_MapValueOperation.h" #include "COM_ExecutionSystem.h" -MapValueNode::MapValueNode(bNode *editorNode): Node(editorNode) +MapValueNode::MapValueNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void MapValueNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void MapValueNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *colourSocket = this->getInputSocket(0); OutputSocket *valueSocket = this->getOutputSocket(0); - TexMapping *storage = (TexMapping*)this->getbNode()->storage; + TexMapping *storage = (TexMapping *)this->getbNode()->storage; MapValueOperation *convertProg = new MapValueOperation(); convertProg->setSettings(storage); colourSocket->relinkConnections(convertProg->getInputSocket(0), 0, graph); diff --git a/source/blender/compositor/nodes/COM_MaskNode.cpp b/source/blender/compositor/nodes/COM_MaskNode.cpp index 4371a848a3d..ed07e41a649 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.cpp +++ b/source/blender/compositor/nodes/COM_MaskNode.cpp @@ -29,11 +29,12 @@ extern "C" { #include "DNA_mask_types.h" } -MaskNode::MaskNode(bNode *editorNode): Node(editorNode) +MaskNode::MaskNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { const RenderData *data = &context->getScene()->r; @@ -54,7 +55,7 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * c operation->setMask(mask); operation->setFramenumber(context->getFramenumber()); - operation->setSmooth((bool)editorNode->custom1); + operation->setSmooth((bool)editorNode->custom1); graph->addOperation(operation); } diff --git a/source/blender/compositor/nodes/COM_MathNode.cpp b/source/blender/compositor/nodes/COM_MathNode.cpp index eabd0481e38..6e9b49253e7 100644 --- a/source/blender/compositor/nodes/COM_MathNode.cpp +++ b/source/blender/compositor/nodes/COM_MathNode.cpp @@ -24,61 +24,61 @@ #include "COM_MathBaseOperation.h" #include "COM_ExecutionSystem.h" -void MathNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void MathNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { - MathBaseOperation *operation=NULL; + MathBaseOperation *operation = NULL; switch (this->getbNode()->custom1) { - case 0: /* Add */ + case 0: /* Add */ operation = new MathAddOperation(); break; - case 1: /* Subtract */ + case 1: /* Subtract */ operation = new MathSubtractOperation(); break; - case 2: /* Multiply */ + case 2: /* Multiply */ operation = new MathMultiplyOperation(); break; - case 3: /* Divide */ + case 3: /* Divide */ operation = new MathDivideOperation(); break; - case 4: /* Sine */ + case 4: /* Sine */ operation = new MathSineOperation(); break; - case 5: /* Cosine */ + case 5: /* Cosine */ operation = new MathCosineOperation(); break; - case 6: /* Tangent */ + case 6: /* Tangent */ operation = new MathTangentOperation(); break; - case 7: /* Arc-Sine */ + case 7: /* Arc-Sine */ operation = new MathArcSineOperation(); break; - case 8: /* Arc-Cosine */ + case 8: /* Arc-Cosine */ operation = new MathArcCosineOperation(); break; - case 9: /* Arc-Tangent */ + case 9: /* Arc-Tangent */ operation = new MathArcTangentOperation(); break; - case 10: /* Power */ + case 10: /* Power */ operation = new MathPowerOperation(); break; - case 11: /* Logarithm */ + case 11: /* Logarithm */ operation = new MathLogarithmOperation(); break; - case 12: /* Minimum */ + case 12: /* Minimum */ operation = new MathMinimumOperation(); break; - case 13: /* Maximum */ + case 13: /* Maximum */ operation = new MathMaximumOperation(); break; - case 14: /* Round */ + case 14: /* Round */ operation = new MathRoundOperation(); break; - case 15: /* Less Than */ + case 15: /* Less Than */ operation = new MathLessThanOperation(); break; - case 16: /* Greater Than */ + case 16: /* Greater Than */ operation = new MathGreaterThanOperation(); break; } diff --git a/source/blender/compositor/nodes/COM_MixNode.cpp b/source/blender/compositor/nodes/COM_MixNode.cpp index 42e32a4e55e..eb62ebd2635 100644 --- a/source/blender/compositor/nodes/COM_MixNode.cpp +++ b/source/blender/compositor/nodes/COM_MixNode.cpp @@ -46,12 +46,12 @@ #include "DNA_material_types.h" // the ramp types -MixNode::MixNode(bNode *editorNode): Node(editorNode) +MixNode::MixNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } - -void MixNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void MixNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *valueSocket = this->getInputSocket(0); InputSocket *color1Socket = this->getInputSocket(1); @@ -62,62 +62,62 @@ void MixNode::convertToOperations(ExecutionSystem *graph, CompositorContext * co MixBaseOperation *convertProg; switch (editorNode->custom1) { - case MA_RAMP_ADD: - convertProg = new MixAddOperation(); - break; - case MA_RAMP_MULT: - convertProg = new MixMultiplyOperation(); - break; - case MA_RAMP_LIGHT: - convertProg = new MixLightenOperation(); - break; - case MA_RAMP_BURN: - convertProg = new MixBurnOperation(); - break; - case MA_RAMP_HUE: - convertProg = new MixHueOperation(); - break; - case MA_RAMP_COLOR: - convertProg = new MixColorOperation(); - break; - case MA_RAMP_SOFT: - convertProg = new MixSoftLightOperation(); - break; - case MA_RAMP_SCREEN: - convertProg = new MixScreenOperation(); - break; - case MA_RAMP_LINEAR: - convertProg = new MixLinearLightOperation(); - break; - case MA_RAMP_DIFF: - convertProg = new MixDifferenceOperation(); - break; - case MA_RAMP_SAT: - convertProg = new MixSaturationOperation(); - break; - case MA_RAMP_DIV: - convertProg = new MixDivideOperation(); - break; - case MA_RAMP_SUB: - convertProg = new MixSubtractOperation(); - break; - case MA_RAMP_DARK: - convertProg = new MixDarkenOperation(); - break; - case MA_RAMP_OVERLAY: - convertProg = new MixOverlayOperation(); - break; - case MA_RAMP_VAL: - convertProg = new MixValueOperation(); - break; - case MA_RAMP_DODGE: - convertProg = new MixDodgeOperation(); - break; - - case MA_RAMP_BLEND: - default: - convertProg = new MixBlendOperation(); - break; + case MA_RAMP_ADD: + convertProg = new MixAddOperation(); + break; + case MA_RAMP_MULT: + convertProg = new MixMultiplyOperation(); + break; + case MA_RAMP_LIGHT: + convertProg = new MixLightenOperation(); + break; + case MA_RAMP_BURN: + convertProg = new MixBurnOperation(); + break; + case MA_RAMP_HUE: + convertProg = new MixHueOperation(); + break; + case MA_RAMP_COLOR: + convertProg = new MixColorOperation(); + break; + case MA_RAMP_SOFT: + convertProg = new MixSoftLightOperation(); + break; + case MA_RAMP_SCREEN: + convertProg = new MixScreenOperation(); + break; + case MA_RAMP_LINEAR: + convertProg = new MixLinearLightOperation(); + break; + case MA_RAMP_DIFF: + convertProg = new MixDifferenceOperation(); + break; + case MA_RAMP_SAT: + convertProg = new MixSaturationOperation(); + break; + case MA_RAMP_DIV: + convertProg = new MixDivideOperation(); + break; + case MA_RAMP_SUB: + convertProg = new MixSubtractOperation(); + break; + case MA_RAMP_DARK: + convertProg = new MixDarkenOperation(); + break; + case MA_RAMP_OVERLAY: + convertProg = new MixOverlayOperation(); + break; + case MA_RAMP_VAL: + convertProg = new MixValueOperation(); + break; + case MA_RAMP_DODGE: + convertProg = new MixDodgeOperation(); + break; + + case MA_RAMP_BLEND: + default: + convertProg = new MixBlendOperation(); + break; } convertProg->setUseValueAlphaMultiply(this->getbNode()->custom2); diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.cpp b/source/blender/compositor/nodes/COM_MovieClipNode.cpp index 083d1bf42b9..89bd0e8549e 100644 --- a/source/blender/compositor/nodes/COM_MovieClipNode.cpp +++ b/source/blender/compositor/nodes/COM_MovieClipNode.cpp @@ -33,11 +33,12 @@ extern "C" { #include "IMB_imbuf.h" } -MovieClipNode::MovieClipNode(bNode *editorNode): Node(editorNode) +MovieClipNode::MovieClipNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { OutputSocket *outputMovieClip = this->getOutputSocket(0); OutputSocket *offsetXMovieClip = this->getOutputSocket(1); @@ -46,10 +47,10 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex OutputSocket *angleMovieClip = this->getOutputSocket(4); bNode *editorNode = this->getbNode(); - MovieClip *movieClip = (MovieClip*)editorNode->id; - MovieClipUser *movieClipUser = (MovieClipUser*)editorNode->storage; + MovieClip *movieClip = (MovieClip *)editorNode->id; + MovieClipUser *movieClipUser = (MovieClipUser *)editorNode->storage; - ImBuf * ibuf = NULL; + ImBuf *ibuf = NULL; if (movieClip) { ibuf = BKE_movieclip_get_ibuf(movieClip, movieClipUser); } @@ -90,7 +91,7 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex angle = 0.0f; if (ibuf) { - if (stab->flag&TRACKING_2D_STABILIZATION) { + if (stab->flag & TRACKING_2D_STABILIZATION) { int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(movieClip, context->getFramenumber()); BKE_tracking_stabilization_data_get(&movieClip->tracking, clip_framenr, ibuf->x, ibuf->y, loc, &scale, &angle); @@ -98,25 +99,25 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex } if (offsetXMovieClip->isConnected()) { - SetValueOperation * operationSetValue = new SetValueOperation(); + SetValueOperation *operationSetValue = new SetValueOperation(); operationSetValue->setValue(loc[0]); offsetXMovieClip->relinkConnections(operationSetValue->getOutputSocket()); graph->addOperation(operationSetValue); } if (offsetYMovieClip->isConnected()) { - SetValueOperation * operationSetValue = new SetValueOperation(); + SetValueOperation *operationSetValue = new SetValueOperation(); operationSetValue->setValue(loc[1]); offsetYMovieClip->relinkConnections(operationSetValue->getOutputSocket()); graph->addOperation(operationSetValue); } if (scaleMovieClip->isConnected()) { - SetValueOperation * operationSetValue = new SetValueOperation(); + SetValueOperation *operationSetValue = new SetValueOperation(); operationSetValue->setValue(scale); scaleMovieClip->relinkConnections(operationSetValue->getOutputSocket()); graph->addOperation(operationSetValue); } if (angleMovieClip->isConnected()) { - SetValueOperation * operationSetValue = new SetValueOperation(); + SetValueOperation *operationSetValue = new SetValueOperation(); operationSetValue->setValue(angle); angleMovieClip->relinkConnections(operationSetValue->getOutputSocket()); graph->addOperation(operationSetValue); diff --git a/source/blender/compositor/nodes/COM_MovieDistortionNode.cpp b/source/blender/compositor/nodes/COM_MovieDistortionNode.cpp index bdf4c53fa72..c29bc27cd80 100644 --- a/source/blender/compositor/nodes/COM_MovieDistortionNode.cpp +++ b/source/blender/compositor/nodes/COM_MovieDistortionNode.cpp @@ -28,16 +28,17 @@ MovieDistortionNode::MovieDistortionNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void MovieDistortionNode::convertToOperations(ExecutionSystem *system, CompositorContext * context) +void MovieDistortionNode::convertToOperations(ExecutionSystem *system, CompositorContext *context) { InputSocket *inputSocket = this->getInputSocket(0); OutputSocket *outputSocket = this->getOutputSocket(0); bNode *bnode = this->getbNode(); - MovieClip * clip = (MovieClip*)bnode->id; + MovieClip *clip = (MovieClip *)bnode->id; - MovieDistortionOperation * operation = new MovieDistortionOperation(bnode->custom1 == 1); + MovieDistortionOperation *operation = new MovieDistortionOperation(bnode->custom1 == 1); operation->setMovieClip(clip); operation->setFramenumber(context->getFramenumber()); diff --git a/source/blender/compositor/nodes/COM_MuteNode.cpp b/source/blender/compositor/nodes/COM_MuteNode.cpp index 57b7871318b..ccf7721b989 100644 --- a/source/blender/compositor/nodes/COM_MuteNode.cpp +++ b/source/blender/compositor/nodes/COM_MuteNode.cpp @@ -27,14 +27,15 @@ #include "COM_SetVectorOperation.h" #include "COM_SetColorOperation.h" -MuteNode::MuteNode(bNode *editorNode): Node(editorNode) +MuteNode::MuteNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void MuteNode::reconnect(ExecutionSystem * graph, OutputSocket * output) +void MuteNode::reconnect(ExecutionSystem *graph, OutputSocket *output) { - vector &inputsockets = this->getInputSockets(); - for (unsigned int index = 0; index < inputsockets.size() ; index ++) { + vector &inputsockets = this->getInputSockets(); + for (unsigned int index = 0; index < inputsockets.size(); index++) { InputSocket *input = inputsockets[index]; if (input->getDataType() == output->getDataType()) { if (input->isConnected()) { @@ -82,12 +83,12 @@ void MuteNode::reconnect(ExecutionSystem * graph, OutputSocket * output) output->clearConnections(); } -void MuteNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void MuteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { - vector &outputsockets = this->getOutputSockets(); + vector &outputsockets = this->getOutputSockets(); - for (unsigned int index = 0 ; index < outputsockets.size() ; index ++) { - OutputSocket * output = outputsockets[index]; + for (unsigned int index = 0; index < outputsockets.size(); index++) { + OutputSocket *output = outputsockets[index]; if (output->isConnected()) { reconnect(graph, output); } diff --git a/source/blender/compositor/nodes/COM_NormalNode.cpp b/source/blender/compositor/nodes/COM_NormalNode.cpp index 0b1faafe302..e00e71e50e9 100644 --- a/source/blender/compositor/nodes/COM_NormalNode.cpp +++ b/source/blender/compositor/nodes/COM_NormalNode.cpp @@ -26,19 +26,21 @@ #include "COM_DotproductOperation.h" #include "COM_SetVectorOperation.h" -NormalNode::NormalNode(bNode *editorNode): Node(editorNode) -{} +NormalNode::NormalNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} -void NormalNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void NormalNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *inputSocket = this->getInputSocket(0); OutputSocket *outputSocket = this->getOutputSocket(0); OutputSocket *outputSocketDotproduct = this->getOutputSocket(1); bNode *editorNode = this->getbNode(); - SetVectorOperation * operationSet = new SetVectorOperation(); - bNodeSocket * insock = (bNodeSocket*)editorNode->outputs.first; - bNodeSocketValueVector *dval = (bNodeSocketValueVector*)insock->default_value; + SetVectorOperation *operationSet = new SetVectorOperation(); + bNodeSocket *insock = (bNodeSocket *)editorNode->outputs.first; + bNodeSocketValueVector *dval = (bNodeSocketValueVector *)insock->default_value; operationSet->setX(dval->value[0]); operationSet->setY(dval->value[1]); operationSet->setZ(dval->value[2]); diff --git a/source/blender/compositor/nodes/COM_NormalizeNode.cpp b/source/blender/compositor/nodes/COM_NormalizeNode.cpp index 11173b3a73f..7c1c695f8b6 100644 --- a/source/blender/compositor/nodes/COM_NormalizeNode.cpp +++ b/source/blender/compositor/nodes/COM_NormalizeNode.cpp @@ -23,11 +23,12 @@ #include "COM_NormalizeOperation.h" #include "COM_ExecutionSystem.h" -NormalizeNode::NormalizeNode(bNode *editorNode): Node(editorNode) +NormalizeNode::NormalizeNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void NormalizeNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void NormalizeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { NormalizeOperation *operation = new NormalizeOperation(); diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cpp b/source/blender/compositor/nodes/COM_OutputFileNode.cpp index e5deb595d78..402529b9186 100644 --- a/source/blender/compositor/nodes/COM_OutputFileNode.cpp +++ b/source/blender/compositor/nodes/COM_OutputFileNode.cpp @@ -27,13 +27,14 @@ #include "BLI_path_util.h" #include "BKE_utildefines.h" -OutputFileNode::OutputFileNode(bNode *editorNode): Node(editorNode) +OutputFileNode::OutputFileNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void OutputFileNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void OutputFileNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { - NodeImageMultiFile *storage = (NodeImageMultiFile*)this->getbNode()->storage; + NodeImageMultiFile *storage = (NodeImageMultiFile *)this->getbNode()->storage; if (!context->isRendering()) { /* XXX TODO as in previous implementation? @@ -41,14 +42,14 @@ void OutputFileNode::convertToOperations(ExecutionSystem *graph, CompositorConte */ } - if (storage->format.imtype==R_IMF_IMTYPE_MULTILAYER) { + if (storage->format.imtype == R_IMF_IMTYPE_MULTILAYER) { /* single output operation for the multilayer file */ OutputOpenExrMultiLayerOperation *outputOperation = new OutputOpenExrMultiLayerOperation( - context->getScene(), context->getbNodeTree(), storage->base_path, storage->format.exr_codec); + context->getScene(), context->getbNodeTree(), storage->base_path, storage->format.exr_codec); int num_inputs = getNumberOfInputSockets(); bool hasConnections = false; - for (int i=0; i < num_inputs; ++i) { + for (int i = 0; i < num_inputs; ++i) { InputSocket *input = getInputSocket(i); if (input->isConnected()) { hasConnections = true; @@ -63,10 +64,10 @@ void OutputFileNode::convertToOperations(ExecutionSystem *graph, CompositorConte graph->addOperation(outputOperation); } - else { /* single layer format */ + else { /* single layer format */ int num_inputs = getNumberOfInputSockets(); bool previewAdded = false; - for (int i=0; i < num_inputs; ++i) { + for (int i = 0; i < num_inputs; ++i) { InputSocket *input = getInputSocket(i); if (input->isConnected()) { NodeImageMultiFileSocket *sockdata = (NodeImageMultiFileSocket *)input->getbNodeSocket()->storage; @@ -77,7 +78,7 @@ void OutputFileNode::convertToOperations(ExecutionSystem *graph, CompositorConte BLI_join_dirfile(path, FILE_MAX, storage->base_path, sockdata->path); OutputSingleLayerOperation *outputOperation = new OutputSingleLayerOperation( - context->getScene(), context->getbNodeTree(), input->getDataType(), format, path); + context->getScene(), context->getbNodeTree(), input->getDataType(), format, path); input->relinkConnections(outputOperation->getInputSocket(0)); graph->addOperation(outputOperation); if (!previewAdded) { diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp index 8216205b925..95e759fde24 100644 --- a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp +++ b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp @@ -47,14 +47,15 @@ #include "COM_ScaleOperation.h" #include "COM_SetValueOperation.h" -RenderLayersNode::RenderLayersNode(bNode *editorNode): Node(editorNode) +RenderLayersNode::RenderLayersNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void RenderLayersNode::testSocketConnection(ExecutionSystem *system, int outputSocketNumber, RenderLayersBaseProg * operation) +void RenderLayersNode::testSocketConnection(ExecutionSystem *system, int outputSocketNumber, RenderLayersBaseProg *operation) { OutputSocket *outputSocket = this->getOutputSocket(outputSocketNumber); - Scene *scene = (Scene*)this->getbNode()->id; + Scene *scene = (Scene *)this->getbNode()->id; short layerId = this->getbNode()->custom1; if (outputSocket->isConnected()) { @@ -79,7 +80,7 @@ void RenderLayersNode::testSocketConnection(ExecutionSystem *system, int outputS } } -void RenderLayersNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void RenderLayersNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { testSocketConnection(graph, 0, new RenderLayersColourProg()); testSocketConnection(graph, 1, new RenderLayersAlphaProg()); diff --git a/source/blender/compositor/nodes/COM_RotateNode.cpp b/source/blender/compositor/nodes/COM_RotateNode.cpp index 48acc567739..bb058d18b80 100644 --- a/source/blender/compositor/nodes/COM_RotateNode.cpp +++ b/source/blender/compositor/nodes/COM_RotateNode.cpp @@ -28,9 +28,10 @@ RotateNode::RotateNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void RotateNode::convertToOperations(ExecutionSystem *system, CompositorContext * context) +void RotateNode::convertToOperations(ExecutionSystem *system, CompositorContext *context) { InputSocket *inputSocket = this->getInputSocket(0); InputSocket *inputDegreeSocket = this->getInputSocket(1); @@ -39,15 +40,15 @@ void RotateNode::convertToOperations(ExecutionSystem *system, CompositorContext SetSamplerOperation *sampler = new SetSamplerOperation(); switch (this->getbNode()->custom1) { - case 0: - sampler->setSampler(COM_PS_NEAREST); - break ; - case 1: - sampler->setSampler(COM_PS_BILINEAR); - break; - case 2: - sampler->setSampler(COM_PS_BICUBIC); - break; + case 0: + sampler->setSampler(COM_PS_NEAREST); + break; + case 1: + sampler->setSampler(COM_PS_BILINEAR); + break; + case 2: + sampler->setSampler(COM_PS_BICUBIC); + break; } diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp index 870ed8f2484..17b521c589d 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.cpp +++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp @@ -29,6 +29,7 @@ ScaleNode::ScaleNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_SeparateHSVANode.cpp b/source/blender/compositor/nodes/COM_SeparateHSVANode.cpp index cfce56a080a..4f93b226fa1 100644 --- a/source/blender/compositor/nodes/COM_SeparateHSVANode.cpp +++ b/source/blender/compositor/nodes/COM_SeparateHSVANode.cpp @@ -27,11 +27,12 @@ #include "COM_SetValueOperation.h" #include "COM_ConvertRGBToHSVOperation.h" -SeparateHSVANode::SeparateHSVANode(bNode *editorNode): SeparateRGBANode(editorNode) +SeparateHSVANode::SeparateHSVANode(bNode *editorNode) : SeparateRGBANode(editorNode) { + /* pass */ } -void SeparateHSVANode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void SeparateHSVANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { ConvertRGBToHSVOperation *operation = new ConvertRGBToHSVOperation(); InputSocket *inputSocket = this->getInputSocket(0); diff --git a/source/blender/compositor/nodes/COM_SeparateRGBANode.cpp b/source/blender/compositor/nodes/COM_SeparateRGBANode.cpp index dd154fe604d..67ac6ffc388 100644 --- a/source/blender/compositor/nodes/COM_SeparateRGBANode.cpp +++ b/source/blender/compositor/nodes/COM_SeparateRGBANode.cpp @@ -28,12 +28,13 @@ #include "DNA_material_types.h" // the ramp types -SeparateRGBANode::SeparateRGBANode(bNode *editorNode): Node(editorNode) +SeparateRGBANode::SeparateRGBANode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void SeparateRGBANode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void SeparateRGBANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *imageSocket = this->getInputSocket(0); OutputSocket *outputRSocket = this->getOutputSocket(0); diff --git a/source/blender/compositor/nodes/COM_SeparateYCCANode.cpp b/source/blender/compositor/nodes/COM_SeparateYCCANode.cpp index 68d20235de7..154e2bcd550 100644 --- a/source/blender/compositor/nodes/COM_SeparateYCCANode.cpp +++ b/source/blender/compositor/nodes/COM_SeparateYCCANode.cpp @@ -25,8 +25,9 @@ #include "COM_SetValueOperation.h" #include "COM_ConvertRGBToYCCOperation.h" -SeparateYCCANode::SeparateYCCANode(bNode *editorNode): SeparateRGBANode(editorNode) +SeparateYCCANode::SeparateYCCANode(bNode *editorNode) : SeparateRGBANode(editorNode) { + /* pass */ } void SeparateYCCANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_SeparateYUVANode.cpp b/source/blender/compositor/nodes/COM_SeparateYUVANode.cpp index 650e5d1340b..8a647b7f849 100644 --- a/source/blender/compositor/nodes/COM_SeparateYUVANode.cpp +++ b/source/blender/compositor/nodes/COM_SeparateYUVANode.cpp @@ -25,8 +25,9 @@ #include "COM_SetValueOperation.h" #include "COM_ConvertRGBToYUVOperation.h" -SeparateYUVANode::SeparateYUVANode(bNode *editorNode): SeparateRGBANode(editorNode) +SeparateYUVANode::SeparateYUVANode(bNode *editorNode) : SeparateRGBANode(editorNode) { + /* pass */ } void SeparateYUVANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_SetAlphaNode.cpp b/source/blender/compositor/nodes/COM_SetAlphaNode.cpp index 1d09b81c4d2..709dc75b502 100644 --- a/source/blender/compositor/nodes/COM_SetAlphaNode.cpp +++ b/source/blender/compositor/nodes/COM_SetAlphaNode.cpp @@ -24,7 +24,7 @@ #include "COM_SetAlphaOperation.h" #include "COM_ExecutionSystem.h" -void SetAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void SetAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { SetAlphaOperation *operation = new SetAlphaOperation(); diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp index cdb844cad54..bfb32a96156 100644 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp +++ b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp @@ -28,7 +28,7 @@ #include "COM_SetVectorOperation.h" #include "COM_SetColorOperation.h" -SocketProxyNode::SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput): Node(editorNode, false) +SocketProxyNode::SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput) : Node(editorNode, false) { DataType dt; @@ -43,10 +43,10 @@ SocketProxyNode::SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bN this->addOutputSocket(dt, editorOutput); } -void SocketProxyNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void SocketProxyNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { - OutputSocket * outputsocket = this->getOutputSocket(0); - InputSocket * inputsocket = this->getInputSocket(0); + OutputSocket *outputsocket = this->getOutputSocket(0); + InputSocket *inputsocket = this->getInputSocket(0); if (outputsocket->isConnected()) { if (inputsocket->isConnected()) { SocketProxyOperation *operation = new SocketProxyOperation(this->getOutputSocket()->getDataType()); @@ -57,33 +57,33 @@ void SocketProxyNode::convertToOperations(ExecutionSystem *graph, CompositorCont else { /* If input is not connected, add a constant value operation instead */ switch (outputsocket->getDataType()) { - case COM_DT_VALUE: - { - SetValueOperation *operation = new SetValueOperation(); - bNodeSocketValueFloat *dval = (bNodeSocketValueFloat*)inputsocket->getbNodeSocket()->default_value; - operation->setValue(dval->value); - outputsocket->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - break; - } - case COM_DT_COLOR: - { - SetColorOperation *operation = new SetColorOperation(); - bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA*)inputsocket->getbNodeSocket()->default_value; - operation->setChannels(dval->value); - outputsocket->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - break; - } - case COM_DT_VECTOR: - { - SetVectorOperation *operation = new SetVectorOperation(); - bNodeSocketValueVector *dval = (bNodeSocketValueVector*)inputsocket->getbNodeSocket()->default_value; - operation->setVector(dval->value); - outputsocket->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - break; - } + case COM_DT_VALUE: + { + SetValueOperation *operation = new SetValueOperation(); + bNodeSocketValueFloat *dval = (bNodeSocketValueFloat *)inputsocket->getbNodeSocket()->default_value; + operation->setValue(dval->value); + outputsocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + break; + } + case COM_DT_COLOR: + { + SetColorOperation *operation = new SetColorOperation(); + bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA *)inputsocket->getbNodeSocket()->default_value; + operation->setChannels(dval->value); + outputsocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + break; + } + case COM_DT_VECTOR: + { + SetVectorOperation *operation = new SetVectorOperation(); + bNodeSocketValueVector *dval = (bNodeSocketValueVector *)inputsocket->getbNodeSocket()->default_value; + operation->setVector(dval->value); + outputsocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + break; + } } } } diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp index 7e8a218cbc1..22a00410384 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp @@ -28,6 +28,7 @@ SplitViewerNode::SplitViewerNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_Stabilize2dNode.cpp b/source/blender/compositor/nodes/COM_Stabilize2dNode.cpp index 7234e71a43c..85b8695263f 100644 --- a/source/blender/compositor/nodes/COM_Stabilize2dNode.cpp +++ b/source/blender/compositor/nodes/COM_Stabilize2dNode.cpp @@ -32,18 +32,19 @@ extern "C" { #include "BKE_tracking.h" } -Stabilize2dNode::Stabilize2dNode(bNode *editorNode): Node(editorNode) +Stabilize2dNode::Stabilize2dNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void Stabilize2dNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void Stabilize2dNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *imageInput = this->getInputSocket(0); MovieClip *clip = (MovieClip *)getbNode()->id; - ScaleOperation * scaleOperation = new ScaleOperation(); - RotateOperation * rotateOperation = new RotateOperation(); - TranslateOperation * translateOperation = new TranslateOperation(); + ScaleOperation *scaleOperation = new ScaleOperation(); + RotateOperation *rotateOperation = new RotateOperation(); + TranslateOperation *translateOperation = new TranslateOperation(); MovieClipAttributeOperation *scaleAttribute = new MovieClipAttributeOperation(); MovieClipAttributeOperation *angleAttribute = new MovieClipAttributeOperation(); MovieClipAttributeOperation *xAttribute = new MovieClipAttributeOperation(); diff --git a/source/blender/compositor/nodes/COM_SwitchNode.cpp b/source/blender/compositor/nodes/COM_SwitchNode.cpp index bb1a9c119f8..2a4616fcd3e 100644 --- a/source/blender/compositor/nodes/COM_SwitchNode.cpp +++ b/source/blender/compositor/nodes/COM_SwitchNode.cpp @@ -24,14 +24,15 @@ #include "COM_ExecutionSystem.h" #include "COM_SocketProxyOperation.h" -SwitchNode::SwitchNode(bNode *editorNode): Node(editorNode) +SwitchNode::SwitchNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void SwitchNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void SwitchNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { - SocketProxyOperation * operation = new SocketProxyOperation(COM_DT_COLOR); + SocketProxyOperation *operation = new SocketProxyOperation(COM_DT_COLOR); int switchFrame = this->getbNode()->custom1; if (!switchFrame) { diff --git a/source/blender/compositor/nodes/COM_TextureNode.cpp b/source/blender/compositor/nodes/COM_TextureNode.cpp index fe8a8e2250e..a3526e3c1a1 100644 --- a/source/blender/compositor/nodes/COM_TextureNode.cpp +++ b/source/blender/compositor/nodes/COM_TextureNode.cpp @@ -24,14 +24,15 @@ #include "COM_ExecutionSystem.h" #include "COM_TextureOperation.h" -TextureNode::TextureNode(bNode *editorNode): Node(editorNode) +TextureNode::TextureNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void TextureNode::convertToOperations(ExecutionSystem *system, CompositorContext * context) +void TextureNode::convertToOperations(ExecutionSystem *system, CompositorContext *context) { bNode *editorNode = this->getbNode(); - Tex *texture = (Tex*)editorNode->id; + Tex *texture = (Tex *)editorNode->id; TextureOperation *operation = new TextureOperation(); this->getOutputSocket(1)->relinkConnections(operation->getOutputSocket()); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system); diff --git a/source/blender/compositor/nodes/COM_TimeNode.cpp b/source/blender/compositor/nodes/COM_TimeNode.cpp index b3ce27a3829..8e155e375e1 100644 --- a/source/blender/compositor/nodes/COM_TimeNode.cpp +++ b/source/blender/compositor/nodes/COM_TimeNode.cpp @@ -29,11 +29,12 @@ extern "C" { } #include "BLI_utildefines.h" -TimeNode::TimeNode(bNode *editorNode): Node(editorNode) +TimeNode::TimeNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void TimeNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void TimeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { SetValueOperation *operation = new SetValueOperation(); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); @@ -50,10 +51,10 @@ void TimeNode::convertToOperations(ExecutionSystem *graph, CompositorContext * c fac = 1.0f; } else if (node->custom1 < node->custom2) { - fac = (context->getFramenumber() - node->custom1)/(float)(node->custom2-node->custom1); + fac = (context->getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1); } - fac = curvemapping_evaluateF((CurveMapping*)node->storage, 0, fac); + fac = curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac); operation->setValue(CLAMPIS(fac, 0.0f, 1.0f)); graph->addOperation(operation); } diff --git a/source/blender/compositor/nodes/COM_TonemapNode.cpp b/source/blender/compositor/nodes/COM_TonemapNode.cpp index 80f02f3edbb..a1f33ed464b 100644 --- a/source/blender/compositor/nodes/COM_TonemapNode.cpp +++ b/source/blender/compositor/nodes/COM_TonemapNode.cpp @@ -25,14 +25,15 @@ #include "COM_TonemapOperation.h" #include "COM_ExecutionSystem.h" -TonemapNode::TonemapNode(bNode *editorNode): Node(editorNode) +TonemapNode::TonemapNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void TonemapNode::convertToOperations(ExecutionSystem *system, CompositorContext * context) +void TonemapNode::convertToOperations(ExecutionSystem *system, CompositorContext *context) { - NodeTonemap *data = (NodeTonemap*)this->getbNode()->storage; - TonemapOperation *operation = data->type==1?new PhotoreceptorTonemapOperation():new TonemapOperation(); + NodeTonemap *data = (NodeTonemap *)this->getbNode()->storage; + TonemapOperation *operation = data->type == 1 ? new PhotoreceptorTonemapOperation() : new TonemapOperation(); operation->setData(data); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system); diff --git a/source/blender/compositor/nodes/COM_TransformNode.cpp b/source/blender/compositor/nodes/COM_TransformNode.cpp index da3e85036a5..ff6e276d1ac 100644 --- a/source/blender/compositor/nodes/COM_TransformNode.cpp +++ b/source/blender/compositor/nodes/COM_TransformNode.cpp @@ -28,11 +28,12 @@ #include "COM_SetValueOperation.h" #include "COM_SetSamplerOperation.h" -TransformNode::TransformNode(bNode *editorNode): Node(editorNode) +TransformNode::TransformNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void TransformNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void TransformNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *imageInput = this->getInputSocket(0); InputSocket *xInput = this->getInputSocket(1); @@ -40,21 +41,21 @@ void TransformNode::convertToOperations(ExecutionSystem *graph, CompositorContex InputSocket *angleInput = this->getInputSocket(3); InputSocket *scaleInput = this->getInputSocket(4); - ScaleOperation * scaleOperation = new ScaleOperation(); - RotateOperation * rotateOperation = new RotateOperation(); - TranslateOperation * translateOperation = new TranslateOperation(); + ScaleOperation *scaleOperation = new ScaleOperation(); + RotateOperation *rotateOperation = new RotateOperation(); + TranslateOperation *translateOperation = new TranslateOperation(); SetSamplerOperation *sampler = new SetSamplerOperation(); switch (this->getbNode()->custom1) { - case 0: - sampler->setSampler(COM_PS_NEAREST); - break ; - case 1: - sampler->setSampler(COM_PS_BILINEAR); - break; - case 2: - sampler->setSampler(COM_PS_BICUBIC); - break; + case 0: + sampler->setSampler(COM_PS_NEAREST); + break; + case 1: + sampler->setSampler(COM_PS_BILINEAR); + break; + case 2: + sampler->setSampler(COM_PS_BICUBIC); + break; } imageInput->relinkConnections(sampler->getInputSocket(0), 0, graph); diff --git a/source/blender/compositor/nodes/COM_TranslateNode.cpp b/source/blender/compositor/nodes/COM_TranslateNode.cpp index 407c6da4e4d..c805f8f8baa 100644 --- a/source/blender/compositor/nodes/COM_TranslateNode.cpp +++ b/source/blender/compositor/nodes/COM_TranslateNode.cpp @@ -27,9 +27,10 @@ TranslateNode::TranslateNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void TranslateNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void TranslateNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *inputSocket = this->getInputSocket(0); InputSocket *inputXSocket = this->getInputSocket(1); diff --git a/source/blender/compositor/nodes/COM_ValueNode.cpp b/source/blender/compositor/nodes/COM_ValueNode.cpp index 39245e75a2f..89b0602f8b0 100644 --- a/source/blender/compositor/nodes/COM_ValueNode.cpp +++ b/source/blender/compositor/nodes/COM_ValueNode.cpp @@ -25,15 +25,16 @@ #include "COM_SetValueOperation.h" #include "COM_ExecutionSystem.h" -ValueNode::ValueNode(bNode *editorNode): Node(editorNode) +ValueNode::ValueNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void ValueNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void ValueNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { SetValueOperation *operation = new SetValueOperation(); bNodeSocket *socket = this->getEditorOutputSocket(0); - bNodeSocketValueFloat *dval = (bNodeSocketValueFloat*)socket->default_value; + bNodeSocketValueFloat *dval = (bNodeSocketValueFloat *)socket->default_value; this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); operation->setValue(dval->value); graph->addOperation(operation); diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.cpp b/source/blender/compositor/nodes/COM_VectorBlurNode.cpp index 78b9065b4da..5ef384a9984 100644 --- a/source/blender/compositor/nodes/COM_VectorBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_VectorBlurNode.cpp @@ -26,6 +26,7 @@ VectorBlurNode::VectorBlurNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } void VectorBlurNode::convertToOperations(ExecutionSystem *system, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_VectorCurveNode.cpp b/source/blender/compositor/nodes/COM_VectorCurveNode.cpp index 908e1a19f16..ee32c3b77a3 100644 --- a/source/blender/compositor/nodes/COM_VectorCurveNode.cpp +++ b/source/blender/compositor/nodes/COM_VectorCurveNode.cpp @@ -25,18 +25,19 @@ #include "COM_VectorCurveOperation.h" #include "COM_ExecutionSystem.h" -VectorCurveNode::VectorCurveNode(bNode *editorNode): Node(editorNode) +VectorCurveNode::VectorCurveNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } -void VectorCurveNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +void VectorCurveNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { VectorCurveOperation *operation = new VectorCurveOperation(); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); - operation->setCurveMapping((CurveMapping*)this->getbNode()->storage); + operation->setCurveMapping((CurveMapping *)this->getbNode()->storage); graph->addOperation(operation); } diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp index a7974efe954..309568c3aec 100644 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp @@ -28,7 +28,9 @@ ViewLevelsNode::ViewLevelsNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } + void ViewLevelsNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { InputSocket *input = this->getInputSocket(0); diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp index 79c76f2e89e..9228fdbef85 100644 --- a/source/blender/compositor/nodes/COM_ViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp @@ -28,6 +28,7 @@ ViewerNode::ViewerNode(bNode *editorNode) : Node(editorNode) { + /* pass */ } void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.cpp b/source/blender/compositor/nodes/COM_ZCombineNode.cpp index 2495d1a5ab2..f48fca72c05 100644 --- a/source/blender/compositor/nodes/COM_ZCombineNode.cpp +++ b/source/blender/compositor/nodes/COM_ZCombineNode.cpp @@ -30,10 +30,10 @@ #include "DNA_material_types.h" // the ramp types -void ZCombineNode::convertToOperations(ExecutionSystem *system, CompositorContext * context) +void ZCombineNode::convertToOperations(ExecutionSystem *system, CompositorContext *context) { if (this->getOutputSocket(0)->isConnected()) { - ZCombineOperation * operation = NULL; + ZCombineOperation *operation = NULL; if (this->getbNode()->custom1) { operation = new ZCombineAlphaOperation(); } @@ -48,7 +48,7 @@ void ZCombineNode::convertToOperations(ExecutionSystem *system, CompositorContex this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); system->addOperation(operation); if (this->getOutputSocket(1)->isConnected()) { - MathMinimumOperation * zoperation = new MathMinimumOperation(); + MathMinimumOperation *zoperation = new MathMinimumOperation(); addLink(system, operation->getInputSocket(1)->getConnection()->getFromSocket(), zoperation->getInputSocket(0)); addLink(system, operation->getInputSocket(3)->getConnection()->getFromSocket(), zoperation->getInputSocket(1)); this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket()); @@ -57,7 +57,7 @@ void ZCombineNode::convertToOperations(ExecutionSystem *system, CompositorContex } else { if (this->getOutputSocket(1)->isConnected()) { - MathMinimumOperation * zoperation = new MathMinimumOperation(); + MathMinimumOperation *zoperation = new MathMinimumOperation(); this->getInputSocket(1)->relinkConnections(zoperation->getInputSocket(0), 1, system); this->getInputSocket(3)->relinkConnections(zoperation->getInputSocket(1), 3, system); this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket()); diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp index 0c9f9b97031..4a0c8b7ab7f 100644 --- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp @@ -24,6 +24,7 @@ AlphaOverKeyOperation::AlphaOverKeyOperation(): MixBaseOperation() { + /* pass */ } void AlphaOverKeyOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp index db67f2e0406..5b36f83af41 100644 --- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp @@ -24,6 +24,7 @@ AlphaOverPremultiplyOperation::AlphaOverPremultiplyOperation(): MixBaseOperation() { + /* pass */ } void AlphaOverPremultiplyOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp index dfe1b6aa329..884c22021df 100644 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp @@ -28,6 +28,7 @@ CalculateStandardDeviationOperation::CalculateStandardDeviationOperation(): CalculateMeanOperation() { + /* pass */ } void CalculateStandardDeviationOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data) diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp index 6edb046a070..18a12a21f26 100644 --- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp @@ -25,6 +25,7 @@ ConvolutionEdgeFilterOperation::ConvolutionEdgeFilterOperation() : ConvolutionFilterOperation() { + /* pass */ } void ConvolutionEdgeFilterOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data) diff --git a/source/blender/compositor/operations/COM_CropOperation.cpp b/source/blender/compositor/operations/COM_CropOperation.cpp index 192ad8d0bda..9b105bb2760 100644 --- a/source/blender/compositor/operations/COM_CropOperation.cpp +++ b/source/blender/compositor/operations/COM_CropOperation.cpp @@ -70,6 +70,7 @@ void CropBaseOperation::deinitExecution() CropOperation::CropOperation() :CropBaseOperation() { + /* pass */ } void CropOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) @@ -87,6 +88,7 @@ void CropOperation::executePixel(float *color, float x, float y, PixelSampler sa CropImageOperation::CropImageOperation() :CropBaseOperation() { + /* pass */ } bool CropImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp index f6d794fe564..306a2d96985 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp @@ -257,6 +257,7 @@ void DilateDistanceOperation::executeOpenCL(cl_context context, cl_program progr // Erode Distance ErodeDistanceOperation::ErodeDistanceOperation() : DilateDistanceOperation() { + /* pass */ } void ErodeDistanceOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) @@ -411,6 +412,7 @@ bool DilateStepOperation::determineDependingAreaOfInterest(rcti *input, ReadBuff // Erode step ErodeStepOperation::ErodeStepOperation() : DilateStepOperation() { + /* pass */ } void *ErodeStepOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) diff --git a/source/blender/compositor/operations/COM_MixAddOperation.cpp b/source/blender/compositor/operations/COM_MixAddOperation.cpp index a4f601ae9e6..2c25635e3bc 100644 --- a/source/blender/compositor/operations/COM_MixAddOperation.cpp +++ b/source/blender/compositor/operations/COM_MixAddOperation.cpp @@ -24,6 +24,7 @@ MixAddOperation::MixAddOperation(): MixBaseOperation() { + /* pass */ } void MixAddOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixBlendOperation.cpp b/source/blender/compositor/operations/COM_MixBlendOperation.cpp index 579f15bcc27..fadac8bbf21 100644 --- a/source/blender/compositor/operations/COM_MixBlendOperation.cpp +++ b/source/blender/compositor/operations/COM_MixBlendOperation.cpp @@ -24,6 +24,7 @@ MixBlendOperation::MixBlendOperation(): MixBaseOperation() { + /* pass */ } void MixBlendOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixBurnOperation.cpp b/source/blender/compositor/operations/COM_MixBurnOperation.cpp index 7cad107c5e9..8231a5d60af 100644 --- a/source/blender/compositor/operations/COM_MixBurnOperation.cpp +++ b/source/blender/compositor/operations/COM_MixBurnOperation.cpp @@ -24,6 +24,7 @@ MixBurnOperation::MixBurnOperation(): MixBaseOperation() { + /* pass */ } void MixBurnOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixColorOperation.cpp b/source/blender/compositor/operations/COM_MixColorOperation.cpp index e14b10b305e..035e764d780 100644 --- a/source/blender/compositor/operations/COM_MixColorOperation.cpp +++ b/source/blender/compositor/operations/COM_MixColorOperation.cpp @@ -28,6 +28,7 @@ extern "C" { MixColorOperation::MixColorOperation(): MixBaseOperation() { + /* pass */ } void MixColorOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixDarkenOperation.cpp b/source/blender/compositor/operations/COM_MixDarkenOperation.cpp index 666db9d8f32..a1da5dce9c8 100644 --- a/source/blender/compositor/operations/COM_MixDarkenOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDarkenOperation.cpp @@ -24,6 +24,7 @@ MixDarkenOperation::MixDarkenOperation(): MixBaseOperation() { + /* pass */ } void MixDarkenOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp b/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp index 497bb9c2bb5..883837f0917 100644 --- a/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp @@ -25,6 +25,7 @@ MixDifferenceOperation::MixDifferenceOperation(): MixBaseOperation() { + /* pass */ } void MixDifferenceOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixDivideOperation.cpp b/source/blender/compositor/operations/COM_MixDivideOperation.cpp index c522fcf225a..706308dccc5 100644 --- a/source/blender/compositor/operations/COM_MixDivideOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDivideOperation.cpp @@ -24,6 +24,7 @@ MixDivideOperation::MixDivideOperation(): MixBaseOperation() { + /* pass */ } void MixDivideOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixDodgeOperation.cpp b/source/blender/compositor/operations/COM_MixDodgeOperation.cpp index 10c04ba376b..619819e6298 100644 --- a/source/blender/compositor/operations/COM_MixDodgeOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDodgeOperation.cpp @@ -24,6 +24,7 @@ MixDodgeOperation::MixDodgeOperation(): MixBaseOperation() { + /* pass */ } void MixDodgeOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixGlareOperation.cpp b/source/blender/compositor/operations/COM_MixGlareOperation.cpp index 229fc1e5313..71b676622c5 100644 --- a/source/blender/compositor/operations/COM_MixGlareOperation.cpp +++ b/source/blender/compositor/operations/COM_MixGlareOperation.cpp @@ -24,6 +24,7 @@ MixGlareOperation::MixGlareOperation(): MixBaseOperation() { + /* pass */ } void MixGlareOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixHueOperation.cpp b/source/blender/compositor/operations/COM_MixHueOperation.cpp index de376f3500c..d97109c244c 100644 --- a/source/blender/compositor/operations/COM_MixHueOperation.cpp +++ b/source/blender/compositor/operations/COM_MixHueOperation.cpp @@ -28,6 +28,7 @@ extern "C" { MixHueOperation::MixHueOperation(): MixBaseOperation() { + /* pass */ } void MixHueOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixLightenOperation.cpp b/source/blender/compositor/operations/COM_MixLightenOperation.cpp index bc3e5090bd8..09d81afcec7 100644 --- a/source/blender/compositor/operations/COM_MixLightenOperation.cpp +++ b/source/blender/compositor/operations/COM_MixLightenOperation.cpp @@ -24,6 +24,7 @@ MixLightenOperation::MixLightenOperation(): MixBaseOperation() { + /* pass */ } void MixLightenOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp b/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp index b68064f0e47..2e3907c15d4 100644 --- a/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp +++ b/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp @@ -24,6 +24,7 @@ MixLinearLightOperation::MixLinearLightOperation(): MixBaseOperation() { + /* pass */ } void MixLinearLightOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixMultiplyOperation.cpp b/source/blender/compositor/operations/COM_MixMultiplyOperation.cpp index fdf8c1ca51b..223aa476f18 100644 --- a/source/blender/compositor/operations/COM_MixMultiplyOperation.cpp +++ b/source/blender/compositor/operations/COM_MixMultiplyOperation.cpp @@ -24,6 +24,7 @@ MixMultiplyOperation::MixMultiplyOperation(): MixBaseOperation() { + /* pass */ } void MixMultiplyOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixOverlayOperation.cpp b/source/blender/compositor/operations/COM_MixOverlayOperation.cpp index 0025daeb3f5..dfea8440b67 100644 --- a/source/blender/compositor/operations/COM_MixOverlayOperation.cpp +++ b/source/blender/compositor/operations/COM_MixOverlayOperation.cpp @@ -24,6 +24,7 @@ MixOverlayOperation::MixOverlayOperation(): MixBaseOperation() { + /* pass */ } void MixOverlayOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixSaturationOperation.cpp b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp index f6f6ec73c6e..25342abec8a 100644 --- a/source/blender/compositor/operations/COM_MixSaturationOperation.cpp +++ b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp @@ -28,6 +28,7 @@ extern "C" { MixSaturationOperation::MixSaturationOperation(): MixBaseOperation() { + /* pass */ } void MixSaturationOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixScreenOperation.cpp b/source/blender/compositor/operations/COM_MixScreenOperation.cpp index a1a98bd82a2..8b9916165e2 100644 --- a/source/blender/compositor/operations/COM_MixScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_MixScreenOperation.cpp @@ -24,6 +24,7 @@ MixScreenOperation::MixScreenOperation(): MixBaseOperation() { + /* pass */ } void MixScreenOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp b/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp index ea6a3ddd498..a4882b7b83b 100644 --- a/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp +++ b/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp @@ -24,6 +24,7 @@ MixSoftLightOperation::MixSoftLightOperation(): MixBaseOperation() { + /* pass */ } void MixSoftLightOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])\ diff --git a/source/blender/compositor/operations/COM_MixSubtractOperation.cpp b/source/blender/compositor/operations/COM_MixSubtractOperation.cpp index 57320dcd611..d7c7da688a3 100644 --- a/source/blender/compositor/operations/COM_MixSubtractOperation.cpp +++ b/source/blender/compositor/operations/COM_MixSubtractOperation.cpp @@ -24,6 +24,7 @@ MixSubtractOperation::MixSubtractOperation(): MixBaseOperation() { + /* pass */ } void MixSubtractOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_MixValueOperation.cpp b/source/blender/compositor/operations/COM_MixValueOperation.cpp index 8c43bb6af8c..f680692f529 100644 --- a/source/blender/compositor/operations/COM_MixValueOperation.cpp +++ b/source/blender/compositor/operations/COM_MixValueOperation.cpp @@ -28,6 +28,7 @@ extern "C" { MixValueOperation::MixValueOperation(): MixBaseOperation() { + /* pass */ } void MixValueOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cpp b/source/blender/compositor/operations/COM_NormalizeOperation.cpp index 4dd94943f4e..df382547f13 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.cpp +++ b/source/blender/compositor/operations/COM_NormalizeOperation.cpp @@ -110,4 +110,5 @@ void *NormalizeOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBu void NormalizeOperation::deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data) { + /* pass */ } diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cpp b/source/blender/compositor/operations/COM_TonemapOperation.cpp index b281fb938fd..412cdbdf661 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.cpp +++ b/source/blender/compositor/operations/COM_TonemapOperation.cpp @@ -156,4 +156,5 @@ void *TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuff void TonemapOperation::deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data) { + /* pass */ } From 8fd2267e56d3d0b6bb860800eb8059bcbfa0b501 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Jun 2012 18:31:46 +0000 Subject: [PATCH 357/360] Changed behavior of how pattern is controlling by mouse: - Removed scaling option which used to be Ctrl+Slide of individual pattern corner. - Added extra rectangle area which is being drawing around pattern and which supports the following things: * Slide by it's left upper corner would define offset of marker * Slide by it's right bottom corner would scale overall pattern - Added extra handle which is drawing from pattern center and which is being used to define scale and rotation of pattern area. --- source/blender/editors/space_clip/clip_draw.c | 34 +++ .../blender/editors/space_clip/tracking_ops.c | 232 ++++++++++++------ 2 files changed, 196 insertions(+), 70 deletions(-) diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 9b0c5f6296d..8deb83b6f0d 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -812,6 +812,9 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) { int i; + float pat_min[2], pat_max[2]; + float dx = 12.0f / width, dy = 12.0f / height; + float tilt_ctrl[2]; if (!outline) { if (track->pat_flag & SELECT) @@ -825,6 +828,37 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1], patdx / 1.5f, patdy / 1.5f, outline, px); } + + /* ** sliders to control overall pattern ** */ + add_v2_v2v2(tilt_ctrl, marker->pattern_corners[1], marker->pattern_corners[2]); + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + glEnable(GL_LINE_STIPPLE); + glLineStipple(3, 0xaaaa); + + glBegin(GL_LINE_LOOP); + glVertex2f(pat_min[0] - dx, pat_min[1] - dy); + glVertex2f(pat_max[0] + dx, pat_min[1] - dy); + glVertex2f(pat_max[0] + dx, pat_max[1] + dy); + glVertex2f(pat_min[0] - dx, pat_max[1] + dy); + glEnd(); + + glBegin(GL_LINES); + glVertex2f(0.0f, 0.0f); + glVertex2fv(tilt_ctrl); + glEnd(); + + glDisable(GL_LINE_STIPPLE); + + /* marker's offset slider */ + draw_marker_slide_square(pat_min[0] - dx, pat_max[1] + dy, patdx, patdy, outline, px); + + /* pattern re-sizing triangle */ + draw_marker_slide_triangle(pat_max[0] + dx, pat_min[1] - dy, patdx, patdy, outline, px); + + /* slider to control pattern tilt */ + draw_marker_slide_square(tilt_ctrl[0], tilt_ctrl[1], patdx, patdy, outline, px); } glPopMatrix(); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 14df63e4661..8ca483c94d3 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -249,9 +249,10 @@ void CLIP_OT_delete_marker(wmOperatorType *ot) /********************** slide marker operator *********************/ -#define SLIDE_ACTION_POS 0 -#define SLIDE_ACTION_SIZE 1 -#define SLIDE_ACTION_OFFSET 2 +#define SLIDE_ACTION_POS 0 +#define SLIDE_ACTION_SIZE 1 +#define SLIDE_ACTION_OFFSET 2 +#define SLIDE_ACTION_TILT_SIZE 3 typedef struct { short area, action; @@ -263,7 +264,7 @@ typedef struct { float *min, *max, *pos, *offset, (*corners)[2]; float spos[2]; - short lock, accurate, scale; + short lock, accurate; /* data to restore on cancel */ float old_search_min[2], old_search_max[2], old_pos[2], old_offset[2]; @@ -271,6 +272,12 @@ typedef struct { float (*old_markers)[2]; } SlideMarkerData; +static void slide_marker_tilt_slider(MovieTrackingMarker *marker, float slider[2]) +{ + add_v2_v2v2(slider, marker->pattern_corners[1], marker->pattern_corners[2]); + add_v2_v2(slider, marker->pos); +} + static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, wmEvent *event, int area, int corner, int action, int width, int height) @@ -308,6 +315,10 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra data->pos = marker->pattern_corners[corner]; copy_v2_v2(data->spos, data->pos); } + else if (action == SLIDE_ACTION_TILT_SIZE) { + data->corners = marker->pattern_corners; + slide_marker_tilt_slider(marker, data->spos); + } } else if (area == TRACK_AREA_SEARCH) { data->min = marker->search_min; @@ -333,13 +344,14 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra return data; } -static int mouse_on_corner(SpaceClip *sc, MovieTrackingMarker *marker, - int area, float co[2], int corner, int width, int height) +static int mouse_on_slide_zone(SpaceClip *sc, MovieTrackingMarker *marker, + int area, float co[2], float slide_zone[2], + float padding, int width, int height) { + const float size = 12.0f; int inside = 0; - float size = 12.0f; float min[2], max[2]; - float crn[2], dx, dy, tdx, tdy; + float dx, dy; if (area == TRACK_AREA_SEARCH) { copy_v2_v2(min, marker->search_min); @@ -349,29 +361,52 @@ static int mouse_on_corner(SpaceClip *sc, MovieTrackingMarker *marker, BKE_tracking_marker_pattern_minmax(marker, min, max); } + min[0] -= padding / width; + min[1] -= padding / height; + max[0] += padding / width; + max[1] += padding / height; + dx = size / width / sc->zoom; dy = size / height / sc->zoom; - tdx = 5.0f / width / sc->zoom; - tdy = 5.0f / height / sc->zoom; + dx = MIN2(dx, (max[0] - min[0]) / 6.0f); + dy = MIN2(dy, (max[1] - min[1]) / 6.0f); - dx = MIN2(dx, (max[0] - min[0]) / 6.0f) + tdx; - dy = MIN2(dy, (max[1] - min[1]) / 6.0f) + tdy; + return IN_RANGE_INCL(co[0], slide_zone[0] - dx, slide_zone[0] + dx) && + IN_RANGE_INCL(co[1], slide_zone[1] - dy, slide_zone[1] + dy); + + return inside; +} + +static int mouse_on_corner(SpaceClip *sc, MovieTrackingMarker *marker, + int area, float co[2], int corner, float padding, + int width, int height) +{ + float min[2], max[2], crn[2]; + + if (area == TRACK_AREA_SEARCH) { + copy_v2_v2(min, marker->search_min); + copy_v2_v2(max, marker->search_max); + } + else { + BKE_tracking_marker_pattern_minmax(marker, min, max); + } + + min[0] -= padding / width; + min[1] -= padding / height; + max[0] += padding / width; + max[1] += padding / height; if (corner == 0) { crn[0] = marker->pos[0] + max[0]; crn[1] = marker->pos[1] + min[1]; - - inside = co[0] >= crn[0] - dx && co[0] <= crn[0] + tdx && co[1] >= crn[1] - tdy && co[1] <= crn[1] + dy; } else { crn[0] = marker->pos[0] + min[0]; crn[1] = marker->pos[1] + max[1]; - - inside = co[0] >= crn[0] - dx && co[0] <= crn[0] + dx && co[1] >= crn[1] - dy && co[1] <= crn[1] + dy; } - return inside; + return mouse_on_slide_zone(sc, marker, area, co, crn, padding, width, height); } static int get_mouse_pattern_corner(SpaceClip *sc, MovieTrackingMarker *marker, float co[2], int width, int height) @@ -389,11 +424,11 @@ static int get_mouse_pattern_corner(SpaceClip *sc, MovieTrackingMarker *marker, len = MIN2(cur_len, len); } - dx = 6.0f / width / sc->zoom; - dy = 6.0f / height / sc->zoom; + dx = 12.0f / width / sc->zoom; + dy = 12.0f / height / sc->zoom; - dx = MIN2(dx * 2.0f / 3.0f, len / 6.0f); - dy = MIN2(dy * 2.0f / 3.0f, len * width / height / 6.0f); + dx = MIN2(dx, len * 2.0f / 3.0f); + dy = MIN2(dy, len * width / height * 2.0f / 3.0f); for (i = 0; i < 4; i++) { float crn[2]; @@ -430,6 +465,15 @@ static int mouse_on_offset(SpaceClip *sc, MovieTrackingTrack *track, MovieTracki return co[0] >= pos[0] - dx && co[0] <= pos[0] + dx && co[1] >= pos[1] - dy && co[1] <= pos[1] + dy; } +static int mouse_on_tilt(SpaceClip *sc, MovieTrackingMarker *marker, float co[2], int width, int height) +{ + float slider[2]; + + slide_marker_tilt_slider(marker, slider); + + return mouse_on_slide_zone(sc, marker, TRACK_AREA_PAT, co, slider, 0.0f, width, height); +} + static int slide_check_corners(float (*corners)[2]) { int i, next, prev; @@ -509,12 +553,12 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event, int } if (!ok && (sc->flag & SC_SHOW_MARKER_SEARCH)) { - if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 1, width, height)) { + if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 1, 0.0f, width, height)) { area = TRACK_AREA_SEARCH; action = SLIDE_ACTION_OFFSET; ok = TRUE; } - else if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 0, width, height)) { + else if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 0, 0.0f, width, height)) { area = TRACK_AREA_SEARCH; action = SLIDE_ACTION_SIZE; ok = TRUE; @@ -522,30 +566,30 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event, int } if (!ok && (sc->flag & SC_SHOW_MARKER_PATTERN)) { - /* XXX: need to be real check if affine tracking is enabled, but for now not - * sure how to do this, so assume affine tracker is always enabled */ - if (TRUE) { - int current_corner = get_mouse_pattern_corner(sc, marker, co, width, height); + int current_corner = get_mouse_pattern_corner(sc, marker, co, width, height); - if (current_corner != -1) { - area = TRACK_AREA_PAT; - action = SLIDE_ACTION_POS; - corner = current_corner; - ok = TRUE; - } + if (current_corner != -1) { + area = TRACK_AREA_PAT; + action = SLIDE_ACTION_POS; + corner = current_corner; + ok = TRUE; } else { - if (mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 1, width, height)) { + if (mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 1, 12.0f, width, height)) { area = TRACK_AREA_PAT; action = SLIDE_ACTION_OFFSET; ok = TRUE; } - - if (!ok && mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 0, width, height)) { + if (!ok && mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 0, 12.0f, width, height)) { area = TRACK_AREA_PAT; action = SLIDE_ACTION_SIZE; ok = TRUE; } + if (!ok && mouse_on_tilt(sc, marker, co, width, height)) { + area = TRACK_AREA_PAT; + action = SLIDE_ACTION_TILT_SIZE; + ok = TRUE; + } } } @@ -663,10 +707,6 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) data->lock = event->val == KM_RELEASE; - if (data->action == SLIDE_ACTION_POS) - if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) - data->scale = event->val == KM_PRESS; - if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) data->accurate = event->val == KM_PRESS; @@ -703,17 +743,39 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } else if (data->area == TRACK_AREA_PAT) { if (data->action == SLIDE_ACTION_SIZE) { - data->corners[0][0] = data->old_corners[0][0] - dx; - data->corners[0][1] = data->old_corners[0][1] + dy; + float start[2], end[2]; + float scale; - data->corners[1][0] = data->old_corners[1][0] + dx; - data->corners[1][1] = data->old_corners[1][1] + dy; + ED_clip_point_stable_pos(C, data->mval[0], data->mval[1], &start[0], &start[1]); - data->corners[2][0] = data->old_corners[2][0] + dx; - data->corners[2][1] = data->old_corners[2][1] - dy; + sub_v2_v2(start, data->old_pos); - data->corners[3][0] = data->old_corners[3][0] - dx; - data->corners[3][1] = data->old_corners[3][1] - dy; + if (len_v2(start) > 0.0f) { + float mval[2]; + + if (data->accurate) { + mval[0] = data->mval[0] + (event->mval[0] - data->mval[0]) / 5.0f; + mval[1] = data->mval[1] + (event->mval[1] - data->mval[1]) / 5.0f; + } + else { + mval[0] = event->mval[0]; + mval[1] = event->mval[1]; + } + + ED_clip_point_stable_pos(C, mval[0], mval[1], &end[0], &end[1]); + + sub_v2_v2(end, data->old_pos); + + scale = len_v2(end) / len_v2(start); + + if (scale > 0.0f) { + int a; + + for (a = 0; a < 4; a++) { + mul_v2_v2fl(data->corners[a], data->old_corners[a], scale); + } + } + } BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM); } @@ -727,36 +789,66 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) sub_v2_v2v2(data->offset, data->old_offset, d); } else if (data->action == SLIDE_ACTION_POS) { - if (data->scale) { - float scale = 1.0f + 10.0f * (dx - dy); + float spos[2]; - if (scale > 0.0f) { - int a; + copy_v2_v2(spos, data->pos); - for (a = 0; a < 4; a++) { - mul_v2_v2fl(data->corners[a], data->old_corners[a], scale); - } - } - } - else { - float spos[2]; + data->pos[0] = data->spos[0] + dx; + data->pos[1] = data->spos[1] + dy; - copy_v2_v2(spos, data->pos); - - /* corners might've been scaled before, restore their original position */ - memcpy(data->corners, data->old_corners, sizeof(data->old_corners)); - - data->pos[0] = data->spos[0] + dx; - data->pos[1] = data->spos[1] + dy; - - if (!slide_check_corners(data->corners)) { - copy_v2_v2(data->pos, spos); - } + if (!slide_check_corners(data->corners)) { + copy_v2_v2(data->pos, spos); } /* currently only patterns are allowed to have such combination of event and data */ BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM); } + else if (data->action == SLIDE_ACTION_TILT_SIZE) { + float start[2], end[2]; + float scale = 1.0f, angle = 0.0f; + int a; + float mval[2]; + + if (data->accurate) { + mval[0] = data->mval[0] + (event->mval[0] - data->mval[0]) / 5.0f; + mval[1] = data->mval[1] + (event->mval[1] - data->mval[1]) / 5.0f; + } + else { + mval[0] = event->mval[0]; + mval[1] = event->mval[1]; + } + + sub_v2_v2v2(start, data->spos, data->old_pos); + + ED_clip_point_stable_pos(C, mval[0], mval[1], &end[0], &end[1]); + sub_v2_v2(end, data->old_pos); + + if (len_v2(start) > 0.0f) { + scale = len_v2(end) / len_v2(start); + + if (scale < 0.0f) { + scale = 0.0; + } + } + + angle = -angle_signed_v2v2(start, end); + + for (a = 0; a < 4; a++) { + float vec[2]; + + mul_v2_v2fl(data->corners[a], data->old_corners[a], scale); + + copy_v2_v2(vec, data->corners[a]); + vec[0] *= data->width; + vec[1] *= data->height; + + data->corners[a][0] = (vec[0] * cos(angle) - vec[1] * sin(angle)) / data->width; + data->corners[a][1] = (vec[1] * cos(angle) + vec[0] * sin(angle)) / data->height; + } + + BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM); + + } } else if (data->area == TRACK_AREA_SEARCH) { if (data->action == SLIDE_ACTION_SIZE) { From 570cc70772d78703053956ce57b20c6c4ed74c95 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 18:42:03 +0000 Subject: [PATCH 358/360] style cleanup: compositor operations --- .../compositor/intern/COM_OpenCLDevice.h | 14 +- .../operations/COM_AlphaOverKeyOperation.cpp | 12 +- .../COM_AlphaOverMixedOperation.cpp | 18 +- .../COM_AlphaOverPremultiplyOperation.cpp | 14 +- .../operations/COM_AntiAliasOperation.cpp | 22 +- .../operations/COM_BokehImageOperation.cpp | 18 +- .../operations/COM_BoxMaskOperation.cpp | 36 +- .../operations/COM_BrightnessOperation.cpp | 16 +- .../operations/COM_CalculateMeanOperation.cpp | 38 +- ...OM_CalculateStandardDeviationOperation.cpp | 50 +- .../operations/COM_ChangeHSVOperation.cpp | 6 +- .../operations/COM_ChannelMatteOperation.cpp | 10 +- .../operations/COM_ChromaMatteOperation.cpp | 28 +- .../COM_ColorBalanceASCCDLOperation.cpp | 8 +- .../COM_ColorBalanceLGGOperation.cpp | 8 +- .../COM_ColorCorrectionOperation.cpp | 26 +- .../operations/COM_ColorCurveOperation.cpp | 8 +- .../operations/COM_ColorMatteOperation.cpp | 17 +- .../operations/COM_ColorRampOperation.cpp | 2 +- .../operations/COM_ColorSpillOperation.cpp | 8 +- .../COM_CombineChannelsOperation.cpp | 2 +- .../COM_ConvertColorProfileOperation.cpp | 2 +- .../COM_ConvertColorToBWOperation.cpp | 4 +- .../COM_ConvertColorToVectorOperation.cpp | 2 +- .../COM_ConvertColourToValueProg.cpp | 4 +- .../COM_ConvertDepthToRadiusOperation.cpp | 22 +- .../COM_ConvertHSVToRGBOperation.cpp | 2 +- .../COM_ConvertKeyToPremulOperation.cpp | 2 +- .../COM_ConvertPremulToKeyOperation.cpp | 2 +- .../COM_ConvertRGBToHSVOperation.cpp | 2 +- .../COM_ConvertRGBToYCCOperation.cpp | 22 +- .../COM_ConvertRGBToYUVOperation.cpp | 2 +- .../COM_ConvertValueToColourProg.cpp | 2 +- .../COM_ConvertValueToVectorOperation.cpp | 2 +- .../COM_ConvertVectorToColorOperation.cpp | 2 +- .../COM_ConvertVectorToValueOperation.cpp | 4 +- .../COM_ConvertYCCToRGBOperation.cpp | 22 +- .../COM_ConvertYUVToRGBOperation.cpp | 2 +- .../COM_ConvolutionEdgeFilterOperation.cpp | 16 +- .../COM_ConvolutionFilterOperation.cpp | 20 +- .../operations/COM_CropOperation.cpp | 8 +- .../operations/COM_CurveBaseOperation.cpp | 2 +- .../COM_DifferenceMatteOperation.cpp | 16 +- .../operations/COM_DisplaceOperation.cpp | 16 +- .../COM_DisplaceSimpleOperation.cpp | 12 +- .../operations/COM_DistanceMatteOperation.cpp | 28 +- .../operations/COM_DotproductOperation.cpp | 6 +- .../COM_DoubleEdgeMaskOperation.cpp | 1062 ++++++++--------- .../operations/COM_EllipseMaskOperation.cpp | 46 +- .../operations/COM_FlipOperation.cpp | 14 +- .../operations/COM_GammaCorrectOperation.cpp | 16 +- .../operations/COM_GammaOperation.cpp | 2 +- .../operations/COM_GaussianXBlurOperation.h | 6 +- ...COM_HueSaturationValueCorrectOperation.cpp | 4 +- .../operations/COM_IDMaskOperation.cpp | 4 +- .../operations/COM_ImageOperation.cpp | 52 +- .../operations/COM_InvertOperation.cpp | 10 +- .../operations/COM_KeyingClipOperation.cpp | 4 +- .../operations/COM_KeyingDespillOperation.cpp | 2 +- .../operations/COM_KeyingOperation.cpp | 2 +- .../operations/COM_KeyingScreenOperation.cpp | 8 +- .../COM_LuminanceMatteOperation.cpp | 26 +- .../operations/COM_MapUVOperation.cpp | 66 +- .../operations/COM_MapValueOperation.cpp | 8 +- .../operations/COM_MaskOperation.cpp | 12 +- .../operations/COM_MathBaseOperation.cpp | 17 +- .../operations/COM_MixAddOperation.cpp | 8 +- .../operations/COM_MixBaseOperation.cpp | 10 +- .../operations/COM_MixBlendOperation.cpp | 8 +- .../operations/COM_MixBurnOperation.cpp | 8 +- .../operations/COM_MixColorOperation.cpp | 18 +- .../operations/COM_MixDarkenOperation.cpp | 8 +- .../operations/COM_MixDifferenceOperation.cpp | 8 +- .../operations/COM_MixDivideOperation.cpp | 8 +- .../operations/COM_MixDodgeOperation.cpp | 8 +- .../operations/COM_MixGlareOperation.cpp | 10 +- .../operations/COM_MixHueOperation.cpp | 18 +- .../operations/COM_MixLightenOperation.cpp | 8 +- .../COM_MixLinearLightOperation.cpp | 14 +- .../operations/COM_MixMultiplyOperation.cpp | 8 +- .../operations/COM_MixOverlayOperation.cpp | 14 +- .../operations/COM_MixSaturationOperation.cpp | 10 +- .../operations/COM_MixScreenOperation.cpp | 8 +- .../operations/COM_MixSoftLightOperation.cpp | 14 +- .../operations/COM_MixSubtractOperation.cpp | 8 +- .../operations/COM_MixValueOperation.cpp | 8 +- .../COM_MovieClipAttributeOperation.cpp | 26 +- .../operations/COM_MovieClipOperation.cpp | 24 +- .../COM_MovieDistortionOperation.cpp | 8 +- .../COM_MultilayerImageOperation.cpp | 34 +- .../operations/COM_NormalizeOperation.cpp | 16 +- .../operations/COM_OutputFileOperation.cpp | 92 +- .../operations/COM_PreviewOperation.cpp | 32 +- .../COM_ProjectorLensDistortionOperation.cpp | 18 +- .../operations/COM_QualityStepHelper.cpp | 64 +- .../operations/COM_ReadBufferOperation.cpp | 10 +- .../COM_RenderLayersAOOperation.cpp | 2 +- .../operations/COM_RenderLayersAlphaProg.cpp | 8 +- .../operations/COM_RenderLayersBaseProg.cpp | 26 +- .../COM_RenderLayersColorOperation.cpp | 2 +- .../COM_RenderLayersCyclesOperation.cpp | 2 +- .../operations/COM_RenderLayersDepthProg.cpp | 2 +- .../COM_RenderLayersDiffuseOperation.cpp | 2 +- .../COM_RenderLayersEmitOperation.cpp | 2 +- .../COM_RenderLayersEnvironmentOperation.cpp | 2 +- .../operations/COM_RenderLayersImageProg.cpp | 2 +- .../COM_RenderLayersIndirectOperation.cpp | 2 +- ...COM_RenderLayersMaterialIndexOperation.cpp | 2 +- .../COM_RenderLayersMistOperation.cpp | 2 +- .../COM_RenderLayersNormalOperation.cpp | 2 +- .../COM_RenderLayersObjectIndexOperation.cpp | 2 +- .../COM_RenderLayersReflectionOperation.cpp | 2 +- .../COM_RenderLayersRefractionOperation.cpp | 2 +- .../COM_RenderLayersShadowOperation.cpp | 2 +- .../COM_RenderLayersSpecularOperation.cpp | 2 +- .../COM_RenderLayersSpeedOperation.cpp | 2 +- .../COM_RenderLayersUVOperation.cpp | 2 +- .../operations/COM_RotateOperation.cpp | 38 +- .../COM_ScreenLensDistortionOperation.cpp | 98 +- .../COM_SeparateChannelOperation.cpp | 2 +- .../operations/COM_SetAlphaOperation.cpp | 2 +- .../operations/COM_SetColorOperation.cpp | 2 +- .../operations/COM_SetSamplerOperation.cpp | 2 +- .../operations/COM_SetValueOperation.cpp | 2 +- .../operations/COM_SetVectorOperation.cpp | 2 +- .../operations/COM_SocketProxyOperation.cpp | 2 +- .../operations/COM_TextureOperation.cpp | 26 +- .../operations/COM_TonemapOperation.cpp | 16 +- .../operations/COM_TranslateOperation.cpp | 4 +- .../operations/COM_VectorCurveOperation.cpp | 2 +- .../operations/COM_WriteBufferOperation.cpp | 46 +- .../operations/COM_ZCombineOperation.cpp | 14 +- 132 files changed, 1400 insertions(+), 1404 deletions(-) diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.h b/source/blender/compositor/intern/COM_OpenCLDevice.h index 75c326eda23..83ce8cec811 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.h +++ b/source/blender/compositor/intern/COM_OpenCLDevice.h @@ -37,29 +37,29 @@ class OpenCLDevice; class OpenCLDevice : public Device { private: /** - *@brief opencl context + * @brief opencl context */ cl_context context; /** - *@brief opencl device + * @brief opencl device */ cl_device_id device; /** - *@brief opencl program + * @brief opencl program */ cl_program program; /** - *@brief opencl command queue + * @brief opencl command queue */ cl_command_queue queue; public: /** - *@brief constructor with opencl device - *@param context - *@param device + * @brief constructor with opencl device + * @param context + * @param device */ OpenCLDevice(cl_context context, cl_device_id device, cl_program program); diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp index 4a0c8b7ab7f..e614e1fa15a 100644 --- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp @@ -22,7 +22,7 @@ #include "COM_AlphaOverKeyOperation.h" -AlphaOverKeyOperation::AlphaOverKeyOperation(): MixBaseOperation() +AlphaOverKeyOperation::AlphaOverKeyOperation() : MixBaseOperation() { /* pass */ } @@ -44,12 +44,12 @@ void AlphaOverKeyOperation::executePixel(float *outputValue, float x, float y, P copy_v4_v4(outputValue, inputOverColor); } else { - float premul = value[0]*inputOverColor[3]; + float premul = value[0] * inputOverColor[3]; float mul = 1.0f - premul; - outputValue[0] = (mul*inputColor1[0]) + premul*inputOverColor[0]; - outputValue[1] = (mul*inputColor1[1]) + premul*inputOverColor[1]; - outputValue[2] = (mul*inputColor1[2]) + premul*inputOverColor[2]; - outputValue[3] = (mul*inputColor1[3]) + value[0]*inputOverColor[3]; + outputValue[0] = (mul * inputColor1[0]) + premul * inputOverColor[0]; + outputValue[1] = (mul * inputColor1[1]) + premul * inputOverColor[1]; + outputValue[2] = (mul * inputColor1[2]) + premul * inputOverColor[2]; + outputValue[3] = (mul * inputColor1[3]) + value[0] * inputOverColor[3]; } } diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp index 850bbd5cc00..81c1e4d2587 100644 --- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp @@ -22,7 +22,7 @@ #include "COM_AlphaOverMixedOperation.h" -AlphaOverMixedOperation::AlphaOverMixedOperation(): MixBaseOperation() +AlphaOverMixedOperation::AlphaOverMixedOperation() : MixBaseOperation() { this->x = 0.0f; } @@ -44,14 +44,14 @@ void AlphaOverMixedOperation::executePixel(float outputValue[4], float x, float copy_v4_v4(outputValue, inputOverColor); } else { - float addfac = 1.0f - this->x + inputOverColor[3]*this->x; - float premul = value[0]*addfac; - float mul = 1.0f - value[0]*inputOverColor[3]; - - outputValue[0] = (mul*inputColor1[0]) + premul*inputOverColor[0]; - outputValue[1] = (mul*inputColor1[1]) + premul*inputOverColor[1]; - outputValue[2] = (mul*inputColor1[2]) + premul*inputOverColor[2]; - outputValue[3] = (mul*inputColor1[3]) + value[0]*inputOverColor[3]; + float addfac = 1.0f - this->x + inputOverColor[3] * this->x; + float premul = value[0] * addfac; + float mul = 1.0f - value[0] * inputOverColor[3]; + + outputValue[0] = (mul * inputColor1[0]) + premul * inputOverColor[0]; + outputValue[1] = (mul * inputColor1[1]) + premul * inputOverColor[1]; + outputValue[2] = (mul * inputColor1[2]) + premul * inputOverColor[2]; + outputValue[3] = (mul * inputColor1[3]) + value[0] * inputOverColor[3]; } } diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp index 5b36f83af41..a6bf8b8834c 100644 --- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp @@ -22,7 +22,7 @@ #include "COM_AlphaOverPremultiplyOperation.h" -AlphaOverPremultiplyOperation::AlphaOverPremultiplyOperation(): MixBaseOperation() +AlphaOverPremultiplyOperation::AlphaOverPremultiplyOperation() : MixBaseOperation() { /* pass */ } @@ -38,19 +38,19 @@ void AlphaOverPremultiplyOperation::executePixel(float *outputValue, float x, fl inputColor2Operation->read(inputOverColor, x, y, sampler, inputBuffers); /* Zero alpha values should still permit an add of RGB data */ - if (inputOverColor[3]<0.0f) { + if (inputOverColor[3] < 0.0f) { copy_v4_v4(outputValue, inputColor1); } else if (value[0] == 1.0f && inputOverColor[3] >= 1.0f) { copy_v4_v4(outputValue, inputOverColor); } else { - float mul = 1.0f - value[0]*inputOverColor[3]; + float mul = 1.0f - value[0] * inputOverColor[3]; - outputValue[0] = (mul*inputColor1[0]) + value[0]*inputOverColor[0]; - outputValue[1] = (mul*inputColor1[1]) + value[0]*inputOverColor[1]; - outputValue[2] = (mul*inputColor1[2]) + value[0]*inputOverColor[2]; - outputValue[3] = (mul*inputColor1[3]) + value[0]*inputOverColor[3]; + outputValue[0] = (mul * inputColor1[0]) + value[0] * inputOverColor[0]; + outputValue[1] = (mul * inputColor1[1]) + value[0] * inputOverColor[1]; + outputValue[2] = (mul * inputColor1[2]) + value[0] * inputOverColor[2]; + outputValue[3] = (mul * inputColor1[3]) + value[0] * inputOverColor[3]; } } diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp index 4cd9552b108..458d11f2616 100644 --- a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp @@ -28,7 +28,7 @@ extern "C" { } -AntiAliasOperation::AntiAliasOperation(): NodeOperation() +AntiAliasOperation::AntiAliasOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -42,14 +42,14 @@ void AntiAliasOperation::initExecution() NodeOperation::initMutex(); } -void AntiAliasOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data) +void AntiAliasOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { if (y < 0 || (unsigned int)y >= this->height || x < 0 || (unsigned int)x >= this->width) { color[0] = 0.0f; } else { - int offset = y*this->width + x; - color[0] = buffer[offset]/255.0f; + int offset = y * this->width + x; + color[0] = buffer[offset] / 255.0f; } } @@ -84,17 +84,17 @@ bool AntiAliasOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe void *AntiAliasOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { - if (this->buffer) {return buffer;} + if (this->buffer) {return buffer; } lockMutex(); if (this->buffer == NULL) { - MemoryBuffer *tile = (MemoryBuffer*)valueReader->initializeTileData(rect, memoryBuffers); - int size = tile->getHeight()*tile->getWidth(); - float * input = tile->getBuffer(); + MemoryBuffer *tile = (MemoryBuffer *)valueReader->initializeTileData(rect, memoryBuffers); + int size = tile->getHeight() * tile->getWidth(); + float *input = tile->getBuffer(); char *valuebuffer = new char[size]; - for (int i = 0 ; i < size ; i ++) { + for (int i = 0; i < size; i++) { float in = input[i * COM_NUMBER_OF_CHANNELS]; - if (in < 0.0f) { in = 0.0f;} - if (in > 1.0f) {in = 1.0f;} + if (in < 0.0f) { in = 0.0f; } + if (in > 1.0f) {in = 1.0f; } valuebuffer[i] = in * 255; } antialias_tagbuf(tile->getWidth(), tile->getHeight(), valuebuffer); diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.cpp b/source/blender/compositor/operations/COM_BokehImageOperation.cpp index 189ba98aa57..abb378e2adb 100644 --- a/source/blender/compositor/operations/COM_BokehImageOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehImageOperation.cpp @@ -23,7 +23,7 @@ #include "COM_BokehImageOperation.h" #include "BLI_math.h" -BokehImageOperation::BokehImageOperation(): NodeOperation() +BokehImageOperation::BokehImageOperation() : NodeOperation() { this->addOutputSocket(COM_DT_COLOR); this->deleteData = false; @@ -35,7 +35,7 @@ void BokehImageOperation::initExecution() this->center[0] = this->centerX; this->center[1] = this->centerY; this->inverseRounding = 1.0f - this->data->rounding; - this->circularDistance = getWidth()/2; + this->circularDistance = getWidth() / 2; this->flapRad = (float)(M_PI * 2) / this->data->flaps; this->flapRadAdd = (this->data->angle / 360.0f) * (float)(M_PI * 2.0); while (this->flapRadAdd < 0.0f) { @@ -64,19 +64,19 @@ float BokehImageOperation::isInsideBokeh(float distance, float x, float y) const float distanceToCenter = len_v2v2(point, center); const float bearing = (atan2f(deltaX, deltaY) + (float)(M_PI * 2.0)); - int flapNumber = (int)((bearing-flapRadAdd)/flapRad); + int flapNumber = (int)((bearing - flapRadAdd) / flapRad); detemineStartPointOfFlap(lineP1, flapNumber, distance); - detemineStartPointOfFlap(lineP2, flapNumber+1, distance); + detemineStartPointOfFlap(lineP2, flapNumber + 1, distance); closest_to_line_v2(closestPoint, point, lineP1, lineP2); const float distanceLineToCenter = len_v2v2(center, closestPoint); - const float distanceRoundingToCenter = inverseRounding*distanceLineToCenter+this->data->rounding*distance; + const float distanceRoundingToCenter = inverseRounding * distanceLineToCenter + this->data->rounding * distance; const float catadioptricDistanceToCenter = distanceRoundingToCenter * this->data->catadioptric; - if (distanceRoundingToCenter>=distanceToCenter && catadioptricDistanceToCenter <= distanceToCenter) { + if (distanceRoundingToCenter >= distanceToCenter && catadioptricDistanceToCenter <= distanceToCenter) { if (distanceRoundingToCenter - distanceToCenter < 1.0f) { - insideBokeh = (distanceRoundingToCenter-distanceToCenter); + insideBokeh = (distanceRoundingToCenter - distanceToCenter); } else if (this->data->catadioptric != 0.0f && distanceToCenter - catadioptricDistanceToCenter < 1.0f) { insideBokeh = (distanceToCenter - catadioptricDistanceToCenter); @@ -95,7 +95,7 @@ void BokehImageOperation::executePixel(float *color, float x, float y, PixelSamp float insideBokehMax = isInsideBokeh(distance, x, y); float insideBokehMed = isInsideBokeh(distance - fabsf(shift2 * distance), x, y); float insideBokehMin = isInsideBokeh(distance - fabsf(shift * distance), x, y); - if (shift<0) { + if (shift < 0) { color[0] = insideBokehMax; color[1] = insideBokehMed; color[2] = insideBokehMin; @@ -105,7 +105,7 @@ void BokehImageOperation::executePixel(float *color, float x, float y, PixelSamp color[1] = insideBokehMed; color[2] = insideBokehMax; } - color[3] = (insideBokehMax+insideBokehMed+insideBokehMin)/3.0f; + color[3] = (insideBokehMax + insideBokehMed + insideBokehMin) / 3.0f; } void BokehImageOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cpp b/source/blender/compositor/operations/COM_BoxMaskOperation.cpp index ae83115ff69..3b99fc9a2a0 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cpp @@ -24,7 +24,7 @@ #include "BLI_math.h" #include "DNA_node_types.h" -BoxMaskOperation::BoxMaskOperation(): NodeOperation() +BoxMaskOperation::BoxMaskOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_VALUE); @@ -41,7 +41,7 @@ void BoxMaskOperation::initExecution() const double rad = DEG2RAD((double)this->data->rotation); this->cosine = cos(rad); this->sine = sin(rad); - this->aspectRatio = ((float)this->getWidth())/this->getHeight(); + this->aspectRatio = ((float)this->getWidth()) / this->getHeight(); } void BoxMaskOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) @@ -49,13 +49,13 @@ void BoxMaskOperation::executePixel(float *color, float x, float y, PixelSampler float inputMask[4]; float inputValue[4]; - float rx = x/this->getWidth(); - float ry = y/this->getHeight(); + float rx = x / this->getWidth(); + float ry = y / this->getHeight(); - const float dy = (ry - this->data->y)/this->aspectRatio; + const float dy = (ry - this->data->y) / this->aspectRatio; const float dx = rx - this->data->x; - rx = this->data->x+(this->cosine*dx + this->sine*dy); - ry = this->data->y+(-this->sine*dx + this->cosine*dy); + rx = this->data->x + (this->cosine * dx + this->sine * dy); + ry = this->data->y + (-this->sine * dx + this->cosine * dy); this->inputMask->read(inputMask, x, y, sampler, inputBuffers); this->inputValue->read(inputValue, x, y, sampler, inputBuffers); @@ -70,7 +70,7 @@ void BoxMaskOperation::executePixel(float *color, float x, float y, PixelSampler switch (this->maskType) { case CMP_NODE_MASKTYPE_ADD: if (inside) { - color[0] = max(inputMask[0],inputValue[0]); + color[0] = max(inputMask[0], inputValue[0]); } else { color[0] = inputMask[0]; @@ -78,7 +78,7 @@ void BoxMaskOperation::executePixel(float *color, float x, float y, PixelSampler break; case CMP_NODE_MASKTYPE_SUBTRACT: if (inside) { - color[0] = inputMask[0]-inputValue[0]; + color[0] = inputMask[0] - inputValue[0]; CLAMP(color[0], 0, 1); } else { @@ -87,24 +87,24 @@ void BoxMaskOperation::executePixel(float *color, float x, float y, PixelSampler break; case CMP_NODE_MASKTYPE_MULTIPLY: if (inside) { - color[0] = inputMask[0]*inputValue[0]; + color[0] = inputMask[0] * inputValue[0]; } else { color[0] = 0; } break; case CMP_NODE_MASKTYPE_NOT: - if (inside) { - if (inputMask[0]>0.0f) { - color[0] = 0; + if (inside) { + if (inputMask[0] > 0.0f) { + color[0] = 0; + } + else { + color[0] = inputValue[0]; + } } else { - color[0] = inputValue[0]; + color[0] = inputMask[0]; } - } - else { - color[0] = inputMask[0]; - } break; } diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.cpp b/source/blender/compositor/operations/COM_BrightnessOperation.cpp index a4396a43cf7..95862a1fd83 100644 --- a/source/blender/compositor/operations/COM_BrightnessOperation.cpp +++ b/source/blender/compositor/operations/COM_BrightnessOperation.cpp @@ -22,7 +22,7 @@ #include "COM_BrightnessOperation.h" -BrightnessOperation::BrightnessOperation(): NodeOperation() +BrightnessOperation::BrightnessOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); @@ -52,10 +52,10 @@ void BrightnessOperation::executePixel(float *color, float x, float y, PixelSamp float delta = contrast / 200.0f; a = 1.0f - delta * 2.0f; /* - * The algorithm is by Werner D. Streidt - * (http://visca.com/ffactory/archives/5-99/msg00021.html) - * Extracted of OpenCV demhist.c - */ + * The algorithm is by Werner D. Streidt + * (http://visca.com/ffactory/archives/5-99/msg00021.html) + * Extracted of OpenCV demhist.c + */ if (contrast > 0) { a = 1.0f / a; b = a * (brightness - delta); @@ -65,9 +65,9 @@ void BrightnessOperation::executePixel(float *color, float x, float y, PixelSamp b = a * (brightness + delta); } - color[0] = a*inputValue[0]+b; - color[1] = a*inputValue[1]+b; - color[2] = a*inputValue[2]+b; + color[0] = a * inputValue[0] + b; + color[1] = a * inputValue[1] + b; + color[2] = a * inputValue[2] + b; color[3] = inputValue[3]; } diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp index 077d8473f0b..3f9003b8c48 100644 --- a/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp +++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp @@ -26,7 +26,7 @@ -CalculateMeanOperation::CalculateMeanOperation(): NodeOperation() +CalculateMeanOperation::CalculateMeanOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->addOutputSocket(COM_DT_VALUE); @@ -42,7 +42,7 @@ void CalculateMeanOperation::initExecution() NodeOperation::initMutex(); } -void CalculateMeanOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data) +void CalculateMeanOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { color[0] = this->result; } @@ -74,7 +74,7 @@ void *CalculateMeanOperation::initializeTileData(rcti *rect, MemoryBuffer **memo { lockMutex(); if (!this->iscalculated) { - MemoryBuffer *tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); + MemoryBuffer *tile = (MemoryBuffer *)imageReader->initializeTileData(rect, memoryBuffers); calculateMean(tile); this->iscalculated = true; } @@ -82,44 +82,44 @@ void *CalculateMeanOperation::initializeTileData(rcti *rect, MemoryBuffer **memo return NULL; } -void CalculateMeanOperation::calculateMean(MemoryBuffer * tile) +void CalculateMeanOperation::calculateMean(MemoryBuffer *tile) { this->result = 0.0f; float *buffer = tile->getBuffer(); - int size = tile->getWidth()*tile->getHeight(); + int size = tile->getWidth() * tile->getHeight(); int pixels = 0; float sum; - for (int i = 0, offset = 0 ; i < size ; i ++, offset +=4) { - if (buffer[offset+3] > 0) { - pixels ++; + for (int i = 0, offset = 0; i < size; i++, offset += 4) { + if (buffer[offset + 3] > 0) { + pixels++; switch (this->setting) { - case 1: + case 1: { - sum += buffer[offset]*0.35f + buffer[offset+1]*0.45f + buffer[offset+2]*0.2f; + sum += buffer[offset] * 0.35f + buffer[offset + 1] * 0.45f + buffer[offset + 2] * 0.2f; break; } - case 2: + case 2: { - sum+= buffer[offset]; + sum += buffer[offset]; break; } - case 3: + case 3: { - sum+= buffer[offset+1]; + sum += buffer[offset + 1]; break; } - case 4: + case 4: { - sum+= buffer[offset+2]; + sum += buffer[offset + 2]; break; } - case 5: + case 5: { float yuv[3]; - rgb_to_yuv(buffer[offset], buffer[offset+1], buffer[offset+2], &yuv[0], &yuv[1], &yuv[2]); - sum+=yuv[0]; + rgb_to_yuv(buffer[offset], buffer[offset + 1], buffer[offset + 2], &yuv[0], &yuv[1], &yuv[2]); + sum += yuv[0]; break; } } diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp index 884c22021df..b0739cd7567 100644 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp @@ -26,12 +26,12 @@ -CalculateStandardDeviationOperation::CalculateStandardDeviationOperation(): CalculateMeanOperation() +CalculateStandardDeviationOperation::CalculateStandardDeviationOperation() : CalculateMeanOperation() { /* pass */ } -void CalculateStandardDeviationOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data) +void CalculateStandardDeviationOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { color[0] = this->standardDeviation; } @@ -40,57 +40,57 @@ void *CalculateStandardDeviationOperation::initializeTileData(rcti *rect, Memory { lockMutex(); if (!this->iscalculated) { - MemoryBuffer *tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); + MemoryBuffer *tile = (MemoryBuffer *)imageReader->initializeTileData(rect, memoryBuffers); CalculateMeanOperation::calculateMean(tile); this->standardDeviation = 0.0f; float *buffer = tile->getBuffer(); - int size = tile->getWidth()*tile->getHeight(); + int size = tile->getWidth() * tile->getHeight(); int pixels = 0; float sum; float mean = this->result; - for (int i = 0, offset = 0 ; i < size ; i ++, offset +=4) { - if (buffer[offset+3] > 0) { - pixels ++; + for (int i = 0, offset = 0; i < size; i++, offset += 4) { + if (buffer[offset + 3] > 0) { + pixels++; switch (this->setting) { - case 1: + case 1: { - float value = buffer[offset]*0.35f + buffer[offset+1]*0.45f + buffer[offset+2]*0.2f; - sum+=(value-mean)*(value-mean); + float value = buffer[offset] * 0.35f + buffer[offset + 1] * 0.45f + buffer[offset + 2] * 0.2f; + sum += (value - mean) * (value - mean); break; } - case 2: + case 2: { float value = buffer[offset]; - sum+=value; - sum+=(value-mean)*(value-mean); + sum += value; + sum += (value - mean) * (value - mean); break; } - case 3: + case 3: { - float value = buffer[offset+1]; - sum+=value; - sum+=(value-mean)*(value-mean); + float value = buffer[offset + 1]; + sum += value; + sum += (value - mean) * (value - mean); break; } - case 4: + case 4: { - float value = buffer[offset+2]; - sum+=value; - sum+=(value-mean)*(value-mean); + float value = buffer[offset + 2]; + sum += value; + sum += (value - mean) * (value - mean); } - case 5: + case 5: { float yuv[3]; - rgb_to_yuv(buffer[offset], buffer[offset+1], buffer[offset+2], &yuv[0], &yuv[1], &yuv[2]); - sum+=(yuv[0]-mean)*(yuv[0]-mean); + rgb_to_yuv(buffer[offset], buffer[offset + 1], buffer[offset + 2], &yuv[0], &yuv[1], &yuv[2]); + sum += (yuv[0] - mean) * (yuv[0] - mean); break; } } } } - this->standardDeviation = sqrt(sum / (float)(pixels-1)); + this->standardDeviation = sqrt(sum / (float)(pixels - 1)); this->iscalculated = true; } unlockMutex(); diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp b/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp index f949b0a55fa..487c1869782 100644 --- a/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp +++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ChangeHSVOperation.h" -ChangeHSVOperation::ChangeHSVOperation(): NodeOperation() +ChangeHSVOperation::ChangeHSVOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); @@ -46,8 +46,8 @@ void ChangeHSVOperation::executePixel(float *outputValue, float x, float y, Pixe inputOperation->read(inputColor1, x, y, sampler, inputBuffers); outputValue[0] = inputColor1[0] + (this->hue - 0.5f); - if (outputValue[0] > 1.0f) outputValue[0] -= 1.0f; - else if (outputValue[0] < 0.0f) outputValue[0] += 1.0f; + if (outputValue[0] > 1.0f) outputValue[0] -= 1.0f; + else if (outputValue[0] < 0.0f) outputValue[0] += 1.0f; outputValue[1] = inputColor1[1] * this->saturation; outputValue[2] = inputColor1[2] * this->value; outputValue[3] = inputColor1[3]; diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp index 70bfc8f8cfa..24af1a3aa53 100644 --- a/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ChannelMatteOperation.h" #include "BLI_math.h" -ChannelMatteOperation::ChannelMatteOperation(): NodeOperation() +ChannelMatteOperation::ChannelMatteOperation() : NodeOperation() { addInputSocket(COM_DT_COLOR); addOutputSocket(COM_DT_VALUE); @@ -39,9 +39,9 @@ void ChannelMatteOperation::initExecution() switch (this->limit_method) { /* SINGLE */ case 0: { - /* 123 / RGB / HSV / YUV / YCC */ - const int matte_channel=this->matte_channel-1; - const int limit_channel=this->limit_channel-1; + /* 123 / RGB / HSV / YUV / YCC */ + const int matte_channel = this->matte_channel - 1; + const int limit_channel = this->limit_channel - 1; this->ids[0] = matte_channel; this->ids[1] = limit_channel; this->ids[2] = limit_channel; @@ -107,7 +107,7 @@ void ChannelMatteOperation::executePixel(float *outputValue, float x, float y, P else if (alpha < limit_min) { alpha = 0.f; } - else {/*blend */ + else { /*blend */ alpha = (alpha - limit_min) / limit_range; } diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp index e082ffed2b6..0ce1a585598 100644 --- a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ChromaMatteOperation.h" #include "BLI_math.h" -ChromaMatteOperation::ChromaMatteOperation(): NodeOperation() +ChromaMatteOperation::ChromaMatteOperation() : NodeOperation() { addInputSocket(COM_DT_COLOR); addInputSocket(COM_DT_COLOR); @@ -66,36 +66,36 @@ void ChromaMatteOperation::executePixel(float *outputValue, float x, float y, Pi /* Algorithm from book "Video Demistified," does not include the spill reduction part */ /* find theta, the angle that the color space should be rotated based on key*/ - theta=atan2(inKey[2], inKey[1]); + theta = atan2(inKey[2], inKey[1]); /*rotate the cb and cr into x/z space */ - x_angle=inImage[1]*cosf(theta)+inImage[2]*sinf(theta); - z_angle=inImage[2]*cosf(theta)-inImage[1]*sinf(theta); + x_angle = inImage[1] * cosf(theta) + inImage[2] * sinf(theta); + z_angle = inImage[2] * cosf(theta) - inImage[1] * sinf(theta); /*if within the acceptance angle */ /* if kfg is <0 then the pixel is outside of the key color */ - kfg = x_angle-(fabsf(z_angle)/tanf(acceptance/2.f)); + kfg = x_angle - (fabsf(z_angle) / tanf(acceptance / 2.f)); - if (kfg>0.f) { /* found a pixel that is within key color */ - alpha=(1.f-kfg)*(gain); + if (kfg > 0.f) { /* found a pixel that is within key color */ + alpha = (1.f - kfg) * (gain); - beta=atan2(z_angle,x_angle); + beta = atan2(z_angle, x_angle); /* if beta is within the cutoff angle */ - if (fabsf(beta) < (cutoff/2.f)) { - alpha=0.f; + if (fabsf(beta) < (cutoff / 2.f)) { + alpha = 0.f; } /* don't make something that was more transparent less transparent */ - if (alphaaddInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); @@ -61,9 +61,9 @@ void ColorBalanceASCCDLOperation::executePixel(float *outputColor, float x, floa fac = min(1.0f, fac); const float mfac = 1.0f - fac; - outputColor[0] = mfac*inputColor[0] + fac * colorbalance_cdl(inputColor[0], this->lift[0], this->gamma[0], this->gain[0]); - outputColor[1] = mfac*inputColor[1] + fac * colorbalance_cdl(inputColor[1], this->lift[1], this->gamma[1], this->gain[1]); - outputColor[2] = mfac*inputColor[2] + fac * colorbalance_cdl(inputColor[2], this->lift[2], this->gamma[2], this->gain[2]); + outputColor[0] = mfac * inputColor[0] + fac *colorbalance_cdl(inputColor[0], this->lift[0], this->gamma[0], this->gain[0]); + outputColor[1] = mfac * inputColor[1] + fac *colorbalance_cdl(inputColor[1], this->lift[1], this->gamma[1], this->gain[1]); + outputColor[2] = mfac * inputColor[2] + fac *colorbalance_cdl(inputColor[2], this->lift[2], this->gamma[2], this->gain[2]); outputColor[3] = inputColor[3]; } diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp index 82958a7086e..7a8d62dfe21 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp @@ -38,7 +38,7 @@ inline float colorbalance_lgg(float in, float lift_lgg, float gamma_inv, float g return powf(srgb_to_linearrgb(x), gamma_inv); } -ColorBalanceLGGOperation::ColorBalanceLGGOperation(): NodeOperation() +ColorBalanceLGGOperation::ColorBalanceLGGOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); @@ -66,9 +66,9 @@ void ColorBalanceLGGOperation::executePixel(float *outputColor, float x, float y fac = min(1.0f, fac); const float mfac = 1.0f - fac; - outputColor[0] = mfac*inputColor[0] + fac * colorbalance_lgg(inputColor[0], this->lift[0], this->gamma_inv[0], this->gain[0]); - outputColor[1] = mfac*inputColor[1] + fac * colorbalance_lgg(inputColor[1], this->lift[1], this->gamma_inv[1], this->gain[1]); - outputColor[2] = mfac*inputColor[2] + fac * colorbalance_lgg(inputColor[2], this->lift[2], this->gamma_inv[2], this->gain[2]); + outputColor[0] = mfac * inputColor[0] + fac *colorbalance_lgg(inputColor[0], this->lift[0], this->gamma_inv[0], this->gain[0]); + outputColor[1] = mfac * inputColor[1] + fac *colorbalance_lgg(inputColor[1], this->lift[1], this->gamma_inv[1], this->gain[1]); + outputColor[2] = mfac * inputColor[2] + fac *colorbalance_lgg(inputColor[2], this->lift[2], this->gamma_inv[2], this->gain[2]); outputColor[3] = inputColor[3]; } diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp index 8ff58be7980..5f62f9ec403 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp @@ -23,7 +23,7 @@ #include "COM_ColorCorrectionOperation.h" #include "BLI_math.h" -ColorCorrectionOperation::ColorCorrectionOperation(): NodeOperation() +ColorCorrectionOperation::ColorCorrectionOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); @@ -47,7 +47,7 @@ void ColorCorrectionOperation::executePixel(float *output, float x, float y, Pix this->inputImage->read(inputImageColor, x, y, sampler, inputBuffers); this->inputMask->read(inputMask, x, y, sampler, inputBuffers); - float level = (inputImageColor[0] + inputImageColor[1] + inputImageColor[2])/3.0f; + float level = (inputImageColor[0] + inputImageColor[1] + inputImageColor[2]) / 3.0f; float contrast = this->data->master.contrast; float saturation = this->data->master.saturation; float gamma = this->data->master.gamma; @@ -83,11 +83,11 @@ void ColorCorrectionOperation::executePixel(float *output, float x, float y, Pix } #undef MARGIN #undef MARGIN_DIV - contrast *= (levelShadows*this->data->shadows.contrast)+(levelMidtones*this->data->midtones.contrast)+(levelHighlights*this->data->highlights.contrast); - saturation *= (levelShadows*this->data->shadows.saturation)+(levelMidtones*this->data->midtones.saturation)+(levelHighlights*this->data->highlights.saturation); - gamma *= (levelShadows*this->data->shadows.gamma)+(levelMidtones*this->data->midtones.gamma)+(levelHighlights*this->data->highlights.gamma); - gain *= (levelShadows*this->data->shadows.gain)+(levelMidtones*this->data->midtones.gain)+(levelHighlights*this->data->highlights.gain); - lift += (levelShadows*this->data->shadows.lift)+(levelMidtones*this->data->midtones.lift)+(levelHighlights*this->data->highlights.lift); + contrast *= (levelShadows * this->data->shadows.contrast) + (levelMidtones * this->data->midtones.contrast) + (levelHighlights * this->data->highlights.contrast); + saturation *= (levelShadows * this->data->shadows.saturation) + (levelMidtones * this->data->midtones.saturation) + (levelHighlights * this->data->highlights.saturation); + gamma *= (levelShadows * this->data->shadows.gamma) + (levelMidtones * this->data->midtones.gamma) + (levelHighlights * this->data->highlights.gamma); + gain *= (levelShadows * this->data->shadows.gain) + (levelMidtones * this->data->midtones.gain) + (levelHighlights * this->data->highlights.gain); + lift += (levelShadows * this->data->shadows.lift) + (levelMidtones * this->data->midtones.lift) + (levelHighlights * this->data->highlights.lift); float invgamma = 1.0f / gamma; float luma = rgb_to_luma_y(inputImageColor); @@ -104,15 +104,15 @@ void ColorCorrectionOperation::executePixel(float *output, float x, float y, Pix g = 0.5f + ((g - 0.5f) * contrast); b = 0.5f + ((b - 0.5f) * contrast); - r = powf(r*gain+lift, invgamma); - g = powf(g*gain+lift, invgamma); - b = powf(b*gain+lift, invgamma); + r = powf(r * gain + lift, invgamma); + g = powf(g * gain + lift, invgamma); + b = powf(b * gain + lift, invgamma); // mix with mask - r = mvalue*inputImageColor[0] + value * r; - g = mvalue*inputImageColor[1] + value * g; - b = mvalue*inputImageColor[2] + value * b; + r = mvalue * inputImageColor[0] + value * r; + g = mvalue * inputImageColor[1] + value * g; + b = mvalue * inputImageColor[2] + value * b; if (this->redChannelEnabled) { output[0] = r; diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp index c4336ed5e06..4feac3e7273 100644 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp @@ -31,7 +31,7 @@ extern "C" { #include "MEM_guardedalloc.h" #endif -ColorCurveOperation::ColorCurveOperation(): CurveBaseOperation() +ColorCurveOperation::ColorCurveOperation() : CurveBaseOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); @@ -60,8 +60,8 @@ void ColorCurveOperation::initExecution() void ColorCurveOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { - CurveMapping* cumap = this->curveMapping; - CurveMapping* workingCopy = (CurveMapping*)MEM_dupallocN(cumap); + CurveMapping *cumap = this->curveMapping; + CurveMapping *workingCopy = (CurveMapping *)MEM_dupallocN(cumap); float black[4]; float white[4]; @@ -104,7 +104,7 @@ void ColorCurveOperation::deinitExecution() // Constant level curve mapping -ConstantLevelColorCurveOperation::ConstantLevelColorCurveOperation(): CurveBaseOperation() +ConstantLevelColorCurveOperation::ConstantLevelColorCurveOperation() : CurveBaseOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.cpp b/source/blender/compositor/operations/COM_ColorMatteOperation.cpp index 7706559be00..afb362dbdcd 100644 --- a/source/blender/compositor/operations/COM_ColorMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorMatteOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ColorMatteOperation.h" #include "BLI_math.h" -ColorMatteOperation::ColorMatteOperation(): NodeOperation() +ColorMatteOperation::ColorMatteOperation() : NodeOperation() { addInputSocket(COM_DT_COLOR); addInputSocket(COM_DT_COLOR); @@ -64,16 +64,17 @@ void ColorMatteOperation::executePixel(float *outputValue, float x, float y, Pix */ if ( - /* do hue last because it needs to wrap, and does some more checks */ + /* do hue last because it needs to wrap, and does some more checks */ - /* sat */ (fabsf(inColor[1] - inKey[1]) < sat) && - /* val */ (fabsf(inColor[2] - inKey[2]) < val) && + /* sat */ (fabsf(inColor[1] - inKey[1]) < sat) && + /* val */ (fabsf(inColor[2] - inKey[2]) < val) && - /* multiply by 2 because it wraps on both sides of the hue, - * otherwise 0.5 would key all hue's */ + /* multiply by 2 because it wraps on both sides of the hue, + * otherwise 0.5 would key all hue's */ - /* hue */ ((h_wrap = 2.f * fabsf(inColor[0]-inKey[0])) < hue || (2.f - h_wrap) < hue) - ) { + /* hue */ ((h_wrap = 2.f * fabsf(inColor[0] - inKey[0])) < hue || (2.f - h_wrap) < hue) + ) + { outputValue[0] = 0.0f; /*make transparent*/ } diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.cpp b/source/blender/compositor/operations/COM_ColorRampOperation.cpp index 992bf3b9d1d..9af70ddc5a7 100644 --- a/source/blender/compositor/operations/COM_ColorRampOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorRampOperation.cpp @@ -30,7 +30,7 @@ extern "C" { } #endif -ColorRampOperation::ColorRampOperation(): NodeOperation() +ColorRampOperation::ColorRampOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.cpp b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp index 9b57d64eb40..1a534d778c0 100644 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp @@ -22,9 +22,9 @@ #include "COM_ColorSpillOperation.h" #include "BLI_math.h" -#define avg(a,b) ((a+b)/2) +#define AVG(a, b) ((a + b) / 2) -ColorSpillOperation::ColorSpillOperation(): NodeOperation() +ColorSpillOperation::ColorSpillOperation() : NodeOperation() { addInputSocket(COM_DT_COLOR); addInputSocket(COM_DT_VALUE); @@ -104,11 +104,11 @@ void ColorSpillOperation::executePixel(float *outputValue, float x, float y, Pix } float ColorSpillOperation::calculateMapValue(float fac, float *input) { - return fac * (input[this->spillChannel]-(this->settings->limscale*input[this->settings->limchan])); + return fac * (input[this->spillChannel] - (this->settings->limscale * input[this->settings->limchan])); } float ColorSpillAverageOperation::calculateMapValue(float fac, float *input) { - return fac * (input[this->spillChannel]-(this->settings->limscale*avg(input[this->channel2], input[this->channel3]))); + return fac * (input[this->spillChannel] - (this->settings->limscale * AVG(input[this->channel2], input[this->channel3]))); } diff --git a/source/blender/compositor/operations/COM_CombineChannelsOperation.cpp b/source/blender/compositor/operations/COM_CombineChannelsOperation.cpp index 6b64934f0b8..dff8ccf7e73 100644 --- a/source/blender/compositor/operations/COM_CombineChannelsOperation.cpp +++ b/source/blender/compositor/operations/COM_CombineChannelsOperation.cpp @@ -53,7 +53,7 @@ void CombineChannelsOperation::deinitExecution() } -void CombineChannelsOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void CombineChannelsOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { float input[4]; /// @todo: remove if statements diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp index df12a7d6b49..2e8fc9005b8 100644 --- a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp @@ -25,7 +25,7 @@ extern "C" { #include "IMB_imbuf.h" } -ConvertColorProfileOperation::ConvertColorProfileOperation(): NodeOperation() +ConvertColorProfileOperation::ConvertColorProfileOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp index f4be7d2e65b..c66cb8df9be 100644 --- a/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertColorToBWOperation.h" -ConvertColorToBWOperation::ConvertColorToBWOperation(): NodeOperation() +ConvertColorToBWOperation::ConvertColorToBWOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VALUE); @@ -38,7 +38,7 @@ void ConvertColorToBWOperation::executePixel(float *outputValue, float x, float { float inputColor[4]; inputOperation->read(&inputColor[0], x, y, sampler, inputBuffers); - outputValue[0] = inputColor[0]*0.35f + inputColor[1]*0.45f + inputColor[2]*0.2f; + outputValue[0] = inputColor[0] * 0.35f + inputColor[1] * 0.45f + inputColor[2] * 0.2f; } void ConvertColorToBWOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.cpp b/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.cpp index ce45266ace0..613bfe68fbb 100644 --- a/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertColorToVectorOperation.h" -ConvertColorToVectorOperation::ConvertColorToVectorOperation(): NodeOperation() +ConvertColorToVectorOperation::ConvertColorToVectorOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VECTOR); diff --git a/source/blender/compositor/operations/COM_ConvertColourToValueProg.cpp b/source/blender/compositor/operations/COM_ConvertColourToValueProg.cpp index 0d4f2df22d8..2c8caec6f61 100644 --- a/source/blender/compositor/operations/COM_ConvertColourToValueProg.cpp +++ b/source/blender/compositor/operations/COM_ConvertColourToValueProg.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertColourToValueProg.h" -ConvertColourToValueProg::ConvertColourToValueProg(): NodeOperation() +ConvertColourToValueProg::ConvertColourToValueProg() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VALUE); @@ -38,7 +38,7 @@ void ConvertColourToValueProg::executePixel(float *outputValue, float x, float y { float inputColor[4]; inputOperation->read(&inputColor[0], x, y, sampler, inputBuffers); - outputValue[0] = (inputColor[0] + inputColor[1] + inputColor[2])/3.0f; + outputValue[0] = (inputColor[0] + inputColor[1] + inputColor[2]) / 3.0f; } void ConvertColourToValueProg::deinitExecution() diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp index f64f0c054b1..1746afea713 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp @@ -24,7 +24,7 @@ #include "BLI_math.h" #include "DNA_camera_types.h" -ConvertDepthToRadiusOperation::ConvertDepthToRadiusOperation(): NodeOperation() +ConvertDepthToRadiusOperation::ConvertDepthToRadiusOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -41,7 +41,7 @@ float ConvertDepthToRadiusOperation::determineFocalDistance() return 10.0f; } else { - Camera *camera = (Camera*)this->cameraObject->data; + Camera *camera = (Camera *)this->cameraObject->data; cam_lens = camera->lens; if (camera->dof_ob) { /* too simple, better to return the distance on the view axis only @@ -62,12 +62,12 @@ void ConvertDepthToRadiusOperation::initExecution() { this->inputOperation = this->getInputSocketReader(0); float focalDistance = determineFocalDistance(); - if (focalDistance == 0.0f) focalDistance = 1e10f; /* if the dof is 0.0 then set it be be far away */ - inverseFocalDistance = 1.f/focalDistance; + if (focalDistance == 0.0f) focalDistance = 1e10f; /* if the dof is 0.0 then set it be be far away */ + inverseFocalDistance = 1.f / focalDistance; this->aspect = (this->getWidth() > this->getHeight()) ? (this->getHeight() / (float)this->getWidth()) : (this->getWidth() / (float)this->getHeight()); - this->aperture = 0.5f*(this->cam_lens / (this->aspect*32.f)) / this->fStop; + this->aperture = 0.5f * (this->cam_lens / (this->aspect * 32.f)) / this->fStop; float minsz = MIN2(getWidth(), getHeight()); - this->dof_sp = (float)minsz / (16.f / cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov); + this->dof_sp = (float)minsz / (16.f / cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov); } void ConvertDepthToRadiusOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) @@ -77,16 +77,16 @@ void ConvertDepthToRadiusOperation::executePixel(float *outputValue, float x, fl float radius; inputOperation->read(inputValue, x, y, sampler, inputBuffers); z = inputValue[0]; - if (z!=0.f) { - float iZ = (1.f/z); + if (z != 0.f) { + float iZ = (1.f / z); // bug #6656 part 2b, do not rescale - /* +#if 0 bcrad = 0.5f*fabs(aperture*(dof_sp*(cam_invfdist - iZ) - 1.f)); // scale crad back to original maximum and blend crad->rect[px] = bcrad + wts->rect[px]*(scf*crad->rect[px] - bcrad); - */ - radius = 0.5f*fabsf(this->aperture*(dof_sp*(inverseFocalDistance - iZ) - 1.f)); +#endif + radius = 0.5f * fabsf(this->aperture * (dof_sp * (inverseFocalDistance - iZ) - 1.f)); // 'bug' #6615, limit minimum radius to 1 pixel, not really a solution, but somewhat mitigates the problem if (radius < 0.5f) radius = 0.5f; if (radius > maxRadius) { diff --git a/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.cpp b/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.cpp index 97dd7e69092..e8c0061319c 100644 --- a/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.cpp @@ -23,7 +23,7 @@ #include "COM_ConvertHSVToRGBOperation.h" #include "BLI_math_color.h" -ConvertHSVToRGBOperation::ConvertHSVToRGBOperation(): NodeOperation() +ConvertHSVToRGBOperation::ConvertHSVToRGBOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp index db27e07d52f..842546a2755 100644 --- a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertKeyToPremulOperation.h" #include "BLI_math.h" -ConvertKeyToPremulOperation::ConvertKeyToPremulOperation(): NodeOperation() +ConvertKeyToPremulOperation::ConvertKeyToPremulOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp index 920b5f8a775..3554be53e3f 100644 --- a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertPremulToKeyOperation.h" #include "BLI_math.h" -ConvertPremulToKeyOperation::ConvertPremulToKeyOperation(): NodeOperation() +ConvertPremulToKeyOperation::ConvertPremulToKeyOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.cpp b/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.cpp index 99054efc267..051d9d2b8f9 100644 --- a/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.cpp @@ -23,7 +23,7 @@ #include "COM_ConvertRGBToHSVOperation.h" #include "BLI_math_color.h" -ConvertRGBToHSVOperation::ConvertRGBToHSVOperation(): NodeOperation() +ConvertRGBToHSVOperation::ConvertRGBToHSVOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp b/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp index ce62cf0ae49..d984a1ab943 100644 --- a/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertRGBToYCCOperation.h" #include "BLI_math_color.h" -ConvertRGBToYCCOperation::ConvertRGBToYCCOperation(): NodeOperation() +ConvertRGBToYCCOperation::ConvertRGBToYCCOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); @@ -38,16 +38,16 @@ void ConvertRGBToYCCOperation::setMode(int mode) { switch (mode) { - case 1: - this->mode = BLI_YCC_ITU_BT709; - break; - case 2: - this->mode = BLI_YCC_JFIF_0_255; - break; - case 0: - default: - this->mode = BLI_YCC_ITU_BT601; - break; + case 1: + this->mode = BLI_YCC_ITU_BT709; + break; + case 2: + this->mode = BLI_YCC_JFIF_0_255; + break; + case 0: + default: + this->mode = BLI_YCC_ITU_BT601; + break; } } diff --git a/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.cpp b/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.cpp index c4b870d6ad5..e5a8e7de1bb 100644 --- a/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertRGBToYUVOperation.h" #include "BLI_math_color.h" -ConvertRGBToYUVOperation::ConvertRGBToYUVOperation(): NodeOperation() +ConvertRGBToYUVOperation::ConvertRGBToYUVOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ConvertValueToColourProg.cpp b/source/blender/compositor/operations/COM_ConvertValueToColourProg.cpp index dce554efbac..9d95c51a546 100644 --- a/source/blender/compositor/operations/COM_ConvertValueToColourProg.cpp +++ b/source/blender/compositor/operations/COM_ConvertValueToColourProg.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertValueToColourProg.h" -ConvertValueToColourProg::ConvertValueToColourProg(): NodeOperation() +ConvertValueToColourProg::ConvertValueToColourProg() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.cpp b/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.cpp index ba7913d24ee..5ba3f6ef4a9 100644 --- a/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertValueToVectorOperation.h" -ConvertValueToVectorOperation::ConvertValueToVectorOperation(): NodeOperation() +ConvertValueToVectorOperation::ConvertValueToVectorOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VECTOR); diff --git a/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.cpp b/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.cpp index 5a4cc4d3549..f6a2072932c 100644 --- a/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertVectorToColorOperation.h" -ConvertVectorToColorOperation::ConvertVectorToColorOperation(): NodeOperation() +ConvertVectorToColorOperation::ConvertVectorToColorOperation() : NodeOperation() { this->addInputSocket(COM_DT_VECTOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.cpp b/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.cpp index 67cc42ac8fc..ef2d45eea03 100644 --- a/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertVectorToValueOperation.h" -ConvertVectorToValueOperation::ConvertVectorToValueOperation(): NodeOperation() +ConvertVectorToValueOperation::ConvertVectorToValueOperation() : NodeOperation() { this->addInputSocket(COM_DT_VECTOR); this->addOutputSocket(COM_DT_VALUE); @@ -38,7 +38,7 @@ void ConvertVectorToValueOperation::executePixel(float *outputValue, float x, fl { float input[4]; inputOperation->read(input, x, y, sampler, inputBuffers); - outputValue[0] = (input[0]+input[1]+input[2])/3.0f; + outputValue[0] = (input[0] + input[1] + input[2]) / 3.0f; } void ConvertVectorToValueOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp b/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp index dbfe4847c78..373de25a276 100644 --- a/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertYCCToRGBOperation.h" #include "BLI_math_color.h" -ConvertYCCToRGBOperation::ConvertYCCToRGBOperation(): NodeOperation() +ConvertYCCToRGBOperation::ConvertYCCToRGBOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); @@ -38,16 +38,16 @@ void ConvertYCCToRGBOperation::setMode(int mode) { switch (mode) { - case 1: - this->mode = BLI_YCC_ITU_BT709; - break; - case 2: - this->mode = BLI_YCC_JFIF_0_255; - break; - case 0: - default: - this->mode = BLI_YCC_ITU_BT601; - break; + case 1: + this->mode = BLI_YCC_ITU_BT709; + break; + case 2: + this->mode = BLI_YCC_JFIF_0_255; + break; + case 0: + default: + this->mode = BLI_YCC_ITU_BT601; + break; } } diff --git a/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.cpp b/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.cpp index d7037a2c2d1..a77806d16d0 100644 --- a/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.cpp @@ -22,7 +22,7 @@ #include "COM_ConvertYUVToRGBOperation.h" #include "BLI_math_color.h" -ConvertYUVToRGBOperation::ConvertYUVToRGBOperation(): NodeOperation() +ConvertYUVToRGBOperation::ConvertYUVToRGBOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp index 18a12a21f26..5ac8c2254dc 100644 --- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp @@ -28,9 +28,9 @@ ConvolutionEdgeFilterOperation::ConvolutionEdgeFilterOperation() : ConvolutionFi /* pass */ } -void ConvolutionEdgeFilterOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data) +void ConvolutionEdgeFilterOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { - float in1[4],in2[4], res1[4], res2[4]; + float in1[4], in2[4], res1[4], res2[4]; int x1 = x - 1; int x2 = x; @@ -38,12 +38,12 @@ void ConvolutionEdgeFilterOperation::executePixel(float *color,int x, int y, Mem int y1 = y - 1; int y2 = y; int y3 = y + 1; - CLAMP(x1, 0, getWidth()-1); - CLAMP(x2, 0, getWidth()-1); - CLAMP(x3, 0, getWidth()-1); - CLAMP(y1, 0, getHeight()-1); - CLAMP(y2, 0, getHeight()-1); - CLAMP(y3, 0, getHeight()-1); + CLAMP(x1, 0, getWidth() - 1); + CLAMP(x2, 0, getWidth() - 1); + CLAMP(x3, 0, getWidth() - 1); + CLAMP(y1, 0, getHeight() - 1); + CLAMP(y2, 0, getHeight() - 1); + CLAMP(y3, 0, getHeight() - 1); float value[4]; this->inputValueOperation->read(value, x2, y2, inputBuffers, NULL); diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp index 3c9cde92e2e..b4f2714360e 100644 --- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp @@ -61,13 +61,13 @@ void ConvolutionFilterOperation::deinitExecution() this->inputOperation = NULL; this->inputValueOperation = NULL; if (this->filter) { - delete [] this->filter; + delete[] this->filter; this->filter = NULL; } } -void ConvolutionFilterOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data) +void ConvolutionFilterOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { float in1[4]; float in2[4]; @@ -77,12 +77,12 @@ void ConvolutionFilterOperation::executePixel(float *color,int x, int y, MemoryB int y1 = y - 1; int y2 = y; int y3 = y + 1; - CLAMP(x1, 0, getWidth()-1); - CLAMP(x2, 0, getWidth()-1); - CLAMP(x3, 0, getWidth()-1); - CLAMP(y1, 0, getHeight()-1); - CLAMP(y2, 0, getHeight()-1); - CLAMP(y3, 0, getHeight()-1); + CLAMP(x1, 0, getWidth() - 1); + CLAMP(x2, 0, getWidth() - 1); + CLAMP(x3, 0, getWidth() - 1); + CLAMP(y1, 0, getHeight() - 1); + CLAMP(y2, 0, getHeight() - 1); + CLAMP(y3, 0, getHeight() - 1); float value[4]; this->inputValueOperation->read(value, x2, y2, inputBuffers, NULL); const float mval = 1.0f - value[0]; @@ -116,8 +116,8 @@ void ConvolutionFilterOperation::executePixel(float *color,int x, int y, MemoryB bool ConvolutionFilterOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { rcti newInput; - int addx = (this->filterWidth-1)/2+1; - int addy = (this->filterHeight-1)/2+1; + int addx = (this->filterWidth - 1) / 2 + 1; + int addy = (this->filterHeight - 1) / 2 + 1; newInput.xmax = input->xmax + addx; newInput.xmin = input->xmin - addx; newInput.ymax = input->ymax + addy; diff --git a/source/blender/compositor/operations/COM_CropOperation.cpp b/source/blender/compositor/operations/COM_CropOperation.cpp index 9b105bb2760..0bdd2cfcb51 100644 --- a/source/blender/compositor/operations/COM_CropOperation.cpp +++ b/source/blender/compositor/operations/COM_CropOperation.cpp @@ -23,7 +23,7 @@ #include "COM_CropOperation.h" #include "BLI_math.h" -CropBaseOperation::CropBaseOperation() :NodeOperation() +CropBaseOperation::CropBaseOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->addOutputSocket(COM_DT_COLOR); @@ -33,7 +33,7 @@ CropBaseOperation::CropBaseOperation() :NodeOperation() void CropBaseOperation::updateArea() { - SocketReader * inputReference = this->getInputSocketReader(0); + SocketReader *inputReference = this->getInputSocketReader(0); float width = inputReference->getWidth(); float height = inputReference->getHeight(); if (this->relative) { @@ -68,7 +68,7 @@ void CropBaseOperation::deinitExecution() this->inputOperation = NULL; } -CropOperation::CropOperation() :CropBaseOperation() +CropOperation::CropOperation() : CropBaseOperation() { /* pass */ } @@ -86,7 +86,7 @@ void CropOperation::executePixel(float *color, float x, float y, PixelSampler sa } } -CropImageOperation::CropImageOperation() :CropBaseOperation() +CropImageOperation::CropImageOperation() : CropBaseOperation() { /* pass */ } diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.cpp b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp index fda5b00e2a0..6aa8bc2a0df 100644 --- a/source/blender/compositor/operations/COM_CurveBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp @@ -30,7 +30,7 @@ extern "C" { } #endif -CurveBaseOperation::CurveBaseOperation(): NodeOperation() +CurveBaseOperation::CurveBaseOperation() : NodeOperation() { this->curveMapping = NULL; } diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp index 0b1ac1b2127..c27e699f627 100644 --- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp @@ -23,7 +23,7 @@ #include "COM_DifferenceMatteOperation.h" #include "BLI_math.h" -DifferenceMatteOperation::DifferenceMatteOperation(): NodeOperation() +DifferenceMatteOperation::DifferenceMatteOperation() : NodeOperation() { addInputSocket(COM_DT_COLOR); addInputSocket(COM_DT_COLOR); @@ -49,8 +49,8 @@ void DifferenceMatteOperation::executePixel(float *outputValue, float x, float y float inColor1[4]; float inColor2[4]; - const float tolerence=this->settings->t1; - const float falloff=this->settings->t2; + const float tolerence = this->settings->t1; + const float falloff = this->settings->t2; float difference; float alpha; @@ -69,15 +69,15 @@ void DifferenceMatteOperation::executePixel(float *outputValue, float x, float y outputValue[0] = 0.0f; } /*in the falloff region, make partially transparent */ - else if (difference < falloff+tolerence) { - difference=difference-tolerence; - alpha=difference/falloff; + else if (difference < falloff + tolerence) { + difference = difference - tolerence; + alpha = difference / falloff; /*only change if more transparent than before */ if (alpha < inColor1[3]) { - outputValue[0]=alpha; + outputValue[0] = alpha; } else { /* leave as before */ - outputValue[0]=inColor1[3]; + outputValue[0] = inColor1[3]; } } else { diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cpp b/source/blender/compositor/operations/COM_DisplaceOperation.cpp index 2add367f39e..be50641a125 100644 --- a/source/blender/compositor/operations/COM_DisplaceOperation.cpp +++ b/source/blender/compositor/operations/COM_DisplaceOperation.cpp @@ -23,7 +23,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -DisplaceOperation::DisplaceOperation(): NodeOperation() +DisplaceOperation::DisplaceOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VECTOR); @@ -52,14 +52,14 @@ void DisplaceOperation::initExecution() /* minimum distance (in pixels) a pixel has to be displaced * in order to take effect */ -#define DISPLACE_EPSILON 0.01f +#define DISPLACE_EPSILON 0.01f void DisplaceOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { float inVector[4]; float inScale[4]; - float p_dx, p_dy; /* main displacement in pixel space */ + float p_dx, p_dy; /* main displacement in pixel space */ float d_dx, d_dy; float dxt, dyt; float u, v; @@ -83,17 +83,17 @@ void DisplaceOperation::executePixel(float *color, int x, int y, MemoryBuffer *i v = y - p_dy + 0.5f; /* calc derivatives */ - this->inputVectorProgram->read(inVector, x+1, y, COM_PS_NEAREST, inputBuffers); + this->inputVectorProgram->read(inVector, x + 1, y, COM_PS_NEAREST, inputBuffers); d_dx = inVector[0] * xs; - this->inputVectorProgram->read(inVector, x, y+1, COM_PS_NEAREST, inputBuffers); + this->inputVectorProgram->read(inVector, x, y + 1, COM_PS_NEAREST, inputBuffers); d_dy = inVector[0] * ys; /* clamp derivatives to minimum displacement distance in UV space */ dxt = p_dx - d_dx; dyt = p_dy - d_dy; - dxt = signf(dxt)*maxf(fabsf(dxt), DISPLACE_EPSILON)/this->getWidth(); - dyt = signf(dyt)*maxf(fabsf(dyt), DISPLACE_EPSILON)/this->getHeight(); + dxt = signf(dxt) * maxf(fabsf(dxt), DISPLACE_EPSILON) / this->getWidth(); + dyt = signf(dyt) * maxf(fabsf(dyt), DISPLACE_EPSILON) / this->getHeight(); /* EWA filtering */ this->inputColorProgram->read(color, u, v, dxt, dyt, inputBuffers); @@ -111,7 +111,7 @@ bool DisplaceOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffer { rcti colorInput; rcti vectorInput; - NodeOperation *operation=NULL; + NodeOperation *operation = NULL; /* the vector buffer only needs a 2x2 buffer. The image needs whole buffer */ /* image */ diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp index 8675caca1e2..716646e9c36 100644 --- a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp +++ b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp @@ -23,7 +23,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -DisplaceSimpleOperation::DisplaceSimpleOperation(): NodeOperation() +DisplaceSimpleOperation::DisplaceSimpleOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VECTOR); @@ -51,14 +51,14 @@ void DisplaceSimpleOperation::initExecution() /* minimum distance (in pixels) a pixel has to be displaced * in order to take effect */ -#define DISPLACE_EPSILON 0.01f +#define DISPLACE_EPSILON 0.01f void DisplaceSimpleOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { float inVector[4]; float inScale[4]; - float p_dx, p_dy; /* main displacement in pixel space */ + float p_dx, p_dy; /* main displacement in pixel space */ float u, v; this->inputScaleXProgram->read(inScale, x, y, sampler, inputBuffers); @@ -79,8 +79,8 @@ void DisplaceSimpleOperation::executePixel(float *color, float x, float y, Pixel /* clamp nodes to avoid glitches */ u = x - p_dx + 0.5f; v = y - p_dy + 0.5f; - CLAMP(u, 0.f, this->getWidth()-1.f); - CLAMP(v, 0.f, this->getHeight()-1.f); + CLAMP(u, 0.f, this->getWidth() - 1.f); + CLAMP(v, 0.f, this->getHeight() - 1.f); this->inputColorProgram->read(color, u, v, sampler, inputBuffers); } @@ -96,7 +96,7 @@ void DisplaceSimpleOperation::deinitExecution() bool DisplaceSimpleOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { rcti colorInput; - NodeOperation *operation=NULL; + NodeOperation *operation = NULL; /* the vector buffer only needs a 2x2 buffer. The image needs whole buffer */ /* image */ diff --git a/source/blender/compositor/operations/COM_DistanceMatteOperation.cpp b/source/blender/compositor/operations/COM_DistanceMatteOperation.cpp index 304f7fa5066..ec01ba922b5 100644 --- a/source/blender/compositor/operations/COM_DistanceMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_DistanceMatteOperation.cpp @@ -22,7 +22,7 @@ #include "COM_DistanceMatteOperation.h" #include "BLI_math.h" -DistanceMatteOperation::DistanceMatteOperation(): NodeOperation() +DistanceMatteOperation::DistanceMatteOperation() : NodeOperation() { addInputSocket(COM_DT_COLOR); addInputSocket(COM_DT_COLOR); @@ -49,8 +49,8 @@ void DistanceMatteOperation::executePixel(float *outputValue, float x, float y, float inKey[4]; float inImage[4]; - const float tolerence=this->settings->t1; - const float falloff=this->settings->t2; + const float tolerence = this->settings->t1; + const float falloff = this->settings->t2; float distance; float alpha; @@ -58,9 +58,9 @@ void DistanceMatteOperation::executePixel(float *outputValue, float x, float y, this->inputKeyProgram->read(inKey, x, y, sampler, inputBuffers); this->inputImageProgram->read(inImage, x, y, sampler, inputBuffers); - distance = sqrt(pow((inKey[0]-inImage[0]),2)+ - pow((inKey[1]-inImage[1]),2)+ - pow((inKey[2]-inImage[2]),2)); + distance = sqrt(pow((inKey[0] - inImage[0]), 2) + + pow((inKey[1] - inImage[1]), 2) + + pow((inKey[2] - inImage[2]), 2)); /* store matte(alpha) value in [0] to go with * COM_SetAlphaOperation and the Value output @@ -68,23 +68,23 @@ void DistanceMatteOperation::executePixel(float *outputValue, float x, float y, /*make 100% transparent */ if (distance < tolerence) { - outputValue[0]=0.f; + outputValue[0] = 0.f; } /*in the falloff region, make partially transparent */ - else if (distance < falloff+tolerence) { - distance=distance-tolerence; - alpha=distance/falloff; + else if (distance < falloff + tolerence) { + distance = distance - tolerence; + alpha = distance / falloff; /*only change if more transparent than before */ if (alpha < inImage[3]) { - outputValue[0]=alpha; + outputValue[0] = alpha; } else { /* leave as before */ - outputValue[0]=inImage[3]; + outputValue[0] = inImage[3]; } } else { - /* leave as before */ - outputValue[0]=inImage[3]; + /* leave as before */ + outputValue[0] = inImage[3]; } } diff --git a/source/blender/compositor/operations/COM_DotproductOperation.cpp b/source/blender/compositor/operations/COM_DotproductOperation.cpp index b03b176f08a..e225a677989 100644 --- a/source/blender/compositor/operations/COM_DotproductOperation.cpp +++ b/source/blender/compositor/operations/COM_DotproductOperation.cpp @@ -44,12 +44,12 @@ void DotproductOperation::deinitExecution() } /** @todo: current implementation is the inverse of a dotproduct. not 'logically' correct - */ -void DotproductOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) + */ +void DotproductOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { float input1[4]; float input2[4]; this->input1Operation->read(input1, x, y, sampler, inputBuffers); this->input2Operation->read(input2, x, y, sampler, inputBuffers); - color[0] = -(input1[0]*input2[0]+input1[1]*input2[1]+input1[2]*input2[2]); + color[0] = -(input1[0] * input2[0] + input1[1] * input2[1] + input1[2] * input2[2]); } diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp index df04b889200..ba54c8ad9d6 100644 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp @@ -30,735 +30,735 @@ static void do_adjacentKeepBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize) { int x; - unsigned int isz=0; // inner edge size - unsigned int osz=0; // outer edge size - unsigned int gsz=0; // gradient fill area size + unsigned int isz = 0; // inner edge size + unsigned int osz = 0; // outer edge size + unsigned int gsz = 0; // gradient fill area size /* Test the four corners */ /* upper left corner */ - x=t-rw+1; + x = t - rw + 1; // test if inner mask is filled if (limask[x]) { // test if pixel underneath, or to the right, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+1] && lomask[x+1])) { + if ((!limask[x - rw] && lomask[x - rw]) || (!limask[x + 1] && lomask[x + 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size lres[x] = 3; // flag pixel as outer edge } /* upper right corner */ - x=t; + x = t; // test if inner mask is filled if (limask[x]) { // test if pixel underneath, or to the left, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x-1] && lomask[x-1])) { + if ((!limask[x - rw] && lomask[x - rw]) || (!limask[x - 1] && lomask[x - 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } /* lower left corner */ - x=0; + x = 0; // test if inner mask is filled if (limask[x]) { // test if pixel above, or to the right, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x+rw] && lomask[x+rw]) || (!limask[x+1] && lomask[x+1])) { + if ((!limask[x + rw] && lomask[x + rw]) || (!limask[x + 1] && lomask[x + 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } /* lower right corner */ - x=rw-1; + x = rw - 1; // test if inner mask is filled if (limask[x]) { // test if pixel above, or to the left, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x+rw] && lomask[x+rw]) || (!limask[x-1] && lomask[x-1])) { + if ((!limask[x + rw] && lomask[x + rw]) || (!limask[x - 1] && lomask[x - 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } /* Test the TOP row of pixels in buffer, except corners */ - for (x = t-1; x>=(t-rw)+2; x--) { + for (x = t - 1; x >= (t - rw) + 2; x--) { // test if inner mask is filled if (limask[x]) { // test if pixel to the right, or to the left, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + if ((!limask[x - 1] && lomask[x - 1]) || (!limask[x + 1] && lomask[x + 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } } /* Test the BOTTOM row of pixels in buffer, except corners */ - for (x = rw-2; x; x--) { + for (x = rw - 2; x; x--) { // test if inner mask is filled if (limask[x]) { // test if pixel to the right, or to the left, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + if ((!limask[x - 1] && lomask[x - 1]) || (!limask[x + 1] && lomask[x + 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } } /* Test the LEFT edge of pixels in buffer, except corners */ - for (x = t-(rw<<1)+1; x>=rw; x-=rw) { + for (x = t - (rw << 1) + 1; x >= rw; x -= rw) { // test if inner mask is filled if (limask[x]) { // test if pixel underneath, or above, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + if ((!limask[x - rw] && lomask[x - rw]) || (!limask[x + rw] && lomask[x + rw])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } } /* Test the RIGHT edge of pixels in buffer, except corners */ - for (x = t-rw; x>rw; x-=rw) { + for (x = t - rw; x > rw; x -= rw) { // test if inner mask is filled if (limask[x]) { // test if pixel underneath, or above, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + if ((!limask[x - rw] && lomask[x - rw]) || (!limask[x + rw] && lomask[x + rw])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } } - rsize[0]=isz; // fill in our return sizes for edges + fill - rsize[1]=osz; - rsize[2]=gsz; + rsize[0] = isz; // fill in our return sizes for edges + fill + rsize[1] = osz; + rsize[2] = gsz; } static void do_adjacentBleedBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize) { int x; - unsigned int isz=0; // inner edge size - unsigned int osz=0; // outer edge size - unsigned int gsz=0; // gradient fill area size + unsigned int isz = 0; // inner edge size + unsigned int osz = 0; // outer edge size + unsigned int gsz = 0; // gradient fill area size /* Test the four corners */ /* upper left corner */ - x=t-rw+1; + x = t - rw + 1; // test if inner mask is filled if (limask[x]) { // test if pixel underneath, or to the right, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+1] && lomask[x+1])) { + if ((!limask[x - rw] && lomask[x - rw]) || (!limask[x + 1] && lomask[x + 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right + if (!lomask[x - rw] || !lomask[x + 1]) { // test if outer mask is empty underneath or to the right osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } /* upper right corner */ - x=t; + x = t; // test if inner mask is filled if (limask[x]) { // test if pixel underneath, or to the left, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x-1] && lomask[x-1])) { + if ((!limask[x - rw] && lomask[x - rw]) || (!limask[x - 1] && lomask[x - 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-rw] || !lomask[x-1]) { // test if outer mask is empty underneath or to the left + if (!lomask[x - rw] || !lomask[x - 1]) { // test if outer mask is empty underneath or to the left osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } /* lower left corner */ - x=0; + x = 0; // test if inner mask is filled if (limask[x]) { // test if pixel above, or to the right, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x+rw] && lomask[x+rw]) || (!limask[x+1] && lomask[x+1])) { + if ((!limask[x + rw] && lomask[x + rw]) || (!limask[x + 1] && lomask[x + 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x+rw] || !lomask[x+1]) { // test if outer mask is empty above or to the right + if (!lomask[x + rw] || !lomask[x + 1]) { // test if outer mask is empty above or to the right osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } /* lower right corner */ - x=rw-1; + x = rw - 1; // test if inner mask is filled if (limask[x]) { // test if pixel above, or to the left, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x+rw] && lomask[x+rw]) || (!limask[x-1] && lomask[x-1])) { + if ((!limask[x + rw] && lomask[x + rw]) || (!limask[x - 1] && lomask[x - 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x+rw] || !lomask[x-1]) { // test if outer mask is empty above or to the left + if (!lomask[x + rw] || !lomask[x - 1]) { // test if outer mask is empty above or to the left osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } /* Test the TOP row of pixels in buffer, except corners */ - for (x = t-1; x>=(t-rw)+2; x--) { + for (x = t - 1; x >= (t - rw) + 2; x--) { // test if inner mask is filled if (limask[x]) { // test if pixel to the left, or to the right, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + if ((!limask[x - 1] && lomask[x - 1]) || (!limask[x + 1] && lomask[x + 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + if (!lomask[x - 1] || !lomask[x + 1]) { // test if outer mask is empty to the left or to the right osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } } /* Test the BOTTOM row of pixels in buffer, except corners */ - for (x = rw-2; x; x--) { + for (x = rw - 2; x; x--) { // test if inner mask is filled if (limask[x]) { // test if pixel to the left, or to the right, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + if ((!limask[x - 1] && lomask[x - 1]) || (!limask[x + 1] && lomask[x + 1])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + if (!lomask[x - 1] || !lomask[x + 1]) { // test if outer mask is empty to the left or to the right osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } } /* Test the LEFT edge of pixels in buffer, except corners */ - for (x = t-(rw<<1)+1; x>=rw; x-=rw) { + for (x = t - (rw << 1) + 1; x >= rw; x -= rw) { // test if inner mask is filled if (limask[x]) { // test if pixel underneath, or above, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + if ((!limask[x - rw] && lomask[x - rw]) || (!limask[x + rw] && lomask[x + rw])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + if (!lomask[x - rw] || !lomask[x + rw]) { // test if outer mask is empty underneath or above osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } } /* Test the RIGHT edge of pixels in buffer, except corners */ - for (x = t-rw; x>rw; x-=rw) { + for (x = t - rw; x > rw; x -= rw) { // test if inner mask is filled if (limask[x]) { // test if pixel underneath, or above, are empty in the inner mask, // but filled in the outer mask - if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + if ((!limask[x - rw] && lomask[x - rw]) || (!limask[x + rw] && lomask[x + rw])) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + if (!lomask[x - rw] || !lomask[x + rw]) { // test if outer mask is empty underneath or above osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } } - rsize[0]=isz; // fill in our return sizes for edges + fill - rsize[1]=osz; - rsize[2]=gsz; + rsize[0] = isz; // fill in our return sizes for edges + fill + rsize[1] = osz; + rsize[2] = gsz; } static void do_allKeepBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize) { int x; - unsigned int isz=0; // inner edge size - unsigned int osz=0; // outer edge size - unsigned int gsz=0; // gradient fill area size + unsigned int isz = 0; // inner edge size + unsigned int osz = 0; // outer edge size + unsigned int gsz = 0; // gradient fill area size /* Test the four corners */ /* upper left corner */ - x=t-rw+1; + x = t - rw + 1; // test if inner mask is filled if (limask[x]) { // test if the inner mask is empty underneath or to the right - if (!limask[x-rw] || !limask[x+1]) { + if (!limask[x - rw] || !limask[x + 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } /* upper right corner */ - x=t; + x = t; // test if inner mask is filled if (limask[x]) { // test if the inner mask is empty underneath or to the left - if (!limask[x-rw] || !limask[x-1]) { + if (!limask[x - rw] || !limask[x - 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } /* lower left corner */ - x=0; + x = 0; // test if inner mask is filled if (limask[x]) { // test if inner mask is empty above or to the right - if (!limask[x+rw] || !limask[x+1]) { + if (!limask[x + rw] || !limask[x + 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } /* lower right corner */ - x=rw-1; + x = rw - 1; // test if inner mask is filled if (limask[x]) { // test if inner mask is empty above or to the left - if (!limask[x+rw] || !limask[x-1]) { + if (!limask[x + rw] || !limask[x - 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } /* Test the TOP row of pixels in buffer, except corners */ - for (x = t-1; x>=(t-rw)+2; x--) { + for (x = t - 1; x >= (t - rw) + 2; x--) { // test if inner mask is filled if (limask[x]) { // test if inner mask is empty to the left or to the right - if (!limask[x-1] || !limask[x+1]) { + if (!limask[x - 1] || !limask[x + 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } } /* Test the BOTTOM row of pixels in buffer, except corners */ - for (x = rw-2; x; x--) { + for (x = rw - 2; x; x--) { // test if inner mask is filled if (limask[x]) { // test if inner mask is empty to the left or to the right - if (!limask[x-1] || !limask[x+1]) { + if (!limask[x - 1] || !limask[x + 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } } /* Test the LEFT edge of pixels in buffer, except corners */ - for (x = t-(rw<<1)+1; x>=rw; x-=rw) { + for (x = t - (rw << 1) + 1; x >= rw; x -= rw) { // test if inner mask is filled if (limask[x]) { // test if inner mask is empty underneath or above - if (!limask[x-rw] || !limask[x+rw]) { + if (!limask[x - rw] || !limask[x + rw]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } } /* Test the RIGHT edge of pixels in buffer, except corners */ - for (x = t-rw; x>rw; x-=rw) { + for (x = t - rw; x > rw; x -= rw) { // test if inner mask is filled if (limask[x]) { // test if inner mask is empty underneath or above - if (!limask[x-rw] || !limask[x+rw]) { + if (!limask[x - rw] || !limask[x + rw]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } } - rsize[0]=isz; // fill in our return sizes for edges + fill - rsize[1]=osz; - rsize[2]=gsz; + rsize[0] = isz; // fill in our return sizes for edges + fill + rsize[1] = osz; + rsize[2] = gsz; } static void do_allBleedBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize) { int x; - unsigned int isz=0; // inner edge size - unsigned int osz=0; // outer edge size - unsigned int gsz=0; // gradient fill area size + unsigned int isz = 0; // inner edge size + unsigned int osz = 0; // outer edge size + unsigned int gsz = 0; // gradient fill area size /* Test the four corners */ /* upper left corner */ - x=t-rw+1; + x = t - rw + 1; // test if inner mask is filled if (limask[x]) { // test if the inner mask is empty underneath or to the right - if (!limask[x-rw] || !limask[x+1]) { + if (!limask[x - rw] || !limask[x + 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right + if (!lomask[x - rw] || !lomask[x + 1]) { // test if outer mask is empty underneath or to the right osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } /* upper right corner */ - x=t; + x = t; // test if inner mask is filled if (limask[x]) { // test if the inner mask is empty underneath or to the left - if (!limask[x-rw] || !limask[x-1]) { + if (!limask[x - rw] || !limask[x - 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-rw] || !lomask[x-1]) { // test if outer mask is empty above or to the left + if (!lomask[x - rw] || !lomask[x - 1]) { // test if outer mask is empty above or to the left osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } /* lower left corner */ - x=0; + x = 0; // test if inner mask is filled if (limask[x]) { // test if inner mask is empty above or to the right - if (!limask[x+rw] || !limask[x+1]) { + if (!limask[x + rw] || !limask[x + 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x+rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right + if (!lomask[x + rw] || !lomask[x + 1]) { // test if outer mask is empty underneath or to the right osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } /* lower right corner */ - x=rw-1; + x = rw - 1; // test if inner mask is filled if (limask[x]) { // test if inner mask is empty above or to the left - if (!limask[x+rw] || !limask[x-1]) { + if (!limask[x + rw] || !limask[x - 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x+rw] || !lomask[x-1]) { // test if outer mask is empty underneath or to the left + if (!lomask[x + rw] || !lomask[x - 1]) { // test if outer mask is empty underneath or to the left osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } /* Test the TOP row of pixels in buffer, except corners */ - for (x = t-1; x>=(t-rw)+2; x--) { + for (x = t - 1; x >= (t - rw) + 2; x--) { // test if inner mask is filled if (limask[x]) { // test if inner mask is empty to the left or to the right - if (!limask[x-1] || !limask[x+1]) { + if (!limask[x - 1] || !limask[x + 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + if (!lomask[x - 1] || !lomask[x + 1]) { // test if outer mask is empty to the left or to the right osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } } /* Test the BOTTOM row of pixels in buffer, except corners */ - for (x = rw-2; x; x--) { + for (x = rw - 2; x; x--) { // test if inner mask is filled if (limask[x]) { // test if inner mask is empty to the left or to the right - if (!limask[x-1] || !limask[x+1]) { + if (!limask[x - 1] || !limask[x + 1]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + if (!lomask[x - 1] || !lomask[x + 1]) { // test if outer mask is empty to the left or to the right osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } } /* Test the LEFT edge of pixels in buffer, except corners */ - for (x = t-(rw<<1)+1; x>=rw; x-=rw) { + for (x = t - (rw << 1) + 1; x >= rw; x -= rw) { // test if inner mask is filled if (limask[x]) { // test if inner mask is empty underneath or above - if (!limask[x-rw] || !limask[x+rw]) { + if (!limask[x - rw] || !limask[x + rw]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + if (!lomask[x - rw] || !lomask[x + rw]) { // test if outer mask is empty underneath or above osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } } /* Test the RIGHT edge of pixels in buffer, except corners */ - for (x = t-rw; x>rw; x-=rw) { + for (x = t - rw; x > rw; x -= rw) { // test if inner mask is filled if (limask[x]) { // test if inner mask is empty underneath or above - if (!limask[x-rw] || !limask[x+rw]) { + if (!limask[x - rw] || !limask[x + rw]) { isz++; // increment inner edge size - lres[x]=4; // flag pixel as inner edge + lres[x] = 4; // flag pixel as inner edge } else { - res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + res[x] = 1.0f; // pixel is just part of inner mask, and it's not an edge } } - else if (lomask[x]) { // inner mask was empty, test if outer mask is filled - if (!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + else if (lomask[x]) { // inner mask was empty, test if outer mask is filled + if (!lomask[x - rw] || !lomask[x + rw]) { // test if outer mask is empty underneath or above osz++; // increment outer edge size - lres[x]=3; // flag pixel as outer edge + lres[x] = 3; // flag pixel as outer edge } else { gsz++; // increment the gradient pixel count - lres[x]=2; // flag pixel as gradient + lres[x] = 2; // flag pixel as gradient } } } - rsize[0]=isz; // fill in our return sizes for edges + fill - rsize[1]=osz; - rsize[2]=gsz; + rsize[0] = isz; // fill in our return sizes for edges + fill + rsize[1] = osz; + rsize[2] = gsz; } static void do_allEdgeDetection(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize, unsigned int in_isz, unsigned int in_osz, unsigned int in_gsz) @@ -771,43 +771,43 @@ static void do_allEdgeDetection(unsigned int t, unsigned int rw, unsigned int *l int pix_prevCol; // pix_prevCol = pixel one column behind the one we are testing in a loop int pix_nextCol; // pix_nextCol = pixel one column in front of the one we are testing in a loop /* Test all rows between the FIRST and LAST rows, excluding left and right edges */ - for (x = (t-rw)+1, dx=x-(rw-2); dx>rw; x-=rw,dx-=rw) { - a=x-2; - pix_prevRow=a+rw; - pix_nextRow=a-rw; - pix_prevCol=a+1; - pix_nextCol=a-1; - while (a>dx-2) { + for (x = (t - rw) + 1, dx = x - (rw - 2); dx > rw; x -= rw, dx -= rw) { + a = x - 2; + pix_prevRow = a + rw; + pix_nextRow = a - rw; + pix_prevCol = a + 1; + pix_nextCol = a - 1; + while (a > dx - 2) { if (!limask[a]) { // if the inner mask is empty if (lomask[a]) { // if the outer mask is full /* - Next we test all 4 directions around the current pixel: next/prev/up/down - The test ensures that the outer mask is empty and that the inner mask - is also empty. If both conditions are true for any one of the 4 adjacent pixels - then the current pixel is counted as being a true outer edge pixel. - */ + Next we test all 4 directions around the current pixel: next/prev/up/down + The test ensures that the outer mask is empty and that the inner mask + is also empty. If both conditions are true for any one of the 4 adjacent pixels + then the current pixel is counted as being a true outer edge pixel. + */ if ((!lomask[pix_nextCol] && !limask[pix_nextCol]) || (!lomask[pix_prevCol] && !limask[pix_prevCol]) || (!lomask[pix_nextRow] && !limask[pix_nextRow]) || (!lomask[pix_prevRow] && !limask[pix_prevRow])) { - in_osz++; // increment the outer boundary pixel count - lres[a]=3; // flag pixel as part of outer edge + in_osz++; // increment the outer boundary pixel count + lres[a] = 3; // flag pixel as part of outer edge } - else { // it's not a boundary pixel, but it is a gradient pixel - in_gsz++; // increment the gradient pixel count - lres[a]=2; // flag pixel as gradient + else { // it's not a boundary pixel, but it is a gradient pixel + in_gsz++; // increment the gradient pixel count + lres[a] = 2; // flag pixel as gradient } } } else { if (!limask[pix_nextCol] || !limask[pix_prevCol] || !limask[pix_nextRow] || !limask[pix_prevRow]) { - in_isz++; // increment the inner boundary pixel count - lres[a]=4; // flag pixel as part of inner edge + in_isz++; // increment the inner boundary pixel count + lres[a] = 4; // flag pixel as part of inner edge } else { - res[a]=1.0f; // pixel is part of inner mask, but not at an edge + res[a] = 1.0f; // pixel is part of inner mask, but not at an edge } } a--; @@ -818,9 +818,9 @@ static void do_allEdgeDetection(unsigned int t, unsigned int rw, unsigned int *l } } - rsize[0]=in_isz; // fill in our return sizes for edges + fill - rsize[1]=in_osz; - rsize[2]=in_gsz; + rsize[0] = in_isz; // fill in our return sizes for edges + fill + rsize[1] = in_osz; + rsize[2] = in_gsz; } static void do_adjacentEdgeDetection(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize, unsigned int in_isz, unsigned int in_osz, unsigned int in_gsz) @@ -833,32 +833,32 @@ static void do_adjacentEdgeDetection(unsigned int t, unsigned int rw, unsigned i int pix_prevCol; // pix_prevCol = pixel one column behind the one we are testing in a loop int pix_nextCol; // pix_nextCol = pixel one column in front of the one we are testing in a loop /* Test all rows between the FIRST and LAST rows, excluding left and right edges */ - for (x = (t-rw)+1, dx=x-(rw-2); dx>rw; x-=rw,dx-=rw) { - a=x-2; - pix_prevRow=a+rw; - pix_nextRow=a-rw; - pix_prevCol=a+1; - pix_nextCol=a-1; - while (a>dx-2) { - if (!limask[a]) { // if the inner mask is empty - if (lomask[a]) { // if the outer mask is full + for (x = (t - rw) + 1, dx = x - (rw - 2); dx > rw; x -= rw, dx -= rw) { + a = x - 2; + pix_prevRow = a + rw; + pix_nextRow = a - rw; + pix_prevCol = a + 1; + pix_nextCol = a - 1; + while (a > dx - 2) { + if (!limask[a]) { // if the inner mask is empty + if (lomask[a]) { // if the outer mask is full /* - Next we test all 4 directions around the current pixel: next/prev/up/down - The test ensures that the outer mask is empty and that the inner mask - is also empty. If both conditions are true for any one of the 4 adjacent pixels - then the current pixel is counted as being a true outer edge pixel. - */ + Next we test all 4 directions around the current pixel: next/prev/up/down + The test ensures that the outer mask is empty and that the inner mask + is also empty. If both conditions are true for any one of the 4 adjacent pixels + then the current pixel is counted as being a true outer edge pixel. + */ if ((!lomask[pix_nextCol] && !limask[pix_nextCol]) || (!lomask[pix_prevCol] && !limask[pix_prevCol]) || (!lomask[pix_nextRow] && !limask[pix_nextRow]) || (!lomask[pix_prevRow] && !limask[pix_prevRow])) { - in_osz++; // increment the outer boundary pixel count - lres[a]=3; // flag pixel as part of outer edge + in_osz++; // increment the outer boundary pixel count + lres[a] = 3; // flag pixel as part of outer edge } - else { // it's not a boundary pixel, but it is a gradient pixel - in_gsz++; // increment the gradient pixel count - lres[a]=2; // flag pixel as gradient + else { // it's not a boundary pixel, but it is a gradient pixel + in_gsz++; // increment the gradient pixel count + lres[a] = 2; // flag pixel as gradient } } @@ -869,24 +869,24 @@ static void do_adjacentEdgeDetection(unsigned int t, unsigned int rw, unsigned i (!limask[pix_nextRow] && lomask[pix_nextRow]) || (!limask[pix_prevRow] && lomask[pix_prevRow])) { - in_isz++; // increment the inner boundary pixel count - lres[a]=4; // flag pixel as part of inner edge + in_isz++; // increment the inner boundary pixel count + lres[a] = 4; // flag pixel as part of inner edge } else { - res[a]=1.0f; // pixel is part of inner mask, but not at an edge + res[a] = 1.0f; // pixel is part of inner mask, but not at an edge } } a--; - pix_prevRow--; // advance all four "surrounding" pixel pointers + pix_prevRow--; // advance all four "surrounding" pixel pointers pix_nextRow--; pix_prevCol--; pix_nextCol--; } } - rsize[0]=in_isz; // fill in our return sizes for edges + fill - rsize[1]=in_osz; - rsize[2]=in_gsz; + rsize[0] = in_isz; // fill in our return sizes for edges + fill + rsize[1] = in_osz; + rsize[2] = in_gsz; } static void do_createEdgeLocationBuffer(unsigned int t, unsigned int rw, unsigned int *lres, float *res, unsigned short *gbuf, unsigned int *innerEdgeOffset, unsigned int *outerEdgeOffset, unsigned int isz, unsigned int gsz) @@ -898,102 +898,102 @@ static void do_createEdgeLocationBuffer(unsigned int t, unsigned int rw, unsigne unsigned int rsl; // long used for finding fast 1.0/sqrt unsigned int gradientFillOffset; - unsigned int innerAccum=0; // for looping inner edge pixel indexes, represents current position from offset - unsigned int outerAccum=0; // for looping outer edge pixel indexes, represents current position from offset - unsigned int gradientAccum=0; // for looping gradient pixel indexes, represents current position from offset + unsigned int innerAccum = 0; // for looping inner edge pixel indexes, represents current position from offset + unsigned int outerAccum = 0; // for looping outer edge pixel indexes, represents current position from offset + unsigned int gradientAccum = 0; // for looping gradient pixel indexes, represents current position from offset /* - Here we compute the size of buffer needed to hold (row,col) coordinates - for each pixel previously determined to be either gradient, inner edge, - or outer edge. - - Allocation is done by requesting 4 bytes "sizeof(int)" per pixel, even - though gbuf[] is declared as unsigned short* (2 bytes) because we don't - store the pixel indexes, we only store x,y location of pixel in buffer. - - This does make the assumption that x and y can fit in 16 unsigned bits - so if Blender starts doing renders greater than 65536 in either direction - this will need to allocate gbuf[] as unsigned int *and allocate 8 bytes - per flagged pixel. - - In general, the buffer on-screen: - - Example: 9 by 9 pixel block - - . = pixel non-white in both outer and inner mask - o = pixel white in outer, but not inner mask, adjacent to "." pixel - g = pixel white in outer, but not inner mask, not adjacent to "." pixel - i = pixel white in inner mask, adjacent to "g" or "." pixel - F = pixel white in inner mask, only adjacent to other pixels white in the inner mask - - - ......... <----- pixel #80 - ..oooo... - .oggggo.. - .oggiggo. - .ogiFigo. - .oggiggo. - .oggggo.. - ..oooo... - pixel #00 -----> ......... - - gsz = 18 (18 "g" pixels above) - isz = 4 (4 "i" pixels above) - osz = 18 (18 "o" pixels above) - - - The memory in gbuf[] after filling will look like this: - - gradientFillOffset (0 pixels) innerEdgeOffset (18 pixels) outerEdgeOffset (22 pixels) - / / / - / / / - |X Y X Y X Y X Y > <----------------> <------------------------> <----------------+ - |0 2 4 6 8 10 12 14 > ... <68 70 72 74 > ... <80 82 84 86 88 90 > ... <152 154 156 158 | <- bytes - +--------------------------------> <----------------> <------------------------> <----------------+ - |g0 g0 g1 g1 g2 g2 g3 g3 > ......... + + gsz = 18 (18 "g" pixels above) + isz = 4 (4 "i" pixels above) + osz = 18 (18 "o" pixels above) + + + The memory in gbuf[] after filling will look like this: + + gradientFillOffset (0 pixels) innerEdgeOffset (18 pixels) outerEdgeOffset (22 pixels) + / / / + / / / + |X Y X Y X Y X Y > <----------------> <------------------------> <----------------+ + |0 2 4 6 8 10 12 14 > ... <68 70 72 74 > ... <80 82 84 86 88 90 > ... <152 154 156 158 | <- bytes + +--------------------------------> <----------------> <------------------------> <----------------+ + |g0 g0 g1 g1 g2 g2 g3 g3 > =0; x--) { - gradientFillOffset=x<<1; - t=gbuf[gradientFillOffset]; // calculate column of pixel indexed by gbuf[x] - fsz=gbuf[gradientFillOffset+1]; // calculate row of pixel indexed by gbuf[x] - dmin=0xffffffff; // reset min distance to edge pixel - for (a=outerEdgeOffset+osz-1; a>=outerEdgeOffset; a--) { // loop through all outer edge buffer pixels - ud=a<<1; - dy=t-gbuf[ud]; // set dx to gradient pixel column - outer edge pixel row - dx=fsz-gbuf[ud+1]; // set dy to gradient pixel row - outer edge pixel column - ud=dx*dx+dy*dy; // compute sum of squares - if (ud= 0; x--) { + gradientFillOffset = x << 1; + t = gbuf[gradientFillOffset]; // calculate column of pixel indexed by gbuf[x] + fsz = gbuf[gradientFillOffset + 1]; // calculate row of pixel indexed by gbuf[x] + dmin = 0xffffffff; // reset min distance to edge pixel + for (a = outerEdgeOffset + osz - 1; a >= outerEdgeOffset; a--) { // loop through all outer edge buffer pixels + ud = a << 1; + dy = t - gbuf[ud]; // set dx to gradient pixel column - outer edge pixel row + dx = fsz - gbuf[ud + 1]; // set dy to gradient pixel row - outer edge pixel column + ud = dx * dx + dy * dy; // compute sum of squares + if (ud < dmin) { // if our new sum of squares is less than the current minimum + dmin = ud; // set a new minimum equal to the new lower value } } - odist=(float)(dmin); // cast outer min to a float - rsf=odist*0.5f; // - rsl=*(unsigned int*)&odist; // use some peculiar properties of the way bits are stored - rsl=0x5f3759df-(rsl>>1); // in floats vs. unsigned ints to compute an approximate - odist=*(float*)&rsl; // reciprocal square root - odist=odist*(rsopf-(rsf*odist*odist)); // -- ** this line can be iterated for more accuracy ** -- - dmin=0xffffffff; // reset min distance to edge pixel - for (a = innerEdgeOffset+isz-1; a>=innerEdgeOffset; a--) { // loop through all inside edge pixels - ud=a<<1; - dy=t-gbuf[ud]; // compute delta in Y from gradient pixel to inside edge pixel - dx=fsz-gbuf[ud+1]; // compute delta in X from gradient pixel to inside edge pixel - ud=dx*dx+dy*dy; // compute sum of squares - if (ud> 1); // in floats vs. unsigned ints to compute an approximate + odist = *(float *)&rsl; // reciprocal square root + odist = odist * (rsopf - (rsf * odist * odist)); // -- ** this line can be iterated for more accuracy ** -- + dmin = 0xffffffff; // reset min distance to edge pixel + for (a = innerEdgeOffset + isz - 1; a >= innerEdgeOffset; a--) { // loop through all inside edge pixels + ud = a << 1; + dy = t - gbuf[ud]; // compute delta in Y from gradient pixel to inside edge pixel + dx = fsz - gbuf[ud + 1]; // compute delta in X from gradient pixel to inside edge pixel + ud = dx * dx + dy * dy; // compute sum of squares + if (ud < dmin) { // if our new sum of squares is less than the current minimum we've found + dmin = ud; // set a new minimum equal to the new lower value } } - idist=(float)(dmin); // cast inner min to a float - rsf=idist*0.5f; // - rsl=*(unsigned int*)&idist; // - rsl=0x5f3759df-(rsl>>1); // see notes above - idist=*(float*)&rsl; // - idist=idist*(rsopf-(rsf*idist*idist)); // + idist = (float)(dmin); // cast inner min to a float + rsf = idist * 0.5f; // + rsl = *(unsigned int *)&idist; // + rsl = 0x5f3759df - (rsl >> 1); // see notes above + idist = *(float *)&rsl; // + idist = idist * (rsopf - (rsf * idist * idist)); // /* - Note once again that since we are using reciprocals of distance values our - proportion is already the correct intensity, and does not need to be - subracted from 1.0 like it would have if we used real distances. - */ + * Note once again that since we are using reciprocals of distance values our + * proportion is already the correct intensity, and does not need to be + * subracted from 1.0 like it would have if we used real distances. + */ /* - Here we reconstruct the pixel's memory location in the CompBuf by - Pixel Index = Pixel Column + ( Pixel Row * Row Width ) - */ - res[gbuf[gradientFillOffset+1]+(gbuf[gradientFillOffset]*rw)]=(idist/(idist+odist)); //set intensity + * Here we reconstruct the pixel's memory location in the CompBuf by + * Pixel Index = Pixel Column + ( Pixel Row * Row Width ) + */ + res[gbuf[gradientFillOffset + 1] + (gbuf[gradientFillOffset] * rw)] = (idist / (idist + odist)); //set intensity } } @@ -1140,92 +1140,92 @@ void DoubleEdgeMaskOperation::doDoubleEdgeMask(float *imask, float *omask, float int t; // t = total number of pixels in buffer - 1 (used for loop starts) int fsz; // size of the frame - unsigned int isz=0; // size (in pixels) of inside edge pixel index buffer - unsigned int osz=0; // size (in pixels) of outside edge pixel index buffer - unsigned int gsz=0; // size (in pixels) of gradient pixel index buffer - unsigned int rsize[3]; // size storage to pass to helper functions - unsigned int innerEdgeOffset=0; // offset into final buffer where inner edge pixel indexes start - unsigned int outerEdgeOffset=0; // offset into final buffer where outer edge pixel indexes start + unsigned int isz = 0; // size (in pixels) of inside edge pixel index buffer + unsigned int osz = 0; // size (in pixels) of outside edge pixel index buffer + unsigned int gsz = 0; // size (in pixels) of gradient pixel index buffer + unsigned int rsize[3]; // size storage to pass to helper functions + unsigned int innerEdgeOffset = 0; // offset into final buffer where inner edge pixel indexes start + unsigned int outerEdgeOffset = 0; // offset into final buffer where outer edge pixel indexes start unsigned short *gbuf; // gradient/inner/outer pixel location index buffer if (true) { // if both input sockets have some data coming in... - t=(this->getWidth()*this->getHeight())-1; // determine size of the frame + t = (this->getWidth() * this->getHeight()) - 1; // determine size of the frame - lres = (unsigned int*)res; // unsigned int pointer to output buffer (for bit level ops) - limask=(unsigned int*)imask; // unsigned int pointer to input mask (for bit level ops) - lomask=(unsigned int*)omask; // unsigned int pointer to output mask (for bit level ops) + lres = (unsigned int *)res; // unsigned int pointer to output buffer (for bit level ops) + limask = (unsigned int *)imask; // unsigned int pointer to input mask (for bit level ops) + lomask = (unsigned int *)omask; // unsigned int pointer to output mask (for bit level ops) rw = this->getWidth(); // width of a row of pixels /* - The whole buffer is broken up into 4 parts. The four CORNERS, the FIRST and LAST rows, the - LEFT and RIGHT edges (excluding the corner pixels), and all OTHER rows. - This allows for quick computation of outer edge pixels where - a screen edge pixel is marked to be gradient. - - The pixel type (gradient vs inner-edge vs outer-edge) tests change - depending on the user selected "Inner Edge Mode" and the user selected - "Buffer Edge Mode" on the node's GUI. There are 4 sets of basically the - same algorithm: - - 1.) Inner Edge -> Adjacent Only - Buffer Edge -> Keep Inside - - 2.) Inner Edge -> Adjacent Only - Buffer Edge -> Bleed Out - - 3.) Inner Edge -> All - Buffer Edge -> Keep Inside - - 4.) Inner Edge -> All - Buffer Edge -> Bleed Out - - Each version has slightly different criteria for detecting an edge pixel. + * The whole buffer is broken up into 4 parts. The four CORNERS, the FIRST and LAST rows, the + * LEFT and RIGHT edges (excluding the corner pixels), and all OTHER rows. + * This allows for quick computation of outer edge pixels where + * a screen edge pixel is marked to be gradient. + * + * The pixel type (gradient vs inner-edge vs outer-edge) tests change + * depending on the user selected "Inner Edge Mode" and the user selected + * "Buffer Edge Mode" on the node's GUI. There are 4 sets of basically the + * same algorithm: + * + * 1.) Inner Edge -> Adjacent Only + * Buffer Edge -> Keep Inside + * + * 2.) Inner Edge -> Adjacent Only + * Buffer Edge -> Bleed Out + * + * 3.) Inner Edge -> All + * Buffer Edge -> Keep Inside + * + * 4.) Inner Edge -> All + * Buffer Edge -> Bleed Out + * + * Each version has slightly different criteria for detecting an edge pixel. */ - if (this->adjecentOnly) { // if "adjacent only" inner edge mode is turned on - if (this->keepInside) { // if "keep inside" buffer edge mode is turned on - do_adjacentKeepBorders(t,rw,limask,lomask,lres,res,rsize); + if (this->adjecentOnly) { // if "adjacent only" inner edge mode is turned on + if (this->keepInside) { // if "keep inside" buffer edge mode is turned on + do_adjacentKeepBorders(t, rw, limask, lomask, lres, res, rsize); } - else { // "bleed out" buffer edge mode is turned on - do_adjacentBleedBorders(t,rw,limask,lomask,lres,res,rsize); + else { // "bleed out" buffer edge mode is turned on + do_adjacentBleedBorders(t, rw, limask, lomask, lres, res, rsize); } - isz=rsize[0]; // set up inner edge, outer edge, and gradient buffer sizes after border pass - osz=rsize[1]; - gsz=rsize[2]; + isz = rsize[0]; // set up inner edge, outer edge, and gradient buffer sizes after border pass + osz = rsize[1]; + gsz = rsize[2]; // detect edges in all non-border pixels in the buffer - do_adjacentEdgeDetection(t,rw,limask,lomask,lres,res,rsize,isz,osz,gsz); + do_adjacentEdgeDetection(t, rw, limask, lomask, lres, res, rsize, isz, osz, gsz); } - else { // "all" inner edge mode is turned on - if (this->keepInside) { // if "keep inside" buffer edge mode is turned on - do_allKeepBorders(t,rw,limask,lomask,lres,res,rsize); + else { // "all" inner edge mode is turned on + if (this->keepInside) { // if "keep inside" buffer edge mode is turned on + do_allKeepBorders(t, rw, limask, lomask, lres, res, rsize); } - else { // "bleed out" buffer edge mode is turned on - do_allBleedBorders(t,rw,limask,lomask,lres,res,rsize); + else { // "bleed out" buffer edge mode is turned on + do_allBleedBorders(t, rw, limask, lomask, lres, res, rsize); } - isz=rsize[0]; // set up inner edge, outer edge, and gradient buffer sizes after border pass - osz=rsize[1]; - gsz=rsize[2]; + isz = rsize[0]; // set up inner edge, outer edge, and gradient buffer sizes after border pass + osz = rsize[1]; + gsz = rsize[2]; // detect edges in all non-border pixels in the buffer - do_allEdgeDetection(t,rw,limask,lomask,lres,res,rsize,isz,osz,gsz); + do_allEdgeDetection(t, rw, limask, lomask, lres, res, rsize, isz, osz, gsz); } - isz=rsize[0]; // set edge and gradient buffer sizes once again... - osz=rsize[1]; // the sizes in rsize[] may have been modified - gsz=rsize[2]; // by the do_*EdgeDetection() function. + isz = rsize[0]; // set edge and gradient buffer sizes once again... + osz = rsize[1]; // the sizes in rsize[] may have been modified + gsz = rsize[2]; // by the do_*EdgeDetection() function. - fsz=gsz+isz+osz; // calculate size of pixel index buffer needed - gbuf = (unsigned short*)MEM_callocN(sizeof (unsigned short)*fsz*2, "DEM"); // allocate edge/gradient pixel index buffer + fsz = gsz + isz + osz; // calculate size of pixel index buffer needed + gbuf = (unsigned short *)MEM_callocN(sizeof (unsigned short) * fsz * 2, "DEM"); // allocate edge/gradient pixel index buffer - do_createEdgeLocationBuffer(t,rw,lres,res,gbuf,&innerEdgeOffset,&outerEdgeOffset,isz,gsz); - do_fillGradientBuffer(rw,res,gbuf,isz,osz,gsz,innerEdgeOffset,outerEdgeOffset); + do_createEdgeLocationBuffer(t, rw, lres, res, gbuf, &innerEdgeOffset, &outerEdgeOffset, isz, gsz); + do_fillGradientBuffer(rw, res, gbuf, isz, osz, gsz, innerEdgeOffset, outerEdgeOffset); - MEM_freeN(gbuf); // free the gradient index buffer + MEM_freeN(gbuf); // free the gradient index buffer } } -DoubleEdgeMaskOperation::DoubleEdgeMaskOperation(): NodeOperation() +DoubleEdgeMaskOperation::DoubleEdgeMaskOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_VALUE); @@ -1266,9 +1266,9 @@ void *DoubleEdgeMaskOperation::initializeTileData(rcti *rect, MemoryBuffer **mem lockMutex(); if (this->cachedInstance == NULL) { - MemoryBuffer *innerMask = (MemoryBuffer*)inputInnerMask->initializeTileData(rect, memoryBuffers); - MemoryBuffer *outerMask = (MemoryBuffer*)inputOuterMask->initializeTileData(rect, memoryBuffers); - float *data = new float[this->getWidth()*this->getHeight()]; + MemoryBuffer *innerMask = (MemoryBuffer *)inputInnerMask->initializeTileData(rect, memoryBuffers); + MemoryBuffer *outerMask = (MemoryBuffer *)inputOuterMask->initializeTileData(rect, memoryBuffers); + float *data = new float[this->getWidth() * this->getHeight()]; float *imask = innerMask->convertToValueBuffer(); float *omask = outerMask->convertToValueBuffer(); doDoubleEdgeMask(imask, omask, data); @@ -1281,12 +1281,12 @@ void *DoubleEdgeMaskOperation::initializeTileData(rcti *rect, MemoryBuffer **mem } void DoubleEdgeMaskOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { - float *buffer = (float*) data; - int index = (y*this->getWidth() + x); + float *buffer = (float *) data; + int index = (y * this->getWidth() + x); color[0] = buffer[index]; - color[1] = buffer[index+1]; - color[2] = buffer[index+2]; - color[3] = buffer[index+3]; + color[1] = buffer[index + 1]; + color[2] = buffer[index + 2]; + color[3] = buffer[index + 3]; } void DoubleEdgeMaskOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp b/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp index 650c57dd8dc..0beacd02738 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp @@ -24,7 +24,7 @@ #include "BLI_math.h" #include "DNA_node_types.h" -EllipseMaskOperation::EllipseMaskOperation(): NodeOperation() +EllipseMaskOperation::EllipseMaskOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_VALUE); @@ -41,7 +41,7 @@ void EllipseMaskOperation::initExecution() const double rad = DEG2RAD((double)this->data->rotation); this->cosine = cos(rad); this->sine = sin(rad); - this->aspectRatio = ((float)this->getWidth())/this->getHeight(); + this->aspectRatio = ((float)this->getWidth()) / this->getHeight(); } void EllipseMaskOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) @@ -49,32 +49,32 @@ void EllipseMaskOperation::executePixel(float *color, float x, float y, PixelSam float inputMask[4]; float inputValue[4]; - float rx = x/this->getWidth(); - float ry = y/this->getHeight(); + float rx = x / this->getWidth(); + float ry = y / this->getHeight(); - const float dy = (ry - this->data->y)/this->aspectRatio; + const float dy = (ry - this->data->y) / this->aspectRatio; const float dx = rx - this->data->x; - rx = this->data->x+(this->cosine*dx + this->sine*dy); - ry = this->data->y+(-this->sine*dx + this->cosine*dy); + rx = this->data->x + (this->cosine * dx + this->sine * dy); + ry = this->data->y + (-this->sine * dx + this->cosine * dy); this->inputMask->read(inputMask, x, y, sampler, inputBuffers); this->inputValue->read(inputValue, x, y, sampler, inputBuffers); - const float halfHeight = (this->data->height)/2.0f; - const float halfWidth = this->data->width/2.0f; - float sx = rx-this->data->x; + const float halfHeight = (this->data->height) / 2.0f; + const float halfWidth = this->data->width / 2.0f; + float sx = rx - this->data->x; sx *= sx; const float tx = halfWidth * halfWidth; - float sy = ry-this->data->y; + float sy = ry - this->data->y; sy *= sy; const float ty = halfHeight * halfHeight; - bool inside = ((sx/tx)+(sy/ty))<1.0f; + bool inside = ((sx / tx) + (sy / ty)) < 1.0f; switch (this->maskType) { case CMP_NODE_MASKTYPE_ADD: if (inside) { - color[0] = max(inputMask[0],inputValue[0]); + color[0] = max(inputMask[0], inputValue[0]); } else { color[0] = inputMask[0]; @@ -82,7 +82,7 @@ void EllipseMaskOperation::executePixel(float *color, float x, float y, PixelSam break; case CMP_NODE_MASKTYPE_SUBTRACT: if (inside) { - color[0] = inputMask[0]-inputValue[0]; + color[0] = inputMask[0] - inputValue[0]; CLAMP(color[0], 0, 1); } else { @@ -91,24 +91,24 @@ void EllipseMaskOperation::executePixel(float *color, float x, float y, PixelSam break; case CMP_NODE_MASKTYPE_MULTIPLY: if (inside) { - color[0] = inputMask[0]*inputValue[0]; + color[0] = inputMask[0] * inputValue[0]; } else { color[0] = 0; } break; case CMP_NODE_MASKTYPE_NOT: - if (inside) { - if (inputMask[0]>0.0f) { - color[0] = 0; + if (inside) { + if (inputMask[0] > 0.0f) { + color[0] = 0; + } + else { + color[0] = inputValue[0]; + } } else { - color[0] = inputValue[0]; + color[0] = inputMask[0]; } - } - else { - color[0] = inputMask[0]; - } break; } diff --git a/source/blender/compositor/operations/COM_FlipOperation.cpp b/source/blender/compositor/operations/COM_FlipOperation.cpp index 38018ffc3f7..5023473f4aa 100644 --- a/source/blender/compositor/operations/COM_FlipOperation.cpp +++ b/source/blender/compositor/operations/COM_FlipOperation.cpp @@ -42,10 +42,10 @@ void FlipOperation::deinitExecution() } -void FlipOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void FlipOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { - float nx = this->flipX?this->getWidth()-1-x:x; - float ny = this->flipY?this->getHeight()-1-y:y; + float nx = this->flipX ? this->getWidth() - 1 - x : x; + float ny = this->flipY ? this->getHeight() - 1 - y : y; this->inputOperation->read(color, nx, ny, sampler, inputBuffers); } @@ -55,16 +55,16 @@ bool FlipOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOper rcti newInput; if (this->flipX) { - newInput.xmax = (this->getWidth()- 1 - input->xmin)+1; - newInput.xmin = (this->getWidth()- 1 - input->xmax)-1; + newInput.xmax = (this->getWidth() - 1 - input->xmin) + 1; + newInput.xmin = (this->getWidth() - 1 - input->xmax) - 1; } else { newInput.xmin = input->xmin; newInput.xmax = input->xmax; } if (this->flipY) { - newInput.ymax = (this->getHeight()- 1 - input->ymin)+1; - newInput.ymin = (this->getHeight()- 1 - input->ymax)-1; + newInput.ymax = (this->getHeight() - 1 - input->ymin) + 1; + newInput.ymin = (this->getHeight() - 1 - input->ymax) - 1; } else { newInput.ymin = input->ymin; diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp index a4fb20402a4..3e90b643604 100644 --- a/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp +++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp @@ -23,7 +23,7 @@ #include "COM_GammaCorrectOperation.h" #include "BLI_math.h" -GammaCorrectOperation::GammaCorrectOperation(): NodeOperation() +GammaCorrectOperation::GammaCorrectOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); @@ -45,9 +45,9 @@ void GammaCorrectOperation::executePixel(float *color, float x, float y, PixelSa } /* check for negative to avoid nan's */ - color[0] = inputColor[0]>0.0f?inputColor[0]*inputColor[0] :0.0f; - color[1] = inputColor[1]>0.0f?inputColor[1]*inputColor[1] :0.0f; - color[2] = inputColor[2]>0.0f?inputColor[2]*inputColor[2] :0.0f; + color[0] = inputColor[0] > 0.0f ? inputColor[0] * inputColor[0] : 0.0f; + color[1] = inputColor[1] > 0.0f ? inputColor[1] * inputColor[1] : 0.0f; + color[2] = inputColor[2] > 0.0f ? inputColor[2] * inputColor[2] : 0.0f; inputColor[0] *= inputColor[3]; inputColor[1] *= inputColor[3]; @@ -64,7 +64,7 @@ void GammaCorrectOperation::deinitExecution() this->inputProgram = NULL; } -GammaUncorrectOperation::GammaUncorrectOperation(): NodeOperation() +GammaUncorrectOperation::GammaUncorrectOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); @@ -86,9 +86,9 @@ void GammaUncorrectOperation::executePixel(float *color, float x, float y, Pixel inputColor[2] /= inputColor[3]; } - color[0] = inputColor[0]>0.0f?sqrtf(inputColor[0]) :0.0f; - color[1] = inputColor[1]>0.0f?sqrtf(inputColor[1]) :0.0f; - color[2] = inputColor[2]>0.0f?sqrtf(inputColor[2]) :0.0f; + color[0] = inputColor[0] > 0.0f ? sqrtf(inputColor[0]) : 0.0f; + color[1] = inputColor[1] > 0.0f ? sqrtf(inputColor[1]) : 0.0f; + color[2] = inputColor[2] > 0.0f ? sqrtf(inputColor[2]) : 0.0f; inputColor[0] *= inputColor[3]; inputColor[1] *= inputColor[3]; diff --git a/source/blender/compositor/operations/COM_GammaOperation.cpp b/source/blender/compositor/operations/COM_GammaOperation.cpp index 989ffd5dfba..2c3e78840ee 100644 --- a/source/blender/compositor/operations/COM_GammaOperation.cpp +++ b/source/blender/compositor/operations/COM_GammaOperation.cpp @@ -23,7 +23,7 @@ #include "COM_GammaOperation.h" #include "BLI_math.h" -GammaOperation::GammaOperation(): NodeOperation() +GammaOperation::GammaOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h index 5dc896fafaa..10a8a538391 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h @@ -34,17 +34,17 @@ public: GaussianXBlurOperation(); /** - *@brief the inner loop of this program + * @brief the inner loop of this program */ void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); /** - *@brief initialize the execution + * @brief initialize the execution */ void initExecution(); /** - *@brief Deinitialize the execution + * @brief Deinitialize the execution */ void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp index 2afcc2e5cc7..b8e46e2d0be 100644 --- a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp +++ b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp @@ -32,7 +32,7 @@ extern "C" { } #endif -HueSaturationValueCorrectOperation::HueSaturationValueCorrectOperation(): CurveBaseOperation() +HueSaturationValueCorrectOperation::HueSaturationValueCorrectOperation() : CurveBaseOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); @@ -53,7 +53,7 @@ void HueSaturationValueCorrectOperation::executePixel(float *output, float x, fl /* adjust hue, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(this->curveMapping, 0, hsv[0]); - hsv[0] += f-0.5f; + hsv[0] += f - 0.5f; /* adjust saturation, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(this->curveMapping, 1, hsv[0]); diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.cpp b/source/blender/compositor/operations/COM_IDMaskOperation.cpp index 834ca4fc5ed..d02367088d7 100644 --- a/source/blender/compositor/operations/COM_IDMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_IDMaskOperation.cpp @@ -22,7 +22,7 @@ #include "COM_IDMaskOperation.h" -IDMaskOperation::IDMaskOperation(): NodeOperation() +IDMaskOperation::IDMaskOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -38,7 +38,7 @@ void IDMaskOperation::executePixel(float *color, float x, float y, PixelSampler float inputValue[4]; this->inputProgram->read(inputValue, x, y, sampler, inputBuffers); - const float a = (inputValue[0] == this->objectIndex)?1.0f:0.0f; + const float a = (inputValue[0] == this->objectIndex) ? 1.0f : 0.0f; color[0] = a; } diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp index 04cd91d3c3a..9dbe8419daa 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cpp +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -36,7 +36,7 @@ extern "C" { #include "IMB_imbuf_types.h" } -BaseImageOperation::BaseImageOperation(): NodeOperation() +BaseImageOperation::BaseImageOperation() : NodeOperation() { this->image = NULL; this->buffer = NULL; @@ -48,15 +48,15 @@ BaseImageOperation::BaseImageOperation(): NodeOperation() this->depthBuffer = NULL; this->numberOfChannels = 0; } -ImageOperation::ImageOperation(): BaseImageOperation() +ImageOperation::ImageOperation() : BaseImageOperation() { this->addOutputSocket(COM_DT_COLOR); } -ImageAlphaOperation::ImageAlphaOperation(): BaseImageOperation() +ImageAlphaOperation::ImageAlphaOperation() : BaseImageOperation() { this->addOutputSocket(COM_DT_VALUE); } -ImageDepthOperation::ImageDepthOperation(): BaseImageOperation() +ImageDepthOperation::ImageDepthOperation() : BaseImageOperation() { this->addOutputSocket(COM_DT_VALUE); } @@ -66,12 +66,12 @@ ImBuf *BaseImageOperation::getImBuf() ImBuf *ibuf; ibuf = BKE_image_get_ibuf(this->image, this->imageUser); - if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { - return NULL; + if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) { + return NULL; } if (ibuf->rect_float == NULL) { - IMB_float_from_rect(ibuf); + IMB_float_from_rect(ibuf); } return ibuf; } @@ -108,7 +108,7 @@ void BaseImageOperation::determineResolution(unsigned int resolution[], unsigned } } -void ImageOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])\ +void ImageOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { if (this->imageBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { color[0] = 0.0f; @@ -118,15 +118,15 @@ void ImageOperation::executePixel(float *color, float x, float y, PixelSampler s } else { switch (sampler) { - case COM_PS_NEAREST: - neareast_interpolation_color(this->buffer, NULL, color, x, y); - break; - case COM_PS_BILINEAR: - bilinear_interpolation_color(this->buffer, NULL, color, x, y); - break; - case COM_PS_BICUBIC: - bicubic_interpolation_color(this->buffer, NULL, color, x, y); - break; + case COM_PS_NEAREST: + neareast_interpolation_color(this->buffer, NULL, color, x, y); + break; + case COM_PS_BILINEAR: + bilinear_interpolation_color(this->buffer, NULL, color, x, y); + break; + case COM_PS_BICUBIC: + bicubic_interpolation_color(this->buffer, NULL, color, x, y); + break; } } } @@ -141,15 +141,15 @@ void ImageAlphaOperation::executePixel(float *color, float x, float y, PixelSamp else { tempcolor[3] = 1.0f; switch (sampler) { - case COM_PS_NEAREST: - neareast_interpolation_color(this->buffer, NULL, tempcolor, x, y); - break; - case COM_PS_BILINEAR: - bilinear_interpolation_color(this->buffer, NULL, tempcolor, x, y); - break; - case COM_PS_BICUBIC: - bicubic_interpolation_color(this->buffer, NULL, tempcolor, x, y); - break; + case COM_PS_NEAREST: + neareast_interpolation_color(this->buffer, NULL, tempcolor, x, y); + break; + case COM_PS_BILINEAR: + bilinear_interpolation_color(this->buffer, NULL, tempcolor, x, y); + break; + case COM_PS_BICUBIC: + bicubic_interpolation_color(this->buffer, NULL, tempcolor, x, y); + break; } color[0] = tempcolor[3]; } diff --git a/source/blender/compositor/operations/COM_InvertOperation.cpp b/source/blender/compositor/operations/COM_InvertOperation.cpp index 82158c4adad..6142959a12e 100644 --- a/source/blender/compositor/operations/COM_InvertOperation.cpp +++ b/source/blender/compositor/operations/COM_InvertOperation.cpp @@ -22,7 +22,7 @@ #include "COM_InvertOperation.h" -InvertOperation::InvertOperation(): NodeOperation() +InvertOperation::InvertOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); @@ -50,16 +50,16 @@ void InvertOperation::executePixel(float *out, float x, float y, PixelSampler sa const float invertedValue = 1.0f - value; if (color) { - out[0] = (1.0f - inputColor[0])*value + inputColor[0]*invertedValue; - out[1] = (1.0f - inputColor[1])*value + inputColor[1]*invertedValue; - out[2] = (1.0f - inputColor[2])*value + inputColor[2]*invertedValue; + out[0] = (1.0f - inputColor[0]) * value + inputColor[0] * invertedValue; + out[1] = (1.0f - inputColor[1]) * value + inputColor[1] * invertedValue; + out[2] = (1.0f - inputColor[2]) * value + inputColor[2] * invertedValue; } else { copy_v3_v3(out, inputColor); } if (alpha) - out[3] = (1.0f - inputColor[3])*value + inputColor[3]*invertedValue; + out[3] = (1.0f - inputColor[3]) * value + inputColor[3] * invertedValue; else out[3] = inputColor[3]; diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp index 09b5b7a523c..2c9949f2b4b 100644 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp @@ -28,7 +28,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" -KeyingClipOperation::KeyingClipOperation(): NodeOperation() +KeyingClipOperation::KeyingClipOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -56,7 +56,7 @@ void KeyingClipOperation::executePixel(float *color, int x, int y, MemoryBuffer const int delta = this->kernelRadius; const float tolerance = this->kernelTolerance; - MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); int bufferWidth = inputBuffer->getWidth(); diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp b/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp index b7fd2772729..04523384653 100644 --- a/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp @@ -40,7 +40,7 @@ static int get_pixel_primary_channel(float *pixel) return 2; } -KeyingDespillOperation::KeyingDespillOperation(): NodeOperation() +KeyingDespillOperation::KeyingDespillOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp index e04c79f6713..0a450cc3bf8 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp @@ -52,7 +52,7 @@ static float get_pixel_saturation(float pixelColor[4], float screen_balance, int return (pixelColor[primary_channel] - val) * fabsf(1.0f - val); } -KeyingOperation::KeyingOperation(): NodeOperation() +KeyingOperation::KeyingOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp index f6301557aaf..b728f6c5cca 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -39,7 +39,7 @@ extern "C" { #include "IMB_imbuf_types.h" } -KeyingScreenOperation::KeyingScreenOperation(): NodeOperation() +KeyingScreenOperation::KeyingScreenOperation() : NodeOperation() { this->addOutputSocket(COM_DT_COLOR); this->movieClip = NULL; @@ -149,7 +149,7 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri BLI_voronoi_triangulate(sites, sites_total, &edges, width, height, &triangulation->triangulated_points, &triangulation->triangulated_points_total, - &triangulation->triangles, &triangulation->triangles_total); + &triangulation->triangles, &triangulation->triangles_total); MEM_freeN(sites); BLI_freelistN(&edges); @@ -204,8 +204,8 @@ void KeyingScreenOperation::executePixel(float *color, int x, int y, MemoryBuffe for (i = 0; i < triangulation->triangles_total; i++) { int *triangle = triangulation->triangles[i]; VoronoiTriangulationPoint *a = &triangulation->triangulated_points[triangle[0]], - *b = &triangulation->triangulated_points[triangle[1]], - *c = &triangulation->triangulated_points[triangle[2]]; + *b = &triangulation->triangulated_points[triangle[1]], + *c = &triangulation->triangulated_points[triangle[2]]; float co[2] = {(float) x, (float) y}, w[3]; if (barycentric_coords_v2(a->co, b->co, c->co, co, w)) { diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp index f206bf4df8e..6e8aa9461e6 100644 --- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp @@ -22,7 +22,7 @@ #include "COM_LuminanceMatteOperation.h" #include "BLI_math.h" -LuminanceMatteOperation::LuminanceMatteOperation(): NodeOperation() +LuminanceMatteOperation::LuminanceMatteOperation() : NodeOperation() { addInputSocket(COM_DT_COLOR); addOutputSocket(COM_DT_VALUE); @@ -44,26 +44,26 @@ void LuminanceMatteOperation::executePixel(float *outputValue, float x, float y, { float inColor[4]; - const float high=this->settings->t1; - const float low=this->settings->t2; + const float high = this->settings->t1; + const float low = this->settings->t2; float alpha; this->inputImageProgram->read(inColor, x, y, sampler, inputBuffers); /* one line thread-friend algorithm: - outputValue[0] = max(inputValue[3], min(high, max(low, ((inColor[0]-low)/(high-low)))) - */ + * outputValue[0] = max(inputValue[3], min(high, max(low, ((inColor[0]-low)/(high-low)))) + */ /* test range*/ if (inColor[0] > high) { - alpha=1.f; + alpha = 1.f; } else if (inColor[0] < low) { - alpha=0.f; + alpha = 0.f; } - else {/*blend */ - alpha=(inColor[0]-low)/(high-low); + else { /*blend */ + alpha = (inColor[0] - low) / (high - low); } @@ -72,12 +72,12 @@ void LuminanceMatteOperation::executePixel(float *outputValue, float x, float y, */ /* don't make something that was more transparent less transparent */ - if (alphaaddInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VECTOR); @@ -44,7 +44,7 @@ void MapUVOperation::executePixel(float *color, float x, float y, PixelSampler s { float inputUV[4]; float uv_a[4], uv_b[4]; - float u,v; + float u, v; float dx, dy; float uv_l, uv_r; @@ -52,48 +52,45 @@ void MapUVOperation::executePixel(float *color, float x, float y, PixelSampler s this->inputUVProgram->read(inputUV, x, y, sampler, inputBuffers); if (inputUV[2] == 0.f) { - color[0] = 0.f; - color[1] = 0.f; - color[2] = 0.f; - color[3] = 0.f; - return; + zero_v4(color); + return; } /* adaptive sampling, red (U) channel */ - this->inputUVProgram->read(uv_a, x-1, y, COM_PS_NEAREST, inputBuffers); - this->inputUVProgram->read(uv_b, x+1, y, COM_PS_NEAREST, inputBuffers); - uv_l = uv_a[2]!=0.f? fabsf(inputUV[0] - uv_a[0]) : 0.f; - uv_r = uv_b[2]!=0.f? fabsf(inputUV[0] - uv_b[0]) : 0.f; + this->inputUVProgram->read(uv_a, x - 1, y, COM_PS_NEAREST, inputBuffers); + this->inputUVProgram->read(uv_b, x + 1, y, COM_PS_NEAREST, inputBuffers); + uv_l = uv_a[2] != 0.f ? fabsf(inputUV[0] - uv_a[0]) : 0.f; + uv_r = uv_b[2] != 0.f ? fabsf(inputUV[0] - uv_b[0]) : 0.f; dx = 0.5f * (uv_l + uv_r); /* adaptive sampling, green (V) channel */ - this->inputUVProgram->read(uv_a, x, y-1, COM_PS_NEAREST, inputBuffers); - this->inputUVProgram->read(uv_b, x, y+1, COM_PS_NEAREST, inputBuffers); - uv_u = uv_a[2]!=0.f? fabsf(inputUV[1] - uv_a[1]) : 0.f; - uv_d = uv_b[2]!=0.f? fabsf(inputUV[1] - uv_b[1]) : 0.f; + this->inputUVProgram->read(uv_a, x, y - 1, COM_PS_NEAREST, inputBuffers); + this->inputUVProgram->read(uv_b, x, y + 1, COM_PS_NEAREST, inputBuffers); + uv_u = uv_a[2] != 0.f ? fabsf(inputUV[1] - uv_a[1]) : 0.f; + uv_d = uv_b[2] != 0.f ? fabsf(inputUV[1] - uv_b[1]) : 0.f; dy = 0.5f * (uv_u + uv_d); /* more adaptive sampling, red and green (UV) channels */ - this->inputUVProgram->read(uv_a, x-1, y-1, COM_PS_NEAREST, inputBuffers); - this->inputUVProgram->read(uv_b, x-1, y+1, COM_PS_NEAREST, inputBuffers); - uv_l = uv_a[2]!=0.f? fabsf(inputUV[0] - uv_a[0]) : 0.f; - uv_r = uv_b[2]!=0.f? fabsf(inputUV[0] - uv_b[0]) : 0.f; - uv_u = uv_a[2]!=0.f? fabsf(inputUV[1] - uv_a[1]) : 0.f; - uv_d = uv_b[2]!=0.f? fabsf(inputUV[1] - uv_b[1]) : 0.f; + this->inputUVProgram->read(uv_a, x - 1, y - 1, COM_PS_NEAREST, inputBuffers); + this->inputUVProgram->read(uv_b, x - 1, y + 1, COM_PS_NEAREST, inputBuffers); + uv_l = uv_a[2] != 0.f ? fabsf(inputUV[0] - uv_a[0]) : 0.f; + uv_r = uv_b[2] != 0.f ? fabsf(inputUV[0] - uv_b[0]) : 0.f; + uv_u = uv_a[2] != 0.f ? fabsf(inputUV[1] - uv_a[1]) : 0.f; + uv_d = uv_b[2] != 0.f ? fabsf(inputUV[1] - uv_b[1]) : 0.f; - dx+= 0.25f * (uv_l + uv_r); - dy+= 0.25f * (uv_u + uv_d); + dx += 0.25f * (uv_l + uv_r); + dy += 0.25f * (uv_u + uv_d); - this->inputUVProgram->read(uv_a, x+1, y-1, COM_PS_NEAREST, inputBuffers); - this->inputUVProgram->read(uv_b, x+1, y+1, COM_PS_NEAREST, inputBuffers); - uv_l = uv_a[2]!=0.f? fabsf(inputUV[0] - uv_a[0]) : 0.f; - uv_r = uv_b[2]!=0.f? fabsf(inputUV[0] - uv_b[0]) : 0.f; - uv_u = uv_a[2]!=0.f? fabsf(inputUV[1] - uv_a[1]) : 0.f; - uv_d = uv_b[2]!=0.f? fabsf(inputUV[1] - uv_b[1]) : 0.f; + this->inputUVProgram->read(uv_a, x + 1, y - 1, COM_PS_NEAREST, inputBuffers); + this->inputUVProgram->read(uv_b, x + 1, y + 1, COM_PS_NEAREST, inputBuffers); + uv_l = uv_a[2] != 0.f ? fabsf(inputUV[0] - uv_a[0]) : 0.f; + uv_r = uv_b[2] != 0.f ? fabsf(inputUV[0] - uv_b[0]) : 0.f; + uv_u = uv_a[2] != 0.f ? fabsf(inputUV[1] - uv_a[1]) : 0.f; + uv_d = uv_b[2] != 0.f ? fabsf(inputUV[1] - uv_b[1]) : 0.f; - dx+= 0.25f * (uv_l + uv_r); - dy+= 0.25f * (uv_u + uv_d); + dx += 0.25f * (uv_l + uv_r); + dy += 0.25f * (uv_u + uv_d); /* UV to alpha threshold */ const float threshold = this->alpha * 0.05f; @@ -114,10 +111,7 @@ void MapUVOperation::executePixel(float *color, float x, float y, PixelSampler s /* "premul" */ if (alpha < 1.0f) { - color[0]*= alpha; - color[1]*= alpha; - color[2]*= alpha; - color[3]*= alpha; + mul_v4_fl(color, alpha); } } @@ -131,7 +125,7 @@ bool MapUVOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOpe { rcti colorInput; rcti uvInput; - NodeOperation *operation=NULL; + NodeOperation *operation = NULL; /* the uv buffer only needs a 3x3 buffer. The image needs whole buffer */ diff --git a/source/blender/compositor/operations/COM_MapValueOperation.cpp b/source/blender/compositor/operations/COM_MapValueOperation.cpp index bf6d29c0456..6d7804dd6e3 100644 --- a/source/blender/compositor/operations/COM_MapValueOperation.cpp +++ b/source/blender/compositor/operations/COM_MapValueOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MapValueOperation.h" -MapValueOperation::MapValueOperation(): NodeOperation() +MapValueOperation::MapValueOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -39,12 +39,12 @@ void MapValueOperation::executePixel(float *outputValue, float x, float y, Pixel float src[4]; inputOperation->read(src, x, y, sampler, inputBuffers); TexMapping *texmap = this->settings; - float value = (src[0] + texmap->loc[0])*texmap->size[0]; + float value = (src[0] + texmap->loc[0]) * texmap->size[0]; if (texmap->flag & TEXMAP_CLIP_MIN) - if (valuemin[0]) + if (value < texmap->min[0]) value = texmap->min[0]; if (texmap->flag & TEXMAP_CLIP_MAX) - if (value>texmap->max[0]) + if (value > texmap->max[0]) value = texmap->max[0]; outputValue[0] = value; diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index 8f7115659a1..0493bdee12c 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -32,10 +32,10 @@ extern "C" { #include "BKE_mask.h" - #include "../../../../intern/raskter/raskter.h" + #include "../../../../intern/raskter/raskter.h" } -MaskOperation::MaskOperation(): NodeOperation() +MaskOperation::MaskOperation() : NodeOperation() { this->addOutputSocket(COM_DT_VALUE); this->mask = NULL; @@ -76,9 +76,9 @@ void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers buffer = (float *)MEM_callocN(sizeof(float) * width * height, "rasterized mask"); BKE_mask_rasterize(mask, width, height, buffer, TRUE, this->smooth); - if(this->smooth) { - PLX_antialias_buffer(buffer, width, height); - } + if (this->smooth) { + PLX_antialias_buffer(buffer, width, height); + } this->rasterizedMask = buffer; } @@ -110,7 +110,7 @@ void MaskOperation::executePixel(float *color, int x, int y, MemoryBuffer *input color[0] = 0.0f; } else { - float *buffer = (float*) data; + float *buffer = (float *) data; int index = (y * this->getWidth() + x); color[0] = buffer[index]; diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp index b943ec88fde..5e9fb70b206 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp @@ -25,7 +25,7 @@ extern "C" { #include "BLI_math.h" } -MathBaseOperation::MathBaseOperation(): NodeOperation() +MathBaseOperation::MathBaseOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_VALUE); @@ -50,14 +50,15 @@ void MathBaseOperation::deinitExecution() void MathBaseOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { InputSocket *socket; - unsigned int tempPreferredResolution[] = {0,0}; + unsigned int tempPreferredResolution[] = {0, 0}; unsigned int tempResolution[2]; socket = this->getInputSocket(0); socket->determineResolution(tempResolution, tempPreferredResolution); if ((tempResolution[0] != 0) && (tempResolution[1] != 0)) { this->setResolutionInputSocketIndex(0); - } else { + } + else { this->setResolutionInputSocketIndex(1); } NodeOperation::determineResolution(resolution, preferredResolution); @@ -104,7 +105,7 @@ void MathDivideOperation::executePixel(float *outputValue, float x, float y, Pix inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); - if (inputValue2[0]==0) /* We don't want to divide by zero. */ + if (inputValue2[0] == 0) /* We don't want to divide by zero. */ outputValue[0] = 0.0; else outputValue[0] = inputValue1[0] / inputValue2[0]; @@ -151,7 +152,7 @@ void MathArcSineOperation::executePixel(float *outputValue, float x, float y, Pi inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); - if (inputValue1[0] <= 1 && inputValue1[0] >= -1 ) + if (inputValue1[0] <= 1 && inputValue1[0] >= -1) outputValue[0] = asin(inputValue1[0]); else outputValue[0] = 0.0; @@ -165,7 +166,7 @@ void MathArcCosineOperation::executePixel(float *outputValue, float x, float y, inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); - if (inputValue1[0] <= 1 && inputValue1[0] >= -1 ) + if (inputValue1[0] <= 1 && inputValue1[0] >= -1) outputValue[0] = acos(inputValue1[0]); else outputValue[0] = 0.0; @@ -260,7 +261,7 @@ void MathLessThanOperation::executePixel(float *outputValue, float x, float y, P inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); - outputValue[0] = inputValue1[0]read(&inputValue1[0], x, y, sampler, inputBuffers); inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); - outputValue[0] = inputValue1[0]>inputValue2[0]?1.0f:0.0f; + outputValue[0] = inputValue1[0] > inputValue2[0] ? 1.0f : 0.0f; } diff --git a/source/blender/compositor/operations/COM_MixAddOperation.cpp b/source/blender/compositor/operations/COM_MixAddOperation.cpp index 2c25635e3bc..bd9538a5600 100644 --- a/source/blender/compositor/operations/COM_MixAddOperation.cpp +++ b/source/blender/compositor/operations/COM_MixAddOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixAddOperation.h" -MixAddOperation::MixAddOperation(): MixBaseOperation() +MixAddOperation::MixAddOperation() : MixBaseOperation() { /* pass */ } @@ -42,9 +42,9 @@ void MixAddOperation::executePixel(float *outputValue, float x, float y, PixelSa if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } - outputValue[0] = inputColor1[0]+value*inputColor2[0]; - outputValue[1] = inputColor1[1]+value*inputColor2[1]; - outputValue[2] = inputColor1[2]+value*inputColor2[2]; + outputValue[0] = inputColor1[0] + value * inputColor2[0]; + outputValue[1] = inputColor1[1] + value * inputColor2[1]; + outputValue[2] = inputColor1[2] + value * inputColor2[2]; outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.cpp b/source/blender/compositor/operations/COM_MixBaseOperation.cpp index 49ae67a06f7..0efab2942b0 100644 --- a/source/blender/compositor/operations/COM_MixBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_MixBaseOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixBaseOperation.h" -MixBaseOperation::MixBaseOperation(): NodeOperation() +MixBaseOperation::MixBaseOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); @@ -55,9 +55,9 @@ void MixBaseOperation::executePixel(float *outputColor, float x, float y, PixelS value *= inputColor2[3]; } float valuem = 1.0f - value; - outputColor[0] = valuem*(inputColor1[0])+value*(inputColor2[0]); - outputColor[1] = valuem*(inputColor1[1])+value*(inputColor2[1]); - outputColor[2] = valuem*(inputColor1[2])+value*(inputColor2[2]); + outputColor[0] = valuem * (inputColor1[0]) + value * (inputColor2[0]); + outputColor[1] = valuem * (inputColor1[1]) + value * (inputColor2[1]); + outputColor[2] = valuem * (inputColor1[2]) + value * (inputColor2[2]); outputColor[3] = inputColor1[3]; } @@ -71,7 +71,7 @@ void MixBaseOperation::deinitExecution() void MixBaseOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { InputSocket *socket; - unsigned int tempPreferredResolution[] = {0,0}; + unsigned int tempPreferredResolution[] = {0, 0}; unsigned int tempResolution[2]; socket = this->getInputSocket(1); diff --git a/source/blender/compositor/operations/COM_MixBlendOperation.cpp b/source/blender/compositor/operations/COM_MixBlendOperation.cpp index fadac8bbf21..f010d23ce60 100644 --- a/source/blender/compositor/operations/COM_MixBlendOperation.cpp +++ b/source/blender/compositor/operations/COM_MixBlendOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixBlendOperation.h" -MixBlendOperation::MixBlendOperation(): MixBaseOperation() +MixBlendOperation::MixBlendOperation() : MixBaseOperation() { /* pass */ } @@ -43,8 +43,8 @@ void MixBlendOperation::executePixel(float *outputValue, float x, float y, Pixel value *= inputColor2[3]; } float valuem = 1.0f - value; - outputValue[0] = valuem*(inputColor1[0])+value*(inputColor2[0]); - outputValue[1] = valuem*(inputColor1[1])+value*(inputColor2[1]); - outputValue[2] = valuem*(inputColor1[2])+value*(inputColor2[2]); + outputValue[0] = valuem * (inputColor1[0]) + value * (inputColor2[0]); + outputValue[1] = valuem * (inputColor1[1]) + value * (inputColor2[1]); + outputValue[2] = valuem * (inputColor1[2]) + value * (inputColor2[2]); outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixBurnOperation.cpp b/source/blender/compositor/operations/COM_MixBurnOperation.cpp index 8231a5d60af..e94834148e8 100644 --- a/source/blender/compositor/operations/COM_MixBurnOperation.cpp +++ b/source/blender/compositor/operations/COM_MixBurnOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixBurnOperation.h" -MixBurnOperation::MixBurnOperation(): MixBaseOperation() +MixBurnOperation::MixBurnOperation() : MixBaseOperation() { /* pass */ } @@ -43,7 +43,7 @@ void MixBurnOperation::executePixel(float *outputValue, float x, float y, PixelS } float valuem = 1.0f - value; - tmp = valuem + value*inputColor2[0]; + tmp = valuem + value * inputColor2[0]; if (tmp <= 0.0f) outputValue[0] = 0.0f; else { @@ -56,7 +56,7 @@ void MixBurnOperation::executePixel(float *outputValue, float x, float y, PixelS outputValue[0] = tmp; } - tmp = valuem + value*inputColor2[1]; + tmp = valuem + value * inputColor2[1]; if (tmp <= 0.0f) outputValue[1] = 0.0f; else { @@ -69,7 +69,7 @@ void MixBurnOperation::executePixel(float *outputValue, float x, float y, PixelS outputValue[1] = tmp; } - tmp = valuem + value*inputColor2[2]; + tmp = valuem + value * inputColor2[2]; if (tmp <= 0.0f) outputValue[2] = 0.0f; else { diff --git a/source/blender/compositor/operations/COM_MixColorOperation.cpp b/source/blender/compositor/operations/COM_MixColorOperation.cpp index 035e764d780..f3e893bc18f 100644 --- a/source/blender/compositor/operations/COM_MixColorOperation.cpp +++ b/source/blender/compositor/operations/COM_MixColorOperation.cpp @@ -26,7 +26,7 @@ extern "C" { #include "BLI_math.h" } -MixColorOperation::MixColorOperation(): MixBaseOperation() +MixColorOperation::MixColorOperation() : MixBaseOperation() { /* pass */ } @@ -46,16 +46,16 @@ void MixColorOperation::executePixel(float *outputValue, float x, float y, Pixel } float valuem = 1.0f - value; - float colH,colS,colV; + float colH, colS, colV; rgb_to_hsv(inputColor2[0], inputColor2[1], inputColor2[2], &colH, &colS, &colV); - if (colS!=0.0f) { - float rH,rS,rV; - float tmpr,tmpg,tmpb; + if (colS != 0.0f) { + float rH, rS, rV; + float tmpr, tmpg, tmpb; rgb_to_hsv(inputColor1[0], inputColor1[1], inputColor1[2], &rH, &rS, &rV); - hsv_to_rgb(colH , colS, rV, &tmpr, &tmpg, &tmpb); - outputValue[0] = valuem*(inputColor1[0]) + value*tmpr; - outputValue[1] = valuem*(inputColor1[1]) + value*tmpg; - outputValue[2] = valuem*(inputColor1[2]) + value*tmpb; + hsv_to_rgb(colH, colS, rV, &tmpr, &tmpg, &tmpb); + outputValue[0] = valuem * (inputColor1[0]) + value * tmpr; + outputValue[1] = valuem * (inputColor1[1]) + value * tmpg; + outputValue[2] = valuem * (inputColor1[2]) + value * tmpb; } outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixDarkenOperation.cpp b/source/blender/compositor/operations/COM_MixDarkenOperation.cpp index a1da5dce9c8..a36c663ddda 100644 --- a/source/blender/compositor/operations/COM_MixDarkenOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDarkenOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixDarkenOperation.h" -MixDarkenOperation::MixDarkenOperation(): MixBaseOperation() +MixDarkenOperation::MixDarkenOperation() : MixBaseOperation() { /* pass */ } @@ -42,13 +42,13 @@ void MixDarkenOperation::executePixel(float *outputValue, float x, float y, Pixe } float valuem = 1.0f - value; float tmp; - tmp=inputColor2[0]+((1.0f-inputColor2[0])*valuem); + tmp = inputColor2[0] + ((1.0f - inputColor2[0]) * valuem); if (tmp < inputColor1[0]) outputValue[0] = tmp; else outputValue[0] = inputColor1[0]; - tmp=inputColor2[1]+((1.0f-inputColor2[1])*valuem); + tmp = inputColor2[1] + ((1.0f - inputColor2[1]) * valuem); if (tmp < inputColor1[1]) outputValue[1] = tmp; else outputValue[1] = inputColor1[1]; - tmp=inputColor2[2]+((1.0f-inputColor2[2])*valuem); + tmp = inputColor2[2] + ((1.0f - inputColor2[2]) * valuem); if (tmp < inputColor1[2]) outputValue[2] = tmp; else outputValue[2] = inputColor1[2]; diff --git a/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp b/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp index 883837f0917..69886753480 100644 --- a/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp @@ -23,7 +23,7 @@ #include "COM_MixDifferenceOperation.h" #include "BLI_math.h" -MixDifferenceOperation::MixDifferenceOperation(): MixBaseOperation() +MixDifferenceOperation::MixDifferenceOperation() : MixBaseOperation() { /* pass */ } @@ -42,9 +42,9 @@ void MixDifferenceOperation::executePixel(float *outputValue, float x, float y, value *= inputColor2[3]; } float valuem = 1.0f - value; - outputValue[0] = valuem*inputColor1[0] + value*fabsf(inputColor1[0]-inputColor2[0]); - outputValue[1] = valuem*inputColor1[1] + value*fabsf(inputColor1[1]-inputColor2[1]); - outputValue[2] = valuem*inputColor1[2] + value*fabsf(inputColor1[2]-inputColor2[2]); + outputValue[0] = valuem * inputColor1[0] + value *fabsf(inputColor1[0] - inputColor2[0]); + outputValue[1] = valuem * inputColor1[1] + value *fabsf(inputColor1[1] - inputColor2[1]); + outputValue[2] = valuem * inputColor1[2] + value *fabsf(inputColor1[2] - inputColor2[2]); outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixDivideOperation.cpp b/source/blender/compositor/operations/COM_MixDivideOperation.cpp index 706308dccc5..8b6586c5336 100644 --- a/source/blender/compositor/operations/COM_MixDivideOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDivideOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixDivideOperation.h" -MixDivideOperation::MixDivideOperation(): MixBaseOperation() +MixDivideOperation::MixDivideOperation() : MixBaseOperation() { /* pass */ } @@ -43,15 +43,15 @@ void MixDivideOperation::executePixel(float *outputValue, float x, float y, Pixe float valuem = 1.0f - value; if (inputColor2[0] != 0.0f) - outputValue[0] = valuem*(inputColor1[0]) + value*(inputColor1[0])/inputColor2[0]; + outputValue[0] = valuem * (inputColor1[0]) + value * (inputColor1[0]) / inputColor2[0]; else outputValue[0] = 0.0f; if (inputColor2[1] != 0.0f) - outputValue[1] = valuem*(inputColor1[1]) + value*(inputColor1[1])/inputColor2[1]; + outputValue[1] = valuem * (inputColor1[1]) + value * (inputColor1[1]) / inputColor2[1]; else outputValue[1] = 0.0f; if (inputColor2[2] != 0.0f) - outputValue[2] = valuem*(inputColor1[2]) + value*(inputColor1[2])/inputColor2[2]; + outputValue[2] = valuem * (inputColor1[2]) + value * (inputColor1[2]) / inputColor2[2]; else outputValue[2] = 0.0f; diff --git a/source/blender/compositor/operations/COM_MixDodgeOperation.cpp b/source/blender/compositor/operations/COM_MixDodgeOperation.cpp index 619819e6298..971ddd5b736 100644 --- a/source/blender/compositor/operations/COM_MixDodgeOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDodgeOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixDodgeOperation.h" -MixDodgeOperation::MixDodgeOperation(): MixBaseOperation() +MixDodgeOperation::MixDodgeOperation() : MixBaseOperation() { /* pass */ } @@ -43,7 +43,7 @@ void MixDodgeOperation::executePixel(float *outputValue, float x, float y, Pixel } if (inputColor1[0] != 0.0f) { - tmp = 1.0f - value*inputColor2[0]; + tmp = 1.0f - value * inputColor2[0]; if (tmp <= 0.0f) outputValue[0] = 1.0f; else { @@ -58,7 +58,7 @@ void MixDodgeOperation::executePixel(float *outputValue, float x, float y, Pixel outputValue[0] = 0.0f; if (inputColor1[1] != 0.0f) { - tmp = 1.0f - value*inputColor2[1]; + tmp = 1.0f - value * inputColor2[1]; if (tmp <= 0.0f) outputValue[1] = 1.0f; else { @@ -73,7 +73,7 @@ void MixDodgeOperation::executePixel(float *outputValue, float x, float y, Pixel outputValue[1] = 0.0f; if (inputColor1[2] != 0.0f) { - tmp = 1.0f - value*inputColor2[2]; + tmp = 1.0f - value * inputColor2[2]; if (tmp <= 0.0f) outputValue[2] = 1.0f; else { diff --git a/source/blender/compositor/operations/COM_MixGlareOperation.cpp b/source/blender/compositor/operations/COM_MixGlareOperation.cpp index 71b676622c5..bfb0efe692f 100644 --- a/source/blender/compositor/operations/COM_MixGlareOperation.cpp +++ b/source/blender/compositor/operations/COM_MixGlareOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixGlareOperation.h" -MixGlareOperation::MixGlareOperation(): MixBaseOperation() +MixGlareOperation::MixGlareOperation() : MixBaseOperation() { /* pass */ } @@ -38,10 +38,10 @@ void MixGlareOperation::executePixel(float *outputValue, float x, float y, Pixel inputColor1Operation->read(inputColor1, x, y, sampler, inputBuffers); inputColor2Operation->read(inputColor2, x, y, sampler, inputBuffers); value = inputValue[0]; - float mf = 2.f - 2.f*fabsf(value - 0.5f); + float mf = 2.f - 2.f * fabsf(value - 0.5f); - outputValue[0] = mf*((inputColor1[0])+value*(inputColor2[0]-inputColor1[0])); - outputValue[1] = mf*((inputColor1[1])+value*(inputColor2[1]-inputColor1[1])); - outputValue[2] = mf*((inputColor1[2])+value*(inputColor2[2]-inputColor1[2])); + outputValue[0] = mf * ((inputColor1[0]) + value * (inputColor2[0] - inputColor1[0])); + outputValue[1] = mf * ((inputColor1[1]) + value * (inputColor2[1] - inputColor1[1])); + outputValue[2] = mf * ((inputColor1[2]) + value * (inputColor2[2] - inputColor1[2])); outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixHueOperation.cpp b/source/blender/compositor/operations/COM_MixHueOperation.cpp index d97109c244c..05d02805ebc 100644 --- a/source/blender/compositor/operations/COM_MixHueOperation.cpp +++ b/source/blender/compositor/operations/COM_MixHueOperation.cpp @@ -26,7 +26,7 @@ extern "C" { #include "BLI_math.h" } -MixHueOperation::MixHueOperation(): MixBaseOperation() +MixHueOperation::MixHueOperation() : MixBaseOperation() { /* pass */ } @@ -46,16 +46,16 @@ void MixHueOperation::executePixel(float *outputValue, float x, float y, PixelSa } float valuem = 1.0f - value; - float colH,colS,colV; + float colH, colS, colV; rgb_to_hsv(inputColor2[0], inputColor2[1], inputColor2[2], &colH, &colS, &colV); - if (colS!=0.0f) { - float rH,rS,rV; - float tmpr,tmpg,tmpb; + if (colS != 0.0f) { + float rH, rS, rV; + float tmpr, tmpg, tmpb; rgb_to_hsv(inputColor1[0], inputColor1[1], inputColor1[2], &rH, &rS, &rV); - hsv_to_rgb(colH , rS, rV, &tmpr, &tmpg, &tmpb); - outputValue[0] = valuem*(inputColor1[0]) + value*tmpr; - outputValue[1] = valuem*(inputColor1[1]) + value*tmpg; - outputValue[2] = valuem*(inputColor1[2]) + value*tmpb; + hsv_to_rgb(colH, rS, rV, &tmpr, &tmpg, &tmpb); + outputValue[0] = valuem * (inputColor1[0]) + value * tmpr; + outputValue[1] = valuem * (inputColor1[1]) + value * tmpg; + outputValue[2] = valuem * (inputColor1[2]) + value * tmpb; } outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixLightenOperation.cpp b/source/blender/compositor/operations/COM_MixLightenOperation.cpp index 09d81afcec7..6e1af7a3c44 100644 --- a/source/blender/compositor/operations/COM_MixLightenOperation.cpp +++ b/source/blender/compositor/operations/COM_MixLightenOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixLightenOperation.h" -MixLightenOperation::MixLightenOperation(): MixBaseOperation() +MixLightenOperation::MixLightenOperation() : MixBaseOperation() { /* pass */ } @@ -41,13 +41,13 @@ void MixLightenOperation::executePixel(float *outputValue, float x, float y, Pix value *= inputColor2[3]; } float tmp; - tmp=value * inputColor2[0]; + tmp = value * inputColor2[0]; if (tmp > inputColor1[0]) outputValue[0] = tmp; else outputValue[0] = inputColor1[0]; - tmp=value * inputColor2[1]; + tmp = value * inputColor2[1]; if (tmp > inputColor1[1]) outputValue[1] = tmp; else outputValue[1] = inputColor1[1]; - tmp=value * inputColor2[2]; + tmp = value * inputColor2[2]; if (tmp > inputColor1[2]) outputValue[2] = tmp; else outputValue[2] = inputColor1[2]; outputValue[3] = inputColor1[3]; diff --git a/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp b/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp index 2e3907c15d4..bf1c181b566 100644 --- a/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp +++ b/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixLinearLightOperation.h" -MixLinearLightOperation::MixLinearLightOperation(): MixBaseOperation() +MixLinearLightOperation::MixLinearLightOperation() : MixBaseOperation() { /* pass */ } @@ -41,17 +41,17 @@ void MixLinearLightOperation::executePixel(float *outputValue, float x, float y, value *= inputColor2[3]; } if (inputColor2[0] > 0.5f) - outputValue[0] = inputColor1[0] + value*(2.0f*(inputColor2[0]-0.5f)); + outputValue[0] = inputColor1[0] + value * (2.0f * (inputColor2[0] - 0.5f)); else - outputValue[0] = inputColor1[0] + value*(2.0f*(inputColor2[0]) - 1.0f); + outputValue[0] = inputColor1[0] + value * (2.0f * (inputColor2[0]) - 1.0f); if (inputColor2[1] > 0.5f) - outputValue[1] = inputColor1[1] + value*(2.0f*(inputColor2[1]-0.5f)); + outputValue[1] = inputColor1[1] + value * (2.0f * (inputColor2[1] - 0.5f)); else - outputValue[1] = inputColor1[1] + value*(2.0f*(inputColor2[1]) - 1.0f); + outputValue[1] = inputColor1[1] + value * (2.0f * (inputColor2[1]) - 1.0f); if (inputColor2[2] > 0.5f) - outputValue[2] = inputColor1[2] + value*(2.0f*(inputColor2[2]-0.5f)); + outputValue[2] = inputColor1[2] + value * (2.0f * (inputColor2[2] - 0.5f)); else - outputValue[2] = inputColor1[2] + value*(2.0f*(inputColor2[2]) - 1.0f); + outputValue[2] = inputColor1[2] + value * (2.0f * (inputColor2[2]) - 1.0f); outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixMultiplyOperation.cpp b/source/blender/compositor/operations/COM_MixMultiplyOperation.cpp index 223aa476f18..62018ed5698 100644 --- a/source/blender/compositor/operations/COM_MixMultiplyOperation.cpp +++ b/source/blender/compositor/operations/COM_MixMultiplyOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixMultiplyOperation.h" -MixMultiplyOperation::MixMultiplyOperation(): MixBaseOperation() +MixMultiplyOperation::MixMultiplyOperation() : MixBaseOperation() { /* pass */ } @@ -42,9 +42,9 @@ void MixMultiplyOperation::executePixel(float *outputValue, float x, float y, Pi value *= inputColor2[3]; } float valuem = 1.0f - value; - outputValue[0] = inputColor1[0] *(valuem+value*inputColor2[0]); - outputValue[1] = inputColor1[1] *(valuem+value*inputColor2[1]); - outputValue[2] = inputColor1[2] *(valuem+value*inputColor2[2]); + outputValue[0] = inputColor1[0] * (valuem + value * inputColor2[0]); + outputValue[1] = inputColor1[1] * (valuem + value * inputColor2[1]); + outputValue[2] = inputColor1[2] * (valuem + value * inputColor2[2]); outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixOverlayOperation.cpp b/source/blender/compositor/operations/COM_MixOverlayOperation.cpp index dfea8440b67..a269045c598 100644 --- a/source/blender/compositor/operations/COM_MixOverlayOperation.cpp +++ b/source/blender/compositor/operations/COM_MixOverlayOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixOverlayOperation.h" -MixOverlayOperation::MixOverlayOperation(): MixBaseOperation() +MixOverlayOperation::MixOverlayOperation() : MixBaseOperation() { /* pass */ } @@ -44,22 +44,22 @@ void MixOverlayOperation::executePixel(float *outputValue, float x, float y, Pix float valuem = 1.0f - value; if (inputColor1[0] < 0.5f) { - outputValue[0] = inputColor1[0] * (valuem + 2.0f*value*inputColor2[0]); + outputValue[0] = inputColor1[0] * (valuem + 2.0f * value * inputColor2[0]); } else { - outputValue[0] = 1.0f - (valuem + 2.0f*value*(1.0f - inputColor2[0])) * (1.0f - inputColor1[0]); + outputValue[0] = 1.0f - (valuem + 2.0f * value * (1.0f - inputColor2[0])) * (1.0f - inputColor1[0]); } if (inputColor1[1] < 0.5f) { - outputValue[1] = inputColor1[1] * (valuem + 2.0f*value*inputColor2[1]); + outputValue[1] = inputColor1[1] * (valuem + 2.0f * value * inputColor2[1]); } else { - outputValue[1] = 1.0f - (valuem + 2.0f*value*(1.0f - inputColor2[1])) * (1.0f - inputColor1[1]); + outputValue[1] = 1.0f - (valuem + 2.0f * value * (1.0f - inputColor2[1])) * (1.0f - inputColor1[1]); } if (inputColor1[2] < 0.5f) { - outputValue[2] = inputColor1[2] * (valuem + 2.0f*value*inputColor2[2]); + outputValue[2] = inputColor1[2] * (valuem + 2.0f * value * inputColor2[2]); } else { - outputValue[2] = 1.0f - (valuem + 2.0f*value*(1.0f - inputColor2[2])) * (1.0f - inputColor1[2]); + outputValue[2] = 1.0f - (valuem + 2.0f * value * (1.0f - inputColor2[2])) * (1.0f - inputColor1[2]); } outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixSaturationOperation.cpp b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp index 25342abec8a..863a17a7f80 100644 --- a/source/blender/compositor/operations/COM_MixSaturationOperation.cpp +++ b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp @@ -26,7 +26,7 @@ extern "C" { #include "BLI_math.h" } -MixSaturationOperation::MixSaturationOperation(): MixBaseOperation() +MixSaturationOperation::MixSaturationOperation() : MixBaseOperation() { /* pass */ } @@ -46,12 +46,12 @@ void MixSaturationOperation::executePixel(float *outputValue, float x, float y, } float valuem = 1.0f - value; - float rH,rS,rV; + float rH, rS, rV; rgb_to_hsv(inputColor1[0], inputColor1[1], inputColor1[2], &rH, &rS, &rV); - if (rS!=0.0f) { - float colH,colS,colV; + if (rS != 0.0f) { + float colH, colS, colV; rgb_to_hsv(inputColor2[0], inputColor2[1], inputColor2[2], &colH, &colS, &colV); - hsv_to_rgb(rH , (valuem*rS+value*colS), rV, &outputValue[0], &outputValue[1], &outputValue[2]); + hsv_to_rgb(rH, (valuem * rS + value * colS), rV, &outputValue[0], &outputValue[1], &outputValue[2]); } outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixScreenOperation.cpp b/source/blender/compositor/operations/COM_MixScreenOperation.cpp index 8b9916165e2..6fb7befeba4 100644 --- a/source/blender/compositor/operations/COM_MixScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_MixScreenOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixScreenOperation.h" -MixScreenOperation::MixScreenOperation(): MixBaseOperation() +MixScreenOperation::MixScreenOperation() : MixBaseOperation() { /* pass */ } @@ -43,9 +43,9 @@ void MixScreenOperation::executePixel(float *outputValue, float x, float y, Pixe } float valuem = 1.0f - value; - outputValue[0] = 1.0f - (valuem + value*(1.0f-inputColor2[0])) *(1.0f-inputColor1[0]); - outputValue[1] = 1.0f - (valuem + value*(1.0f-inputColor2[1])) *(1.0f-inputColor1[1]); - outputValue[2] = 1.0f - (valuem + value*(1.0f-inputColor2[2])) *(1.0f-inputColor1[2]); + outputValue[0] = 1.0f - (valuem + value * (1.0f - inputColor2[0])) * (1.0f - inputColor1[0]); + outputValue[1] = 1.0f - (valuem + value * (1.0f - inputColor2[1])) * (1.0f - inputColor1[1]); + outputValue[2] = 1.0f - (valuem + value * (1.0f - inputColor2[2])) * (1.0f - inputColor1[2]); outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp b/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp index a4882b7b83b..9f7d0823473 100644 --- a/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp +++ b/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp @@ -22,13 +22,13 @@ #include "COM_MixSoftLightOperation.h" -MixSoftLightOperation::MixSoftLightOperation(): MixBaseOperation() +MixSoftLightOperation::MixSoftLightOperation() : MixBaseOperation() { /* pass */ } -void MixSoftLightOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])\ -{ +void MixSoftLightOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) \ + { float inputColor1[4]; float inputColor2[4]; float value; @@ -48,9 +48,9 @@ void MixSoftLightOperation::executePixel(float *outputValue, float x, float y, P scg = 1.0f - (1.0f - inputColor2[1]) * (1.0f - inputColor1[1]); scb = 1.0f - (1.0f - inputColor2[2]) * (1.0f - inputColor1[2]); - outputValue[0] = valuem*(inputColor1[0]) + value*(((1.0f - inputColor1[0]) * inputColor2[0] * (inputColor1[0])) + (inputColor1[0] * scr)); - outputValue[1] = valuem*(inputColor1[1]) + value*(((1.0f - inputColor1[1]) * inputColor2[1] * (inputColor1[1])) + (inputColor1[1] * scg)); - outputValue[2] = valuem*(inputColor1[2]) + value*(((1.0f - inputColor1[2]) * inputColor2[2] * (inputColor1[2])) + (inputColor1[2] * scb)); + outputValue[0] = valuem * (inputColor1[0]) + value * (((1.0f - inputColor1[0]) * inputColor2[0] * (inputColor1[0])) + (inputColor1[0] * scr)); + outputValue[1] = valuem * (inputColor1[1]) + value * (((1.0f - inputColor1[1]) * inputColor2[1] * (inputColor1[1])) + (inputColor1[1] * scg)); + outputValue[2] = valuem * (inputColor1[2]) + value * (((1.0f - inputColor1[2]) * inputColor2[2] * (inputColor1[2])) + (inputColor1[2] * scb)); outputValue[3] = inputColor1[3]; -} + } diff --git a/source/blender/compositor/operations/COM_MixSubtractOperation.cpp b/source/blender/compositor/operations/COM_MixSubtractOperation.cpp index d7c7da688a3..80086053872 100644 --- a/source/blender/compositor/operations/COM_MixSubtractOperation.cpp +++ b/source/blender/compositor/operations/COM_MixSubtractOperation.cpp @@ -22,7 +22,7 @@ #include "COM_MixSubtractOperation.h" -MixSubtractOperation::MixSubtractOperation(): MixBaseOperation() +MixSubtractOperation::MixSubtractOperation() : MixBaseOperation() { /* pass */ } @@ -40,9 +40,9 @@ void MixSubtractOperation::executePixel(float *outputValue, float x, float y, Pi if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } - outputValue[0] = inputColor1[0]-value*(inputColor2[0]); - outputValue[1] = inputColor1[1]-value*(inputColor2[1]); - outputValue[2] = inputColor1[2]-value*(inputColor2[2]); + outputValue[0] = inputColor1[0] - value * (inputColor2[0]); + outputValue[1] = inputColor1[1] - value * (inputColor2[1]); + outputValue[2] = inputColor1[2] - value * (inputColor2[2]); outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MixValueOperation.cpp b/source/blender/compositor/operations/COM_MixValueOperation.cpp index f680692f529..cd79c54318d 100644 --- a/source/blender/compositor/operations/COM_MixValueOperation.cpp +++ b/source/blender/compositor/operations/COM_MixValueOperation.cpp @@ -26,7 +26,7 @@ extern "C" { #include "BLI_math.h" } -MixValueOperation::MixValueOperation(): MixBaseOperation() +MixValueOperation::MixValueOperation() : MixBaseOperation() { /* pass */ } @@ -46,10 +46,10 @@ void MixValueOperation::executePixel(float *outputValue, float x, float y, Pixel } float valuem = 1.0f - value; - float rH,rS,rV; - float colH,colS,colV; + float rH, rS, rV; + float colH, colS, colV; rgb_to_hsv(inputColor1[0], inputColor1[1], inputColor1[2], &rH, &rS, &rV); rgb_to_hsv(inputColor2[0], inputColor2[1], inputColor2[2], &colH, &colS, &colV); - hsv_to_rgb(rH , rS, (valuem*rV+value*colV), &outputValue[0], &outputValue[1], &outputValue[2]); + hsv_to_rgb(rH, rS, (valuem * rV + value * colV), &outputValue[0], &outputValue[1], &outputValue[2]); outputValue[3] = inputColor1[3]; } diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp index d9f9801e2e1..662212567de 100644 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp @@ -25,7 +25,7 @@ extern "C" { #include "BKE_tracking.h" #include "BKE_movieclip.h" } -MovieClipAttributeOperation::MovieClipAttributeOperation(): NodeOperation() +MovieClipAttributeOperation::MovieClipAttributeOperation() : NodeOperation() { this->addOutputSocket(COM_DT_VALUE); this->valueSet = false; @@ -46,18 +46,18 @@ void MovieClipAttributeOperation::executePixel(float *outputValue, float x, floa BKE_tracking_stabilization_data_get(&clip->tracking, clip_framenr, getWidth(), getHeight(), loc, &scale, &angle); } switch (this->attribute) { - case MCA_SCALE: - this->value = scale; - break; - case MCA_ANGLE: - this->value = angle; - break; - case MCA_X: - this->value = loc[0]; - break; - case MCA_Y: - this->value = loc[1]; - break; + case MCA_SCALE: + this->value = scale; + break; + case MCA_ANGLE: + this->value = angle; + break; + case MCA_X: + this->value = loc[0]; + break; + case MCA_Y: + this->value = loc[1]; + break; } valueSet = true; } diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp index 6019ab879be..b8bda12c626 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp @@ -31,7 +31,7 @@ extern "C" { } #include "BKE_image.h" -MovieClipOperation::MovieClipOperation(): NodeOperation() +MovieClipOperation::MovieClipOperation() : NodeOperation() { this->addOutputSocket(COM_DT_COLOR); this->movieClip = NULL; @@ -51,9 +51,9 @@ void MovieClipOperation::initExecution() ibuf = BKE_movieclip_get_ibuf(this->movieClip, this->movieClipUser); if (ibuf) { this->movieClipBuffer = ibuf; - if (ibuf->rect_float == NULL || ibuf->userflags&IB_RECT_INVALID) { + if (ibuf->rect_float == NULL || ibuf->userflags & IB_RECT_INVALID) { IMB_float_from_rect(ibuf); - ibuf->userflags&= ~IB_RECT_INVALID; + ibuf->userflags &= ~IB_RECT_INVALID; } } } @@ -93,15 +93,15 @@ void MovieClipOperation::executePixel(float *color, float x, float y, PixelSampl } else { switch (sampler) { - case COM_PS_NEAREST: - neareast_interpolation_color(this->movieClipBuffer, NULL, color, x, y); - break; - case COM_PS_BILINEAR: - bilinear_interpolation_color(this->movieClipBuffer, NULL, color, x, y); - break; - case COM_PS_BICUBIC: - bicubic_interpolation_color(this->movieClipBuffer, NULL, color, x, y); - break; + case COM_PS_NEAREST: + neareast_interpolation_color(this->movieClipBuffer, NULL, color, x, y); + break; + case COM_PS_BILINEAR: + bilinear_interpolation_color(this->movieClipBuffer, NULL, color, x, y); + break; + case COM_PS_BICUBIC: + bicubic_interpolation_color(this->movieClipBuffer, NULL, color, x, y); + break; } } } diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp index d9e8977871f..5320f901747 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp @@ -29,7 +29,7 @@ extern "C" { } -vector s_cache; +vector s_cache; MovieDistortionOperation::MovieDistortionOperation(bool distortion) : NodeOperation() @@ -52,8 +52,8 @@ void MovieDistortionOperation::initExecution() BKE_movieclip_user_set_frame(&clipUser, this->framenumber); BKE_movieclip_get_size(this->movieClip, &clipUser, &calibration_width, &calibration_height); - for (unsigned int i = 0 ; i < s_cache.size() ; i ++) { - DistortionCache *c = (DistortionCache*)s_cache[i]; + for (unsigned int i = 0; i < s_cache.size(); i++) { + DistortionCache *c = (DistortionCache *)s_cache[i]; if (c->isCacheFor(this->movieClip, this->width, this->height, calibration_width, calibration_height, this->distortion)) { @@ -78,7 +78,7 @@ void MovieDistortionOperation::deinitExecution() } -void MovieDistortionOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void MovieDistortionOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { if (this->cache != NULL) { diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp index 5e81cd639dd..1bd21f6e712 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp @@ -27,7 +27,7 @@ extern "C" { #include "IMB_imbuf_types.h" } -MultilayerBaseOperation::MultilayerBaseOperation(int pass): BaseImageOperation() +MultilayerBaseOperation::MultilayerBaseOperation(int pass) : BaseImageOperation() { this->passId = pass; } @@ -56,22 +56,22 @@ void MultilayerColorOperation::executePixel(float *color, float x, float y, Pixe else { if (this->numberOfChannels == 4) { switch (sampler) { - case COM_PS_NEAREST: - neareast_interpolation_color(this->buffer, NULL, color, x, y); - break; - case COM_PS_BILINEAR: - bilinear_interpolation_color(this->buffer, NULL, color, x, y); - break; - case COM_PS_BICUBIC: - bicubic_interpolation_color(this->buffer, NULL, color, x, y); - break; + case COM_PS_NEAREST: + neareast_interpolation_color(this->buffer, NULL, color, x, y); + break; + case COM_PS_BILINEAR: + bilinear_interpolation_color(this->buffer, NULL, color, x, y); + break; + case COM_PS_BICUBIC: + bicubic_interpolation_color(this->buffer, NULL, color, x, y); + break; } } else { - int offset = (yi*this->getWidth()+xi)*3; + int offset = (yi * this->getWidth() + xi) * 3; color[0] = this->imageBuffer[offset]; - color[1] = this->imageBuffer[offset+1]; - color[2] = this->imageBuffer[offset+2]; + color[1] = this->imageBuffer[offset + 1]; + color[2] = this->imageBuffer[offset + 2]; } } } @@ -84,7 +84,7 @@ void MultilayerValueOperation::executePixel(float *color, float x, float y, Pixe color[0] = 0.0f; } else { - float result = this->imageBuffer[yi*this->getWidth()+xi]; + float result = this->imageBuffer[yi * this->getWidth() + xi]; color[0] = result; } } @@ -97,9 +97,9 @@ void MultilayerVectorOperation::executePixel(float *color, float x, float y, Pix color[0] = 0.0f; } else { - int offset = (yi*this->getWidth()+xi)*3; + int offset = (yi * this->getWidth() + xi) * 3; color[0] = this->imageBuffer[offset]; - color[1] = this->imageBuffer[offset+1]; - color[2] = this->imageBuffer[offset+2]; + color[1] = this->imageBuffer[offset + 1]; + color[2] = this->imageBuffer[offset + 2]; } } diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cpp b/source/blender/compositor/operations/COM_NormalizeOperation.cpp index df382547f13..6d12141a455 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.cpp +++ b/source/blender/compositor/operations/COM_NormalizeOperation.cpp @@ -21,7 +21,7 @@ #include "COM_NormalizeOperation.h" -NormalizeOperation::NormalizeOperation(): NodeOperation() +NormalizeOperation::NormalizeOperation() : NodeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -35,7 +35,7 @@ void NormalizeOperation::initExecution() NodeOperation::initMutex(); } -void NormalizeOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data) +void NormalizeOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { /* using generic two floats struct to store x: min y: mult */ NodeTwoFloats *minmult = (NodeTwoFloats *)data; @@ -78,7 +78,7 @@ void *NormalizeOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBu { lockMutex(); if (this->cachedInstance == NULL) { - MemoryBuffer *tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); + MemoryBuffer *tile = (MemoryBuffer *)imageReader->initializeTileData(rect, memoryBuffers); /* using generic two floats struct to store x: min y: mult */ NodeTwoFloats *minmult = new NodeTwoFloats(); @@ -86,20 +86,20 @@ void *NormalizeOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBu int p = tile->getWidth() * tile->getHeight(); float *bc = buffer; - float minv = 1.0f+BLENDER_ZMAX; - float maxv = -1.0f-BLENDER_ZMAX; + float minv = 1.0f + BLENDER_ZMAX; + float maxv = -1.0f - BLENDER_ZMAX; float value; while (p--) { - value=bc[0]; + value = bc[0]; maxv = max(value, maxv); minv = min(value, minv); - bc+=4; + bc += 4; } minmult->x = minv; /* The rare case of flat buffer would cause a divide by 0 */ - minmult->y = ((maxv!=minv)? 1.0f/(maxv-minv):0.f); + minmult->y = ((maxv != minv) ? 1.0f / (maxv - minv) : 0.f); this->cachedInstance = minmult; } diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp index 1438116f313..e71178a811d 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -41,10 +41,10 @@ extern "C" { static int get_datatype_size(DataType datatype) { switch (datatype) { - case COM_DT_VALUE: return 1; - case COM_DT_VECTOR: return 3; - case COM_DT_COLOR: return 4; - default: return 0; + case COM_DT_VALUE: return 1; + case COM_DT_VECTOR: return 3; + case COM_DT_COLOR: return 4; + default: return 0; } } @@ -53,13 +53,13 @@ static float *init_buffer(unsigned int width, unsigned int height, DataType data // When initializing the tree during initial load the width and height can be zero. if (width != 0 && height != 0) { int size = get_datatype_size(datatype); - return (float *)MEM_callocN(width*height*size*sizeof(float), "OutputFile buffer"); + return (float *)MEM_callocN(width * height * size * sizeof(float), "OutputFile buffer"); } else return NULL; } -static void write_buffer_rect(rcti *rect, MemoryBuffer** memoryBuffers, const bNodeTree *tree, +static void write_buffer_rect(rcti *rect, MemoryBuffer **memoryBuffers, const bNodeTree *tree, SocketReader *reader, float *buffer, unsigned int width, DataType datatype) { float color[4]; @@ -70,29 +70,29 @@ static void write_buffer_rect(rcti *rect, MemoryBuffer** memoryBuffers, const bN int y1 = rect->ymin; int x2 = rect->xmax; int y2 = rect->ymax; - int offset = (y1*width + x1 ) * size; + int offset = (y1 * width + x1) * size; int x; int y; bool breaked = false; - for (y = y1 ; y < y2 && (!breaked); y++) { - for (x = x1 ; x < x2 && (!breaked) ; x++) { + for (y = y1; y < y2 && (!breaked); y++) { + for (x = x1; x < x2 && (!breaked); x++) { reader->read(color, x, y, COM_PS_NEAREST, memoryBuffers); - for (i=0; i < size; ++i) - buffer[offset+i] = color[i]; + for (i = 0; i < size; ++i) + buffer[offset + i] = color[i]; offset += size; if (tree->test_break && tree->test_break(tree->tbh)) breaked = true; } - offset += (width-(x2-x1)) * size; + offset += (width - (x2 - x1)) * size; } } OutputSingleLayerOperation::OutputSingleLayerOperation( - const Scene *scene, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path) + const Scene *scene, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path) { this->scene = scene; this->tree = tree; @@ -113,7 +113,7 @@ void OutputSingleLayerOperation::initExecution() this->outputBuffer = init_buffer(this->getWidth(), this->getHeight(), this->datatype); } -void OutputSingleLayerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) +void OutputSingleLayerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers) { write_buffer_rect(rect, memoryBuffers, this->tree, imageInput, this->outputBuffer, this->getWidth(), this->datatype); } @@ -123,7 +123,7 @@ void OutputSingleLayerOperation::deinitExecution() if (this->getWidth() * this->getHeight() != 0) { int size = get_datatype_size(this->datatype); - ImBuf *ibuf = IMB_allocImBuf(this->getWidth(), this->getHeight(), size*8, 0); + ImBuf *ibuf = IMB_allocImBuf(this->getWidth(), this->getHeight(), size * 8, 0); Main *bmain = G.main; /* TODO, have this passed along */ char filename[FILE_MAX]; @@ -160,7 +160,7 @@ OutputOpenExrLayer::OutputOpenExrLayer(const char *name, DataType datatype) } OutputOpenExrMultiLayerOperation::OutputOpenExrMultiLayerOperation( - const Scene *scene, const bNodeTree *tree, const char *path, char exr_codec) + const Scene *scene, const bNodeTree *tree, const char *path, char exr_codec) { this->scene = scene; this->tree = tree; @@ -177,15 +177,15 @@ void OutputOpenExrMultiLayerOperation::add_layer(const char *name, DataType data void OutputOpenExrMultiLayerOperation::initExecution() { - for (unsigned int i=0; i < layers.size(); ++i) { + for (unsigned int i = 0; i < layers.size(); ++i) { layers[i].imageInput = getInputSocketReader(i); layers[i].outputBuffer = init_buffer(this->getWidth(), this->getHeight(), layers[i].datatype); } } -void OutputOpenExrMultiLayerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) +void OutputOpenExrMultiLayerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers) { - for (unsigned int i=0; i < layers.size(); ++i) { + for (unsigned int i = 0; i < layers.size(); ++i) { write_buffer_rect(rect, memoryBuffers, this->tree, layers[i].imageInput, layers[i].outputBuffer, this->getWidth(), layers[i].datatype); } } @@ -203,39 +203,39 @@ void OutputOpenExrMultiLayerOperation::deinitExecution() (this->scene->r.scemode & R_EXTENSION), true); BLI_make_existing_file(filename); - for (unsigned int i=0; i < layers.size(); ++i) { + for (unsigned int i = 0; i < layers.size(); ++i) { char channelname[EXR_TOT_MAXNAME]; - BLI_strncpy(channelname, layers[i].name, sizeof(channelname)-2); + BLI_strncpy(channelname, layers[i].name, sizeof(channelname) - 2); char *channelname_ext = channelname + strlen(channelname); float *buf = layers[i].outputBuffer; /* create channels */ switch (layers[i].datatype) { - case COM_DT_VALUE: - strcpy(channelname_ext, ".V"); - IMB_exr_add_channel(exrhandle, 0, channelname, 1, width, buf); - break; - case COM_DT_VECTOR: - strcpy(channelname_ext, ".X"); - IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3*width, buf); - strcpy(channelname_ext, ".Y"); - IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3*width, buf+1); - strcpy(channelname_ext, ".Z"); - IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3*width, buf+2); - break; - case COM_DT_COLOR: - strcpy(channelname_ext, ".R"); - IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4*width, buf); - strcpy(channelname_ext, ".G"); - IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4*width, buf+1); - strcpy(channelname_ext, ".B"); - IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4*width, buf+2); - strcpy(channelname_ext, ".A"); - IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4*width, buf+3); - break; - default: - break; + case COM_DT_VALUE: + strcpy(channelname_ext, ".V"); + IMB_exr_add_channel(exrhandle, 0, channelname, 1, width, buf); + break; + case COM_DT_VECTOR: + strcpy(channelname_ext, ".X"); + IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf); + strcpy(channelname_ext, ".Y"); + IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf + 1); + strcpy(channelname_ext, ".Z"); + IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf + 2); + break; + case COM_DT_COLOR: + strcpy(channelname_ext, ".R"); + IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf); + strcpy(channelname_ext, ".G"); + IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 1); + strcpy(channelname_ext, ".B"); + IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 2); + strcpy(channelname_ext, ".A"); + IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 3); + break; + default: + break; } } @@ -251,7 +251,7 @@ void OutputOpenExrMultiLayerOperation::deinitExecution() } IMB_exr_close(exrhandle); - for (unsigned int i=0; i < layers.size(); ++i) { + for (unsigned int i = 0; i < layers.size(); ++i) { if (layers[i].outputBuffer) { MEM_freeN(layers[i].outputBuffer); layers[i].outputBuffer = NULL; diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cpp b/source/blender/compositor/operations/COM_PreviewOperation.cpp index 4975f13a285..54a95af33b9 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.cpp +++ b/source/blender/compositor/operations/COM_PreviewOperation.cpp @@ -52,7 +52,7 @@ void PreviewOperation::initExecution() { this->input = getInputSocketReader(0); if (!this->node->preview) { - this->node->preview = (bNodePreview*)MEM_callocN(sizeof(bNodePreview), "node preview"); + this->node->preview = (bNodePreview *)MEM_callocN(sizeof(bNodePreview), "node preview"); } else { if (this->getWidth() == (unsigned int)this->node->preview->xsize && this->getHeight() == (unsigned int)this->node->preview->ysize) { @@ -61,9 +61,9 @@ void PreviewOperation::initExecution() } if (this->outputBuffer == NULL) { - this->outputBuffer = (unsigned char*)MEM_callocN(sizeof(unsigned char)*4*getWidth()*getHeight(), "PreviewOperation"); + this->outputBuffer = (unsigned char *)MEM_callocN(sizeof(unsigned char) * 4 * getWidth() * getHeight(), "PreviewOperation"); if (this->node->preview->rect) { - MEM_freeN(this->node->preview->rect); + MEM_freeN(this->node->preview->rect); } this->node->preview->xsize = getWidth(); this->node->preview->ysize = getHeight(); @@ -81,11 +81,11 @@ void PreviewOperation::executeRegion(rcti *rect, unsigned int tileNumber, Memory { int offset; float color[4]; - for (int y = rect->ymin ; y < rect->ymax ; y++) { - offset = (y * getWidth() + rect->xmin)*4; - for (int x = rect->xmin ; x < rect->xmax ; x++) { - float rx = floor(x/divider); - float ry = floor(y/divider); + for (int y = rect->ymin; y < rect->ymax; y++) { + offset = (y * getWidth() + rect->xmin) * 4; + for (int x = rect->xmin; x < rect->xmax; x++) { + float rx = floor(x / divider); + float ry = floor(y / divider); color[0] = 0.0f; color[1] = 0.0f; @@ -93,8 +93,8 @@ void PreviewOperation::executeRegion(rcti *rect, unsigned int tileNumber, Memory color[3] = 1.0f; input->read(color, rx, ry, COM_PS_NEAREST, memoryBuffers); linearrgb_to_srgb_v4(color, color); - F4TOCHAR4(color, outputBuffer+offset); - offset +=4; + F4TOCHAR4(color, outputBuffer + offset); + offset += 4; } } } @@ -102,10 +102,10 @@ bool PreviewOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferO { rcti newInput; - newInput.xmin = input->xmin/divider; - newInput.xmax = input->xmax/divider; - newInput.ymin = input->ymin/divider; - newInput.ymax = input->ymax/divider; + newInput.xmin = input->xmin / divider; + newInput.xmax = input->xmax / divider; + newInput.ymin = input->ymin / divider; + newInput.ymax = input->ymax / divider; return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } @@ -116,10 +116,10 @@ void PreviewOperation::determineResolution(unsigned int resolution[], unsigned i int height = resolution[1]; this->divider = 0.0f; if (width > height) { - divider = COM_PREVIEW_SIZE / (width-1); + divider = COM_PREVIEW_SIZE / (width - 1); } else { - divider = COM_PREVIEW_SIZE / (height-1); + divider = COM_PREVIEW_SIZE / (height - 1); } width = width * divider; height = height * divider; diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp index 7695e0f63c2..77f2a06b29b 100644 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp @@ -24,7 +24,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -ProjectorLensDistortionOperation::ProjectorLensDistortionOperation(): NodeOperation() +ProjectorLensDistortionOperation::ProjectorLensDistortionOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); @@ -34,7 +34,7 @@ ProjectorLensDistortionOperation::ProjectorLensDistortionOperation(): NodeOperat void ProjectorLensDistortionOperation::initExecution() { this->inputProgram = this->getInputSocketReader(0); - kr = 0.25f*MAX2(MIN2(this->dispersion, 1.f), 0.f); + kr = 0.25f * MAX2(MIN2(this->dispersion, 1.f), 0.f); kr2 = kr * 20; } @@ -49,14 +49,14 @@ void ProjectorLensDistortionOperation::executePixel(float *color, int x, int y, float inputValue[4]; const float height = this->getHeight(); const float width = this->getWidth(); - const float v = (y + 0.5f)/height; - const float u = (x + 0.5f)/width; - MemoryBuffer * inputBuffer = (MemoryBuffer*)data; - inputBuffer->readCubic(inputValue, (u*width + kr2) - 0.5f, v*height - 0.5f); + const float v = (y + 0.5f) / height; + const float u = (x + 0.5f) / width; + MemoryBuffer *inputBuffer = (MemoryBuffer *)data; + inputBuffer->readCubic(inputValue, (u * width + kr2) - 0.5f, v * height - 0.5f); color[0] = inputValue[0]; inputBuffer->read(inputValue, x, y); color[1] = inputValue[1]; - inputBuffer->readCubic(inputValue, (u*width - kr2) - 0.5f, v*height - 0.5f); + inputBuffer->readCubic(inputValue, (u * width - kr2) - 0.5f, v * height - 0.5f); color[2] = inputValue[2]; color[3] = 1.0f; } @@ -71,7 +71,7 @@ bool ProjectorLensDistortionOperation::determineDependingAreaOfInterest(rcti *in rcti newInput; newInput.ymax = input->ymax; newInput.ymin = input->ymin; - newInput.xmin = input->xmin-kr2-2; - newInput.xmax = input->xmax+kr2+2; + newInput.xmin = input->xmin - kr2 - 2; + newInput.xmax = input->xmax + kr2 + 2; return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } diff --git a/source/blender/compositor/operations/COM_QualityStepHelper.cpp b/source/blender/compositor/operations/COM_QualityStepHelper.cpp index f2d700292a4..18b3b106138 100644 --- a/source/blender/compositor/operations/COM_QualityStepHelper.cpp +++ b/source/blender/compositor/operations/COM_QualityStepHelper.cpp @@ -32,40 +32,40 @@ QualityStepHelper::QualityStepHelper() void QualityStepHelper::initExecution(QualityHelper helper) { switch (helper) { - case COM_QH_INCREASE: - switch (this->quality) { - case COM_QUALITY_HIGH: - default: - this->step = 1; - this->offsetadd = 4; + case COM_QH_INCREASE: + switch (this->quality) { + case COM_QUALITY_HIGH: + default: + this->step = 1; + this->offsetadd = 4; + break; + case COM_QUALITY_MEDIUM: + this->step = 2; + this->offsetadd = 8; + break; + case COM_QUALITY_LOW: + this->step = 3; + this->offsetadd = 12; + break; + } break; - case COM_QUALITY_MEDIUM: - this->step = 2; - this->offsetadd = 8; + case COM_QH_MULTIPLY: + switch (this->quality) { + case COM_QUALITY_HIGH: + default: + this->step = 1; + this->offsetadd = 4; + break; + case COM_QUALITY_MEDIUM: + this->step = 2; + this->offsetadd = 8; + break; + case COM_QUALITY_LOW: + this->step = 4; + this->offsetadd = 16; + break; + } break; - case COM_QUALITY_LOW: - this->step = 3; - this->offsetadd = 12; - break; - } - break; - case COM_QH_MULTIPLY: - switch (this->quality) { - case COM_QUALITY_HIGH: - default: - this->step = 1; - this->offsetadd = 4; - break; - case COM_QUALITY_MEDIUM: - this->step = 2; - this->offsetadd = 8; - break; - case COM_QUALITY_LOW: - this->step = 4; - this->offsetadd = 16; - break; - } - break; } } diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp index 14b6db9037b..fa1f0280207 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp @@ -24,7 +24,7 @@ #include "COM_WriteBufferOperation.h" #include "COM_defines.h" -ReadBufferOperation::ReadBufferOperation():NodeOperation() +ReadBufferOperation::ReadBufferOperation() : NodeOperation() { this->addOutputSocket(COM_DT_COLOR); this->offset = 0; @@ -38,7 +38,7 @@ void *ReadBufferOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryB void ReadBufferOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { if (this->memoryProxy != NULL) { - WriteBufferOperation * operation = memoryProxy->getWriteBufferOperation(); + WriteBufferOperation *operation = memoryProxy->getWriteBufferOperation(); operation->determineResolution(resolution, preferredResolution); operation->setResolution(resolution); @@ -67,9 +67,9 @@ void ReadBufferOperation::executePixel(float *color, float x, float y, float dx, } } -bool ReadBufferOperation::determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti *output) +bool ReadBufferOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { - if (this==readOperation) { + if (this == readOperation) { BLI_init_rcti(output, input->xmin, input->xmax, input->ymin, input->ymax); return true; } @@ -78,7 +78,7 @@ bool ReadBufferOperation::determineDependingAreaOfInterest(rcti * input, ReadBuf void ReadBufferOperation::readResolutionFromWriteBuffer() { if (this->memoryProxy != NULL) { - WriteBufferOperation * operation = memoryProxy->getWriteBufferOperation(); + WriteBufferOperation *operation = memoryProxy->getWriteBufferOperation(); this->setWidth(operation->getWidth()); this->setHeight(operation->getHeight()); } diff --git a/source/blender/compositor/operations/COM_RenderLayersAOOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersAOOperation.cpp index dad082cf0ca..bb165c2fe1c 100644 --- a/source/blender/compositor/operations/COM_RenderLayersAOOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersAOOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersAOOperation.h" -RenderLayersAOOperation::RenderLayersAOOperation() :RenderLayersBaseProg(SCE_PASS_AO, 3) +RenderLayersAOOperation::RenderLayersAOOperation() : RenderLayersBaseProg(SCE_PASS_AO, 3) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersAlphaProg.cpp b/source/blender/compositor/operations/COM_RenderLayersAlphaProg.cpp index ccb7dd91c04..35f787cb59f 100644 --- a/source/blender/compositor/operations/COM_RenderLayersAlphaProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersAlphaProg.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersAlphaProg.h" -RenderLayersAlphaProg::RenderLayersAlphaProg() :RenderLayersBaseProg(SCE_PASS_COMBINED, 4) +RenderLayersAlphaProg::RenderLayersAlphaProg() : RenderLayersBaseProg(SCE_PASS_COMBINED, 4) { this->addOutputSocket(COM_DT_VALUE); } @@ -31,7 +31,7 @@ void RenderLayersAlphaProg::executePixel(float *output, float x, float y, PixelS { int ix = x; int iy = y; - float * inputBuffer = this->getInputBuffer(); + float *inputBuffer = this->getInputBuffer(); if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) { output[0] = 0.0f; @@ -40,8 +40,8 @@ void RenderLayersAlphaProg::executePixel(float *output, float x, float y, PixelS output[3] = 0.0f; } else { - unsigned int offset = (iy*this->getWidth()+ix) * 4; - output[0] = inputBuffer[offset+3]; + unsigned int offset = (iy * this->getWidth() + ix) * 4; + output[0] = inputBuffer[offset + 3]; output[1] = 0.0f; output[2] = 0.0f; output[3] = 0.0f; diff --git a/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp index 35c8753ded6..f27af3c25f5 100644 --- a/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp @@ -31,7 +31,7 @@ extern "C" { #include "RE_render_ext.h" } -RenderLayersBaseProg::RenderLayersBaseProg(int renderpass, int elementsize): NodeOperation() +RenderLayersBaseProg::RenderLayersBaseProg(int renderpass, int elementsize) : NodeOperation() { this->renderpass = renderpass; this->setScene(NULL); @@ -42,15 +42,15 @@ RenderLayersBaseProg::RenderLayersBaseProg(int renderpass, int elementsize): Nod void RenderLayersBaseProg::initExecution() { - Scene * scene = this->getScene(); - Render *re = (scene)? RE_GetRender(scene->id.name): NULL; + Scene *scene = this->getScene(); + Render *re = (scene) ? RE_GetRender(scene->id.name) : NULL; RenderResult *rr = NULL; if (re) rr = RE_AcquireResultRead(re); if (rr) { - SceneRenderLayer *srl = (SceneRenderLayer*)BLI_findlink(&scene->r.layers, getLayerId()); + SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&scene->r.layers, getLayerId()); if (srl) { RenderLayer *rl = RE_GetRenderLayer(rr, srl->name); @@ -81,7 +81,7 @@ void RenderLayersBaseProg::executePixel(float *output, float x, float y, PixelSa output[3] = 0.0f; } else { - unsigned int offset = (iy*this->getWidth()+ix) * elementsize; + unsigned int offset = (iy * this->getWidth() + ix) * elementsize; if (elementsize == 1) { output[0] = inputBuffer[offset]; output[1] = 0.0f; @@ -90,15 +90,15 @@ void RenderLayersBaseProg::executePixel(float *output, float x, float y, PixelSa } else if (elementsize == 3) { output[0] = inputBuffer[offset]; - output[1] = inputBuffer[offset+1]; - output[2] = inputBuffer[offset+2]; + output[1] = inputBuffer[offset + 1]; + output[2] = inputBuffer[offset + 2]; output[3] = 1.0f; } else { output[0] = inputBuffer[offset]; - output[1] = inputBuffer[offset+1]; - output[2] = inputBuffer[offset+2]; - output[3] = inputBuffer[offset+3]; + output[1] = inputBuffer[offset + 1]; + output[2] = inputBuffer[offset + 2]; + output[3] = inputBuffer[offset + 3]; } } } @@ -121,12 +121,12 @@ void RenderLayersBaseProg::determineResolution(unsigned int resolution[], unsign rr = RE_AcquireResultRead(re); if (rr) { - SceneRenderLayer *srl = (SceneRenderLayer*)BLI_findlink(&sce->r.layers, getLayerId()); + SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&sce->r.layers, getLayerId()); if (srl) { RenderLayer *rl = RE_GetRenderLayer(rr, srl->name); if (rl && rl->rectf) { - resolution[0]=rl->rectx; - resolution[1]=rl->recty; + resolution[0] = rl->rectx; + resolution[1] = rl->recty; } } } diff --git a/source/blender/compositor/operations/COM_RenderLayersColorOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersColorOperation.cpp index aee68afe55d..3083c37c2bb 100644 --- a/source/blender/compositor/operations/COM_RenderLayersColorOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersColorOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersColorOperation.h" -RenderLayersColorOperation::RenderLayersColorOperation() :RenderLayersBaseProg(SCE_PASS_RGBA, 4) +RenderLayersColorOperation::RenderLayersColorOperation() : RenderLayersBaseProg(SCE_PASS_RGBA, 4) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersCyclesOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersCyclesOperation.cpp index fc1df884181..b056896994e 100644 --- a/source/blender/compositor/operations/COM_RenderLayersCyclesOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersCyclesOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersCyclesOperation.h" -RenderLayersCyclesOperation::RenderLayersCyclesOperation(int pass) :RenderLayersBaseProg(pass, 3) +RenderLayersCyclesOperation::RenderLayersCyclesOperation(int pass) : RenderLayersBaseProg(pass, 3) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersDepthProg.cpp b/source/blender/compositor/operations/COM_RenderLayersDepthProg.cpp index 985b1c1bee8..ae5fc3b2254 100644 --- a/source/blender/compositor/operations/COM_RenderLayersDepthProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersDepthProg.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersDepthProg.h" -RenderLayersDepthProg::RenderLayersDepthProg() :RenderLayersBaseProg(SCE_PASS_Z, 1) +RenderLayersDepthProg::RenderLayersDepthProg() : RenderLayersBaseProg(SCE_PASS_Z, 1) { this->addOutputSocket(COM_DT_VALUE); } diff --git a/source/blender/compositor/operations/COM_RenderLayersDiffuseOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersDiffuseOperation.cpp index ad73490b92d..6baa25e5600 100644 --- a/source/blender/compositor/operations/COM_RenderLayersDiffuseOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersDiffuseOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersDiffuseOperation.h" -RenderLayersDiffuseOperation::RenderLayersDiffuseOperation() :RenderLayersBaseProg(SCE_PASS_DIFFUSE, 3) +RenderLayersDiffuseOperation::RenderLayersDiffuseOperation() : RenderLayersBaseProg(SCE_PASS_DIFFUSE, 3) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersEmitOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersEmitOperation.cpp index 7537e2d10fc..1b03a4e169f 100644 --- a/source/blender/compositor/operations/COM_RenderLayersEmitOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersEmitOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersEmitOperation.h" -RenderLayersEmitOperation::RenderLayersEmitOperation() :RenderLayersBaseProg(SCE_PASS_EMIT, 3) +RenderLayersEmitOperation::RenderLayersEmitOperation() : RenderLayersBaseProg(SCE_PASS_EMIT, 3) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersEnvironmentOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersEnvironmentOperation.cpp index 0ace9a7c58f..f4d6dc7353b 100644 --- a/source/blender/compositor/operations/COM_RenderLayersEnvironmentOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersEnvironmentOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersEnvironmentOperation.h" -RenderLayersEnvironmentOperation::RenderLayersEnvironmentOperation() :RenderLayersBaseProg(SCE_PASS_ENVIRONMENT, 3) +RenderLayersEnvironmentOperation::RenderLayersEnvironmentOperation() : RenderLayersBaseProg(SCE_PASS_ENVIRONMENT, 3) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersImageProg.cpp b/source/blender/compositor/operations/COM_RenderLayersImageProg.cpp index 264e2f0fd79..14c3d652c42 100644 --- a/source/blender/compositor/operations/COM_RenderLayersImageProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersImageProg.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersImageProg.h" -RenderLayersColourProg::RenderLayersColourProg() :RenderLayersBaseProg(SCE_PASS_COMBINED, 4) +RenderLayersColourProg::RenderLayersColourProg() : RenderLayersBaseProg(SCE_PASS_COMBINED, 4) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersIndirectOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersIndirectOperation.cpp index 645f9768eb2..4258cb94a26 100644 --- a/source/blender/compositor/operations/COM_RenderLayersIndirectOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersIndirectOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersIndirectOperation.h" -RenderLayersIndirectOperation::RenderLayersIndirectOperation() :RenderLayersBaseProg(SCE_PASS_INDIRECT, 3) +RenderLayersIndirectOperation::RenderLayersIndirectOperation() : RenderLayersBaseProg(SCE_PASS_INDIRECT, 3) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersMaterialIndexOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersMaterialIndexOperation.cpp index e5cef7753f2..aab7e0089e4 100644 --- a/source/blender/compositor/operations/COM_RenderLayersMaterialIndexOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersMaterialIndexOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersMaterialIndexOperation.h" -RenderLayersMaterialIndexOperation::RenderLayersMaterialIndexOperation() :RenderLayersBaseProg(SCE_PASS_INDEXMA, 1) +RenderLayersMaterialIndexOperation::RenderLayersMaterialIndexOperation() : RenderLayersBaseProg(SCE_PASS_INDEXMA, 1) { this->addOutputSocket(COM_DT_VALUE); } diff --git a/source/blender/compositor/operations/COM_RenderLayersMistOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersMistOperation.cpp index fae6c73f747..c64ddc6e9d8 100644 --- a/source/blender/compositor/operations/COM_RenderLayersMistOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersMistOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersMistOperation.h" -RenderLayersMistOperation::RenderLayersMistOperation() :RenderLayersBaseProg(SCE_PASS_MIST, 1) +RenderLayersMistOperation::RenderLayersMistOperation() : RenderLayersBaseProg(SCE_PASS_MIST, 1) { this->addOutputSocket(COM_DT_VALUE); } diff --git a/source/blender/compositor/operations/COM_RenderLayersNormalOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersNormalOperation.cpp index 67ea4d68204..9d8e7d6272c 100644 --- a/source/blender/compositor/operations/COM_RenderLayersNormalOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersNormalOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersNormalOperation.h" -RenderLayersNormalOperation::RenderLayersNormalOperation() :RenderLayersBaseProg(SCE_PASS_NORMAL, 3) +RenderLayersNormalOperation::RenderLayersNormalOperation() : RenderLayersBaseProg(SCE_PASS_NORMAL, 3) { this->addOutputSocket(COM_DT_VECTOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersObjectIndexOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersObjectIndexOperation.cpp index 821ff447112..430ea698263 100644 --- a/source/blender/compositor/operations/COM_RenderLayersObjectIndexOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersObjectIndexOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersObjectIndexOperation.h" -RenderLayersObjectIndexOperation::RenderLayersObjectIndexOperation() :RenderLayersBaseProg(SCE_PASS_INDEXOB, 1) +RenderLayersObjectIndexOperation::RenderLayersObjectIndexOperation() : RenderLayersBaseProg(SCE_PASS_INDEXOB, 1) { this->addOutputSocket(COM_DT_VALUE); } diff --git a/source/blender/compositor/operations/COM_RenderLayersReflectionOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersReflectionOperation.cpp index e53144d3501..1fbd599235b 100644 --- a/source/blender/compositor/operations/COM_RenderLayersReflectionOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersReflectionOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersReflectionOperation.h" -RenderLayersReflectionOperation::RenderLayersReflectionOperation() :RenderLayersBaseProg(SCE_PASS_REFLECT, 3) +RenderLayersReflectionOperation::RenderLayersReflectionOperation() : RenderLayersBaseProg(SCE_PASS_REFLECT, 3) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersRefractionOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersRefractionOperation.cpp index 6e333175220..2ec9be46059 100644 --- a/source/blender/compositor/operations/COM_RenderLayersRefractionOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersRefractionOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersRefractionOperation.h" -RenderLayersRefractionOperation::RenderLayersRefractionOperation() :RenderLayersBaseProg(SCE_PASS_REFRACT, 3) +RenderLayersRefractionOperation::RenderLayersRefractionOperation() : RenderLayersBaseProg(SCE_PASS_REFRACT, 3) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersShadowOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersShadowOperation.cpp index ce492d54a79..7582e010e2c 100644 --- a/source/blender/compositor/operations/COM_RenderLayersShadowOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersShadowOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersShadowOperation.h" -RenderLayersShadowOperation::RenderLayersShadowOperation() :RenderLayersBaseProg(SCE_PASS_SHADOW, 3) +RenderLayersShadowOperation::RenderLayersShadowOperation() : RenderLayersBaseProg(SCE_PASS_SHADOW, 3) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersSpecularOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersSpecularOperation.cpp index 7b7d223680c..60c1636dcda 100644 --- a/source/blender/compositor/operations/COM_RenderLayersSpecularOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersSpecularOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersSpecularOperation.h" -RenderLayersSpecularOperation::RenderLayersSpecularOperation() :RenderLayersBaseProg(SCE_PASS_SPEC, 3) +RenderLayersSpecularOperation::RenderLayersSpecularOperation() : RenderLayersBaseProg(SCE_PASS_SPEC, 3) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersSpeedOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersSpeedOperation.cpp index 213d044a9bd..5a0662d13eb 100644 --- a/source/blender/compositor/operations/COM_RenderLayersSpeedOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersSpeedOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersSpeedOperation.h" -RenderLayersSpeedOperation::RenderLayersSpeedOperation() :RenderLayersBaseProg(SCE_PASS_VECTOR, 4) +RenderLayersSpeedOperation::RenderLayersSpeedOperation() : RenderLayersBaseProg(SCE_PASS_VECTOR, 4) { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_RenderLayersUVOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersUVOperation.cpp index e3917d7796b..b966f98632c 100644 --- a/source/blender/compositor/operations/COM_RenderLayersUVOperation.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersUVOperation.cpp @@ -22,7 +22,7 @@ #include "COM_RenderLayersUVOperation.h" -RenderLayersUVOperation::RenderLayersUVOperation() :RenderLayersBaseProg(SCE_PASS_UV, 3) +RenderLayersUVOperation::RenderLayersUVOperation() : RenderLayersBaseProg(SCE_PASS_UV, 3) { this->addOutputSocket(COM_DT_VECTOR); } diff --git a/source/blender/compositor/operations/COM_RotateOperation.cpp b/source/blender/compositor/operations/COM_RotateOperation.cpp index a391a26b89c..ac06048faf3 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.cpp +++ b/source/blender/compositor/operations/COM_RotateOperation.cpp @@ -38,8 +38,8 @@ void RotateOperation::initExecution() { this->imageSocket = this->getInputSocketReader(0); this->degreeSocket = this->getInputSocketReader(1); - this->centerX = this->getWidth()/2.0; - this->centerY = this->getHeight()/2.0; + this->centerX = this->getWidth() / 2.0; + this->centerY = this->getHeight() / 2.0; } void RotateOperation::deinitExecution() @@ -54,10 +54,10 @@ inline void RotateOperation::ensureDegree() { this->degreeSocket->read(degree, 0, 0, COM_PS_NEAREST, NULL); double rad; if (this->doDegree2RadConversion) { - rad = DEG2RAD((double)degree[0]); + rad = DEG2RAD((double)degree[0]); } else { - rad = degree[0]; + rad = degree[0]; } this->cosine = cos(rad); this->sine = sin(rad); @@ -67,13 +67,13 @@ inline void RotateOperation::ensureDegree() { } -void RotateOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void RotateOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { ensureDegree(); const float dy = y - this->centerY; const float dx = x - this->centerX; - const float nx = this->centerX+(this->cosine*dx + this->sine*dy); - const float ny = this->centerY+(-this->sine*dx + this->cosine*dy); + const float nx = this->centerX + (this->cosine * dx + this->sine * dy); + const float ny = this->centerY + (-this->sine * dx + this->cosine * dy); this->imageSocket->read(color, nx, ny, sampler, inputBuffers); } @@ -87,23 +87,23 @@ bool RotateOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOp const float dxmax = input->xmax - this->centerX; const float dymax = input->ymax - this->centerY; - const float x1 = this->centerX+(this->cosine*dxmin + this->sine*dymin); - const float x2 = this->centerX+(this->cosine*dxmax + this->sine*dymin); - const float x3 = this->centerX+(this->cosine*dxmin + this->sine*dymax); - const float x4 = this->centerX+(this->cosine*dxmax + this->sine*dymax); - const float y1 = this->centerY+(-this->sine*dxmin + this->cosine*dymin); - const float y2 = this->centerY+(-this->sine*dxmax + this->cosine*dymin); - const float y3 = this->centerY+(-this->sine*dxmin + this->cosine*dymax); - const float y4 = this->centerY+(-this->sine*dxmax + this->cosine*dymax); + const float x1 = this->centerX + (this->cosine * dxmin + this->sine * dymin); + const float x2 = this->centerX + (this->cosine * dxmax + this->sine * dymin); + const float x3 = this->centerX + (this->cosine * dxmin + this->sine * dymax); + const float x4 = this->centerX + (this->cosine * dxmax + this->sine * dymax); + const float y1 = this->centerY + (-this->sine * dxmin + this->cosine * dymin); + const float y2 = this->centerY + (-this->sine * dxmax + this->cosine * dymin); + const float y3 = this->centerY + (-this->sine * dxmin + this->cosine * dymax); + const float y4 = this->centerY + (-this->sine * dxmax + this->cosine * dymax); const float minx = min(x1, min(x2, min(x3, x4))); const float maxx = max(x1, max(x2, max(x3, x4))); const float miny = min(y1, min(y2, min(y3, y4))); const float maxy = max(y1, max(y2, max(y3, y4))); - newInput.xmax = ceil(maxx)+1; - newInput.xmin = floor(minx)-1; - newInput.ymax = ceil(maxy)+1; - newInput.ymin = floor(miny)-1; + newInput.xmax = ceil(maxx) + 1; + newInput.xmin = floor(minx) - 1; + newInput.ymax = ceil(maxy) + 1; + newInput.ymin = floor(miny) - 1; return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp index 4442fd9075e..3299434a02e 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp @@ -27,7 +27,7 @@ extern "C" { #include "BLI_rand.h" } -ScreenLensDistortionOperation::ScreenLensDistortionOperation(): NodeOperation() +ScreenLensDistortionOperation::ScreenLensDistortionOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); @@ -39,19 +39,19 @@ void ScreenLensDistortionOperation::initExecution() this->inputProgram = this->getInputSocketReader(0); kg = MAX2(MIN2(this->distortion, 1.f), -0.999f); // smaller dispersion range for somewhat more control - const float d = 0.25f*MAX2(MIN2(this->dispersion, 1.f), 0.f); - kr = MAX2(MIN2((kg+d), 1.f), -0.999f); - kb = MAX2(MIN2((kg-d), 1.f), -0.999f); + const float d = 0.25f * MAX2(MIN2(this->dispersion, 1.f), 0.f); + kr = MAX2(MIN2((kg + d), 1.f), -0.999f); + kb = MAX2(MIN2((kg - d), 1.f), -0.999f); maxk = MAX3(kr, kg, kb); - sc = (this->data->fit && (maxk > 0.f)) ? (1.f/(1.f + 2.f*maxk)) : (1.f/(1.f + maxk)); - drg = 4.f*(kg - kr); - dgb = 4.f*(kb - kg); + sc = (this->data->fit && (maxk > 0.f)) ? (1.f / (1.f + 2.f * maxk)) : (1.f / (1.f + maxk)); + drg = 4.f * (kg - kr); + dgb = 4.f * (kb - kg); - kr4 = kr*4; - kg4 = kg*4.f; - kb4 *= kb*4.f; - cx = 0.5f*(float)getWidth(); - cy = 0.5f*(float)getHeight(); + kr4 = kr * 4; + kg4 = kg * 4.f; + kb4 *= kb * 4.f; + cx = 0.5f * (float)getWidth(); + cy = 0.5f * (float)getHeight(); } @@ -65,28 +65,28 @@ void ScreenLensDistortionOperation::executePixel(float *outputColor, int x, int { const float height = this->getHeight(); const float width = this->getWidth(); - MemoryBuffer *buffer = (MemoryBuffer*)data; + MemoryBuffer *buffer = (MemoryBuffer *)data; int dr = 0, dg = 0, db = 0; float d, t, ln[6] = {0, 0, 0, 0, 0, 0}; float tc[4] = {0, 0, 0, 0}; - const float v = sc*((y + 0.5f) - cy)/cy; - const float u = sc*((x + 0.5f) - cx)/cx; + const float v = sc * ((y + 0.5f) - cy) / cy; + const float u = sc * ((x + 0.5f) - cx) / cx; int sta = 0, mid = 0, end = 0; - if ((t = 1.f - kr4*(u*u + v*v)) >= 0.f) { - d = 1.f/(1.f + sqrtf(t)); - ln[0] = (u*d + 0.5f)*width - 0.5f, ln[1] = (v*d + 0.5f)*height - 0.5f; + if ((t = 1.f - kr4 * (u * u + v * v)) >= 0.f) { + d = 1.f / (1.f + sqrtf(t)); + ln[0] = (u * d + 0.5f) * width - 0.5f, ln[1] = (v * d + 0.5f) * height - 0.5f; sta = 1; } - if ((t = 1.f - kg4*(u*u + v*v)) >= 0.f) { - d = 1.f/(1.f + sqrtf(t)); - ln[2] = (u*d + 0.5f)*width - 0.5f, ln[3] = (v*d + 0.5f)*height - 0.5f; + if ((t = 1.f - kg4 * (u * u + v * v)) >= 0.f) { + d = 1.f / (1.f + sqrtf(t)); + ln[2] = (u * d + 0.5f) * width - 0.5f, ln[3] = (v * d + 0.5f) * height - 0.5f; mid = 1; } - if ((t = 1.f - kb4*(u*u + v*v)) >= 0.f) { - d = 1.f/(1.f + sqrtf(t)); - ln[4] = (u*d + 0.5f)*width - 0.5f, ln[5] = (v*d + 0.5f)*height - 0.5f; + if ((t = 1.f - kb4 * (u * u + v * v)) >= 0.f) { + d = 1.f / (1.f + sqrtf(t)); + ln[4] = (u * d + 0.5f) * width - 0.5f, ln[5] = (v * d + 0.5f) * height - 0.5f; end = 1; } @@ -97,43 +97,43 @@ void ScreenLensDistortionOperation::executePixel(float *outputColor, int x, int { // RG const int dx = ln[2] - ln[0], dy = ln[3] - ln[1]; - const float dsf = sqrtf((float)dx*dx + dy*dy) + 1.f; + const float dsf = sqrtf((float)dx * dx + dy * dy) + 1.f; const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf); - const float sd = 1.f/(float)ds; + const float sd = 1.f / (float)ds; - for (z=0; zreadCubic(color, nx, ny); - tc[0] += (1.f-tz)*color[0], tc[1] += tz*color[1]; + tc[0] += (1.f - tz) * color[0], tc[1] += tz * color[1]; dr++, dg++; } } { // GB const int dx = ln[4] - ln[2], dy = ln[5] - ln[3]; - const float dsf = sqrtf((float)dx*dx + dy*dy) + 1.f; + const float dsf = sqrtf((float)dx * dx + dy * dy) + 1.f; const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf); - const float sd = 1.f/(float)ds; + const float sd = 1.f / (float)ds; - for (z=0; zreadCubic(color, nx, ny); - tc[1] += (1.f-tz)*color[1], tc[2] += tz*color[2]; + tc[1] += (1.f - tz) * color[1], tc[2] += tz * color[2]; dg++, db++; } } - if (dr) outputColor[0] = 2.f*tc[0] / (float)dr; - if (dg) outputColor[1] = 2.f*tc[1] / (float)dg; - if (db) outputColor[2] = 2.f*tc[2] / (float)db; + if (dr) outputColor[0] = 2.f * tc[0] / (float)dr; + if (dg) outputColor[1] = 2.f * tc[1] / (float)dg; + if (db) outputColor[2] = 2.f * tc[2] / (float)db; /* set alpha */ outputColor[3] = 1.0f; @@ -153,12 +153,12 @@ void ScreenLensDistortionOperation::deinitExecution() void ScreenLensDistortionOperation::determineUV(float result[2], float x, float y) const { - const float v = sc*((y + 0.5f) - cy)/cy; - const float u = sc*((x + 0.5f) - cx)/cx; - const float t = ABS(MIN3(kr, kg, kb)*4); - float d = 1.f/(1.f + sqrtf(t)); - result[0] = (u*d + 0.5f)*getWidth() - 0.5f; - result[1] = (v*d + 0.5f)*getHeight() - 0.5f; + const float v = sc * ((y + 0.5f) - cy) / cy; + const float u = sc * ((x + 0.5f) - cx) / cx; + const float t = ABS(MIN3(kr, kg, kb) * 4); + float d = 1.f / (1.f + sqrtf(t)); + result[0] = (u * d + 0.5f) * getWidth() - 0.5f; + result[1] = (v * d + 0.5f) * getHeight() - 0.5f; } bool ScreenLensDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_SeparateChannelOperation.cpp b/source/blender/compositor/operations/COM_SeparateChannelOperation.cpp index 680e1648ebd..caa1387da2a 100644 --- a/source/blender/compositor/operations/COM_SeparateChannelOperation.cpp +++ b/source/blender/compositor/operations/COM_SeparateChannelOperation.cpp @@ -39,7 +39,7 @@ void SeparateChannelOperation::deinitExecution() } -void SeparateChannelOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void SeparateChannelOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { float input[4]; this->inputOperation->read(input, x, y, sampler, inputBuffers); diff --git a/source/blender/compositor/operations/COM_SetAlphaOperation.cpp b/source/blender/compositor/operations/COM_SetAlphaOperation.cpp index 0aefb075b64..5924108ed86 100644 --- a/source/blender/compositor/operations/COM_SetAlphaOperation.cpp +++ b/source/blender/compositor/operations/COM_SetAlphaOperation.cpp @@ -22,7 +22,7 @@ #include "COM_SetAlphaOperation.h" -SetAlphaOperation::SetAlphaOperation(): NodeOperation() +SetAlphaOperation::SetAlphaOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_SetColorOperation.cpp b/source/blender/compositor/operations/COM_SetColorOperation.cpp index 50ff2a87a72..5307d7abc24 100644 --- a/source/blender/compositor/operations/COM_SetColorOperation.cpp +++ b/source/blender/compositor/operations/COM_SetColorOperation.cpp @@ -22,7 +22,7 @@ #include "COM_SetColorOperation.h" -SetColorOperation::SetColorOperation(): NodeOperation() +SetColorOperation::SetColorOperation() : NodeOperation() { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.cpp b/source/blender/compositor/operations/COM_SetSamplerOperation.cpp index 8974554e700..dfe7fe91bf8 100644 --- a/source/blender/compositor/operations/COM_SetSamplerOperation.cpp +++ b/source/blender/compositor/operations/COM_SetSamplerOperation.cpp @@ -22,7 +22,7 @@ #include "COM_SetSamplerOperation.h" -SetSamplerOperation::SetSamplerOperation(): NodeOperation() +SetSamplerOperation::SetSamplerOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_SetValueOperation.cpp b/source/blender/compositor/operations/COM_SetValueOperation.cpp index abd4acafea6..483fcc97a1f 100644 --- a/source/blender/compositor/operations/COM_SetValueOperation.cpp +++ b/source/blender/compositor/operations/COM_SetValueOperation.cpp @@ -22,7 +22,7 @@ #include "COM_SetValueOperation.h" -SetValueOperation::SetValueOperation(): NodeOperation() +SetValueOperation::SetValueOperation() : NodeOperation() { this->addOutputSocket(COM_DT_VALUE); } diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.cpp b/source/blender/compositor/operations/COM_SetVectorOperation.cpp index 79c0201733e..3d15a184c4e 100644 --- a/source/blender/compositor/operations/COM_SetVectorOperation.cpp +++ b/source/blender/compositor/operations/COM_SetVectorOperation.cpp @@ -23,7 +23,7 @@ #include "COM_SetVectorOperation.h" #include "COM_defines.h" -SetVectorOperation::SetVectorOperation(): NodeOperation() +SetVectorOperation::SetVectorOperation() : NodeOperation() { this->addOutputSocket(COM_DT_VECTOR); } diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp index 5f86d6bd7c7..55c4b68ee57 100644 --- a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp +++ b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp @@ -39,7 +39,7 @@ void SocketProxyOperation::deinitExecution() this->inputOperation = NULL; } -void SocketProxyOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void SocketProxyOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { if (this->inputOperation) { this->inputOperation->read(color, x, y, sampler, inputBuffers); diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp index 0d85f71c691..072528f3fc6 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.cpp +++ b/source/blender/compositor/operations/COM_TextureOperation.cpp @@ -25,10 +25,10 @@ #include "BLI_listbase.h" #include "DNA_scene_types.h" -TextureBaseOperation::TextureBaseOperation(): NodeOperation() +TextureBaseOperation::TextureBaseOperation() : NodeOperation() { - this->addInputSocket(COM_DT_VECTOR);//offset - this->addInputSocket(COM_DT_VECTOR);//size + this->addInputSocket(COM_DT_VECTOR); //offset + this->addInputSocket(COM_DT_VECTOR); //size this->texture = NULL; this->inputSize = NULL; this->inputOffset = NULL; @@ -57,8 +57,8 @@ void TextureBaseOperation::deinitExecution() void TextureBaseOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { if (preferredResolution[0] == 0 || preferredResolution[1] == 0) { - int width = this->scene->r.xsch*this->scene->r.size/100; - int height = this->scene->r.ysch*this->scene->r.size/100; + int width = this->scene->r.xsch * this->scene->r.size / 100; + int height = this->scene->r.ysch * this->scene->r.size / 100; resolution[0] = width; resolution[1] = height; } @@ -79,22 +79,22 @@ void TextureAlphaOperation::executePixel(float *color, float x, float y, PixelSa void TextureBaseOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { - TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; + TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; float textureSize[4]; float textureOffset[4]; float vec[3]; int retval; - const float cx = this->getWidth()/2; - const float cy = this->getHeight()/2; - const float u = (cx-x)/this->getWidth()*2; - const float v = (cy-y)/this->getHeight()*2; + const float cx = this->getWidth() / 2; + const float cy = this->getHeight() / 2; + const float u = (cx - x) / this->getWidth() * 2; + const float v = (cy - y) / this->getHeight() * 2; this->inputSize->read(textureSize, x, y, sampler, inputBuffers); this->inputOffset->read(textureOffset, x, y, sampler, inputBuffers); - vec[0] = textureSize[0]*(u + textureOffset[0]); - vec[1] = textureSize[1]*(v + textureOffset[1]); - vec[2] = textureSize[2]*textureOffset[2]; + vec[0] = textureSize[0] * (u + textureOffset[0]); + vec[1] = textureSize[1] * (v + textureOffset[1]); + vec[2] = textureSize[2] * textureOffset[2]; retval = multitex_ext(this->texture, vec, NULL, NULL, 0, &texres); diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cpp b/source/blender/compositor/operations/COM_TonemapOperation.cpp index 412cdbdf661..7b978e0f87c 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.cpp +++ b/source/blender/compositor/operations/COM_TonemapOperation.cpp @@ -26,7 +26,7 @@ -TonemapOperation::TonemapOperation(): NodeOperation() +TonemapOperation::TonemapOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->addOutputSocket(COM_DT_COLOR); @@ -41,9 +41,9 @@ void TonemapOperation::initExecution() NodeOperation::initMutex(); } -void TonemapOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data) +void TonemapOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { - AvgLogLum * avg = (AvgLogLum*)data; + AvgLogLum *avg = (AvgLogLum *)data; float output[4]; this->imageReader->read(output, x, y, inputBuffers, NULL); @@ -120,10 +120,10 @@ void *TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuff { lockMutex(); if (this->cachedInstance == NULL) { - MemoryBuffer *tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); + MemoryBuffer *tile = (MemoryBuffer *)imageReader->initializeTileData(rect, memoryBuffers); AvgLogLum *data = new AvgLogLum(); - float * buffer = tile->getBuffer(); + float *buffer = tile->getBuffer(); float lsum = 0.0f; int p = tile->getWidth() * tile->getHeight(); @@ -131,7 +131,7 @@ void *TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuff float avl, maxl = -1e10f, minl = 1e10f; const float sc = 1.0f / p; float Lav = 0.f; - float cav[4] = {0.0f,0.0f,0.0f,0.0f}; + float cav[4] = {0.0f, 0.0f, 0.0f, 0.0f}; while (p--) { float L = rgb_to_luma_y(bc); Lav += L; @@ -139,7 +139,7 @@ void *TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuff lsum += logf(MAX2(L, 0.0f) + 1e-5f); maxl = (L > maxl) ? L : maxl; minl = (L < minl) ? L : minl; - bc+=4; + bc += 4; } data->lav = Lav * sc; mul_v3_v3fl(data->cav, cav, sc); @@ -147,7 +147,7 @@ void *TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuff data->auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.f; float al = exp((double)avl); data->al = (al == 0.f) ? 0.f : (this->data->key / al); - data->igm = (this->data->gamma==0.f) ? 1 : (1.f / this->data->gamma); + data->igm = (this->data->gamma == 0.f) ? 1 : (1.f / this->data->gamma); this->cachedInstance = data; } unlockMutex(); diff --git a/source/blender/compositor/operations/COM_TranslateOperation.cpp b/source/blender/compositor/operations/COM_TranslateOperation.cpp index b9b06d6d356..c41e2c7f156 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.cpp +++ b/source/blender/compositor/operations/COM_TranslateOperation.cpp @@ -50,10 +50,10 @@ void TranslateOperation::deinitExecution() } -void TranslateOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void TranslateOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { ensureDelta(); - this->inputOperation->read(color, x-this->getDeltaX(), y-this->getDeltaY(), sampler, inputBuffers); + this->inputOperation->read(color, x - this->getDeltaX(), y - this->getDeltaY(), sampler, inputBuffers); } bool TranslateOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.cpp b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp index e9045b126e2..3173599ece6 100644 --- a/source/blender/compositor/operations/COM_VectorCurveOperation.cpp +++ b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp @@ -30,7 +30,7 @@ extern "C" { } #endif -VectorCurveOperation::VectorCurveOperation(): CurveBaseOperation() +VectorCurveOperation::VectorCurveOperation() : CurveBaseOperation() { this->addInputSocket(COM_DT_VECTOR); this->addOutputSocket(COM_DT_VECTOR); diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index 087ab50cf47..e1018e0d037 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -24,7 +24,7 @@ #include "COM_defines.h" #include -WriteBufferOperation::WriteBufferOperation() :NodeOperation() +WriteBufferOperation::WriteBufferOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->memoryProxy = new MemoryProxy(); @@ -56,7 +56,7 @@ void WriteBufferOperation::deinitExecution() this->memoryProxy->free(); } -void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) +void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers) { //MemoryBuffer *memoryBuffer = MemoryManager::getMemoryBuffer(this->getMemoryProxy(), tileNumber); MemoryBuffer *memoryBuffer = this->memoryProxy->getBuffer(); @@ -70,11 +70,11 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me int x; int y; bool breaked = false; - for (y = y1 ; y < y2 && (!breaked) ; y++) { - int offset4 = (y*memoryBuffer->getWidth()+x1)*COM_NUMBER_OF_CHANNELS; - for (x = x1 ; x < x2; x++) { + for (y = y1; y < y2 && (!breaked); y++) { + int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS; + for (x = x1; x < x2; x++) { input->read(&(buffer[offset4]), x, y, memoryBuffers, data); - offset4 +=COM_NUMBER_OF_CHANNELS; + offset4 += COM_NUMBER_OF_CHANNELS; } if (isBreaked()) { @@ -96,11 +96,11 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me int x; int y; bool breaked = false; - for (y = y1 ; y < y2 && (!breaked) ; y++) { - int offset4 = (y*memoryBuffer->getWidth()+x1)*COM_NUMBER_OF_CHANNELS; - for (x = x1 ; x < x2 ; x++) { + for (y = y1; y < y2 && (!breaked); y++) { + int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS; + for (x = x1; x < x2; x++) { input->read(&(buffer[offset4]), x, y, COM_PS_NEAREST, memoryBuffers); - offset4 +=COM_NUMBER_OF_CHANNELS; + offset4 += COM_NUMBER_OF_CHANNELS; } if (isBreaked()) { breaked = true; @@ -110,7 +110,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me memoryBuffer->setCreatedState(); } -void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** inputMemoryBuffers, MemoryBuffer* outputBuffer) +void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer **inputMemoryBuffers, MemoryBuffer *outputBuffer) { float *outputFloatBuffer = outputBuffer->getBuffer(); cl_int error; @@ -131,11 +131,11 @@ void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program pr CL_FLOAT }; - cl_mem clOutputBuffer = clCreateImage2D(context, CL_MEM_WRITE_ONLY|CL_MEM_USE_HOST_PTR, &imageFormat, outputBufferWidth, outputBufferHeight, 0, outputFloatBuffer, &error); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + cl_mem clOutputBuffer = clCreateImage2D(context, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, &imageFormat, outputBufferWidth, outputBufferHeight, 0, outputFloatBuffer, &error); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } // STEP 2 - list * clMemToCleanUp = new list(); + list *clMemToCleanUp = new list(); clMemToCleanUp->push_back(clOutputBuffer); list *clKernelsToCleanUp = new list(); @@ -143,40 +143,40 @@ void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program pr // STEP 3 - size_t origin[3] = {0,0,0}; - size_t region[3] = {outputBufferWidth,outputBufferHeight,1}; + size_t origin[3] = {0, 0, 0}; + size_t region[3] = {outputBufferWidth, outputBufferHeight, 1}; // clFlush(queue); // clFinish(queue); error = clEnqueueBarrier(queue); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } error = clEnqueueReadImage(queue, clOutputBuffer, CL_TRUE, origin, region, 0, 0, outputFloatBuffer, 0, NULL, NULL); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } this->getMemoryProxy()->getBuffer()->copyContentFrom(outputBuffer); // STEP 4 - while (clMemToCleanUp->size()>0) { + while (clMemToCleanUp->size() > 0) { cl_mem mem = clMemToCleanUp->front(); error = clReleaseMemObject(mem); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } clMemToCleanUp->pop_front(); } - while (clKernelsToCleanUp->size()>0) { + while (clKernelsToCleanUp->size() > 0) { cl_kernel kernel = clKernelsToCleanUp->front(); error = clReleaseKernel(kernel); - if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } clKernelsToCleanUp->pop_front(); } delete clKernelsToCleanUp; } void WriteBufferOperation::readResolutionFromInputSocket() { - NodeOperation* inputOperation = this->getInputOperation(0); + NodeOperation *inputOperation = this->getInputOperation(0); this->setWidth(inputOperation->getWidth()); this->setHeight(inputOperation->getHeight()); } diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.cpp b/source/blender/compositor/operations/COM_ZCombineOperation.cpp index 7f32bac2e64..eb02b150fa4 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.cpp +++ b/source/blender/compositor/operations/COM_ZCombineOperation.cpp @@ -23,7 +23,7 @@ #include "COM_ZCombineOperation.h" #include "BLI_utildefines.h" -ZCombineOperation::ZCombineOperation(): NodeOperation() +ZCombineOperation::ZCombineOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); @@ -53,7 +53,7 @@ void ZCombineOperation::executePixel(float *color, float x, float y, PixelSample this->depth1Reader->read(depth1, x, y, sampler, inputBuffers); this->depth2Reader->read(depth2, x, y, sampler, inputBuffers); - if (depth1[0]image1Reader->read(color, x, y, sampler, inputBuffers); } else { @@ -69,7 +69,7 @@ void ZCombineAlphaOperation::executePixel(float *color, float x, float y, PixelS this->depth1Reader->read(depth1, x, y, sampler, inputBuffers); this->depth2Reader->read(depth2, x, y, sampler, inputBuffers); - if (depth1[0]image1Reader->read(color1, x, y, sampler, inputBuffers); this->image2Reader->read(color2, x, y, sampler, inputBuffers); } @@ -78,10 +78,10 @@ void ZCombineAlphaOperation::executePixel(float *color, float x, float y, PixelS this->image2Reader->read(color1, x, y, sampler, inputBuffers); } float fac = color1[3]; - float ifac = 1.0f-fac; - color[0] = color1[0]+ifac*color2[0]; - color[1] = color1[1]+ifac*color2[1]; - color[2] = color1[2]+ifac*color2[2]; + float ifac = 1.0f - fac; + color[0] = color1[0] + ifac * color2[0]; + color[1] = color1[1] + ifac * color2[1]; + color[2] = color1[2] + ifac * color2[2]; color[3] = MAX2(color1[3], color2[3]); } From 606d76f07d99637c79d31efbdf28f4e32e8a91a4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 20:59:00 +0000 Subject: [PATCH 359/360] fix for building blender as a python module on windows. --- intern/ghost/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 277b14e2c66..e52ac0af2ed 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -143,6 +143,7 @@ if(WITH_HEADLESS OR WITH_GHOST_SDL) intern/GHOST_SystemPathsCarbon.h ) endif() + elseif(UNIX) list(APPEND SRC intern/GHOST_SystemPathsX11.cpp @@ -152,13 +153,17 @@ if(WITH_HEADLESS OR WITH_GHOST_SDL) if(NOT WITH_INSTALL_PORTABLE) add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}") endif() - elseif(WIN32) + elseif(WIN32) list(APPEND SRC intern/GHOST_SystemPathsWin32.cpp intern/GHOST_SystemPathsWin32.h ) + + list(APPEND INC + ../utfconv + ) endif() if(NOT WITH_HEADLESS) From a2d4fddfd38ce0795d21ec9c5b5cc51fc50f3bd1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Jun 2012 21:19:05 +0000 Subject: [PATCH 360/360] fix for running blender as a python module - dont parse args from python. --- source/creator/creator.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/source/creator/creator.c b/source/creator/creator.c index 0cdbeb940b8..51846c8936e 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -145,8 +145,10 @@ extern char build_system[]; #endif /* Local Function prototypes */ +#ifndef WITH_PYTHON_MODULE static int print_help(int argc, const char **argv, void *data); static int print_version(int argc, const char **argv, void *data); +#endif /* for the callbacks: */ @@ -157,6 +159,8 @@ static int print_version(int argc, const char **argv, void *data); /* Initialize callbacks for the modules that need them */ static void setCallbacks(void); +#ifndef WITH_PYTHON_MODULE + /* set breakpoints here when running in debug mode, useful to catch floating point errors */ #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE) static void fpe_handler(int UNUSED(sig)) @@ -165,7 +169,6 @@ static void fpe_handler(int UNUSED(sig)) } #endif -#ifndef WITH_PYTHON_MODULE /* handling ctrl-c event in console */ static void blender_esc(int sig) { @@ -182,7 +185,6 @@ static void blender_esc(int sig) count++; } } -#endif static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) { @@ -972,7 +974,6 @@ static int set_addons(int argc, const char **argv, void *data) } } - static int load_file(int UNUSED(argc), const char **argv, void *data) { bContext *C = data; @@ -1171,6 +1172,7 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) BLI_argsAdd(ba, 4, "-x", "--use-extension", "\n\tSet option to add the file extension to the end of the file", set_extension, C); } +#endif /* WITH_PYTHON_MODULE */ #ifdef WITH_PYTHON_MODULE /* allow python module to call main */ @@ -1191,9 +1193,12 @@ int main(int argc, const char **UNUSED(argv_c)) /* Do not mess with const */ int main(int argc, const char **argv) #endif { - SYS_SystemHandle syshandle; bContext *C = CTX_create(); + SYS_SystemHandle syshandle; + +#ifndef WITH_PYTHON_MODULE bArgs *ba; +#endif #ifdef WIN32 wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc); @@ -1268,10 +1273,12 @@ int main(int argc, const char **argv) #endif /* first test for background */ +#ifndef WITH_PYTHON_MODULE ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */ setupArguments(C, ba, &syshandle); BLI_argsParse(ba, 1, NULL, NULL); +#endif #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS) G.background = 1; /* python module mode ALWAYS runs in background mode (for now) */ @@ -1290,9 +1297,10 @@ int main(int argc, const char **argv) init_def_material(); if (G.background == 0) { +#ifndef WITH_PYTHON_MODULE BLI_argsParse(ba, 2, NULL, NULL); BLI_argsParse(ba, 3, NULL, NULL); - +#endif WM_init(C, argc, (const char **)argv); /* this is properly initialized with user defs, but this is default */ @@ -1304,7 +1312,9 @@ int main(int argc, const char **argv) #endif } else { +#ifndef WITH_PYTHON_MODULE BLI_argsParse(ba, 3, NULL, NULL); +#endif WM_init(C, argc, (const char **)argv); @@ -1328,9 +1338,13 @@ int main(int argc, const char **argv) WM_keymap_init(C); /* OK we are ready for it */ +#ifndef WITH_PYTHON_MODULE BLI_argsParse(ba, 4, load_file, C); +#endif +#ifndef WITH_PYTHON_MODULE BLI_argsFree(ba); +#endif #ifdef WIN32 while (argci) {